From 9f99182089184d70eef9096ae5a025be0fe6c674 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 25 Jan 2021 10:22:14 +1100 Subject: [PATCH] use catch up scrolling when dragging items --- app/widget/curvewidget/curvewidget.cpp | 14 +++++++ app/widget/curvewidget/curvewidget.h | 4 ++ app/widget/keyframeview/keyframeviewbase.cpp | 14 ++++--- app/widget/keyframeview/keyframeviewbase.h | 7 +++- app/widget/nodeparamview/nodeparamview.cpp | 9 +++++ app/widget/nodeparamview/nodeparamview.h | 2 + app/widget/timebased/timebasedwidget.cpp | 37 +++++++++++-------- app/widget/timebased/timebasedwidget.h | 6 ++- app/widget/timelinewidget/timelinewidget.cpp | 4 ++ .../timelinewidget/view/timelineview.cpp | 2 - 10 files changed, 73 insertions(+), 26 deletions(-) diff --git a/app/widget/curvewidget/curvewidget.cpp b/app/widget/curvewidget/curvewidget.cpp index 2a580cd7a..43b4a99d9 100644 --- a/app/widget/curvewidget/curvewidget.cpp +++ b/app/widget/curvewidget/curvewidget.cpp @@ -101,6 +101,7 @@ CurveWidget::CurveWidget(QWidget *parent) : connect(view_, &CurveView::TimeChanged, this, &CurveWidget::SetTimeAndSignal); connect(view_->scene(), &QGraphicsScene::selectionChanged, this, &CurveWidget::SelectionChanged); connect(view_, &CurveView::ScaleChanged, this, &CurveWidget::SetScale); + connect(view_, &CurveView::Dragged, this, &CurveWidget::KeyframeViewDragged); // TimeBasedWidget's scrollbar has extra functionality that we can take advantage of view_->setHorizontalScrollBar(scrollbar()); @@ -389,4 +390,17 @@ void CurveWidget::InputDoubleClicked(NodeInput *input, int element, int track) view_->ZoomToFitInput(input, element, track); } +void CurveWidget::KeyframeViewDragged(int x, int y) +{ + QMetaObject::invokeMethod(this, "CatchUpScrollToPoint", Qt::QueuedConnection, + Q_ARG(int, x)); + QMetaObject::invokeMethod(this, "CatchUpYScrollToPoint", Qt::QueuedConnection, + Q_ARG(int, y)); +} + +void CurveWidget::CatchUpYScrollToPoint(int point) +{ + PageScrollInternal(view_->verticalScrollBar(), view_->height(), point, false); +} + } diff --git a/app/widget/curvewidget/curvewidget.h b/app/widget/curvewidget/curvewidget.h index 570be9a61..2fbf4720c 100644 --- a/app/widget/curvewidget/curvewidget.h +++ b/app/widget/curvewidget/curvewidget.h @@ -118,6 +118,10 @@ private slots: void InputDoubleClicked(NodeInput* input, int element, int track); + void KeyframeViewDragged(int x, int y); + + void CatchUpYScrollToPoint(int point); + }; } diff --git a/app/widget/keyframeview/keyframeviewbase.cpp b/app/widget/keyframeview/keyframeviewbase.cpp index 473dc6db6..7e0e0aeb2 100644 --- a/app/widget/keyframeview/keyframeviewbase.cpp +++ b/app/widget/keyframeview/keyframeviewbase.cpp @@ -143,7 +143,7 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event) if (item_under_cursor) { dragging_ = true; - drag_start_ = event->pos(); + drag_start_ = mapToScene(event->pos()); // Determine what type of item is under the cursor dragging_bezier_point_ = dynamic_cast(item_under_cursor); @@ -186,7 +186,7 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event) if (dragging_) { // Calculate cursor difference and scale it - QPointF mouse_diff_scaled = GetScaledCursorPos(event->pos() - drag_start_); + QPointF mouse_diff_scaled = GetScaledCursorPos(mapToScene(event->pos()) - drag_start_); if (event->modifiers() & Qt::ShiftModifier) { // If holding shift, only move one axis @@ -241,6 +241,8 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event) QToolTip::hideText(); QToolTip::showText(QCursor::pos(), tip); + + emit Dragged(qRound(initial_drag_item_->x()), qRound(initial_drag_item_->y())); } } } @@ -256,7 +258,7 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event) QGraphicsView::mouseReleaseEvent(event); if (dragging_) { - QPointF mouse_diff_scaled = GetScaledCursorPos(event->pos() - drag_start_); + QPointF mouse_diff_scaled = GetScaledCursorPos(mapToScene(event->pos()) - drag_start_); if (event->modifiers() & Qt::ShiftModifier) { // If holding shift, only move one axis @@ -447,10 +449,10 @@ void KeyframeViewBase::ProcessBezierDrag(QPointF mouse_diff_scaled, bool include } } -QPointF KeyframeViewBase::GetScaledCursorPos(const QPoint &cursor_pos) +QPointF KeyframeViewBase::GetScaledCursorPos(const QPointF &cursor_pos) { - return QPointF(static_cast(cursor_pos.x()) / GetScale(), - static_cast(cursor_pos.y()) / GetYScale()); + return QPointF(cursor_pos.x() / GetScale(), + cursor_pos.y() / GetYScale()); } void KeyframeViewBase::ShowContextMenu() diff --git a/app/widget/keyframeview/keyframeviewbase.h b/app/widget/keyframeview/keyframeviewbase.h index 215747c77..20952dfb9 100644 --- a/app/widget/keyframeview/keyframeviewbase.h +++ b/app/widget/keyframeview/keyframeviewbase.h @@ -48,6 +48,9 @@ public: void DeselectAll(); +signals: + void Dragged(int current_x, int current_y); + public slots: void RemoveKeyframe(NodeKeyframe* key); @@ -82,7 +85,7 @@ private: void ProcessBezierDrag(QPointF mouse_diff_scaled, bool include_opposing, bool undoable); - QPointF GetScaledCursorPos(const QPoint& cursor_pos); + QPointF GetScaledCursorPos(const QPointF &cursor_pos); struct KeyframeItemAndTime { KeyframeViewItem* key; @@ -95,7 +98,7 @@ private: Tool::Item active_tool_; - QPoint drag_start_; + QPointF drag_start_; BezierControlPointItem* dragging_bezier_point_; QPointF dragging_bezier_point_start_; diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index 1e04b927c..1c3cc0f83 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -91,6 +91,7 @@ NodeParamView::NodeParamView(QWidget *parent) : connect(ruler(), &TimeRuler::TimeChanged, keyframe_view_, &KeyframeView::SetTime); connect(keyframe_view_, &KeyframeView::TimeChanged, ruler(), &TimeRuler::SetTime); connect(keyframe_view_, &KeyframeView::TimeChanged, this, &NodeParamView::SetTimestamp); + connect(keyframe_view_, &KeyframeView::Dragged, this, &NodeParamView::KeyframeViewDragged); // Connect keyframe view scaling to this connect(keyframe_view_, &KeyframeView::ScaleChanged, this, &NodeParamView::SetScale); @@ -388,4 +389,12 @@ void NodeParamView::FocusChanged(QWidget* old, QWidget* now) } } +void NodeParamView::KeyframeViewDragged(int x, int y) +{ + Q_UNUSED(y) + + QMetaObject::invokeMethod(this, "CatchUpScrollToPoint", Qt::QueuedConnection, + Q_ARG(int, x)); +} + } diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index 8bbda8f2f..3620551eb 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -140,6 +140,8 @@ private slots: void FocusChanged(QWidget *old, QWidget *now); + void KeyframeViewDragged(int x, int y); + }; } diff --git a/app/widget/timebased/timebasedwidget.cpp b/app/widget/timebased/timebasedwidget.cpp index b279bd9ff..505e99027 100644 --- a/app/widget/timebased/timebasedwidget.cpp +++ b/app/widget/timebased/timebasedwidget.cpp @@ -183,12 +183,17 @@ void TimeBasedWidget::ScrollBarResizeMoved(int movement) void TimeBasedWidget::PageScrollToPlayhead() { - PageScrollInternal(true); + PageScrollInternal(qRound(TimeToScene(GetTime())), true); } void TimeBasedWidget::CatchUpScrollToPlayhead() { - PageScrollInternal(false); + CatchUpScrollToPoint(qRound(TimeToScene(GetTime()))); +} + +void TimeBasedWidget::CatchUpScrollToPoint(int point) +{ + PageScrollInternal(point, false); } TimeRuler *TimeBasedWidget::ruler() const @@ -481,31 +486,33 @@ void TimeBasedWidget::ResetPoint(Timeline::MovementMode m) Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(GetTimelinePointsProject(), points_, r)); } -void TimeBasedWidget::PageScrollInternal(bool whole_page_scroll) +void TimeBasedWidget::PageScrollInternal(QScrollBar *bar, int maximum, int screen_position, bool whole_page_scroll) { - int playhead_pos = qRound(TimeToScene(GetTime())); - - int viewport_width = ruler()->width(); - int viewport_padding = viewport_width / 16; + int viewport_padding = maximum / 16; if (whole_page_scroll) { - if (playhead_pos < scrollbar()->value()) { + if (screen_position < bar->value()) { // Anchor the playhead to the RIGHT of where we scroll to - scrollbar()->setValue(playhead_pos - viewport_width + viewport_padding); - } else if (playhead_pos > scrollbar()->value() + viewport_width) { + bar->setValue(screen_position - maximum + viewport_padding); + } else if (screen_position > bar->value() + maximum) { // Anchor the playhead to the LEFT of where we scroll to - scrollbar()->setValue(playhead_pos - viewport_padding); + bar->setValue(screen_position - viewport_padding); } } else { // Just jump in increments - if (playhead_pos < scrollbar()->value() + viewport_padding) { - scrollbar()->setValue(scrollbar()->value() - viewport_padding); - } else if (playhead_pos > scrollbar()->value() + viewport_width - viewport_padding) { - scrollbar()->setValue(scrollbar()->value() + viewport_padding); + if (screen_position < bar->value() + viewport_padding) { + bar->setValue(bar->value() - viewport_padding); + } else if (screen_position > bar->value() + maximum - viewport_padding) { + bar->setValue(bar->value() + viewport_padding); } } } +void TimeBasedWidget::PageScrollInternal(int screen_position, bool whole_page_scroll) +{ + PageScrollInternal(scrollbar(), ruler()->width(), screen_position, whole_page_scroll); +} + bool TimeBasedWidget::UserIsDraggingPlayhead() const { if (ruler_->IsDraggingPlayhead()) { diff --git a/app/widget/timebased/timebasedwidget.h b/app/widget/timebased/timebasedwidget.h index a5c3cc6da..1905d294c 100644 --- a/app/widget/timebased/timebasedwidget.h +++ b/app/widget/timebased/timebasedwidget.h @@ -137,6 +137,8 @@ protected slots: */ void SetAutoSetTimebase(bool e); + static void PageScrollInternal(QScrollBar* bar, int maximum, int screen_position, bool whole_page_scroll); + signals: void TimeChanged(const int64_t&); @@ -184,7 +186,7 @@ private: */ void ResetPoint(Timeline::MovementMode m); - void PageScrollInternal(bool whole_page_scroll); + void PageScrollInternal(int screen_position, bool whole_page_scroll); bool UserIsDraggingPlayhead() const; @@ -231,6 +233,8 @@ private slots: void CatchUpScrollToPlayhead(); + void CatchUpScrollToPoint(int point); + }; } diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index be503775f..60da89cc9 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -771,7 +771,11 @@ void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event) if (GetConnectedNode()) { if (active_tool_) { active_tool_->MouseMove(event); + UpdateViewports(); + + QMetaObject::invokeMethod(this, "CatchUpScrollToPoint", Qt::QueuedConnection, + Q_ARG(int, qRound(event->GetSceneX()))); } else { // Mouse is not down, attempt a hover event TimelineTool* hover_tool = GetActiveTool(); diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 192ea02bb..44a083c5d 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -76,8 +76,6 @@ void TimelineView::mouseMoveEvent(QMouseEvent *event) { TimelineViewMouseEvent timeline_event = CreateMouseEvent(event); - - if (HandMove(event) || PlayheadMove(event)) { // Let the parent handle this return;