From 9f029bedfaf25a04f1f68d3ffc7ae2a4c5fa83de Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 5 Apr 2019 02:16:12 +1100 Subject: [PATCH] ghosts can traverse tracks again --- panels/timeline.cpp | 2 +- timeline/ghost.cpp | 2 +- timeline/ghost.h | 6 +- timeline/sequence.cpp | 3 +- timeline/timelinefunctions.cpp | 2 +- timeline/track.cpp | 25 ++++++++ timeline/track.h | 4 ++ ui/timelineview.cpp | 102 ++++++++++++++++++++------------- ui/timelineview.h | 5 ++ 9 files changed, 103 insertions(+), 48 deletions(-) diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 7308b6c72..88af64d1e 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -370,7 +370,7 @@ void Timeline::nest() { && c->timeline_out() > g.out))) { // There's a clip occupied by the space taken up by this ghost. Move up a track, and seek again. - g.track = g.track->track_list()->TrackAt(g.track->Index() + 1); + g.track = g.track->Next(); // Restart entire loop again j = -1; diff --git a/timeline/ghost.cpp b/timeline/ghost.cpp index 2e9780709..dccd5ecfd 100644 --- a/timeline/ghost.cpp +++ b/timeline/ghost.cpp @@ -2,5 +2,5 @@ Selection Ghost::ToSelection() const { - return Selection(in, out, track); + return Selection(in, out, track->Sibling(track_movement)); } diff --git a/timeline/ghost.h b/timeline/ghost.h index e0da417d5..cd5dafd5b 100644 --- a/timeline/ghost.h +++ b/timeline/ghost.h @@ -18,16 +18,18 @@ enum TrimType { struct Ghost { Clip* clip; + long in; long out; - Track* track; long clip_in; long old_in; long old_out; - Track* old_track; long old_clip_in; + Track* track; + int track_movement; + // importing variables Media* media; int media_stream; diff --git a/timeline/sequence.cpp b/timeline/sequence.cpp index 93ab5bf2d..19fef2e98 100644 --- a/timeline/sequence.cpp +++ b/timeline/sequence.cpp @@ -189,12 +189,11 @@ void Sequence::AddClipsFromGhosts(ComboAction* ca, const QVector& ghosts) earliest_point = qMin(earliest_point, g.in); - ClipPtr c = std::make_shared(g.track); + ClipPtr c = std::make_shared(g.track->Sibling(g.track_movement)); c->set_media(g.media, g.media_stream); c->set_timeline_in(g.in); c->set_timeline_out(g.out); c->set_clip_in(g.clip_in); - c->set_track(g.track); if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) { Footage* m = c->media()->to_footage(); if (m->video_tracks.size() == 0) { diff --git a/timeline/timelinefunctions.cpp b/timeline/timelinefunctions.cpp index e37a90f89..beaf69929 100644 --- a/timeline/timelinefunctions.cpp +++ b/timeline/timelinefunctions.cpp @@ -165,7 +165,7 @@ QVector olive::timeline::CreateGhostsFromMedia(Sequence *seq, Ghost& g = ghosts[i]; g.old_in = g.in; g.old_out = g.out; - g.old_track = g.track; + g.track_movement = 0; } return ghosts; diff --git a/timeline/track.cpp b/timeline/track.cpp index 469ff66b6..8d74b9999 100644 --- a/timeline/track.cpp +++ b/timeline/track.cpp @@ -195,6 +195,31 @@ Clip *Track::GetClipFromPoint(long point) return nullptr; } +Track *Track::Previous() +{ + int index = Index(); + + if (index == 0) { + return nullptr; + } + + return parent_->TrackAt(index - 1); +} + +Track *Track::Next() +{ + return parent_->TrackAt(Index() + 1); +} + +Track *Track::Sibling(int diff) +{ + if (diff == 0) { + return this; + } + + return track_list()->TrackAt(qMax(0, Index() + diff)); +} + int Track::Index() { return parent_->IndexOfTrack(this); diff --git a/timeline/track.h b/timeline/track.h index b0e079370..23ca28cf4 100644 --- a/timeline/track.h +++ b/timeline/track.h @@ -68,6 +68,10 @@ public: ClipPtr GetClipObjectFromRawPtr(Clip* c); Clip* GetClipFromPoint(long point); + Track* Previous(); + Track* Next(); + Track* Sibling(int diff); + int Index(); bool IsClipSelected(int clip_index, bool containing = true); diff --git a/ui/timelineview.cpp b/ui/timelineview.cpp index 777bb5fde..63eed4044 100644 --- a/ui/timelineview.cpp +++ b/ui/timelineview.cpp @@ -645,7 +645,8 @@ void TimelineView::mousePressEvent(QMouseEvent *event) { if (ParentTimeline()->drag_track_start->type() == create_type) { Ghost g; g.in = g.old_in = g.out = g.old_out = ParentTimeline()->drag_frame_start; - g.track = g.old_track = ParentTimeline()->drag_track_start; + g.track = ParentTimeline()->drag_track_start; + g.track_movement = 0; g.transition = nullptr; g.clip = nullptr; g.trim_type = olive::timeline::TRIM_OUT; @@ -1054,6 +1055,8 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) { c->set_name(tr("Noise")); c->effects.append(Effect::Create(c.get(), Effect::GetInternalMeta(EFFECT_INTERNAL_NOISE, EFFECT_TYPE_EFFECT))); break; + default: + break; } if (c->type() == Track::kTypeAudio && olive::config.add_default_effects_to_clips) { @@ -1081,7 +1084,7 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) { if (g.in != g.old_in || g.out != g.old_out || g.clip_in != g.old_clip_in - || g.track != g.old_track) { + || g.track_movement != 0) { process_moving = true; break; } @@ -1154,10 +1157,10 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) { QVector delete_areas; for (int i=0;ighosts.size();i++) { const Ghost& g = ParentTimeline()->ghosts.at(i); - if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { + if (g.old_in != g.in || g.old_out != g.out || g.track_movement != 0 || g.clip_in != g.old_clip_in) { // create copy of clip - ClipPtr c = g.clip->copy(g.track); + ClipPtr c = g.clip->copy(g.track->Sibling(g.track_movement)); c->set_timeline_in(g.in); c->set_timeline_out(g.out); @@ -1247,7 +1250,7 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) { (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), - g.track, + g.track->Sibling(g.track_movement), false, true); @@ -1302,7 +1305,13 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) { timeline_out_movement = g.out - g.transition->parent_clip->timeline_out(); } - c->Move(ca, (g.in - g.old_in), timeline_out_movement, (g.clip_in - g.old_clip_in), 0, false, true); + c->Move(ca, + (g.in - g.old_in), + timeline_out_movement, + (g.clip_in - g.old_clip_in), + g.track, + false, + true); clip_length -= (g.in - g.old_in); } @@ -1319,7 +1328,7 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) { } // if transition is going to make the clip bigger, make the clip bigger - c->Move(ca, timeline_in_movement, (g.out - g.old_out), timeline_in_movement, 0, false, true); + c->Move(ca, timeline_in_movement, (g.out - g.old_out), timeline_in_movement, c->track(), false, true); clip_length += (g.out - g.old_out); } @@ -1541,7 +1550,8 @@ void TimelineView::init_ghosts() { Ghost& g = ParentTimeline()->ghosts[i]; Clip* c = g.clip; - g.track = g.old_track = c->track(); + g.track = c->track(); + g.track_movement = 0; g.clip_in = g.old_clip_in = c->clip_in(); if (olive::timeline::current_tool == olive::timeline::TIMELINE_TOOL_SLIP) { @@ -1616,6 +1626,7 @@ void TimelineView::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { long frame_diff = (lock_frame) ? 0 : ParentTimeline()->getTimelineFrameFromScreenPoint(mouse_pos.x()) - ParentTimeline()->drag_frame_start; long validator; long earliest_in_point = LONG_MAX; + int track_diff = getTrackIndexFromScreenPoint(mouse_pos.y()) - ParentTimeline()->drag_track_start->Index(); // first try to snap long fm; @@ -1814,18 +1825,12 @@ void TimelineView::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } } - // prevent clips from crossing tracks - /* - if (same_sign(g.old_track, ParentTimeline()->drag_track_start)) { - while (!same_sign(g.old_track, g.old_track + track_diff)) { - if (g.old_track < 0) { - track_diff--; - } else { - track_diff++; - } - } + // Prevent any clips from going below the "zeroeth" track + int track_validator = g.track->Index() + track_diff; + if (track_validator < 0) { + track_diff -= track_validator; } - */ + } else if (effective_tool == olive::timeline::TIMELINE_TOOL_TRANSITION) { if (ParentTimeline()->transition_tool_open_clip == nullptr || ParentTimeline()->transition_tool_close_clip == nullptr) { @@ -1898,7 +1903,7 @@ void TimelineView::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { g.out = g.old_out + ghost_diff; } } else if (clips_are_movable) { - g.track = g.old_track; + g.track_movement = 0; g.in = g.old_in + frame_diff; g.out = g.old_out + frame_diff; @@ -1909,16 +1914,11 @@ void TimelineView::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { if (ParentTimeline()->importing) { - if (mouse_track != nullptr) { - g.track = g.track->track_list()->TrackAt(mouse_track->Index()); - } + g.track_movement = getTrackIndexFromScreenPoint(mouse_pos.y()); - } else if (g.old_track->type() == ParentTimeline()->drag_track_start->type()) { + } else if (g.track->type() == ParentTimeline()->drag_track_start->type()) { - if (mouse_track != nullptr) { - g.track = g.track->track_list()->TrackAt(mouse_track->Index()); - } - //g.track += track_diff; + g.track_movement = track_diff; } } else if (effective_tool == olive::timeline::TIMELINE_TOOL_TRANSITION) { @@ -3250,7 +3250,7 @@ void TimelineView::paintEvent(QPaintEvent*) { first_ghost = qMin(first_ghost, g.in); if (g.track->type() == track_list_->type()) { int ghost_x = ParentTimeline()->getTimelineScreenPointFromFrame(g.in); - int ghost_y = getScreenPointFromTrack(g.track); + int ghost_y = getScreenPointFromTrackIndex(g.track->Index() + g.track_movement); int ghost_width = ParentTimeline()->getTimelineScreenPointFromFrame(g.out) - ghost_x - 1; int ghost_height = g.track->height() - 1; @@ -3320,26 +3320,44 @@ void TimelineView::resizeEvent(QResizeEvent *) { // ************************************** Track *TimelineView::getTrackFromScreenPoint(int y) { + + int index = getTrackIndexFromScreenPoint(y); + + if (index < track_list_->TrackCount()) { + return track_list_->TrackAt(index); + } + + return nullptr; + +} + +int TimelineView::getScreenPointFromTrack(Track *track) { + return getScreenPointFromTrackIndex(track_list_->IndexOfTrack(track)); +} + +int TimelineView::getTrackIndexFromScreenPoint(int y) +{ if (y < 0) { - return track_list_->First(); - } else if (y > height()) { - return track_list_->Last(); + return 0; } y += scroll; int heights = 0; -// for (int i=0;iTrackCount();i++) { int i = 0; while (true) { int new_heights = heights + 1; - new_heights += track_list_->TrackAt(i)->height(); + if (i < track_list_->TrackCount()) { + new_heights += track_list_->TrackAt(i)->height(); + } else { + new_heights += olive::timeline::kTrackDefaultHeight; + } if (y >= heights && y < new_heights) { - return track_list_->TrackAt(i); + return i; } heights = new_heights; @@ -3347,18 +3365,20 @@ Track *TimelineView::getTrackFromScreenPoint(int y) { i++; } -// return nullptr; } -int TimelineView::getScreenPointFromTrack(Track *track) { +int TimelineView::getScreenPointFromTrackIndex(int track) +{ int point = 0; - for (int i=0;iTrackCount();i++) { - if (track == track_list_->TrackAt(i)) { - return point; + for (int i=0;iTrackCount()) { + point += track_list_->TrackAt(i)->height() + 1; + } else { + point += olive::timeline::kTrackDefaultHeight + 1; } - point += track_list_->TrackAt(i)->height() + 1; } + return point - scroll; } diff --git a/ui/timelineview.h b/ui/timelineview.h index 3e743b92b..13be5613f 100644 --- a/ui/timelineview.h +++ b/ui/timelineview.h @@ -72,8 +72,13 @@ protected: private: void init_ghosts(); void update_ghosts(const QPoint& mouse_pos, bool lock_frame); + Track* getTrackFromScreenPoint(int y); int getScreenPointFromTrack(Track* track); + + int getTrackIndexFromScreenPoint(int y); + int getScreenPointFromTrackIndex(int track); + Timeline* ParentTimeline(); Sequence* sequence(); void delete_area_under_ghosts(ComboAction* ca, Sequence *s);