diff --git a/app/widget/curvewidget/curvewidget.cpp b/app/widget/curvewidget/curvewidget.cpp index 71d309f22..123779e1b 100644 --- a/app/widget/curvewidget/curvewidget.cpp +++ b/app/widget/curvewidget/curvewidget.cpp @@ -54,6 +54,7 @@ CurveWidget::CurveWidget(QWidget *parent) : ruler_view_layout->addWidget(ruler()); view_ = new CurveView(); + connect(view_, &CurveView::RequestCenterScrollOnPlayhead, this, &CurveWidget::CenterScrollOnPlayhead); ruler_view_layout->addWidget(view_); layout->addLayout(ruler_view_layout); @@ -62,6 +63,9 @@ 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); + + // TimeBasedWidget's scrollbar has extra functionality that we can take advantage of + view_->setHorizontalScrollBar(scrollbar()); connect(view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll); widget_bridge_layout_ = new QHBoxLayout(); @@ -158,7 +162,7 @@ void CurveWidget::ScaleChangedEvent(const double &scale) { TimeBasedWidget::ScaleChangedEvent(scale); - view_->SetScaleAndCenterOnPlayhead(scale); + view_->SetScale(scale); } void CurveWidget::UpdateInputLabel() diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index 2357ae456..a3a0eccfa 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -69,6 +69,7 @@ NodeParamView::NodeParamView(QWidget *parent) : // Create keyframe view keyframe_view_ = new KeyframeView(); keyframe_view_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + connect(keyframe_view_, &KeyframeView::RequestCenterScrollOnPlayhead, this, &NodeParamView::CenterScrollOnPlayhead); bottom_item_ = keyframe_view_->scene()->addRect(0, 0, 1, 1); keyframe_area_layout->addWidget(keyframe_view_); @@ -104,6 +105,9 @@ NodeParamView::NodeParamView(QWidget *parent) : connect(vertical_scrollbar_, &QScrollBar::valueChanged, scroll_area->verticalScrollBar(), &QScrollBar::setValue); connect(vertical_scrollbar_, &QScrollBar::valueChanged, keyframe_view_->verticalScrollBar(), &QScrollBar::setValue); + // TimeBasedWidget's scrollbar has extra functionality that we can take advantage of + keyframe_view_->setHorizontalScrollBar(scrollbar()); + connect(keyframe_view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll); // Set a default scale - FIXME: Hardcoded @@ -173,7 +177,7 @@ void NodeParamView::ScaleChangedEvent(const double &scale) { TimeBasedWidget::ScaleChangedEvent(scale); - keyframe_view_->SetScaleAndCenterOnPlayhead(scale); + keyframe_view_->SetScale(scale); } void NodeParamView::TimebaseChangedEvent(const rational &timebase) diff --git a/app/widget/timebased/timebased.cpp b/app/widget/timebased/timebased.cpp index ed836ea58..428697347 100644 --- a/app/widget/timebased/timebased.cpp +++ b/app/widget/timebased/timebased.cpp @@ -13,6 +13,15 @@ TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_statu scrollbar_ = new QScrollBar(Qt::Horizontal, this); } +void TimeBasedWidget::SetScaleAndCenterOnPlayhead(const double &scale) +{ + SetScale(scale); + + // Zoom towards the playhead + // (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated) + QTimer::singleShot(0, this, &TimeBasedWidget::CenterScrollOnPlayhead); +} + rational TimeBasedWidget::GetTime() const { return Timecode::timestamp_to_time(ruler()->GetTime(), timebase()); @@ -118,12 +127,12 @@ void TimeBasedWidget::SetScale(const double &scale) void TimeBasedWidget::ZoomIn() { - SetScale(GetScale() * 2); + SetScaleAndCenterOnPlayhead(GetScale() * 2); } void TimeBasedWidget::ZoomOut() { - SetScale(GetScale() * 0.5); + SetScaleAndCenterOnPlayhead(GetScale() * 0.5); } void TimeBasedWidget::GoToPrevCut() @@ -222,3 +231,8 @@ void TimeBasedWidget::SetTimeAndSignal(const int64_t &t) SetTime(t); emit TimeChanged(t); } + +void TimeBasedWidget::CenterScrollOnPlayhead() +{ + scrollbar_->setValue(qRound(TimeToScene(Timecode::timestamp_to_time(ruler_->GetTime(), timebase()))) - scrollbar_->width()/2); +} diff --git a/app/widget/timebased/timebased.h b/app/widget/timebased/timebased.h index 7c5b77304..f0242324e 100644 --- a/app/widget/timebased/timebased.h +++ b/app/widget/timebased/timebased.h @@ -26,6 +26,8 @@ public: void ConnectViewerNode(ViewerOutput *node); + void SetScaleAndCenterOnPlayhead(const double& scale); + public slots: // FIXME: Rename this to SetTimestamp to reduce confusion void SetTime(int64_t timestamp); @@ -70,6 +72,12 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; +protected slots: + /** + * @brief Slot to center the horizontal scroll bar on the playhead's current position + */ + void CenterScrollOnPlayhead(); + signals: void TimeChanged(const int64_t&); diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 16c66501a..d4d2b36f9 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -88,6 +88,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : connect(view, &TimelineView::customContextMenuRequested, this, &TimelineWidget::ShowContextMenu); connect(scrollbar(), &QScrollBar::valueChanged, view->horizontalScrollBar(), &QScrollBar::setValue); connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, scrollbar(), &QScrollBar::setValue); + connect(view, &TimelineView::RequestCenterScrollOnPlayhead, this, &TimelineWidget::CenterScrollOnPlayhead); connect(view, &TimelineView::MousePressed, this, &TimelineWidget::ViewMousePressed); connect(view, &TimelineView::MouseMoved, this, &TimelineWidget::ViewMouseMoved); diff --git a/app/widget/timelinewidget/view/timelineviewbase.cpp b/app/widget/timelinewidget/view/timelineviewbase.cpp index 978dabdb5..31101557d 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.cpp +++ b/app/widget/timelinewidget/view/timelineviewbase.cpp @@ -27,7 +27,7 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) : scene_.addItem(end_item_); // Set default scale - SetScaleAndCenterOnPlayhead(1.0); + SetScale(1.0); SetDefaultDragMode(NoDrag); @@ -57,7 +57,7 @@ void TimelineViewBase::SetTime(const int64_t time) PageScrollToPlayhead(); break; case AutoScroll::kSmooth: - CenterScrollOnPlayhead(); + emit RequestCenterScrollOnPlayhead(); break; } @@ -198,7 +198,7 @@ void TimelineViewBase::ToolChangedEvent(Tool::Item) qreal TimelineViewBase::GetPlayheadX() { - return TimeToScene(rational(playhead_ * timebase().numerator(), timebase().denominator())); + return TimeToScene(Timecode::timestamp_to_time(playhead_, timebase())); } void TimelineViewBase::SetEndTime(const rational &length) @@ -253,11 +253,6 @@ void TimelineViewBase::UpdateSceneRect() scene_.setSceneRect(bounding_rect); } -void TimelineViewBase::CenterScrollOnPlayhead() -{ - horizontalScrollBar()->setValue(qRound(GetPlayheadX()) - viewport()->width()/2); -} - void TimelineViewBase::PageScrollToPlayhead() { int playhead_pos = qRound(GetPlayheadX()); @@ -290,15 +285,6 @@ void TimelineViewBase::ScaleChangedEvent(const double &scale) viewport()->update(); } -void TimelineViewBase::SetScaleAndCenterOnPlayhead(const double &scale) -{ - SetScale(scale); - - // Zoom towards the playhead - // (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated) - QTimer::singleShot(0, this, &TimelineViewBase::CenterScrollOnPlayhead); -} - bool TimelineViewBase::HandleZoomFromScroll(QWheelEvent *event) { if (WheelEventIsAZoomEvent(event)) { diff --git a/app/widget/timelinewidget/view/timelineviewbase.h b/app/widget/timelinewidget/view/timelineviewbase.h index 8201e9773..f63f534c3 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.h +++ b/app/widget/timelinewidget/view/timelineviewbase.h @@ -16,8 +16,6 @@ public: void SetEndTime(const rational& length); - void SetScaleAndCenterOnPlayhead(const double& scale); - static const double kMaximumScale; public slots: @@ -28,6 +26,8 @@ signals: void ScaleChanged(double scale); + void RequestCenterScrollOnPlayhead(); + protected: virtual void drawForeground(QPainter *painter, const QRectF &rect) override; @@ -87,11 +87,6 @@ private slots: */ void UpdateSceneRect(); - /** - * @brief Slot to center the horizontal scroll bar on the playhead's current position - */ - void CenterScrollOnPlayhead(); - /** * @brief Slot to handle page scrolling of the playhead *