diff --git a/app/widget/timelinewidget/tool/transition.cpp b/app/widget/timelinewidget/tool/transition.cpp index 5967b4996..c13a441e1 100644 --- a/app/widget/timelinewidget/tool/transition.cpp +++ b/app/widget/timelinewidget/tool/transition.cpp @@ -28,14 +28,26 @@ void TimelineWidget::TransitionTool::MousePress(TimelineViewMouseEvent *event) olive::timeline::MovementMode trim_mode; rational halfway_point = block_at_time->in() + block_at_time->length() / 2; rational tenth_point = block_at_time->in() + block_at_time->length() / 10; + Block* other_block = nullptr; if (cursor_frame < halfway_point) { transition_start_point = block_at_time->in(); trim_mode = olive::timeline::kTrimIn; - dual_transition_ = (cursor_frame < tenth_point); + + if (cursor_frame < tenth_point + && block_at_time->previous() + && block_at_time->previous()->type() == Block::kClip) { + other_block = block_at_time->previous(); + } } else { transition_start_point = block_at_time->out(); trim_mode = olive::timeline::kTrimOut; dual_transition_ = (cursor_frame > block_at_time->length() - tenth_point); + + if (cursor_frame > block_at_time->length() - tenth_point + && block_at_time->next() + && block_at_time->next()->type() == Block::kClip) { + other_block = block_at_time->next(); + } } // Create ghost @@ -46,6 +58,11 @@ void TimelineWidget::TransitionTool::MousePress(TimelineViewMouseEvent *event) ghost_->SetOut(transition_start_point); ghost_->SetMode(trim_mode); ghost_->setData(TimelineViewGhostItem::kAttachedBlock, Node::PtrToValue(block_at_time)); + + dual_transition_ = (other_block); + if (other_block) + ghost_->setData(TimelineViewGhostItem::kReferenceBlock, Node::PtrToValue(other_block)); + parent()->AddGhost(ghost_); snap_points_.append(transition_start_point); @@ -87,16 +104,27 @@ void TimelineWidget::TransitionTool::MouseRelease(TimelineViewMouseEvent *event) // Place transition in place new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()), - track.index(), - transition, - ghost_->GetAdjustedIn(), - command); + track.index(), + transition, + ghost_->GetAdjustedIn(), + command); // Connect block to transition new NodeEdgeAddCommand(block_to_transition->output(), transition_input_to_connect, command); + // Connect other block to transition + if (dual_transition_) { + Block* other_block = Node::ValueToPtr(ghost_->data(TimelineViewGhostItem::kReferenceBlock)); + NodeInput* alternate_transition_input = (transition_input_to_connect == transition->out_block_input()) + ? transition->in_block_input() + : transition->out_block_input(); + new NodeEdgeAddCommand(other_block->output(), + alternate_transition_input, + command); + } + olive::undo_stack.push(command); }