diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index e300daff8..76a2ae157 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -497,11 +497,6 @@ bool TimelineWidget::PointerTool::IsClipTrimmable(TimelineViewBlockItem* clip, return true; } -rational GetEarliestPointForClip(Block* block) -{ - return qMax(rational(0), block->in() - block->media_in()); -} - rational TimelineWidget::PointerTool::ValidateInTrimming(rational movement, const QVector ghosts, bool prevent_overwriting) @@ -516,41 +511,43 @@ rational TimelineWidget::PointerTool::ValidateInTrimming(rational movement, rational earliest_in = RATIONAL_MIN; rational latest_in = ghost->Out(); - if (block->type() == Block::kTransition) { - // For transitions, validate with the attached block - TransitionBlock* transition = static_cast(block); - - if (transition->connected_in_block() && transition->connected_out_block()) { - // Here, we try to get the latest earliest point for both the in and out blocks, we do in here and out will - // be calculated later - earliest_in = GetEarliestPointForClip(transition->connected_in_block()); - - // We set the block to the out block since that will be before the in block and will be the one we use to - // prevent overwriting since we're trimming the in side of this transition - block = transition->connected_out_block(); - - latest_in = transition->in() + transition->out_offset(); - } else { - // Use whatever block is attached - block = transition->connected_in_block() ? transition->connected_in_block() : transition->connected_out_block(); - } - } - - earliest_in = qMax(earliest_in, GetEarliestPointForClip(block)); - if (!ghost->CanHaveZeroLength()) { latest_in -= parent()->timebase(); } - if (prevent_overwriting) { - // Look for a Block in the way - Block* prev = block->previous(); - while (prev != nullptr) { - if (prev->type() == Block::kClip) { - earliest_in = qMax(earliest_in, prev->out()); - break; + if (block) { + /* FIXME: Rewrite transition logic + if (block->type() == Block::kTransition) { + // For transitions, validate with the attached block + TransitionBlock* transition = static_cast(block); + + if (transition->connected_in_block() && transition->connected_out_block()) { + // Here, we try to get the latest earliest point for both the in and out blocks, we do in here and out will + // be calculated later + earliest_in = GetEarliestPointForClip(transition->connected_in_block()); + + // We set the block to the out block since that will be before the in block and will be the one we use to + // prevent overwriting since we're trimming the in side of this transition + block = transition->connected_out_block(); + + latest_in = transition->in() + transition->out_offset(); + } else { + // Use whatever block is attached + block = transition->connected_in_block() ? transition->connected_in_block() : transition->connected_out_block(); + } + } + */ + + if (prevent_overwriting) { + // Look for a Block in the way + Block* prev = block->previous(); + while (prev != nullptr) { + if (prev->type() == Block::kClip) { + earliest_in = qMax(earliest_in, prev->out()); + break; + } + prev = prev->previous(); } - prev = prev->previous(); } } @@ -586,33 +583,38 @@ rational TimelineWidget::PointerTool::ValidateOutTrimming(rational movement, rational latest_out = RATIONAL_MAX; - if (block->type() == Block::kTransition) { - // For transitions, validate with the attached block - TransitionBlock* transition = static_cast(block); + // Ripple tool creates block-less ghosts and creates gaps with them later + if (block) { + /* FIXME: Rewrite transition logic + if (block->type() == Block::kTransition) { + // For transitions, validate with the attached block + TransitionBlock* transition = static_cast(block); - if (transition->connected_in_block() && transition->connected_out_block()) { - // We set the block to the out block since that will be before the in block and will be the one we use to - // prevent overwriting since we're trimming the in side of this transition + if (transition->connected_in_block() && transition->connected_out_block()) { + // We set the block to the out block since that will be before the in block and will be the one we use to + // prevent overwriting since we're trimming the in side of this transition - // FIXME: At some point we may add some better logic to `latest_out` akin to the logic in ValidateInTrimming - // which is why this hasn't yet been collapsed into the ternary below. - block = transition->connected_in_block(); + // FIXME: At some point we may add some better logic to `latest_out` akin to the logic in ValidateInTrimming + // which is why this hasn't yet been collapsed into the ternary below. + block = transition->connected_in_block(); - earliest_out = transition->out() - transition->in_offset(); - } else { - block = transition->connected_in_block() ? transition->connected_in_block() : transition->connected_out_block(); + earliest_out = transition->out() - transition->in_offset(); + } else { + block = transition->connected_in_block() ? transition->connected_in_block() : transition->connected_out_block(); + } } - } + */ - if (prevent_overwriting) { - // Determine if there's a block in the way - Block* next = block->next(); - while (next != nullptr) { - if (next->type() == Block::kClip) { - latest_out = qMin(latest_out, next->in()); - break; + if (prevent_overwriting) { + // Determine if there's a block in the way + Block* next = block->next(); + while (next != nullptr) { + if (next->type() == Block::kClip) { + latest_out = qMin(latest_out, next->in()); + break; + } + next = next->next(); } - next = next->next(); } } diff --git a/app/widget/timelinewidget/tool/ripple.cpp b/app/widget/timelinewidget/tool/ripple.cpp index ed441b5de..9fb88ff40 100644 --- a/app/widget/timelinewidget/tool/ripple.cpp +++ b/app/widget/timelinewidget/tool/ripple.cpp @@ -87,13 +87,18 @@ void TimelineWidget::RippleTool::InitiateDrag(TimelineViewBlockItem *clicked_ite if (block_before_ripple->type() == Block::kGap) { // If this Block is already a Gap, ghost it now ghost = AddGhostFromBlock(block_before_ripple, track_ref, trim_mode); - } else { - // If there's no gap here, we'll need to create one - ghost = AddGhostFromNull(block_before_ripple->out(), block_before_ripple->out(), track_ref, trim_mode); - ghost->setData(TimelineViewGhostItem::kReferenceBlock, Node::PtrToValue(block_before_ripple)); - } + } else if (block_before_ripple->next()) { + // Assuming this block is NOT at the end of the track (i.e. next != null) - ghost->SetInvisible(true); + // We're going to create a gap after it. If next is a gap, we can just use that + if (block_before_ripple->next()->type() == Block::kGap) { + ghost = AddGhostFromBlock(block_before_ripple->next(), track_ref, trim_mode); + } else { + // If next is NOT a gap, we'll need to create one, for which we'll use a null ghost + ghost = AddGhostFromNull(block_before_ripple->out(), block_before_ripple->out(), track_ref, trim_mode); + ghost->setData(TimelineViewGhostItem::kReferenceBlock, Node::PtrToValue(block_before_ripple)); + } + } } } } diff --git a/app/widget/timelinewidget/undo/undo.cpp b/app/widget/timelinewidget/undo/undo.cpp index 9c46b09ca..9b03b5bec 100644 --- a/app/widget/timelinewidget/undo/undo.cpp +++ b/app/widget/timelinewidget/undo/undo.cpp @@ -1398,8 +1398,12 @@ void TrackListRippleToolCommand::redo_internal() const RippleInfo& info = info_.at(i); if (info.block) { - new_latest_pt = qMax(new_latest_pt, info.block->out()); - } else { + if (info.new_length > 0) { + new_latest_pt = qMax(new_latest_pt, info.block->out()); + } else { + new_latest_pt = qMax(new_latest_pt, info.block->in()); + } + } else if (info.new_length > 0) { new_latest_pt = qMax(new_latest_pt, working_data_.at(i).created_gap->out()); } } @@ -1427,6 +1431,8 @@ void TrackListRippleToolCommand::redo_internal() void TrackListRippleToolCommand::undo_internal() { + // FIXME: Add cache shift optimization + // Clean created gaps for (int i=info_.size()-1; i>=0; i--) { const RippleInfo& info = info_.at(i);