don't automatically create gaps if one already exists that can be resized

Rather than constantly create gaps, we can more intelligently determine whether
a gap can be extended to take the place of a block being removed, etc.
This commit is contained in:
itsmattkc
2019-12-14 00:44:41 +11:00
parent 323718bc11
commit bc5e7349ef
4 changed files with 77 additions and 21 deletions
+66 -20
View File
@@ -163,26 +163,72 @@ void TimelineWidget::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *e
// Since all the ghosts will be leaving their old position in some way, we replace all of them with gaps here so the
// entire timeline isn't disrupted in the process
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
for (int i=0;i<parent()->ghost_items_.size();i++) {
TimelineViewGhostItem* ghost = parent()->ghost_items_.at(i);
// If the ghost has not been adjusted nothing needs to be done
if (!ghost->HasBeenAdjusted()) {
continue;
}
Block* b = Node::ValueToPtr<Block>(ghost->data(TimelineViewGhostItem::kAttachedBlock));
// Replace old Block with a new Gap
GapBlock* gap = new GapBlock();
gap->set_length(b->length());
bool previous_is_gap = (b->previous() && b->previous()->type() == Block::kGap);
bool next_is_gap = (b->next() && b->next()->type() == Block::kGap);
new NodeAddCommand(static_cast<NodeGraph*>(b->parent()),
gap,
command);
TrackOutput* original_track = parent()->GetTrackFromReference(ghost->Track());
new TrackReplaceBlockCommand(parent()->GetTrackFromReference(ghost->Track()),
b,
gap,
command);
if (!previous_is_gap && !next_is_gap) {
// Make new gap and replace old Block with it for now
GapBlock* gap = new GapBlock();
gap->set_length(b->length());
new NodeAddCommand(static_cast<NodeGraph*>(b->parent()),
gap,
command);
new TrackReplaceBlockCommand(original_track,
b,
gap,
command);
} else {
// Remove the block from the track (this does NOT remove the block from the graph however)
new TrackRippleRemoveBlockCommand(original_track,
b,
command);
if (previous_is_gap && next_is_gap) {
// Clip is surrounded by gaps, merge both together
// Remove one of the gaps
new TrackRippleRemoveBlockCommand(original_track,
b->next(),
command);
// Resize the other to match both
new BlockResizeCommand(b->previous(),
b->previous()->length() + b->length() + b->next()->length(),
command);
} else {
// Resize the surrounding block to take its place
Block* gap_to_resize = previous_is_gap ? b->previous() : b->next();
new BlockResizeCommand(gap_to_resize,
gap_to_resize->length() + b->length(),
command);
}
}
}
// Now we place the clips back in the timeline where the user moved them. It's legal for them to overwrite parts or
// all of the gaps we inserted earlier
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
for (int i=0;i<parent()->ghost_items_.size();i++) {
TimelineViewGhostItem* ghost = parent()->ghost_items_.at(i);
// If the ghost has not been adjusted nothing needs to be done
if (!ghost->HasBeenAdjusted()) {
continue;
}
Block* b = Node::ValueToPtr<Block>(ghost->data(TimelineViewGhostItem::kAttachedBlock));
// Normal blocks work in conjunction with the gap made above
@@ -330,8 +376,8 @@ void TimelineWidget::PointerTool::ProcessDrag(const TimelineCoordinate &mouse_po
}
void TimelineWidget::PointerTool::InitiateGhosts(TimelineViewBlockItem* clicked_item,
olive::timeline::MovementMode trim_mode,
bool allow_gap_trimming)
olive::timeline::MovementMode trim_mode,
bool allow_gap_trimming)
{
// Convert selected items list to clips list
QList<TimelineViewBlockItem*> clips = parent()->GetSelectedBlocks();
@@ -432,8 +478,8 @@ void TimelineWidget::PointerTool::AddGhostInternal(TimelineViewGhostItem* ghost,
}
bool TimelineWidget::PointerTool::IsClipTrimmable(TimelineViewBlockItem* clip,
const QList<TimelineViewBlockItem*>& items,
const olive::timeline::MovementMode& mode)
const QList<TimelineViewBlockItem*>& items,
const olive::timeline::MovementMode& mode)
{
foreach (TimelineViewBlockItem* compare, items) {
if (clip->Track() == compare->Track()
@@ -448,8 +494,8 @@ bool TimelineWidget::PointerTool::IsClipTrimmable(TimelineViewBlockItem* clip,
}
rational TimelineWidget::PointerTool::ValidateInTrimming(rational movement,
const QVector<TimelineViewGhostItem *> ghosts,
bool prevent_overwriting)
const QVector<TimelineViewGhostItem *> ghosts,
bool prevent_overwriting)
{
foreach (TimelineViewGhostItem* ghost, ghosts) {
if (ghost->mode() != olive::timeline::kTrimIn) {
@@ -493,8 +539,8 @@ rational TimelineWidget::PointerTool::ValidateInTrimming(rational movement,
}
rational TimelineWidget::PointerTool::ValidateOutTrimming(rational movement,
const QVector<TimelineViewGhostItem *> ghosts,
bool prevent_overwriting)
const QVector<TimelineViewGhostItem *> ghosts,
bool prevent_overwriting)
{
foreach (TimelineViewGhostItem* ghost, ghosts) {
if (ghost->mode() != olive::timeline::kTrimOut) {
@@ -122,7 +122,7 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
case Block::kGap:
if (option->state & QStyle::State_Selected) {
// FIXME: Make this palette or CSS
painter->fillRect(rect(), Qt::white);
painter->fillRect(rect(), QColor(255, 255, 255, 128));
}
break;
case Block::kTransition:
@@ -184,6 +184,14 @@ void TimelineViewGhostItem::SetMode(const olive::timeline::MovementMode &mode)
mode_ = mode;
}
bool TimelineViewGhostItem::HasBeenAdjusted() const
{
return InAdjustment() != 0
|| OutAdjustment() != 0
|| MediaInAdjustment() != 0
|| TrackAdjustment() != 0;
}
void TimelineViewGhostItem::UpdateRect()
{
rational length = GetAdjustedOut() - GetAdjustedIn();
@@ -77,6 +77,8 @@ public:
const olive::timeline::MovementMode& mode() const;
void SetMode(const olive::timeline::MovementMode& mode);
bool HasBeenAdjusted() const;
virtual void UpdateRect() override;
protected: