diff --git a/app/widget/curvewidget/curvewidget.cpp b/app/widget/curvewidget/curvewidget.cpp index 89f631170..512992201 100644 --- a/app/widget/curvewidget/curvewidget.cpp +++ b/app/widget/curvewidget/curvewidget.cpp @@ -77,6 +77,7 @@ CurveWidget::CurveWidget(QWidget *parent) : view_ = new CurveView(); connect(view_, &CurveView::RequestCenterScrollOnPlayhead, this, &CurveWidget::CenterScrollOnPlayhead); + ConnectTimelineView(view_); ruler_view_layout->addWidget(view_); layout->addLayout(ruler_view_layout); diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index dcb183ece..897e03cfc 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -71,6 +71,7 @@ NodeParamView::NodeParamView(QWidget *parent) : // Create keyframe view keyframe_view_ = new KeyframeView(); keyframe_view_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ConnectTimelineView(keyframe_view_); connect(keyframe_view_, &KeyframeView::RequestCenterScrollOnPlayhead, this, &NodeParamView::CenterScrollOnPlayhead); bottom_item_ = keyframe_view_->scene()->addRect(0, 0, 1, 1); keyframe_area_layout->addWidget(keyframe_view_); @@ -109,6 +110,7 @@ NodeParamView::NodeParamView(QWidget *parent) : // TimeBasedWidget's scrollbar has extra functionality that we can take advantage of keyframe_view_->setHorizontalScrollBar(scrollbar()); + keyframe_view_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); connect(keyframe_view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll); @@ -120,6 +122,8 @@ NodeParamView::NodeParamView(QWidget *parent) : void NodeParamView::SetNodes(QList nodes) { + ConnectViewerNode(nullptr); + // If we already have item widgets, delete them all now foreach (NodeParamViewItem* item, items_) { delete item; @@ -134,26 +138,28 @@ void NodeParamView::SetNodes(QList nodes) // Set the internal list to the one we've received nodes_ = nodes; - // For each node, create a widget - foreach (Node* node, nodes_) { - NodeParamViewItem* item = new NodeParamViewItem(node); - - // Insert the widget before the stretch - param_layout_->insertWidget(param_layout_->count() - 1, item); - - connect(item, &NodeParamViewItem::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe); - connect(item, &NodeParamViewItem::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe); - connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged); - connect(item, &NodeParamViewItem::InputClicked, this, &NodeParamView::SelectedInputChanged); - - items_.append(item); - - QTimer::singleShot(1, item, &NodeParamViewItem::SignalAllKeyframes); - } - if (!nodes_.isEmpty()) { + // For each node, create a widget + foreach (Node* node, nodes_) { + NodeParamViewItem* item = new NodeParamViewItem(node); + + // Insert the widget before the stretch + param_layout_->insertWidget(param_layout_->count() - 1, item); + + connect(item, &NodeParamViewItem::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe); + connect(item, &NodeParamViewItem::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe); + connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged); + connect(item, &NodeParamViewItem::InputClicked, this, &NodeParamView::SelectedInputChanged); + + items_.append(item); + + QTimer::singleShot(1, item, &NodeParamViewItem::SignalAllKeyframes); + } + ViewerOutput* viewer = nodes_.first()->FindOutputNode(); + ConnectViewerNode(viewer); + if (viewer) { SetTimebase(viewer->video_params().time_base()); @@ -166,9 +172,10 @@ void NodeParamView::SetNodes(QList nodes) emit TimeTargetChanged(viewer); } - } - SetTime(0); + // Forces the scroll to update to this time + keyframe_view_->SetTime(ruler()->GetTime()); + } } void NodeParamView::resizeEvent(QResizeEvent *event) diff --git a/app/widget/timebased/timebased.cpp b/app/widget/timebased/timebased.cpp index 01f787093..b2e2c7836 100644 --- a/app/widget/timebased/timebased.cpp +++ b/app/widget/timebased/timebased.cpp @@ -96,15 +96,23 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node) ConnectNodeInternal(viewer_node_); } + + UpdateMaximumScroll(); } void TimeBasedWidget::UpdateMaximumScroll() { - if (!viewer_node_ || !auto_max_scrollbar_) { - return; + rational length = (viewer_node_) ? viewer_node_->Length() : rational(); + + if (auto_max_scrollbar_) { + scrollbar_->setMaximum(qMax(0, qCeil(TimeToScene(length)) - width())); } - scrollbar_->setMaximum(qMax(0, qCeil(TimeToScene(viewer_node_->Length())) - width())); + foreach (TimelineViewBase* base, timeline_views_) { + base->SetEndTime(length); + } + + ruler()->SetCacheStatusLength(length); } void TimeBasedWidget::ScrollBarResized(const double &multiplier) @@ -183,6 +191,11 @@ TimelinePoints *TimeBasedWidget::GetConnectedTimelinePoints() const return points_; } +void TimeBasedWidget::ConnectTimelineView(TimelineViewBase *base) +{ + timeline_views_.append(base); +} + void TimeBasedWidget::SetTime(int64_t timestamp) { ruler_->SetTime(timestamp); diff --git a/app/widget/timebased/timebased.h b/app/widget/timebased/timebased.h index 52377d6cc..110e1e101 100644 --- a/app/widget/timebased/timebased.h +++ b/app/widget/timebased/timebased.h @@ -27,6 +27,7 @@ #include "node/output/viewer/viewer.h" #include "widget/resizablescrollbar/resizablescrollbar.h" #include "widget/timelinewidget/timelinescaledobject.h" +#include "widget/timelinewidget/view/timelineview.h" #include "widget/timeruler/timeruler.h" OLIVE_NAMESPACE_ENTER @@ -111,6 +112,8 @@ protected: TimelinePoints* GetConnectedTimelinePoints() const; + void ConnectTimelineView(TimelineViewBase* base); + protected slots: /** * @brief Slot to center the horizontal scroll bar on the playhead's current position @@ -153,6 +156,8 @@ private: TimelinePoints* points_; + QList timeline_views_; + private slots: void UpdateMaximumScroll(); diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index ec953cb12..fdcc57c5c 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -106,6 +106,8 @@ TimelineWidget::TimelineWidget(QWidget *parent) : view_splitter->addWidget(tview); + ConnectTimelineView(view); + connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll); connect(view, &TimelineView::ScaleChanged, this, &TimelineWidget::SetScale); connect(view, &TimelineView::TimeChanged, this, &TimelineWidget::ViewTimestampChanged); @@ -223,7 +225,6 @@ void TimelineWidget::ScaleChangedEvent(const double &scale) void TimelineWidget::ConnectNodeInternal(ViewerOutput *n) { - connect(n, &ViewerOutput::LengthChanged, this, &TimelineWidget::UpdateTimelineLength); connect(n, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock); connect(n, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock); connect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack); @@ -232,7 +233,6 @@ void TimelineWidget::ConnectNodeInternal(ViewerOutput *n) connect(n, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged); SetTimebase(n->video_params().time_base()); - UpdateTimelineLength(n->Length()); for (int i=0;i(i); @@ -242,7 +242,6 @@ void TimelineWidget::ConnectNodeInternal(ViewerOutput *n) track_view->ConnectTrackList(track_list); view->ConnectTrackList(track_list); - view->SetEndTime(n->Length()); // Defer to the track to make all the block UI items necessary foreach (TrackOutput* track, n->track_list(track_type)->Tracks()) { @@ -253,7 +252,6 @@ void TimelineWidget::ConnectNodeInternal(ViewerOutput *n) void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n) { - disconnect(n, &ViewerOutput::LengthChanged, this, &TimelineWidget::UpdateTimelineLength); disconnect(n, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock); disconnect(n, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock); disconnect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack); @@ -860,14 +858,6 @@ bool TimelineWidget::HasGhosts() return !ghost_items_.isEmpty(); } -void TimelineWidget::UpdateTimelineLength(const rational &length) -{ - foreach (TimelineAndTrackView* view, views_) { - view->view()->SetEndTime(length); - } - ruler()->SetCacheStatusLength(length); -} - TimelineWidget::Tool *TimelineWidget::GetActiveTool() { return tools_.at(Core::instance()->tool()); diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index aaf47d064..b4f893070 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -467,8 +467,6 @@ private: void UpdateViewTimebases(); private slots: - void UpdateTimelineLength(const rational& length); - void ViewMousePressed(TimelineViewMouseEvent* event); void ViewMouseMoved(TimelineViewMouseEvent* event); void ViewMouseReleased(TimelineViewMouseEvent* event); diff --git a/app/widget/timelinewidget/view/timelineviewbase.cpp b/app/widget/timelinewidget/view/timelineviewbase.cpp index b328d816a..bd1e97960 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.cpp +++ b/app/widget/timelinewidget/view/timelineviewbase.cpp @@ -74,7 +74,7 @@ void TimelineViewBase::SetTime(const int64_t time) // Do nothing break; case AutoScroll::kPage: - PageScrollToPlayhead(); + QMetaObject::invokeMethod(this, "PageScrollToPlayhead", Qt::QueuedConnection); break; case AutoScroll::kSmooth: emit RequestCenterScrollOnPlayhead(); diff --git a/app/widget/timelinewidget/view/timelineviewbase.h b/app/widget/timelinewidget/view/timelineviewbase.h index 63f95e43b..ccd1d0b68 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.h +++ b/app/widget/timelinewidget/view/timelineviewbase.h @@ -36,13 +36,13 @@ class TimelineViewBase : public QGraphicsView, public TimelineScaledObject public: TimelineViewBase(QWidget* parent = nullptr); - void SetEndTime(const rational& length); - static const double kMaximumScale; public slots: void SetTime(const int64_t time); + void SetEndTime(const rational& length); + signals: void TimeChanged(const int64_t& time);