timeline: fixed some ripple tool behavior bugs

This commit is contained in:
itsmattkc
2020-07-07 18:06:49 +10:00
parent 6c3313721b
commit a239fa0e2f
3 changed files with 77 additions and 64 deletions
+58 -56
View File
@@ -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<TimelineViewGhostItem *> 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<TransitionBlock*>(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<TransitionBlock*>(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<TransitionBlock*>(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<TransitionBlock*>(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();
}
}
+11 -6
View File
@@ -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));
}
}
}
}
}
+8 -2
View File
@@ -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);