From afe87b97e53f3bd473cc1111a5630ebfb8cb9049 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 8 Aug 2018 16:01:59 +1000 Subject: [PATCH] better transition handling --- effects/crossdissolvetransition.cpp | 4 +- panels/timeline.cpp | 67 ++++++++++++++++++----------- panels/timeline.h | 3 +- ui/timelinewidget.cpp | 66 +++++++++++++++++++--------- 4 files changed, 93 insertions(+), 47 deletions(-) diff --git a/effects/crossdissolvetransition.cpp b/effects/crossdissolvetransition.cpp index 4eb2af20c..12920bf2b 100644 --- a/effects/crossdissolvetransition.cpp +++ b/effects/crossdissolvetransition.cpp @@ -11,5 +11,7 @@ void CrossDissolveTransition::process_transition(float progress) { } Transition* CrossDissolveTransition::copy() { - return new CrossDissolveTransition(); + Transition* t = new CrossDissolveTransition(); + t->length = length; + return t; } diff --git a/panels/timeline.cpp b/panels/timeline.cpp index fef8e4aea..ad47d9a9d 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -314,7 +314,7 @@ void Timeline::delete_in_out(bool ripple) { areas.append(s); } TimelineAction* ta = new TimelineAction(); - panel_timeline->delete_areas_and_relink(ta, areas); + delete_areas_and_relink(ta, areas); if (ripple) ta->ripple(sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out); ta->set_in_out(sequence, false, 0, 0); undo_stack.push(ta); @@ -455,27 +455,34 @@ void Timeline::on_snappingButton_toggled(bool checked) { } Clip* Timeline::split_clip(TimelineAction* ta, int p, long frame) { + return split_clip(ta, p, frame, frame); +} + +Clip* Timeline::split_clip(TimelineAction* ta, int p, long frame, long post_in) { Clip* pre = sequence->get_clip(p); if (pre != NULL && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points Clip* post = pre->copy(sequence); - ta->set_timeline_out(sequence, p, frame); - post->timeline_in = frame; - post->clip_in = pre->clip_in + (frame - pre->timeline_in); + long new_clip_length = frame - pre->timeline_in; - long pre_length = pre->getLength(); + post->timeline_in = post_in; + post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); - if (pre->closing_transition != NULL) { - post->closing_transition = pre->closing_transition; - pre->closing_transition = NULL; - long post_length = post->getLength(); - if (post->closing_transition->length > post_length) { - post->closing_transition->length = post_length; - } - } - if (pre->opening_transition != NULL && pre->opening_transition->length > pre_length) { - pre->opening_transition->length = pre_length; - } + ta->set_timeline_out(sequence, p, frame); + + if (pre->opening_transition != NULL) { + if (pre->opening_transition->length > new_clip_length) { + ta->modify_transition(sequence, p, TA_OPENING_TRANSITION, new_clip_length); + } + + delete post->opening_transition; + post->opening_transition = NULL; + } + if (pre->closing_transition != NULL) { + ta->delete_transition(sequence, p, TA_CLOSING_TRANSITION); + + post->closing_transition->length = qMin((long) post->closing_transition->length, post->getLength()); + } return post; } @@ -595,21 +602,33 @@ void Timeline::delete_areas_and_relink(TimelineAction* ta, QVector& a // middle of clip is within deletion area // duplicate clip - Clip* post = c->copy(sequence); + Clip* post = split_clip(ta, j, s.in, s.out); - ta->set_timeline_out(sequence, j, s.in); - post->timeline_in = s.out; - post->clip_in = c->clip_in + (s.in - c->timeline_in) + (s.out - s.in); - - pre_clips.append(j); - post_clips.append(post); + pre_clips.append(j); + post_clips.append(post); } else if (c->timeline_in < s.in && c->timeline_out > s.in) { // only out point is in deletion area ta->set_timeline_out(sequence, j, s.in); + + if (c->closing_transition != NULL) { + if (s.in < c->timeline_out - c->closing_transition->length) { + ta->delete_transition(sequence, j, TA_CLOSING_TRANSITION); + } else { + ta->modify_transition(sequence, j, TA_CLOSING_TRANSITION, c->closing_transition->length - (c->timeline_out - s.in)); + } + } } else if (c->timeline_in < s.out && c->timeline_out > s.out) { // only in point is in deletion area ta->increase_clip_in(sequence, j, s.out - c->timeline_in); ta->set_timeline_in(sequence, j, s.out); + + if (c->opening_transition != NULL) { + if (s.out > c->timeline_in + c->opening_transition->length) { + ta->delete_transition(sequence, j, TA_OPENING_TRANSITION); + } else { + ta->modify_transition(sequence, j, TA_OPENING_TRANSITION, c->opening_transition->length - (s.out - c->timeline_in)); + } + } } } } @@ -949,7 +968,7 @@ void Timeline::snap_to_clip(long* l, bool playhead_inclusive) { break; } else if (c->opening_transition != NULL && snap_to_point(c->timeline_in + c->opening_transition->length, l)) { break; - } else if (c->closing_transition != NULL && snap_to_point(c->timeline_in + c->closing_transition->length, l)) { + } else if (c->closing_transition != NULL && snap_to_point(c->timeline_out - c->closing_transition->length, l)) { break; } } diff --git a/panels/timeline.h b/panels/timeline.h index 1615eabb9..c07c3f6e2 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -78,7 +78,8 @@ public: void copy(bool del); void paste(); void deselect(); - Clip* split_clip(TimelineAction* ta, int p, long frame); + Clip* split_clip(TimelineAction* ta, int p, long frame); + Clip* split_clip(TimelineAction* ta, int p, long frame, long post_in); bool split_selection(TimelineAction* ta); void split_at_playhead(); bool split_clip_and_relink(TimelineAction* ta, int clip, long frame, bool relink); diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index a035f5285..31181652f 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -586,17 +586,44 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } else { Clip* c = sequence->get_clip(g.clip); bool is_opening_transition = (g.transition == c->opening_transition); + long new_transition_length = g.out - g.in; ta->modify_transition( sequence, g.clip, is_opening_transition ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION, - g.out - g.in + new_transition_length ); - if (is_opening_transition && g.in != g.old_in) { - ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in); - ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in); - } else if (!is_opening_transition && g.out != g.old_out) { - ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out); + + long clip_length = c->getLength(); + if (is_opening_transition) { + if (g.in != g.old_in) { + // if transition is going to make the clip bigger, make the clip bigger + ta->increase_timeline_in(sequence, g.clip, g.in - g.old_in); + clip_length -= (g.in - g.old_in); + ta->increase_clip_in(sequence, g.clip, g.clip_in - g.old_clip_in); + } + + if (c->closing_transition != NULL) { + if (new_transition_length == clip_length) { + ta->delete_transition(sequence, g.clip, TA_CLOSING_TRANSITION); + } else if (new_transition_length > clip_length - c->closing_transition->length) { + ta->modify_transition(sequence, g.clip, TA_CLOSING_TRANSITION, clip_length - new_transition_length); + } + } + } else { + if (g.out != g.old_out) { + // if transition is going to make the clip bigger, make the clip bigger + ta->increase_timeline_out(sequence, g.clip, g.out - g.old_out); + clip_length += (g.out - g.old_out); + } + + if (c->opening_transition != NULL) { + if (new_transition_length == clip_length) { + ta->delete_transition(sequence, g.clip, TA_OPENING_TRANSITION); + } else if (new_transition_length > clip_length - c->opening_transition->length) { + ta->modify_transition(sequence, g.clip, TA_OPENING_TRANSITION, clip_length - new_transition_length); + } + } } } } @@ -783,7 +810,7 @@ void validate_snapping(const Ghost& g, long* frame_diff) { void TimelineWidget::update_ghosts(QPoint& mouse_pos) { int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); long frame_diff = panel_timeline->getFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; - int track_diff = (panel_timeline->tool == TIMELINE_TOOL_SLIDE) ? 0 : mouse_track - panel_timeline->drag_track_start; + int track_diff = (panel_timeline->tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != TA_NO_TRANSITION) ? 0 : mouse_track - panel_timeline->drag_track_start; long validator; // first try to snap @@ -945,7 +972,7 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) { g.track += abs_track_diff; } } - } else if (same_sign(g.old_track, panel_timeline->drag_track_start) && panel_timeline->transition_select == TA_NO_TRANSITION) { + } else if (same_sign(g.old_track, panel_timeline->drag_track_start)) { g.track += track_diff; } } @@ -967,17 +994,16 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) { s.in = s.old_in + frame_diff; s.out = s.old_out + frame_diff; s.track = s.old_track; - if (panel_timeline->transition_select == TA_NO_TRANSITION) { - if (panel_timeline->importing) { - int abs_track_diff = abs(track_diff); - if (s.old_track < 0) { - s.track -= abs_track_diff; - } else { - s.track += abs_track_diff; - } + + if (panel_timeline->importing) { + int abs_track_diff = abs(track_diff); + if (s.old_track < 0) { + s.track -= abs_track_diff; } else { - if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff; + s.track += abs_track_diff; } + } else { + if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff; } } } @@ -992,8 +1018,6 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->cursor_frame = panel_timeline->getFrameFromScreenPoint(event->pos().x()); panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); - - if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) { panel_timeline->snap_to_clip(&panel_timeline->cursor_frame, !config.edit_tool_also_seeks || !panel_timeline->selecting); } @@ -1389,7 +1413,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { long transition_point = c->timeline_in + c->opening_transition->length; if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { - int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame); + int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame); if (nc < closeness) { panel_timeline->trim_target = i; panel_timeline->trim_in_point = false; @@ -1402,7 +1426,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (c->closing_transition != NULL) { long transition_point = c->timeline_out - c->closing_transition->length; if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { - int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame); + int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame); if (nc < closeness) { panel_timeline->trim_target = i; panel_timeline->trim_in_point = true;