timeline: fixed some ripple tool behavior bugs
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user