From 2c7e974f786cb4f5fbf6021d7247a9edbdbfbfe0 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 24 Jan 2021 18:38:57 +1100 Subject: [PATCH] scroll only in increments when dragging the playhead --- app/widget/timebased/timebasedview.h | 5 + app/widget/timebased/timebasedwidget.cpp | 97 +++++++++++++++----- app/widget/timebased/timebasedwidget.h | 8 +- app/widget/timelinewidget/timelinewidget.cpp | 6 +- app/widget/timeruler/seekablewidget.cpp | 6 +- app/widget/timeruler/seekablewidget.h | 7 ++ 6 files changed, 98 insertions(+), 31 deletions(-) diff --git a/app/widget/timebased/timebasedview.h b/app/widget/timebased/timebasedview.h index 2aa646719..40acd8b63 100644 --- a/app/widget/timebased/timebasedview.h +++ b/app/widget/timebased/timebasedview.h @@ -52,6 +52,11 @@ public: static bool WheelEventIsAZoomEvent(QWheelEvent* event); + bool IsDraggingPlayhead() const + { + return dragging_playhead_; + } + public slots: void SetTime(const int64_t time); diff --git a/app/widget/timebased/timebasedwidget.cpp b/app/widget/timebased/timebasedwidget.cpp index 7267161f9..b279bd9ff 100644 --- a/app/widget/timebased/timebasedwidget.cpp +++ b/app/widget/timebased/timebasedwidget.cpp @@ -183,18 +183,12 @@ void TimeBasedWidget::ScrollBarResizeMoved(int movement) void TimeBasedWidget::PageScrollToPlayhead() { - int playhead_pos = qRound(TimeToScene(GetTime())); + PageScrollInternal(true); +} - int viewport_width = ruler()->width(); - int viewport_padding = viewport_width / 16; - - if (playhead_pos < scrollbar()->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) { - // Anchor the playhead to the LEFT of where we scroll to - scrollbar()->setValue(playhead_pos - viewport_padding); - } +void TimeBasedWidget::CatchUpScrollToPlayhead() +{ + PageScrollInternal(false); } TimeRuler *TimeBasedWidget::ruler() const @@ -259,8 +253,13 @@ TimelinePoints *TimeBasedWidget::GetConnectedTimelinePoints() const return points_; } -void TimeBasedWidget::ConnectTimelineView(TimeBasedView *base) +void TimeBasedWidget::ConnectTimelineView(TimeBasedView *base, bool connect_time_change_event) { + if (connect_time_change_event) { + connect(base, &TimeBasedView::TimeChanged, this, &TimeBasedWidget::SetTimestamp); + connect(base, &TimeBasedView::TimeChanged, this, &TimeBasedWidget::TimeChanged); + } + timeline_views_.append(base); } @@ -272,21 +271,29 @@ void TimeBasedWidget::PassWheelEventsToScrollBar(QObject *object) void TimeBasedWidget::SetTimestamp(int64_t timestamp) { - ruler_->SetTime(timestamp); + if (GetTime() != timestamp) { + if (UserIsDraggingPlayhead()) { + // If the user is dragging the playhead, we will simply nudge over and not use autoscroll rules. + QMetaObject::invokeMethod(this, "CatchUpScrollToPlayhead", Qt::QueuedConnection); + } else { + // Otherwise, assume we jumped to this out of nowhere and must now autoscroll + switch (static_cast(Config::Current()["Autoscroll"].toInt())) { + case AutoScroll::kNone: + // Do nothing + break; + case AutoScroll::kPage: + QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection); + break; + case AutoScroll::kSmooth: + QMetaObject::invokeMethod(this, "CenterScrollOnPlayhead", Qt::QueuedConnection); + break; + } + } - switch (static_cast(Config::Current()["Autoscroll"].toInt())) { - case AutoScroll::kNone: - // Do nothing - break; - case AutoScroll::kPage: - QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection); - break; - case AutoScroll::kSmooth: - QMetaObject::invokeMethod(this, "CenterScrollOnPlayhead", Qt::QueuedConnection); - break; + ruler_->SetTime(timestamp); + + TimeChangedEvent(timestamp); } - - TimeChangedEvent(timestamp); } void TimeBasedWidget::SetTimebase(const rational &timebase) @@ -474,6 +481,46 @@ void TimeBasedWidget::ResetPoint(Timeline::MovementMode m) Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(GetTimelinePointsProject(), points_, r)); } +void TimeBasedWidget::PageScrollInternal(bool whole_page_scroll) +{ + int playhead_pos = qRound(TimeToScene(GetTime())); + + int viewport_width = ruler()->width(); + int viewport_padding = viewport_width / 16; + + if (whole_page_scroll) { + if (playhead_pos < scrollbar()->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) { + // Anchor the playhead to the LEFT of where we scroll to + scrollbar()->setValue(playhead_pos - 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); + } + } +} + +bool TimeBasedWidget::UserIsDraggingPlayhead() const +{ + if (ruler_->IsDraggingPlayhead()) { + return true; + } + + foreach (TimeBasedView* view, timeline_views_) { + if (view->IsDraggingPlayhead()) { + return true; + } + } + + return false; +} + void TimeBasedWidget::SetInAtPlayhead() { SetPoint(Timeline::kTrimIn, GetTime()); diff --git a/app/widget/timebased/timebasedwidget.h b/app/widget/timebased/timebasedwidget.h index 253a32acf..a5c3cc6da 100644 --- a/app/widget/timebased/timebasedwidget.h +++ b/app/widget/timebased/timebasedwidget.h @@ -121,7 +121,7 @@ protected: TimelinePoints* GetConnectedTimelinePoints() const; - void ConnectTimelineView(TimeBasedView* base); + void ConnectTimelineView(TimeBasedView* base, bool connect_time_change_event = true); void PassWheelEventsToScrollBar(QObject* object); @@ -184,6 +184,10 @@ private: */ void ResetPoint(Timeline::MovementMode m); + void PageScrollInternal(bool whole_page_scroll); + + bool UserIsDraggingPlayhead() const; + ViewerOutput* viewer_node_; TimeRuler* ruler_; @@ -225,6 +229,8 @@ private slots: */ void PageScrollToPlayhead(); + void CatchUpScrollToPlayhead(); + }; } diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index a302176dc..415a96bcc 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -124,7 +124,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : view_splitter_->addWidget(tview); - ConnectTimelineView(view); + ConnectTimelineView(view, false); connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll); connect(view, &TimelineView::ScaleChanged, this, &TimelineWidget::SetScale); @@ -1012,9 +1012,7 @@ void TimelineWidget::ViewTimestampChanged(int64_t ts) } // Update all other views - SetViewTimestamp(ts); - - ruler()->SetTime(ts); + SetTimestamp(ts); emit TimeChanged(ts); } diff --git a/app/widget/timeruler/seekablewidget.cpp b/app/widget/timeruler/seekablewidget.cpp index b80d332ff..09559a60b 100644 --- a/app/widget/timeruler/seekablewidget.cpp +++ b/app/widget/timeruler/seekablewidget.cpp @@ -34,7 +34,8 @@ SeekableWidget::SeekableWidget(QWidget* parent) : time_(0), timeline_points_(nullptr), scroll_(0), - snap_service_(nullptr) + snap_service_(nullptr), + dragging_(false) { QFontMetrics fm = fontMetrics(); @@ -86,6 +87,7 @@ void SeekableWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { SeekToScreenPoint(event->pos().x()); + dragging_ = true; } } @@ -103,6 +105,8 @@ void SeekableWidget::mouseReleaseEvent(QMouseEvent *event) if (snap_service_) { snap_service_->HideSnaps(); } + + dragging_ = false; } void SeekableWidget::ScaleChangedEvent(const double &) diff --git a/app/widget/timeruler/seekablewidget.h b/app/widget/timeruler/seekablewidget.h index 6f884be39..a21deecbb 100644 --- a/app/widget/timeruler/seekablewidget.h +++ b/app/widget/timeruler/seekablewidget.h @@ -42,6 +42,11 @@ public: void SetSnapService(SnapService* service); + bool IsDraggingPlayhead() const + { + return dragging_; + } + public slots: void SetTime(const int64_t &r); @@ -98,6 +103,8 @@ private: SnapService* snap_service_; + bool dragging_; + }; }