From 94b2cebeea05d5bf15f55fb8c3132d84bd4ac479 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 10 May 2021 11:15:37 +1000 Subject: [PATCH] ui: merged nodeview/timelineview scrolling code Greatly improves code quality and maintainability --- app/widget/curvewidget/curveview.cpp | 7 -- app/widget/curvewidget/curveview.h | 2 - .../handmovableview/handmovableview.cpp | 47 +++++++- app/widget/handmovableview/handmovableview.h | 6 + app/widget/keyframeview/keyframeview.cpp | 8 -- app/widget/keyframeview/keyframeview.h | 2 - app/widget/nodeview/nodeview.cpp | 24 +--- app/widget/nodeview/nodeview.h | 4 +- app/widget/timebased/timebasedview.cpp | 111 +++++++----------- app/widget/timebased/timebasedview.h | 4 +- .../timelinewidget/view/timelineview.cpp | 20 ++-- 11 files changed, 105 insertions(+), 130 deletions(-) diff --git a/app/widget/curvewidget/curveview.cpp b/app/widget/curvewidget/curveview.cpp index 265f0784f..d8dae394f 100644 --- a/app/widget/curvewidget/curveview.cpp +++ b/app/widget/curvewidget/curveview.cpp @@ -305,13 +305,6 @@ void CurveView::VerticalScaleChangedEvent(double scale) } } -void CurveView::wheelEvent(QWheelEvent *event) -{ - if (!HandleZoomFromScroll(event)) { - KeyframeViewBase::wheelEvent(event); - } -} - void CurveView::ContextMenuEvent(Menu &m) { m.addSeparator(); diff --git a/app/widget/curvewidget/curveview.h b/app/widget/curvewidget/curveview.h index bb1ed1657..f86f7ceed 100644 --- a/app/widget/curvewidget/curveview.h +++ b/app/widget/curvewidget/curveview.h @@ -66,8 +66,6 @@ protected: virtual void VerticalScaleChangedEvent(double scale) override; - virtual void wheelEvent(QWheelEvent* event) override; - virtual void ContextMenuEvent(Menu &m) override; private: diff --git a/app/widget/handmovableview/handmovableview.cpp b/app/widget/handmovableview/handmovableview.cpp index 7cc3c4c0a..5fb808f6d 100644 --- a/app/widget/handmovableview/handmovableview.cpp +++ b/app/widget/handmovableview/handmovableview.cpp @@ -22,12 +22,15 @@ #include +#include "config/config.h" #include "core.h" namespace olive { +#define super QGraphicsView + HandMovableView::HandMovableView(QWidget* parent) : - QGraphicsView(parent), + super(parent), dragging_hand_(false) { connect(Core::instance(), &Core::ToolChanged, this, &HandMovableView::ApplicationToolChanged); @@ -62,7 +65,7 @@ bool HandMovableView::HandPress(QMouseEvent *event) Qt::LeftButton, event->modifiers()); - QGraphicsView::mousePressEvent(&transformed); + super::mousePressEvent(&transformed); return true; } @@ -80,7 +83,7 @@ bool HandMovableView::HandMove(QMouseEvent *event) Qt::LeftButton, event->modifiers()); - QGraphicsView::mouseMoveEvent(&transformed); + super::mouseMoveEvent(&transformed); } return dragging_hand_; } @@ -95,7 +98,7 @@ bool HandMovableView::HandRelease(QMouseEvent *event) Qt::LeftButton, event->modifiers()); - QGraphicsView::mouseReleaseEvent(&transformed); + super::mouseReleaseEvent(&transformed); setInteractive(true); setDragMode(pre_hand_drag_mode_); @@ -108,15 +111,47 @@ bool HandMovableView::HandRelease(QMouseEvent *event) return false; } -void HandMovableView::SetDefaultDragMode(QGraphicsView::DragMode mode) +void HandMovableView::SetDefaultDragMode(HandMovableView::DragMode mode) { default_drag_mode_ = mode; setDragMode(default_drag_mode_); } -const QGraphicsView::DragMode &HandMovableView::GetDefaultDragMode() const +const HandMovableView::DragMode &HandMovableView::GetDefaultDragMode() const { return default_drag_mode_; } +bool HandMovableView::WheelEventIsAZoomEvent(QWheelEvent *event) +{ + return (static_cast(event->modifiers() & Qt::ControlModifier) == !Config::Current()[QStringLiteral("ScrollZooms")].toBool()); +} + +void HandMovableView::wheelEvent(QWheelEvent *event) +{ + if (WheelEventIsAZoomEvent(event)) { + if (!event->angleDelta().isNull()) { + qreal multiplier = 1.0 + (static_cast(event->angleDelta().x() + event->angleDelta().y()) * 0.001); + + QPointF cursor_pos; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + cursor_pos = event->position(); +#else + cursor_pos = event->posF(); +#endif + + ZoomIntoCursorPosition(event, multiplier, cursor_pos); + } + } else { + super::wheelEvent(event); + } +} + +void HandMovableView::ZoomIntoCursorPosition(QWheelEvent *event, double multiplier, const QPointF &cursor_pos) +{ + Q_UNUSED(event) + Q_UNUSED(multiplier) + Q_UNUSED(cursor_pos) +} + } diff --git a/app/widget/handmovableview/handmovableview.h b/app/widget/handmovableview/handmovableview.h index 73cb1b2a0..15c5d2b8c 100644 --- a/app/widget/handmovableview/handmovableview.h +++ b/app/widget/handmovableview/handmovableview.h @@ -43,6 +43,12 @@ protected: void SetDefaultDragMode(DragMode mode); const DragMode& GetDefaultDragMode() const; + static bool WheelEventIsAZoomEvent(QWheelEvent* event); + + virtual void wheelEvent(QWheelEvent* event) override; + + virtual void ZoomIntoCursorPosition(QWheelEvent* event, double multiplier, const QPointF &cursor_pos); + private: bool dragging_hand_; DragMode pre_hand_drag_mode_; diff --git a/app/widget/keyframeview/keyframeview.cpp b/app/widget/keyframeview/keyframeview.cpp index 813c7bd5f..bba5f29f9 100644 --- a/app/widget/keyframeview/keyframeview.cpp +++ b/app/widget/keyframeview/keyframeview.cpp @@ -43,14 +43,6 @@ void KeyframeView::SetElementY(const NodeInput &c, int y) } } } - -void KeyframeView::wheelEvent(QWheelEvent *event) -{ - if (!HandleZoomFromScroll(event)) { - KeyframeViewBase::wheelEvent(event); - } -} - void KeyframeView::SceneRectUpdateEvent(QRectF &rect) { rect.setY(0); diff --git a/app/widget/keyframeview/keyframeview.h b/app/widget/keyframeview/keyframeview.h index 9d390b962..9b7f76d89 100644 --- a/app/widget/keyframeview/keyframeview.h +++ b/app/widget/keyframeview/keyframeview.h @@ -39,8 +39,6 @@ public: void SetElementY(const NodeInput& c, int y); protected: - virtual void wheelEvent(QWheelEvent* event) override; - virtual void SceneRectUpdateEvent(QRectF& rect) override; public slots: diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index d15d4a9e0..909861a38 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -622,24 +622,6 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event) super::mouseReleaseEvent(event); } -void NodeView::wheelEvent(QWheelEvent *event) -{ - if (TimeBasedView::WheelEventIsAZoomEvent(event)) { - qreal multiplier = 1.0 + (static_cast(event->angleDelta().x() + event->angleDelta().y()) * 0.001); - - QPointF cursor_pos; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - cursor_pos = event->position(); -#else - cursor_pos = event->posF(); -#endif - - ZoomIntoCursorPosition(multiplier, cursor_pos); - } else { - QWidget::wheelEvent(event); - } -} - void NodeView::UpdateSelectionCache() { QVector current_selection = scene_.GetSelectedNodes(); @@ -874,8 +856,10 @@ void NodeView::DisconnectSelectionChangedSignal() disconnect(&scene_, &QGraphicsScene::selectionChanged, this, &NodeView::UpdateSelectionCache); } -void NodeView::ZoomIntoCursorPosition(double multiplier, const QPointF& cursor_pos) +void NodeView::ZoomIntoCursorPosition(QWheelEvent *event, double multiplier, const QPointF& cursor_pos) { + Q_UNUSED(event) + double test_scale = scale_ * multiplier; if (test_scale > kMinimumScale) { @@ -900,7 +884,7 @@ void NodeView::ZoomFromKeyboard(double multiplier) cursor_pos = QPoint(width()/2, height()/2); } - ZoomIntoCursorPosition(multiplier, cursor_pos); + ZoomIntoCursorPosition(nullptr, multiplier, cursor_pos); } NodeView::NodeViewAttachNodesToCursor::NodeViewAttachNodesToCursor(NodeView *view, const QVector &nodes) : diff --git a/app/widget/nodeview/nodeview.h b/app/widget/nodeview/nodeview.h index e1edc1990..28fb3c2d9 100644 --- a/app/widget/nodeview/nodeview.h +++ b/app/widget/nodeview/nodeview.h @@ -90,7 +90,7 @@ protected: virtual void mouseMoveEvent(QMouseEvent *event) override; virtual void mouseReleaseEvent(QMouseEvent* event) override; - virtual void wheelEvent(QWheelEvent* event) override; + virtual void ZoomIntoCursorPosition(QWheelEvent *event, double multiplier, const QPointF &cursor_pos) override; private: void AttachNodesToCursor(const QVector &nodes); @@ -106,8 +106,6 @@ private: void ConnectSelectionChangedSignal(); void DisconnectSelectionChangedSignal(); - void ZoomIntoCursorPosition(double multiplier, const QPointF &cursor_pos); - void ZoomFromKeyboard(double multiplier); class NodeViewAttachNodesToCursor : public UndoCommand diff --git a/app/widget/timebased/timebasedview.cpp b/app/widget/timebased/timebasedview.cpp index be37f3e20..d0053dd17 100644 --- a/app/widget/timebased/timebasedview.cpp +++ b/app/widget/timebased/timebasedview.cpp @@ -26,7 +26,6 @@ #include #include "common/timecodefunctions.h" -#include "config/config.h" namespace olive { @@ -99,6 +98,47 @@ void TimeBasedView::VerticalScaleChangedEvent(double) { } +void TimeBasedView::ZoomIntoCursorPosition(QWheelEvent *event, double scale_multiplier, const QPointF &cursor_pos) +{ + // If CTRL is held (or a preference is set to swap CTRL behavior), we zoom instead of scrolling + bool only_vertical = false; + bool only_horizontal = false; + + // Ctrl+Shift limits to only one axis + // Alt switches between horizontal only (alt held) or vertical only (alt not held) + if (y_axis_enabled_) { + if (event->modifiers() & Qt::ShiftModifier) { + if (event->modifiers() & Qt::AltModifier) { + only_horizontal = true; + } else { + only_vertical = true; + } + } + } else { + only_horizontal = true; + } + + if (!only_vertical) { + double new_x_scale = GetScale() * scale_multiplier; + + int new_x_scroll = qRound(double(cursor_pos.x() + horizontalScrollBar()->value()) / GetScale() * new_x_scale - cursor_pos.x()); + + emit ScaleChanged(new_x_scale); + + horizontalScrollBar()->setValue(new_x_scroll); + } + + if (!only_horizontal) { + double new_y_scale = GetYScale() * scale_multiplier; + + int new_y_scroll = qRound(double(cursor_pos.y() + verticalScrollBar()->value()) / GetYScale() * new_y_scale - cursor_pos.y()); + + SetYScale(new_y_scale); + + verticalScrollBar()->setValue(new_y_scroll); + } +} + void TimeBasedView::SetYScale(const double &y_scale) { y_scale_ = y_scale; @@ -262,73 +302,4 @@ void TimeBasedView::ScaleChangedEvent(const double &scale) viewport()->update(); } -bool TimeBasedView::HandleZoomFromScroll(QWheelEvent *event) -{ - if (WheelEventIsAZoomEvent(event)) { - // If CTRL is held (or a preference is set to swap CTRL behavior), we zoom instead of scrolling - if (!event->angleDelta().isNull()) { - bool only_vertical = false; - bool only_horizontal = false; - - // Ctrl+Shift limits to only one axis - // Alt switches between horizontal only (alt held) or vertical only (alt not held) - if (y_axis_enabled_) { - if (event->modifiers() & Qt::ShiftModifier) { - if (event->modifiers() & Qt::AltModifier) { - only_horizontal = true; - } else { - only_vertical = true; - } - } - } else { - only_horizontal = true; - } - - double scale_multiplier; - - if (event->angleDelta().x() + event->angleDelta().y() > 0) { - scale_multiplier = 1.1; - } else { - scale_multiplier = 0.9; - } - - QPointF cursor_pos; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - cursor_pos = event->position(); -#else - cursor_pos = event->posF(); -#endif - - if (!only_vertical) { - double new_x_scale = GetScale() * scale_multiplier; - - int new_x_scroll = qRound(double(cursor_pos.x() + horizontalScrollBar()->value()) / GetScale() * new_x_scale - cursor_pos.x()); - - emit ScaleChanged(new_x_scale); - - horizontalScrollBar()->setValue(new_x_scroll); - } - - if (!only_horizontal) { - double new_y_scale = GetYScale() * scale_multiplier; - - int new_y_scroll = qRound(double(cursor_pos.y() + verticalScrollBar()->value()) / GetYScale() * new_y_scale - cursor_pos.y()); - - SetYScale(new_y_scale); - - verticalScrollBar()->setValue(new_y_scroll); - } - } - - return true; - } - - return false; -} - -bool TimeBasedView::WheelEventIsAZoomEvent(QWheelEvent *event) -{ - return (static_cast(event->modifiers() & Qt::ControlModifier) == !Config::Current()[QStringLiteral("ScrollZooms")].toBool()); -} - } diff --git a/app/widget/timebased/timebasedview.h b/app/widget/timebased/timebasedview.h index ef02a12b2..55a6ec6d8 100644 --- a/app/widget/timebased/timebasedview.h +++ b/app/widget/timebased/timebasedview.h @@ -50,8 +50,6 @@ public: const double& GetYScale() const; void SetYScale(const double& y_scale); - static bool WheelEventIsAZoomEvent(QWheelEvent* event); - bool IsDraggingPlayhead() const { return dragging_playhead_; @@ -78,7 +76,7 @@ protected: virtual void VerticalScaleChangedEvent(double scale); - bool HandleZoomFromScroll(QWheelEvent* event); + virtual void ZoomIntoCursorPosition(QWheelEvent *event, double multiplier, const QPointF &cursor_pos) override; rational GetPlayheadTime() const; diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 2b2a24dbc..75cb091ad 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -36,8 +36,10 @@ namespace olive { +#define super TimeBasedView + TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) : - TimeBasedView(parent), + super(parent), selections_(nullptr), ghosts_(nullptr), show_beam_cursor_(false), @@ -65,7 +67,7 @@ void TimelineView::mousePressEvent(QMouseEvent *event) if (dragMode() != GetDefaultDragMode()) { // Use default behavior when hand dragging for instance - TimeBasedView::mousePressEvent(event); + super::mousePressEvent(event); return; } @@ -82,7 +84,7 @@ void TimelineView::mouseMoveEvent(QMouseEvent *event) } if (dragMode() != GetDefaultDragMode()) { - TimeBasedView::mouseMoveEvent(event); + super::mouseMoveEvent(event); return; } @@ -97,7 +99,7 @@ void TimelineView::mouseReleaseEvent(QMouseEvent *event) } if (dragMode() != GetDefaultDragMode()) { - TimeBasedView::mouseReleaseEvent(event); + super::mouseReleaseEvent(event); return; } @@ -115,14 +117,14 @@ void TimelineView::mouseDoubleClickEvent(QMouseEvent *event) void TimelineView::wheelEvent(QWheelEvent *event) { - if (HandleZoomFromScroll(event)) { - return; + if (WheelEventIsAZoomEvent(event)) { + super::wheelEvent(event); } else { #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) QPoint angle_delta = event->angleDelta(); - if (Config::Current()["InvertTimelineScrollAxes"].toBool() // Check if config is set to invert timeline axes + if (Config::Current()[QStringLiteral("InvertTimelineScrollAxes")].toBool() // Check if config is set to invert timeline axes && event->source() != Qt::MouseEventSynthesizedBySystem) { // Never flip axes on Apple trackpads though angle_delta = QPoint(angle_delta.y(), angle_delta.x()); } @@ -164,7 +166,7 @@ void TimelineView::wheelEvent(QWheelEvent *event) ); #endif - QGraphicsView::wheelEvent(&e); + super::wheelEvent(&e); } } @@ -296,7 +298,7 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect) } // Draw standard TimelineViewBase things (such as playhead) - TimeBasedView::drawForeground(painter, rect); + super::drawForeground(painter, rect); } void TimelineView::ToolChangedEvent(Tool::Item tool)