From bc5e7349ef9476238c0c7e5d12b244ff2e84859b Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 14 Dec 2019 00:44:41 +1100 Subject: [PATCH] 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. --- app/widget/timelinewidget/tool/pointer.cpp | 86 ++++++++++++++----- .../view/timelineviewblockitem.cpp | 2 +- .../view/timelineviewghostitem.cpp | 8 ++ .../view/timelineviewghostitem.h | 2 + 4 files changed, 77 insertions(+), 21 deletions(-) diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index 6b3a38fb0..91da510c3 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -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;ighost_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(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(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(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;ighost_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(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 clips = parent()->GetSelectedBlocks(); @@ -432,8 +478,8 @@ void TimelineWidget::PointerTool::AddGhostInternal(TimelineViewGhostItem* ghost, } bool TimelineWidget::PointerTool::IsClipTrimmable(TimelineViewBlockItem* clip, - const QList& items, - const olive::timeline::MovementMode& mode) + const QList& 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 ghosts, - bool prevent_overwriting) + const QVector 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 ghosts, - bool prevent_overwriting) + const QVector ghosts, + bool prevent_overwriting) { foreach (TimelineViewGhostItem* ghost, ghosts) { if (ghost->mode() != olive::timeline::kTrimOut) { diff --git a/app/widget/timelinewidget/view/timelineviewblockitem.cpp b/app/widget/timelinewidget/view/timelineviewblockitem.cpp index 649aa6eef..571499a45 100644 --- a/app/widget/timelinewidget/view/timelineviewblockitem.cpp +++ b/app/widget/timelinewidget/view/timelineviewblockitem.cpp @@ -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: diff --git a/app/widget/timelinewidget/view/timelineviewghostitem.cpp b/app/widget/timelinewidget/view/timelineviewghostitem.cpp index 982232348..f69f58081 100644 --- a/app/widget/timelinewidget/view/timelineviewghostitem.cpp +++ b/app/widget/timelinewidget/view/timelineviewghostitem.cpp @@ -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(); diff --git a/app/widget/timelinewidget/view/timelineviewghostitem.h b/app/widget/timelinewidget/view/timelineviewghostitem.h index 95f99e69f..372311fc8 100644 --- a/app/widget/timelinewidget/view/timelineviewghostitem.h +++ b/app/widget/timelinewidget/view/timelineviewghostitem.h @@ -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: