From ae71b206cd7c6e589ee2045d926ba653a5d5a0a3 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 2 Jan 2020 04:11:50 +1100 Subject: [PATCH] updated timeline tools to allow rounding as well as flooring to find the frame at the mouse cursor point --- .../timelinewidget/timelinescaledobject.cpp | 25 ++++++++++---- .../timelinewidget/timelinescaledobject.h | 4 ++- app/widget/timelinewidget/tool/add.cpp | 6 ++-- app/widget/timelinewidget/tool/import.cpp | 4 +-- app/widget/timelinewidget/tool/razor.cpp | 6 ++-- app/widget/timelinewidget/tool/transition.cpp | 8 ++--- app/widget/timelinewidget/tool/zoom.cpp | 2 +- .../timelinewidget/view/timelineview.cpp | 34 +++++++++++-------- app/widget/timelinewidget/view/timelineview.h | 2 ++ .../view/timelineviewmouseevent.cpp | 34 ++++++++++++------- .../view/timelineviewmouseevent.h | 30 ++++++++++++---- 11 files changed, 101 insertions(+), 54 deletions(-) diff --git a/app/widget/timelinewidget/timelinescaledobject.cpp b/app/widget/timelinewidget/timelinescaledobject.cpp index 554316b15..b92361e1e 100644 --- a/app/widget/timelinewidget/timelinescaledobject.cpp +++ b/app/widget/timelinewidget/timelinescaledobject.cpp @@ -18,18 +18,31 @@ const double &TimelineScaledObject::timebase_dbl() return timebase_dbl_; } +rational TimelineScaledObject::SceneToTime(const double &x, const double &x_scale, const rational &timebase, bool round) +{ + double unscaled_time = x / x_scale / timebase.toDouble(); + + // Adjust screen point by scale and timebase + qint64 rounded_x_mvmt; + + if (round) { + rounded_x_mvmt = qRound64(unscaled_time); + } else { + rounded_x_mvmt = qFloor(unscaled_time); + } + + // Return a time in the timebase + return rational(rounded_x_mvmt * timebase.numerator(), timebase.denominator()); +} + double TimelineScaledObject::TimeToScene(const rational &time) { return time.toDouble() * scale_; } -rational TimelineScaledObject::SceneToTime(const double &x) +rational TimelineScaledObject::SceneToTime(const double &x, bool round) { - // Adjust screen point by scale and timebase - qint64 scaled_x_mvmt = qFloor(x / scale_ / timebase_dbl_); - - // Return a time in the timebase - return rational(scaled_x_mvmt * timebase_.numerator(), timebase_.denominator()); + return SceneToTime(x, scale_, timebase_, round); } void TimelineScaledObject::SetTimebaseInternal(const rational &timebase) diff --git a/app/widget/timelinewidget/timelinescaledobject.h b/app/widget/timelinewidget/timelinescaledobject.h index 6f06e25e5..9c8296f69 100644 --- a/app/widget/timelinewidget/timelinescaledobject.h +++ b/app/widget/timelinewidget/timelinescaledobject.h @@ -11,9 +11,11 @@ public: const rational& timebase(); const double& timebase_dbl(); + static rational SceneToTime(const double &x, const double& x_scale, const rational& timebase, bool round = false); + protected: double TimeToScene(const rational& time); - rational SceneToTime(const double &x); + rational SceneToTime(const double &x, bool round = false); void SetTimebaseInternal(const rational& timebase); diff --git a/app/widget/timelinewidget/tool/add.cpp b/app/widget/timelinewidget/tool/add.cpp index 065458b8d..fe0050ed2 100644 --- a/app/widget/timelinewidget/tool/add.cpp +++ b/app/widget/timelinewidget/tool/add.cpp @@ -11,14 +11,14 @@ TimelineWidget::AddTool::AddTool(TimelineWidget *parent) : void TimelineWidget::AddTool::MousePress(TimelineViewMouseEvent *event) { - const TrackReference& track = event->GetCoordinates().GetTrack(); + const TrackReference& track = event->GetTrack(); TrackOutput* t = parent()->GetTrackFromReference(track); if (t && t->IsLocked()) { return; } - drag_start_point_ = event->GetCoordinates().GetFrame(); + drag_start_point_ = event->GetFrame(); ghost_ = new TimelineViewGhostItem(); ghost_->SetIn(drag_start_point_); @@ -36,7 +36,7 @@ void TimelineWidget::AddTool::MouseMove(TimelineViewMouseEvent *event) return; } - MouseMoveInternal(event->GetCoordinates().GetFrame(), event->GetModifiers() & Qt::AltModifier); + MouseMoveInternal(event->GetFrame(), event->GetModifiers() & Qt::AltModifier); } void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event) diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index 07dbe188d..bd15ae516 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -158,8 +158,8 @@ void TimelineWidget::ImportTool::DragEnter(TimelineViewMouseEvent *event) void TimelineWidget::ImportTool::DragMove(TimelineViewMouseEvent *event) { if (parent()->HasGhosts()) { - rational time_movement = event->GetCoordinates().GetFrame() - drag_start_.GetFrame(); - int track_movement = event->GetCoordinates().GetTrack().index() - drag_start_.GetTrack().index(); + rational time_movement = event->GetFrame() - drag_start_.GetFrame(); + int track_movement = event->GetTrack().index() - drag_start_.GetTrack().index(); // If snapping is enabled, check for snap points if (Core::instance()->snapping()) { diff --git a/app/widget/timelinewidget/tool/razor.cpp b/app/widget/timelinewidget/tool/razor.cpp index 7f60df580..87bafafda 100644 --- a/app/widget/timelinewidget/tool/razor.cpp +++ b/app/widget/timelinewidget/tool/razor.cpp @@ -35,12 +35,12 @@ void TimelineWidget::RazorTool::MousePress(TimelineViewMouseEvent *event) void TimelineWidget::RazorTool::MouseMove(TimelineViewMouseEvent *event) { if (!dragging_) { - drag_start_ = event->GetCoordinates(); + drag_start_ = event->GetCoordinates(true); dragging_ = true; } // Split at the current cursor track - TrackReference split_track = event->GetCoordinates().GetTrack(); + TrackReference split_track = event->GetTrack(); if (!split_tracks_.contains(split_track)) { split_tracks_.append(split_track); @@ -66,7 +66,7 @@ void TimelineWidget::RazorTool::MouseRelease(TimelineViewMouseEvent *event) Block* block_at_time = track->NearestBlockBefore(split_time); // Ensure there's a valid block here - if (block_at_time != track + if (block_at_time && !blocks_to_split.contains(block_at_time)) { blocks_to_split.append(block_at_time); diff --git a/app/widget/timelinewidget/tool/transition.cpp b/app/widget/timelinewidget/tool/transition.cpp index 8e76bb0ee..ec552d45e 100644 --- a/app/widget/timelinewidget/tool/transition.cpp +++ b/app/widget/timelinewidget/tool/transition.cpp @@ -11,15 +11,15 @@ TimelineWidget::TransitionTool::TransitionTool(TimelineWidget *parent) : void TimelineWidget::TransitionTool::MousePress(TimelineViewMouseEvent *event) { - const TrackReference& track = event->GetCoordinates().GetTrack(); + const TrackReference& track = event->GetTrack(); TrackOutput* t = parent()->GetTrackFromReference(track); - rational cursor_frame = event->GetCoordinates().GetFrame(); + rational cursor_frame = event->GetFrame(); if (!t || t->IsLocked()) { return; } - Block* block_at_time = t->BlockAtTime(event->GetCoordinates().GetFrame()); + Block* block_at_time = t->BlockAtTime(event->GetFrame()); if (!block_at_time || block_at_time->type() != Block::kClip) { return; } @@ -78,7 +78,7 @@ void TimelineWidget::TransitionTool::MouseMove(TimelineViewMouseEvent *event) return; } - MouseMoveInternal(event->GetCoordinates().GetFrame(), dual_transition_); + MouseMoveInternal(event->GetFrame(), dual_transition_); } void TimelineWidget::TransitionTool::MouseRelease(TimelineViewMouseEvent *event) diff --git a/app/widget/timelinewidget/tool/zoom.cpp b/app/widget/timelinewidget/tool/zoom.cpp index d208ea7ec..1ee48aec6 100644 --- a/app/widget/timelinewidget/tool/zoom.cpp +++ b/app/widget/timelinewidget/tool/zoom.cpp @@ -40,7 +40,7 @@ void TimelineWidget::ZoomTool::MouseRelease(TimelineViewMouseEvent *event) double scale = parent()->scale_; // Normalize zoom location for 1.0 scale - double frame_x = parent()->TimeToScene(event->GetCoordinates().GetFrame()); + double frame_x = parent()->TimeToScene(event->GetFrame()); if (event->GetModifiers() & Qt::AltModifier) { // Zoom out if the user clicks while holding Alt diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 37f188605..dc34e8550 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -74,8 +74,7 @@ void TimelineView::mousePressEvent(QMouseEvent *event) return; } - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->modifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->modifiers()); emit MousePressed(&timeline_event); } @@ -87,8 +86,7 @@ void TimelineView::mouseMoveEvent(QMouseEvent *event) return; } - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->modifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->modifiers()); emit MouseMoved(&timeline_event); } @@ -100,16 +98,14 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) return; } - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->modifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->modifiers()); emit MouseReleased(&timeline_event); } void TimelineView::mouseDoubleClickEvent(QMouseEvent *event) { - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->modifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->modifiers()); emit MouseDoubleClicked(&timeline_event); } @@ -133,8 +129,7 @@ void TimelineView::wheelEvent(QWheelEvent *event) void TimelineView::dragEnterEvent(QDragEnterEvent *event) { - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->keyboardModifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->keyboardModifiers()); timeline_event.SetMimeData(event->mimeData()); timeline_event.SetEvent(event); @@ -144,8 +139,7 @@ void TimelineView::dragEnterEvent(QDragEnterEvent *event) void TimelineView::dragMoveEvent(QDragMoveEvent *event) { - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->keyboardModifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->keyboardModifiers()); timeline_event.SetMimeData(event->mimeData()); timeline_event.SetEvent(event); @@ -160,8 +154,7 @@ void TimelineView::dragLeaveEvent(QDragLeaveEvent *event) void TimelineView::dropEvent(QDropEvent *event) { - TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), - event->keyboardModifiers()); + TimelineViewMouseEvent timeline_event = CreateMouseEvent(event->pos(), event->keyboardModifiers()); timeline_event.SetMimeData(event->mimeData()); timeline_event.SetEvent(event); @@ -228,6 +221,19 @@ TimelineCoordinate TimelineView::SceneToCoordinate(const QPointF& pt) return TimelineCoordinate(SceneToTime(pt.x()), TrackReference(type_, SceneToTrack(pt.y()))); } +TimelineViewMouseEvent TimelineView::CreateMouseEvent(const QPoint& pos, Qt::KeyboardModifiers modifiers) +{ + QPointF scene_pt = mapToScene(pos); + + TimelineViewMouseEvent timeline_event(scene_pt.x(), + scale_, + timebase(), + TrackReference(type_, SceneToTrack(scene_pt.y())), + modifiers); + + return timeline_event; +} + int TimelineView::GetTrackY(int track_index) { int y = 0; diff --git a/app/widget/timelinewidget/view/timelineview.h b/app/widget/timelinewidget/view/timelineview.h index 7ba030d13..d48ef41ab 100644 --- a/app/widget/timelinewidget/view/timelineview.h +++ b/app/widget/timelinewidget/view/timelineview.h @@ -94,6 +94,8 @@ private: TimelineCoordinate ScreenToCoordinate(const QPoint& pt); TimelineCoordinate SceneToCoordinate(const QPointF& pt); + TimelineViewMouseEvent CreateMouseEvent(const QPoint &pos, Qt::KeyboardModifiers modifiers); + int SceneToTrack(double y); void UserSetTime(const int64_t& time); diff --git a/app/widget/timelinewidget/view/timelineviewmouseevent.cpp b/app/widget/timelinewidget/view/timelineviewmouseevent.cpp index 9f39779f0..e89d0994b 100644 --- a/app/widget/timelinewidget/view/timelineviewmouseevent.cpp +++ b/app/widget/timelinewidget/view/timelineviewmouseevent.cpp @@ -22,35 +22,43 @@ #include -TimelineViewMouseEvent::TimelineViewMouseEvent(const TimelineCoordinate &coord, - const Qt::KeyboardModifiers &modifiers) : - coord_(coord), - modifiers_(modifiers), - source_event_(nullptr), - mime_data_(nullptr) -{ -} +#include "widget/timelinewidget/timelinescaledobject.h" -TimelineViewMouseEvent::TimelineViewMouseEvent(const rational &frame, +TimelineViewMouseEvent::TimelineViewMouseEvent(const qreal &scene_x, + const double &scale_x, + const rational &timebase, const TrackReference &track, const Qt::KeyboardModifiers &modifiers) : - coord_(frame, track), + scene_x_(scene_x), + scale_x_(scale_x), + timebase_(timebase), + track_(track), modifiers_(modifiers), source_event_(nullptr), mime_data_(nullptr) { } -const TimelineCoordinate &TimelineViewMouseEvent::GetCoordinates() +TimelineCoordinate TimelineViewMouseEvent::GetCoordinates(bool round_time) const { - return coord_; + return TimelineCoordinate(GetFrame(round_time), track_); } -const Qt::KeyboardModifiers TimelineViewMouseEvent::GetModifiers() +const Qt::KeyboardModifiers TimelineViewMouseEvent::GetModifiers() const { return modifiers_; } +rational TimelineViewMouseEvent::GetFrame(bool round) const +{ + return TimelineScaledObject::SceneToTime(scene_x_, scale_x_, timebase_, round); +} + +const TrackReference &TimelineViewMouseEvent::GetTrack() const +{ + return track_; +} + const QMimeData* TimelineViewMouseEvent::GetMimeData() { return mime_data_; diff --git a/app/widget/timelinewidget/view/timelineviewmouseevent.h b/app/widget/timelinewidget/view/timelineviewmouseevent.h index 72d074f24..32c86c10b 100644 --- a/app/widget/timelinewidget/view/timelineviewmouseevent.h +++ b/app/widget/timelinewidget/view/timelineviewmouseevent.h @@ -30,15 +30,27 @@ class TimelineViewMouseEvent { public: - TimelineViewMouseEvent(const TimelineCoordinate& coord, - const Qt::KeyboardModifiers& modifiers = Qt::NoModifier); - - TimelineViewMouseEvent(const rational& frame, + TimelineViewMouseEvent(const qreal& scene_x, + const double& scale_x, + const rational& timebase, const TrackReference &track, const Qt::KeyboardModifiers& modifiers = Qt::NoModifier); - const TimelineCoordinate& GetCoordinates(); - const Qt::KeyboardModifiers GetModifiers(); + TimelineCoordinate GetCoordinates(bool round_time = false) const; + const Qt::KeyboardModifiers GetModifiers() const; + + /** + * @brief Gets the time at this cursor point + * + * @param round + * + * If set to true, the time will be rounded to the nearest time. If set to false, the time is floored so the time is + * always to the left of the cursor. The former behavior is better for clicking between frames (e.g. razor tool) and + * the latter is better for clicking directly on frames (e.g. pointer tool). + */ + rational GetFrame(bool round = false) const; + + const TrackReference& GetTrack() const; const QMimeData *GetMimeData(); void SetMimeData(const QMimeData *data); @@ -49,7 +61,11 @@ public: void ignore(); private: - TimelineCoordinate coord_; + qreal scene_x_; + double scale_x_; + rational timebase_; + + TrackReference track_; Qt::KeyboardModifiers modifiers_;