From d1545745d8b697b43f691006c806437973fbbbf5 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Sun, 23 Oct 2022 20:56:04 -0700 Subject: [PATCH] various: moved time from viewer UI to viewer node --- app/core.cpp | 18 ++-- app/core.h | 4 +- app/dialog/export/codec/imagesection.cpp | 1 + app/dialog/export/codec/imagesection.h | 3 + app/dialog/export/export.cpp | 8 +- app/dialog/export/export.h | 8 -- app/dialog/export/exportvideotab.cpp | 1 + app/dialog/export/exportvideotab.h | 2 + app/node/output/viewer/viewer.cpp | 6 ++ app/node/output/viewer/viewer.h | 8 ++ app/panel/timebased/timebased.cpp | 14 --- app/panel/timebased/timebased.h | 8 -- app/widget/curvewidget/curvewidget.cpp | 19 +--- app/widget/curvewidget/curvewidget.h | 5 +- app/widget/keyframeview/keyframeview.cpp | 8 +- app/widget/keyframeview/keyframeview.h | 2 +- app/widget/multicam/multicamwidget.cpp | 6 +- app/widget/nodeparamview/nodeparamview.cpp | 27 +----- app/widget/nodeparamview/nodeparamview.h | 7 +- .../nodeparamviewconnectedlabel.cpp | 31 ++++--- .../nodeparamviewconnectedlabel.h | 4 +- .../nodeparamview/nodeparamviewcontext.cpp | 9 +- .../nodeparamview/nodeparamviewcontext.h | 4 +- .../nodeparamview/nodeparamviewitem.cpp | 23 +---- app/widget/nodeparamview/nodeparamviewitem.h | 18 +--- .../nodeparamviewkeyframecontrol.cpp | 22 ++--- .../nodeparamviewkeyframecontrol.h | 9 +- .../nodeparamviewwidgetbridge.cpp | 25 ++++-- .../nodeparamview/nodeparamviewwidgetbridge.h | 8 +- app/widget/timebased/timebasedview.cpp | 41 +++++---- app/widget/timebased/timebasedview.h | 14 ++- app/widget/timebased/timebasedwidget.cpp | 88 ++++++++----------- app/widget/timebased/timebasedwidget.h | 12 +-- app/widget/timelinewidget/timelinewidget.cpp | 54 +++++------- app/widget/timelinewidget/timelinewidget.h | 3 - .../timelinewidget/view/timelineview.cpp | 13 +-- app/widget/timeruler/seekablewidget.cpp | 8 +- app/widget/timeruler/timeruler.cpp | 2 +- app/widget/timetarget/timetarget.cpp | 13 ++- app/widget/timetarget/timetarget.h | 12 +-- app/widget/viewer/audiowaveformview.cpp | 2 +- app/widget/viewer/footageviewer.cpp | 19 ---- app/widget/viewer/footageviewer.h | 7 -- app/widget/viewer/viewer.cpp | 46 +++++----- app/widget/viewer/viewer.h | 2 +- app/window/mainwindow/mainwindow.cpp | 27 +----- app/window/mainwindow/mainwindow.h | 6 -- 47 files changed, 259 insertions(+), 418 deletions(-) diff --git a/app/core.cpp b/app/core.cpp index c13e83009..78d9b1721 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -379,11 +379,8 @@ void Core::DialogProjectPropertiesShow() void Core::DialogExportShow() { - ViewerOutput* viewer; - rational time; - - if (GetSequenceToExport(&viewer, &time)) { - OpenExportDialogForViewer(viewer, time, false); + if (ViewerOutput* viewer = GetSequenceToExport()) { + OpenExportDialogForViewer(viewer, false); } } @@ -850,7 +847,7 @@ void Core::SaveProjectInternal(Project* project, const QString& override_filenam psm->deleteLater(); } -bool Core::GetSequenceToExport(ViewerOutput **viewer, rational *time) +ViewerOutput *Core::GetSequenceToExport() { // First try the most recently focused time based window TimeBasedPanel* time_panel = PanelManager::instance()->MostRecentlyFocused(); @@ -868,9 +865,7 @@ bool Core::GetSequenceToExport(ViewerOutput **viewer, rational *time) tr("This Sequence is empty. There is nothing to export."), QMessageBox::Ok); } else { - *viewer = time_panel->GetConnectedViewer(); - *time = time_panel->GetTime(); - return true; + return time_panel->GetConnectedViewer(); } } else { QMessageBox::critical(main_window_, @@ -879,7 +874,7 @@ bool Core::GetSequenceToExport(ViewerOutput **viewer, rational *time) QMessageBox::Ok); } - return false; + return nullptr; } QString Core::GetAutoRecoveryIndexFilename() @@ -1249,10 +1244,9 @@ void Core::OpenNodeInViewer(ViewerOutput *viewer) main_window_->OpenNodeInViewer(viewer); } -void Core::OpenExportDialogForViewer(ViewerOutput *viewer, const rational &time, bool start_still_image) +void Core::OpenExportDialogForViewer(ViewerOutput *viewer, bool start_still_image) { ExportDialog* ed = new ExportDialog(viewer, start_still_image, main_window_); - ed->SetTime(time); connect(ed, &ExportDialog::finished, ed, &ExportDialog::deleteLater); ed->open(); connect(ed, &ExportDialog::RequestImportFile, this, &Core::ImportSingleFile); diff --git a/app/core.h b/app/core.h index 8f19c056c..19ffb07dc 100644 --- a/app/core.h +++ b/app/core.h @@ -317,7 +317,7 @@ public: void OpenNodeInViewer(ViewerOutput* viewer); - void OpenExportDialogForViewer(ViewerOutput *viewer, const rational &time, bool start_still_image); + void OpenExportDialogForViewer(ViewerOutput *viewer, bool start_still_image); public slots: /** @@ -551,7 +551,7 @@ private: /** * @brief Retrieves the currently most active sequence for exporting */ - bool GetSequenceToExport(ViewerOutput **viewer, rational *time); + ViewerOutput *GetSequenceToExport(); static QString GetAutoRecoveryIndexFilename(); diff --git a/app/dialog/export/codec/imagesection.cpp b/app/dialog/export/codec/imagesection.cpp index b2bf50fd8..b87ca0a79 100644 --- a/app/dialog/export/codec/imagesection.cpp +++ b/app/dialog/export/codec/imagesection.cpp @@ -47,6 +47,7 @@ ImageSection::ImageSection(QWidget* parent) : frame_slider_->SetMinimum(0); frame_slider_->SetValue(0); frame_slider_->SetDisplayType(RationalSlider::kTime); + connect(frame_slider_, &RationalSlider::ValueChanged, this, &ImageSection::TimeChanged); layout->addWidget(frame_slider_, row, 1); } diff --git a/app/dialog/export/codec/imagesection.h b/app/dialog/export/codec/imagesection.h index 3575ea5a2..b1d6cac61 100644 --- a/app/dialog/export/codec/imagesection.h +++ b/app/dialog/export/codec/imagesection.h @@ -59,6 +59,9 @@ public: frame_slider_->SetValue(t); } +signals: + void TimeChanged(const rational &t); + private: QCheckBox* image_sequence_checkbox_; diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index 386fa2e1b..cf1319488 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -148,6 +148,11 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, bool stills_only_mode, QWi video_tab_ = new ExportVideoTab(color_manager_); AddPreferencesTab(video_tab_, tr("Video")); + // Set video tab time and make connections + connect(viewer_node, &ViewerOutput::PlayheadChanged, video_tab_, &ExportVideoTab::SetTime); + connect(video_tab_, &ExportVideoTab::TimeChanged, viewer_node, &ViewerOutput::SetPlayhead); + video_tab_->SetTime(viewer_node->GetPlayhead()); + audio_tab_ = new ExportAudioTab(); AddPreferencesTab(audio_tab_, tr("Audio")); @@ -206,7 +211,6 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, bool stills_only_mode, QWi preview_viewer_ = new ViewerWidget(); preview_viewer_->ruler()->SetMarkerEditingEnabled(false); preview_viewer_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - connect(preview_viewer_, &ViewerWidget::TimeChanged, video_tab_, &ExportVideoTab::SetTime); preview_layout->addWidget(preview_viewer_); splitter->addWidget(preview_area); @@ -437,7 +441,7 @@ void ExportDialog::PresetComboBoxChanged() if (loading_presets_) { return; } - + QComboBox *c = static_cast(sender()); int preset_number = c->currentData().toInt(); diff --git a/app/dialog/export/export.h b/app/dialog/export/export.h index 594b16380..b0afc83ac 100644 --- a/app/dialog/export/export.h +++ b/app/dialog/export/export.h @@ -51,14 +51,6 @@ public: rational GetSelectedTimebase() const; void SetSelectedTimebase(const rational &r); - void SetTime(const rational &time) - { - preview_viewer_->SetAudioScrubbingEnabled(false); - preview_viewer_->SetTime(time); - video_tab_->SetTime(time); - preview_viewer_->SetAudioScrubbingEnabled(true); - } - EncodingParams GenerateParams() const; void SetParams(const EncodingParams &e); diff --git a/app/dialog/export/exportvideotab.cpp b/app/dialog/export/exportvideotab.cpp index 56ecfcdfc..579aa746c 100644 --- a/app/dialog/export/exportvideotab.cpp +++ b/app/dialog/export/exportvideotab.cpp @@ -184,6 +184,7 @@ QWidget *ExportVideoTab::SetupCodecSection() codec_layout->addWidget(codec_stack_, row, 0, 1, 2); image_section_ = new ImageSection(); + connect(image_section_, &ImageSection::TimeChanged, this, &ExportVideoTab::TimeChanged); codec_stack_->addWidget(image_section_); h264_section_ = new H264Section(); diff --git a/app/dialog/export/exportvideotab.h b/app/dialog/export/exportvideotab.h index 1a23837f6..c401721e9 100644 --- a/app/dialog/export/exportvideotab.h +++ b/app/dialog/export/exportvideotab.h @@ -166,6 +166,8 @@ signals: void ImageSequenceCheckBoxChanged(bool e); + void TimeChanged(const rational &time); + private: QWidget* SetupResolutionSection(); QWidget* SetupColorSection(); diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 50d90f0b3..3f1f3e683 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -316,6 +316,12 @@ void ViewerOutput::VerifyLength() } } +void ViewerOutput::SetPlayhead(const rational &t) +{ + playhead_ = t; + emit PlayheadChanged(t); +} + void ViewerOutput::InputConnectedEvent(const QString &input, int element, Node *output) { if (input == kTextureInput) { diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index b99ebc30b..93df8d46b 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -97,6 +97,8 @@ public: } } + const rational &GetPlayhead() { return playhead_; } + void SetVideoParams(const VideoParams &video, int index = 0) { SetStandardValue(kVideoParamsInput, QVariant::fromValue(video), index); @@ -219,9 +221,13 @@ signals: void ConnectedWaveformChanged(); + void PlayheadChanged(const rational &t); + public slots: void VerifyLength(); + void SetPlayhead(const rational &t); + protected: virtual void InputConnectedEvent(const QString &input, int element, Node *output) override; @@ -253,6 +259,8 @@ private: bool waveform_requests_enabled_; + rational playhead_; + }; } diff --git a/app/panel/timebased/timebased.cpp b/app/panel/timebased/timebased.cpp index b10220dab..ae28aff69 100644 --- a/app/panel/timebased/timebased.cpp +++ b/app/panel/timebased/timebased.cpp @@ -29,11 +29,6 @@ TimeBasedPanel::TimeBasedPanel(const QString &object_name, QWidget *parent) : { } -rational TimeBasedPanel::GetTime() -{ - return widget_->GetTime(); -} - const rational& TimeBasedPanel::timebase() { return widget_->timebase(); @@ -74,11 +69,6 @@ void TimeBasedPanel::SetTimebase(const rational &timebase) widget_->SetTimebase(timebase); } -void TimeBasedPanel::SetTime(const rational &time) -{ - widget_->SetTime(time); -} - void TimeBasedPanel::GoToPrevCut() { widget_->GoToPrevCut(); @@ -122,16 +112,12 @@ void TimeBasedPanel::ConnectViewerNode(ViewerOutput *node) void TimeBasedPanel::SetTimeBasedWidget(TimeBasedWidget *widget) { if (widget_) { - disconnect(widget_, &TimeBasedWidget::TimeChanged, this, &TimeBasedPanel::TimeChanged); - disconnect(widget_, &TimeBasedWidget::TimebaseChanged, this, &TimeBasedPanel::TimebaseChanged); disconnect(widget_, &TimeBasedWidget::ConnectedNodeChanged, this, &TimeBasedPanel::ConnectedNodeChanged); } widget_ = widget; if (widget_) { - connect(widget_, &TimeBasedWidget::TimeChanged, this, &TimeBasedPanel::TimeChanged); - connect(widget_, &TimeBasedWidget::TimebaseChanged, this, &TimeBasedPanel::TimebaseChanged); connect(widget_, &TimeBasedWidget::ConnectedNodeChanged, this, &TimeBasedPanel::ConnectedNodeChanged); } diff --git a/app/panel/timebased/timebased.h b/app/panel/timebased/timebased.h index 4101e6b09..02f1a5b12 100644 --- a/app/panel/timebased/timebased.h +++ b/app/panel/timebased/timebased.h @@ -39,8 +39,6 @@ public: ConnectViewerNode(nullptr); } - rational GetTime(); - // Get the timebase of this panels widget const rational& timebase(); @@ -111,13 +109,7 @@ public: public slots: void SetTimebase(const rational& timebase); - void SetTime(const rational &time); - signals: - void TimeChanged(const rational& time); - - void TimebaseChanged(const rational& timebase); - void PlayPauseRequested(); void PlayInToOutRequested(); diff --git a/app/widget/curvewidget/curvewidget.cpp b/app/widget/curvewidget/curvewidget.cpp index d85e6d168..4079abd4e 100644 --- a/app/widget/curvewidget/curvewidget.cpp +++ b/app/widget/curvewidget/curvewidget.cpp @@ -59,7 +59,6 @@ CurveWidget::CurveWidget(QWidget *parent) : QHBoxLayout* top_controls = new QHBoxLayout(); key_control_ = new NodeParamViewKeyframeControl(false); - connect(key_control_, &NodeParamViewKeyframeControl::RequestSetTime, this, &CurveWidget::SetTimeAndSignal); top_controls->addWidget(key_control_); top_controls->addStretch(); @@ -99,7 +98,6 @@ CurveWidget::CurveWidget(QWidget *parent) : layout->addLayout(ruler_view_layout); // Connect ruler and view together - connect(view_, &CurveView::TimeChanged, this, &CurveWidget::SetTimeAndSignal); connect(view_, &CurveView::SelectionChanged, this, &CurveWidget::SelectionChanged); connect(view_, &CurveView::ScaleChanged, this, &CurveWidget::SetScale); connect(view_, &CurveView::Dragged, this, &CurveWidget::KeyframeViewDragged); @@ -193,14 +191,6 @@ void CurveWidget::SetNodes(const QVector &nodes) } } -void CurveWidget::TimeChangedEvent(const rational &time) -{ - super::TimeChangedEvent(time); - - view_->SetTime(time); - UpdateBridgeTime(time); -} - void CurveWidget::TimebaseChangedEvent(const rational &timebase) { super::TimebaseChangedEvent(timebase); @@ -215,7 +205,7 @@ void CurveWidget::ScaleChangedEvent(const double &scale) view_->SetScale(scale); } -void CurveWidget::TimeTargetChangedEvent(Node *target) +void CurveWidget::TimeTargetChangedEvent(ViewerOutput *target) { TimeTargetObject::TimeTargetChangedEvent(target); @@ -228,6 +218,8 @@ void CurveWidget::ConnectedNodeChangeEvent(ViewerOutput *n) { super::ConnectedNodeChangeEvent(n); + key_control_->SetTimeTarget(n); + SetTimeTarget(n); } @@ -252,11 +244,6 @@ void CurveWidget::SetKeyframeButtonCheckedFromType(NodeKeyframe::Type type) hold_button_->setChecked(type == NodeKeyframe::kHold); } -void CurveWidget::UpdateBridgeTime(const rational &time) -{ - key_control_->SetTime(time); -} - void CurveWidget::ConnectInput(Node *node, const QString &input, int element) { if (element == -1 && node->InputIsArray(input)) { diff --git a/app/widget/curvewidget/curvewidget.h b/app/widget/curvewidget/curvewidget.h index eef0ab62f..5ade8eb31 100644 --- a/app/widget/curvewidget/curvewidget.h +++ b/app/widget/curvewidget/curvewidget.h @@ -65,11 +65,10 @@ public slots: void SetNodes(const QVector &nodes); protected: - virtual void TimeChangedEvent(const rational &) override; virtual void TimebaseChangedEvent(const rational &) override; virtual void ScaleChangedEvent(const double &) override; - virtual void TimeTargetChangedEvent(Node* target) override; + virtual void TimeTargetChangedEvent(ViewerOutput *target) override; virtual void ConnectedNodeChangeEvent(ViewerOutput* n) override; @@ -95,8 +94,6 @@ private: void SetKeyframeButtonCheckedFromType(NodeKeyframe::Type type); - void UpdateBridgeTime(const rational &time); - void ConnectInput(Node *node, const QString &input, int element); void ConnectInputInternal(Node *node, const QString &input, int element); diff --git a/app/widget/keyframeview/keyframeview.cpp b/app/widget/keyframeview/keyframeview.cpp index abc2b1015..0811f416f 100644 --- a/app/widget/keyframeview/keyframeview.cpp +++ b/app/widget/keyframeview/keyframeview.cpp @@ -204,6 +204,10 @@ bool KeyframeView::CopySelected(bool cut) bool KeyframeView::Paste(std::function find_node_function) { + if (!GetViewerNode()) { + return false; + } + ProjectSerializer::Result res = ProjectSerializer::Paste(QStringLiteral("keyframes")); if (res == ProjectSerializer::kSuccess) { const ProjectSerializer::SerializedKeyframes &keys = res.GetLoadData().keyframes; @@ -216,7 +220,7 @@ bool KeyframeView::Paste(std::function find_node_functi min = std::min(min, key->time()); } } - min -= GetTime(); + min -= GetViewerNode()->GetPlayhead(); for (auto it=keys.cbegin(); it!=keys.cend(); it++) { const QString &paste_id = it.key(); @@ -454,7 +458,7 @@ void KeyframeView::ScaleChangedEvent(const double &scale) Redraw(); } -void KeyframeView::TimeTargetChangedEvent(Node *target) +void KeyframeView::TimeTargetChangedEvent(ViewerOutput *v) { Redraw(); } diff --git a/app/widget/keyframeview/keyframeview.h b/app/widget/keyframeview/keyframeview.h index 0ab17f254..541b81583 100644 --- a/app/widget/keyframeview/keyframeview.h +++ b/app/widget/keyframeview/keyframeview.h @@ -101,7 +101,7 @@ protected: virtual void ScaleChangedEvent(const double& scale) override; - virtual void TimeTargetChangedEvent(Node*) override; + virtual void TimeTargetChangedEvent(ViewerOutput *v) override; virtual void TimebaseChangedEvent(const rational &timebase) override; diff --git a/app/widget/multicam/multicamwidget.cpp b/app/widget/multicam/multicamwidget.cpp index 5156fd4ed..a11495339 100644 --- a/app/widget/multicam/multicamwidget.cpp +++ b/app/widget/multicam/multicamwidget.cpp @@ -74,7 +74,7 @@ void MulticamWidget::SetMulticamNodeInternal(ViewerOutput *viewer, MultiCamNode void MulticamWidget::SetMulticamNode(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip, const rational &time) { - if (time.isNaN() || time == GetTime()) { + if (time.isNaN() || !GetConnectedNode() || time == GetConnectedNode()->GetPlayhead()) { SetMulticamNodeInternal(viewer, n, clip); play_queue_.clear(); } else { @@ -125,13 +125,13 @@ void MulticamWidget::Switch(int source, bool split_clip) BlockSplitPreservingLinksCommand *split = nullptr; - if (clip_ && split_clip && clip_->in() < GetTime() && clip_->out() > GetTime()) { + if (clip_ && split_clip && clip_->in() < GetConnectedNode()->GetPlayhead() && clip_->out() > GetConnectedNode()->GetPlayhead()) { QVector blocks; blocks.append(clip_); blocks.append(clip_->block_links()); - split = new BlockSplitPreservingLinksCommand(blocks, {GetTime()}); + split = new BlockSplitPreservingLinksCommand(blocks, {GetConnectedNode()->GetPlayhead()}); split->redo_now(); command->add_child(split); diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index b0d6f1618..bd6d8594e 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -126,9 +126,6 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) : keyframe_area_layout->addWidget(keyframe_view_); // Connect ruler and keyframe view together - connect(ruler(), &TimeRuler::TimeChanged, keyframe_view_, &KeyframeView::SetTime); - connect(keyframe_view_, &KeyframeView::TimeChanged, ruler(), &TimeRuler::SetTime); - connect(keyframe_view_, &KeyframeView::TimeChanged, this, &NodeParamView::SetTime); connect(keyframe_view_, &KeyframeView::Dragged, this, &NodeParamView::KeyframeViewDragged); connect(keyframe_view_, &KeyframeView::Released, this, &NodeParamView::KeyframeViewReleased); @@ -361,19 +358,6 @@ void NodeParamView::TimebaseChangedEvent(const rational &timebase) foreach (NodeParamViewContext* ctx, context_items_) { ctx->SetTimebase(timebase); } - - UpdateItemTime(GetTime()); -} - -void NodeParamView::TimeChangedEvent(const rational &time) -{ - super::TimeChangedEvent(time); - - if (keyframe_view_) { - keyframe_view_->SetTime(time); - } - - UpdateItemTime(time); } void NodeParamView::ConnectedNodeChangeEvent(ViewerOutput *n) @@ -390,7 +374,7 @@ void NodeParamView::ConnectedNodeChangeEvent(ViewerOutput *n) time_target_ = n; } -Node *NodeParamView::GetTimeTarget() const +ViewerOutput *NodeParamView::GetTimeTarget() const { return time_target_; } @@ -683,13 +667,6 @@ bool NodeParamView::Paste(QWidget *parent, std::function(co return true; } -void NodeParamView::UpdateItemTime(const rational &time) -{ - foreach (NodeParamViewContext* item, context_items_) { - item->SetTime(time); - } -} - void NodeParamView::QueueKeyframePositionUpdate() { QMetaObject::invokeMethod(this, &NodeParamView::UpdateElementY, Qt::QueuedConnection); @@ -735,7 +712,6 @@ void NodeParamView::AddNode(Node *n, Node *ctx, NodeParamViewContext *context) NodeParamViewItem* item = new NodeParamViewItem(n, IsGroupMode() ? kCheckBoxesOnNonConnected : kNoCheckBoxes, context->GetDockArea()); - connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::SetTimeAndSignal); connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::SelectNodeFromConnectedLink); connect(item, &NodeParamViewItem::PinToggled, this, &NodeParamView::PinNode); connect(item, &NodeParamViewItem::InputCheckedChanged, this, &NodeParamView::InputCheckBoxChanged); @@ -745,7 +721,6 @@ void NodeParamView::AddNode(Node *n, Node *ctx, NodeParamViewContext *context) item->SetContext(ctx); item->SetTimeTarget(GetTimeTarget()); item->SetTimebase(timebase()); - item->SetTime(GetTime()); context->AddNode(item); diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index 1b78055a9..f9ecc5fb5 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -48,7 +48,7 @@ public: void CloseContextsBelongingToProject(Project *p); - Node* GetTimeTarget() const; + ViewerOutput *GetTimeTarget() const; void DeleteSelected(); @@ -95,7 +95,6 @@ protected: virtual void ScaleChangedEvent(const double &) override; virtual void TimebaseChangedEvent(const rational&) override; - virtual void TimeChangedEvent(const rational &time) override; virtual void ConnectedNodeChangeEvent(ViewerOutput* n) override; @@ -115,8 +114,6 @@ protected: } private: - void UpdateItemTime(const rational &time); - void QueueKeyframePositionUpdate(); void AddContext(Node *context); @@ -159,7 +156,7 @@ private: NodeParamViewItem* focused_node_; QVector selected_nodes_; - Node *time_target_; + ViewerOutput *time_target_; QVector contexts_; QVector current_contexts_; diff --git a/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp b/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp index 937037219..c9454e4a4 100644 --- a/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp +++ b/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp @@ -34,7 +34,8 @@ namespace olive { NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(const NodeInput &input, QWidget *parent) : QWidget(parent), input_(input), - connected_node_(nullptr) + connected_node_(nullptr), + viewer_(nullptr) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); @@ -85,6 +86,20 @@ NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(const NodeInput &input, connect(collapse_btn, &CollapseButton::toggled, this, &NodeParamViewConnectedLabel::SetValueTreeVisible); } +void NodeParamViewConnectedLabel::SetViewerNode(ViewerOutput *viewer) +{ + if (viewer_) { + disconnect(viewer_, &ViewerOutput::PlayheadChanged, this, &NodeParamViewConnectedLabel::UpdateValueTree); + } + + viewer_ = viewer; + + if (viewer_) { + connect(viewer_, &ViewerOutput::PlayheadChanged, this, &NodeParamViewConnectedLabel::UpdateValueTree); + UpdateValueTree(); + } +} + void NodeParamViewConnectedLabel::CreateTree() { // Set up table area @@ -92,15 +107,6 @@ void NodeParamViewConnectedLabel::CreateTree() layout()->addWidget(value_tree_); } -void NodeParamViewConnectedLabel::SetTime(const rational &time) -{ - time_ = time; - - if (value_tree_ && value_tree_->isVisible()) { - UpdateValueTree(); - } -} - void NodeParamViewConnectedLabel::InputConnected(Node *output, const NodeInput& input) { if (input_ != input) { @@ -159,8 +165,8 @@ void NodeParamViewConnectedLabel::UpdateLabel() void NodeParamViewConnectedLabel::UpdateValueTree() { - if (value_tree_) { - value_tree_->SetNode(input_, time_); + if (value_tree_ && viewer_ && value_tree_->isVisible()) { + value_tree_->SetNode(input_, viewer_->GetPlayhead()); } } @@ -173,6 +179,7 @@ void NodeParamViewConnectedLabel::SetValueTreeVisible(bool e) if (e) { if (!value_tree_) { CreateTree(); + value_tree_->setVisible(true); } UpdateValueTree(); diff --git a/app/widget/nodeparamview/nodeparamviewconnectedlabel.h b/app/widget/nodeparamview/nodeparamviewconnectedlabel.h index 9a7a81ee7..16a7428af 100644 --- a/app/widget/nodeparamview/nodeparamviewconnectedlabel.h +++ b/app/widget/nodeparamview/nodeparamviewconnectedlabel.h @@ -32,7 +32,7 @@ class NodeParamViewConnectedLabel : public QWidget { public: NodeParamViewConnectedLabel(const NodeInput& input, QWidget* parent = nullptr); - void SetTime(const rational &time); + void SetViewerNode(ViewerOutput *viewer); signals: void RequestSelectNode(Node *n); @@ -61,7 +61,7 @@ private: NodeValueTree *value_tree_; - rational time_; + ViewerOutput *viewer_; private slots: void SetValueTreeVisible(bool e); diff --git a/app/widget/nodeparamview/nodeparamviewcontext.cpp b/app/widget/nodeparamview/nodeparamviewcontext.cpp index 1d3a22253..a2438bddd 100644 --- a/app/widget/nodeparamview/nodeparamviewcontext.cpp +++ b/app/widget/nodeparamview/nodeparamviewcontext.cpp @@ -113,20 +113,13 @@ void NodeParamViewContext::SetTimebase(const rational &timebase) } } -void NodeParamViewContext::SetTimeTarget(Node *n) +void NodeParamViewContext::SetTimeTarget(ViewerOutput *n) { foreach (NodeParamViewItem* item, items_) { item->SetTimeTarget(n); } } -void NodeParamViewContext::SetTime(const rational &time) -{ - foreach (NodeParamViewItem* item, items_) { - item->SetTime(time); - } -} - void NodeParamViewContext::SetEffectType(Track::Type type) { type_ = type; diff --git a/app/widget/nodeparamview/nodeparamviewcontext.h b/app/widget/nodeparamview/nodeparamviewcontext.h index 11574e2a5..b89db696a 100644 --- a/app/widget/nodeparamview/nodeparamviewcontext.h +++ b/app/widget/nodeparamview/nodeparamviewcontext.h @@ -60,9 +60,7 @@ public: void SetTimebase(const rational &timebase); - void SetTimeTarget(Node *n); - - void SetTime(const rational &time); + void SetTimeTarget(ViewerOutput *n); void SetEffectType(Track::Type type); diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index a27cbe824..7d0f6dc7a 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -90,12 +90,10 @@ void NodeParamViewItem::RecreateBody() body_ = new NodeParamViewItemBody(node_, create_checkboxes_, this); connect(body_, &NodeParamViewItemBody::RequestSelectNode, this, &NodeParamViewItem::RequestSelectNode); - connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime); connect(body_, &NodeParamViewItemBody::ArrayExpandedChanged, this, &NodeParamViewItem::ArrayExpandedChanged); connect(body_, &NodeParamViewItemBody::InputCheckedChanged, this, &NodeParamViewItem::InputCheckedChanged); connect(body_, &NodeParamViewItemBody::RequestEditTextInViewer, this, &NodeParamViewItem::RequestEditTextInViewer); body_->Retranslate(); - body_->SetTime(time_); body_->SetTimebase(timebase_); SetBody(body_); } @@ -259,7 +257,6 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const ui_objects.key_control = new NodeParamViewKeyframeControl(this); ui_objects.key_control->SetInput(resolved); layout->addWidget(ui_objects.key_control, row, kKeyControlColumn); - connect(ui_objects.key_control, &NodeParamViewKeyframeControl::RequestSetTime, this, &NodeParamViewItemBody::RequestSetTime); } input_ui_map_.insert(input_ref, ui_objects); @@ -269,31 +266,17 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const } } -void NodeParamViewItemBody::SetTimeTarget(Node *target) +void NodeParamViewItemBody::SetTimeTarget(ViewerOutput *target) { foreach (const InputUI& ui_obj, input_ui_map_) { // Only keyframable inputs have a key control widget if (ui_obj.key_control) { ui_obj.key_control->SetTimeTarget(target); } - - ui_obj.widget_bridge->SetTimeTarget(target); - } -} - -void NodeParamViewItemBody::SetTime(const rational &time) -{ - foreach (const InputUI& ui_obj, input_ui_map_) { - // Only keyframable inputs have a key control widget - if (ui_obj.key_control) { - ui_obj.key_control->SetTime(time); - } - if (ui_obj.connected_label) { - ui_obj.connected_label->SetTime(time); + ui_obj.connected_label->SetViewerNode(target); } - - ui_obj.widget_bridge->SetTime(time); + ui_obj.widget_bridge->SetTimeTarget(target); } } diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h index 8ec20bb6a..eb52e44d3 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.h +++ b/app/widget/nodeparamview/nodeparamviewitem.h @@ -51,9 +51,7 @@ class NodeParamViewItemBody : public QWidget { public: NodeParamViewItemBody(Node* node, NodeParamViewCheckBoxBehavior create_checkboxes, QWidget* parent = nullptr); - void SetTimeTarget(Node* target); - - void SetTime(const rational& time); + void SetTimeTarget(ViewerOutput *target); void Retranslate(); @@ -65,8 +63,6 @@ public: void SetInputChecked(const NodeInput &input, bool e); signals: - void RequestSetTime(const rational& time); - void RequestSelectNode(Node *node); void ArrayExpandedChanged(bool e); @@ -167,18 +163,11 @@ class NodeParamViewItem : public NodeParamViewItemBase public: NodeParamViewItem(Node* node, NodeParamViewCheckBoxBehavior create_checkboxes, QWidget* parent = nullptr); - void SetTimeTarget(Node* target) + void SetTimeTarget(ViewerOutput* target) { body_->SetTimeTarget(target); } - void SetTime(const rational& time) - { - time_ = time; - - body_->SetTime(time_); - } - void SetTimebase(const rational& timebase) { timebase_ = timebase; @@ -216,8 +205,6 @@ public: } signals: - void RequestSetTime(const rational& time); - void RequestSelectNode(Node *node); void ArrayExpandedChanged(bool e); @@ -238,7 +225,6 @@ private: Node *ctx_; - rational time_; rational timebase_; KeyframeView::NodeConnections keyframe_connections_; diff --git a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp index ea29b036e..85bc9f465 100644 --- a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp +++ b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp @@ -96,10 +96,14 @@ void NodeParamViewKeyframeControl::SetInput(const NodeInput& input) } } -void NodeParamViewKeyframeControl::SetTime(const rational &time) +void NodeParamViewKeyframeControl::TimeTargetDisconnectEvent(ViewerOutput *v) { - time_ = time; + disconnect(v, &ViewerOutput::PlayheadChanged, this, &NodeParamViewKeyframeControl::UpdateState); +} +void NodeParamViewKeyframeControl::TimeTargetConnectEvent(ViewerOutput *v) +{ + connect(v, &ViewerOutput::PlayheadChanged, this, &NodeParamViewKeyframeControl::UpdateState); UpdateState(); } @@ -122,7 +126,7 @@ void NodeParamViewKeyframeControl::SetButtonsEnabled(bool e) rational NodeParamViewKeyframeControl::GetCurrentTimeAsNodeTime() const { - return GetAdjustedTime(GetTimeTarget(), input_.node(), time_, Node::kTransformTowardsInput); + return GetAdjustedTime(GetTimeTarget(), input_.node(), GetTimeTarget()->GetPlayhead(), Node::kTransformTowardsInput); } rational NodeParamViewKeyframeControl::ConvertToViewerTime(const rational &r) const @@ -177,7 +181,7 @@ void NodeParamViewKeyframeControl::ToggleKeyframe(bool e) void NodeParamViewKeyframeControl::UpdateState() { - if (!input_.IsValid() || !input_.IsKeyframing()) { + if (!input_.IsValid() || !input_.IsKeyframing() || !GetTimeTarget()) { return; } @@ -197,10 +201,9 @@ void NodeParamViewKeyframeControl::GoToPreviousKey() NodeKeyframe* previous_key = input_.node()->GetClosestKeyframeBeforeTime(input_, node_time); - if (previous_key) { + if (previous_key && GetTimeTarget()) { rational key_time = ConvertToViewerTime(previous_key->time()); - - emit RequestSetTime(key_time); + GetTimeTarget()->SetPlayhead(key_time); } } @@ -210,10 +213,9 @@ void NodeParamViewKeyframeControl::GoToNextKey() NodeKeyframe* next_key = input_.node()->GetClosestKeyframeAfterTime(input_, node_time); - if (next_key) { + if (next_key && GetTimeTarget()) { rational key_time = ConvertToViewerTime(next_key->time()); - - emit RequestSetTime(key_time); + GetTimeTarget()->SetPlayhead(key_time); } } diff --git a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.h b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.h index 0f8ffab7d..44b017b56 100644 --- a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.h +++ b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.h @@ -46,10 +46,9 @@ public: void SetInput(const NodeInput& input); - void SetTime(const rational& time); - -signals: - void RequestSetTime(const rational& time); +protected: + virtual void TimeTargetDisconnectEvent(ViewerOutput *v) override; + virtual void TimeTargetConnectEvent(ViewerOutput *v) override; private: QPushButton* CreateNewToolButton(const QIcon &icon) const; @@ -67,8 +66,6 @@ private: NodeInput input_; - rational time_; - private slots: void ShowButtonsFromKeyframeEnable(bool e); diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index b5b4db823..5a519fd03 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -57,13 +57,6 @@ NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(NodeInput input, QObject *p CreateWidgets(); } -void NodeParamViewWidgetBridge::SetTime(const rational &time) -{ - time_ = time; - - UpdateWidgetValues(); -} - int GetSliderCount(NodeValue::Type type) { return NodeValue::get_number_of_keyframe_tracks(type); @@ -528,7 +521,11 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues() rational NodeParamViewWidgetBridge::GetCurrentTimeAsNodeTime() const { - return GetAdjustedTime(GetTimeTarget(), GetInnerInput().node(), time_, Node::kTransformTowardsInput); + if (GetTimeTarget()) { + return GetAdjustedTime(GetTimeTarget(), GetInnerInput().node(), GetTimeTarget()->GetPlayhead(), Node::kTransformTowardsInput); + } else { + return 0; + } } void NodeParamViewWidgetBridge::SetTimebase(const rational& timebase) @@ -538,11 +535,21 @@ void NodeParamViewWidgetBridge::SetTimebase(const rational& timebase) } } +void NodeParamViewWidgetBridge::TimeTargetDisconnectEvent(ViewerOutput *v) +{ + disconnect(v, &ViewerOutput::PlayheadChanged, this, &NodeParamViewWidgetBridge::UpdateWidgetValues); +} + +void NodeParamViewWidgetBridge::TimeTargetConnectEvent(ViewerOutput *v) +{ + connect(v, &ViewerOutput::PlayheadChanged, this, &NodeParamViewWidgetBridge::UpdateWidgetValues); +} + void NodeParamViewWidgetBridge::InputValueChanged(const NodeInput &input, const TimeRange &range) { if (GetInnerInput() == input && !dragger_.IsStarted() - && range.in() <= time_ && range.out() >= time_) { + && range.in() <= GetTimeTarget()->GetPlayhead() && range.out() >= GetTimeTarget()->GetPlayhead()) { // We'll need to update the widgets because the values have changed on our current time UpdateWidgetValues(); } diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h index 772febbde..457c618c6 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h @@ -42,8 +42,6 @@ class NodeParamViewWidgetBridge : public QObject, public TimeTargetObject public: NodeParamViewWidgetBridge(NodeInput input, QObject* parent); - void SetTime(const rational& time); - const QVector& widgets() const { return widgets_; @@ -59,6 +57,10 @@ signals: void RequestEditTextInViewer(); +protected: + virtual void TimeTargetDisconnectEvent(ViewerOutput *v) override; + virtual void TimeTargetConnectEvent(ViewerOutput *v) override; + private: void CreateWidgets(); @@ -102,8 +104,6 @@ private: QVector widgets_; - rational time_; - NodeInputDragger dragger_; NodeParamViewScrollBlocker scroll_filter_; diff --git a/app/widget/timebased/timebasedview.cpp b/app/widget/timebased/timebasedview.cpp index 310df8866..869bc6d78 100644 --- a/app/widget/timebased/timebasedview.cpp +++ b/app/widget/timebased/timebasedview.cpp @@ -38,7 +38,8 @@ TimeBasedView::TimeBasedView(QWidget *parent) : snapped_(false), snap_service_(nullptr), y_axis_enabled_(false), - y_scale_(1.0) + y_scale_(1.0), + viewer_(nullptr) { // Sets scene to our scene setScene(&scene_); @@ -142,12 +143,17 @@ void TimeBasedView::SetYScale(const double &y_scale) } } -void TimeBasedView::SetTime(const rational &time) +void TimeBasedView::SetViewerNode(ViewerOutput *v) { - playhead_ = time; + if (viewer_) { + disconnect(viewer_, &ViewerOutput::PlayheadChanged, viewport(), static_cast(&TimeBasedView::update)); + } - // Force redraw for playhead - viewport()->update(); + viewer_ = v; + + if (viewer_) { + connect(viewer_, &ViewerOutput::PlayheadChanged, viewport(), static_cast(&TimeBasedView::update)); + } } void TimeBasedView::drawForeground(QPainter *painter, const QRectF &rect) @@ -203,20 +209,21 @@ bool TimeBasedView::PlayheadMove(QMouseEvent *event) return false; } - QPointF scene_pos = mapToScene(event->pos()); - rational mouse_time = qMax(rational(0), SceneToTime(scene_pos.x())); + if (viewer_) { + QPointF scene_pos = mapToScene(event->pos()); + rational mouse_time = qMax(rational(0), SceneToTime(scene_pos.x())); - if (Core::instance()->snapping() && snap_service_) { - rational movement; + if (Core::instance()->snapping() && snap_service_) { + rational movement; - snap_service_->SnapPoint({mouse_time}, &movement, TimeBasedWidget::kSnapAll & ~TimeBasedWidget::kSnapToPlayhead); + snap_service_->SnapPoint({mouse_time}, &movement, TimeBasedWidget::kSnapAll & ~TimeBasedWidget::kSnapToPlayhead); - mouse_time += movement; + mouse_time += movement; + } + + viewer_->SetPlayhead(mouse_time); } - SetTime(mouse_time); - emit TimeChanged(mouse_time); - return true; } @@ -237,7 +244,11 @@ bool TimeBasedView::PlayheadRelease(QMouseEvent*) qreal TimeBasedView::GetPlayheadX() { - return TimeToScene(playhead_); + if (viewer_) { + return TimeToScene(viewer_->GetPlayhead()); + } else { + return 0; + } } void TimeBasedView::SetEndTime(const rational &length) diff --git a/app/widget/timebased/timebasedview.h b/app/widget/timebased/timebasedview.h index 9f708553a..c6459ca52 100644 --- a/app/widget/timebased/timebasedview.h +++ b/app/widget/timebased/timebasedview.h @@ -45,8 +45,6 @@ public: return snapped_; } - const rational &GetTime() const { return playhead_; } - TimeBasedWidget *GetSnapService() const { return snap_service_; } void SetSnapService(TimeBasedWidget* service) { snap_service_ = service; } @@ -62,9 +60,11 @@ public: virtual void SelectionManagerSelectEvent(void *obj){} virtual void SelectionManagerDeselectEvent(void *obj){} -public slots: - void SetTime(const rational &time); + ViewerOutput *GetViewerNode() const { return viewer_; } + void SetViewerNode(ViewerOutput *v); + +public slots: void SetEndTime(const rational& length); /** @@ -73,8 +73,6 @@ public slots: void UpdateSceneRect(); signals: - void TimeChanged(const rational& time); - void ScaleChanged(double scale); protected: @@ -109,8 +107,6 @@ protected: private: qreal GetPlayheadX(); - rational playhead_; - double playhead_scene_left_; double playhead_scene_right_; @@ -129,6 +125,8 @@ private: double y_scale_; + ViewerOutput *viewer_; + }; } diff --git a/app/widget/timebased/timebasedwidget.cpp b/app/widget/timebased/timebasedwidget.cpp index b97521b47..f5bb38378 100644 --- a/app/widget/timebased/timebasedwidget.cpp +++ b/app/widget/timebased/timebasedwidget.cpp @@ -44,7 +44,7 @@ TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_statu markers_(nullptr) { ruler_ = new TimeRuler(ruler_text_visible, ruler_cache_status_visible, this); - ConnectTimelineView(ruler_, true); + ConnectTimelineView(ruler_); ruler()->SetSnapService(this); connect(ruler(), &TimeRuler::DragReleased, this, static_cast(&TimeBasedWidget::StopCatchUpScrollTimer)); @@ -68,11 +68,6 @@ void TimeBasedWidget::SetScaleAndCenterOnPlayhead(const double &scale) QTimer::singleShot(0, this, &TimeBasedWidget::CenterScrollOnPlayhead); } -const rational &TimeBasedWidget::GetTime() const -{ - return ruler_->GetTime(); -} - ViewerOutput *TimeBasedWidget::GetConnectedNode() const { return viewer_node_; @@ -96,6 +91,7 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node) // Disconnect length changed signal disconnect(old, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll); disconnect(old, &ViewerOutput::RemovedFromGraph, this, &TimeBasedWidget::ConnectedNodeRemovedFromGraph); + disconnect(old, &ViewerOutput::PlayheadChanged, this, &TimeBasedWidget::PlayheadTimeChanged); // Disconnect rate change signals if they were connected disconnect(old, &ViewerOutput::FrameRateChanged, this, &TimeBasedWidget::AutoUpdateTimebase); @@ -110,12 +106,16 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node) } // Call derivatives + for (TimeBasedView *view : timeline_views_) { + view->SetViewerNode(viewer_node_); + } ConnectedNodeChangeEvent(viewer_node_); if (viewer_node_) { // Connect length changed signal connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll); connect(viewer_node_, &ViewerOutput::RemovedFromGraph, this, &TimeBasedWidget::ConnectedNodeRemovedFromGraph); + connect(viewer_node_, &ViewerOutput::PlayheadChanged, this, &TimeBasedWidget::PlayheadTimeChanged); // Connect ruler and scrollbar to timeline points ConnectWorkArea(viewer_node_->GetWorkArea()); @@ -209,12 +209,16 @@ void TimeBasedWidget::ScrollBarResizeMoved(int movement) void TimeBasedWidget::PageScrollToPlayhead() { - PageScrollInternal(qRound(TimeToScene(GetTime())), true); + if (GetConnectedNode()) { + PageScrollInternal(qRound(TimeToScene(GetConnectedNode()->GetPlayhead())), true); + } } void TimeBasedWidget::CatchUpScrollToPlayhead() { - CatchUpScrollToPoint(qRound(TimeToScene(GetTime()))); + if (GetConnectedNode()) { + CatchUpScrollToPoint(qRound(TimeToScene(GetConnectedNode()->GetPlayhead()))); + } } void TimeBasedWidget::CatchUpScrollToPoint(int point) @@ -300,12 +304,8 @@ void TimeBasedWidget::resizeEvent(QResizeEvent *event) UpdateMaximumScroll(); } -void TimeBasedWidget::ConnectTimelineView(TimeBasedView *base, bool connect_time_change_event) +void TimeBasedWidget::ConnectTimelineView(TimeBasedView *base) { - if (connect_time_change_event) { - connect(base, &TimeBasedView::TimeChanged, this, &TimeBasedWidget::SetTimeAndSignal); - } - timeline_views_.append(base); } @@ -345,7 +345,7 @@ void TimeBasedWidget::StopCatchUpScrollTimer(QScrollBar *b) } } -void TimeBasedWidget::SetTime(const rational &time) +void TimeBasedWidget::PlayheadTimeChanged(const rational &time) { if (UserIsDraggingPlayhead()) { // If the user is dragging the playhead, we will simply nudge over and not use autoscroll rules. @@ -365,8 +365,6 @@ void TimeBasedWidget::SetTime(const rational &time) } } - ruler_->SetTime(time); - TimeChangedEvent(time); } @@ -400,7 +398,7 @@ void TimeBasedWidget::GoToPrevCut() return; } - if (GetTime().isNull()) { + if (GetConnectedNode()->GetPlayhead().isNull()) { return; } @@ -410,7 +408,7 @@ void TimeBasedWidget::GoToPrevCut() rational this_track_closest_cut = 0; for (Block* block : track->Blocks()) { - if (block->out() < GetTime()) { + if (block->out() < GetConnectedNode()->GetPlayhead()) { this_track_closest_cut = block->out(); } else { break; @@ -420,7 +418,7 @@ void TimeBasedWidget::GoToPrevCut() closest_cut = qMax(closest_cut, this_track_closest_cut); } - SetTimeAndSignal(closest_cut); + GetConnectedNode()->SetPlayhead(closest_cut); } void TimeBasedWidget::GoToNextCut() @@ -437,12 +435,12 @@ void TimeBasedWidget::GoToNextCut() for (Track* track : sequence->GetTracks()) { rational this_track_closest_cut = track->track_length(); - if (this_track_closest_cut <= GetTime()) { + if (this_track_closest_cut <= GetConnectedNode()->GetPlayhead()) { this_track_closest_cut = RATIONAL_MAX; } for (Block* block : track->Blocks()) { - if (block->in() > GetTime()) { + if (block->in() > GetConnectedNode()->GetPlayhead()) { this_track_closest_cut = block->in(); break; } @@ -452,57 +450,51 @@ void TimeBasedWidget::GoToNextCut() } if (closest_cut < RATIONAL_MAX) { - SetTimeAndSignal(closest_cut); + GetConnectedNode()->SetPlayhead(closest_cut); } } void TimeBasedWidget::GoToStart() { if (viewer_node_) { - SetTimeAndSignal(0); + viewer_node_->SetPlayhead(0); } } void TimeBasedWidget::PrevFrame() { if (viewer_node_) { - rational proposed_time = Timecode::snap_time_to_timebase(GetTime() - timebase(), timebase(), Timecode::kCeil); - if (proposed_time == GetTime()) { + rational proposed_time = Timecode::snap_time_to_timebase(GetConnectedNode()->GetPlayhead() - timebase(), timebase(), Timecode::kCeil); + if (proposed_time == GetConnectedNode()->GetPlayhead()) { // Catch rounding error, assume this time is snapped and just subtract a timebase proposed_time -= timebase(); } - SetTimeAndSignal(qMax(rational(0), proposed_time)); + viewer_node_->SetPlayhead(qMax(rational(0), proposed_time)); } } void TimeBasedWidget::NextFrame() { if (viewer_node_) { - rational proposed_time = Timecode::snap_time_to_timebase(GetTime() + timebase(), timebase(), Timecode::kFloor); - if (proposed_time == GetTime()) { + rational proposed_time = Timecode::snap_time_to_timebase(GetConnectedNode()->GetPlayhead() + timebase(), timebase(), Timecode::kFloor); + if (proposed_time == GetConnectedNode()->GetPlayhead()) { // Catch rounding error, assume this time is snapped and just add a timebase proposed_time += timebase(); } - SetTimeAndSignal(proposed_time); + viewer_node_->SetPlayhead(proposed_time); } } void TimeBasedWidget::GoToEnd() { if (viewer_node_) { - SetTimeAndSignal(viewer_node_->GetLength()); + viewer_node_->SetPlayhead(viewer_node_->GetLength()); } } -void TimeBasedWidget::SetTimeAndSignal(const rational &t) -{ - SetTime(t); - emit TimeChanged(t); -} - void TimeBasedWidget::CenterScrollOnPlayhead() { - scrollbar_->setValue(qRound(TimeToScene(ruler_->GetTime())) - scrollbar_->width()/2); + scrollbar_->setValue(qRound(TimeToScene(GetConnectedNode()->GetPlayhead())) - scrollbar_->width()/2); } void TimeBasedWidget::SetAutoSetTimebase(bool e) @@ -603,10 +595,6 @@ void TimeBasedWidget::PageScrollInternal(int screen_position, bool whole_page_sc bool TimeBasedWidget::UserIsDraggingPlayhead() const { - if (ruler_->IsDraggingPlayhead()) { - return true; - } - foreach (TimeBasedView* view, timeline_views_) { if (view->IsDraggingPlayhead()) { return true; @@ -618,12 +606,12 @@ bool TimeBasedWidget::UserIsDraggingPlayhead() const void TimeBasedWidget::SetInAtPlayhead() { - SetPoint(Timeline::kTrimIn, GetTime()); + SetPoint(Timeline::kTrimIn, GetConnectedNode()->GetPlayhead()); } void TimeBasedWidget::SetOutAtPlayhead() { - SetPoint(Timeline::kTrimOut, GetTime()); + SetPoint(Timeline::kTrimOut, GetConnectedNode()->GetPlayhead()); } void TimeBasedWidget::ResetIn() @@ -653,14 +641,14 @@ void TimeBasedWidget::SetMarker() TimelineMarkerList *markers = GetConnectedNode()->GetMarkers(); - if (TimelineMarker *existing = markers->GetMarkerAtTime(GetTime())) { + if (TimelineMarker *existing = markers->GetMarkerAtTime(GetConnectedNode()->GetPlayhead())) { // We already have a marker here, so pop open the edit dialog MarkerPropertiesDialog mpd({existing}, timebase(), this); mpd.exec(); } else { // Create a new marker and place it here int color; - if (TimelineMarker *closest = markers->GetClosestMarkerToTime(GetTime())) { + if (TimelineMarker *closest = markers->GetClosestMarkerToTime(GetConnectedNode()->GetPlayhead())) { // Copy color of closest marker to this time color = closest->color(); } else { @@ -668,7 +656,7 @@ void TimeBasedWidget::SetMarker() color = OLIVE_CONFIG("MarkerColor").toInt(); } - TimelineMarker *marker = new TimelineMarker(color, TimeRange(GetTime(), GetTime())); + TimelineMarker *marker = new TimelineMarker(color, TimeRange(GetConnectedNode()->GetPlayhead(), GetConnectedNode()->GetPlayhead())); if (OLIVE_CONFIG("SetNameWithMarker").toBool()) { MarkerPropertiesDialog mpd({marker}, timebase(), this); @@ -704,8 +692,6 @@ void TimeBasedWidget::ToggleShowAll() w = timeline_views_.first()->width(); } - - toggle_show_all_old_scale_ = GetScale(); toggle_show_all_old_scroll_ = scrollbar_->value(); @@ -721,7 +707,7 @@ void TimeBasedWidget::GoToIn() { if (GetConnectedNode()) { if (GetConnectedNode()->GetWorkArea()->enabled()) { - SetTimeAndSignal(GetConnectedNode()->GetWorkArea()->in()); + GetConnectedNode()->SetPlayhead(GetConnectedNode()->GetWorkArea()->in()); } else { GoToStart(); } @@ -732,7 +718,7 @@ void TimeBasedWidget::GoToOut() { if (GetConnectedNode()) { if (GetConnectedNode()->GetWorkArea()->enabled()) { - SetTimeAndSignal(GetConnectedNode()->GetWorkArea()->out()); + GetConnectedNode()->SetPlayhead(GetConnectedNode()->GetWorkArea()->out()); } else { GoToEnd(); } @@ -787,7 +773,7 @@ bool TimeBasedWidget::SnapPoint(const std::vector &start_times, ration std::vector potential_snaps; if (snap_points & kSnapToPlayhead) { - rational playhead_abs_time = GetTime(); + rational playhead_abs_time = GetConnectedNode()->GetPlayhead(); qreal playhead_pos = TimeToScene(playhead_abs_time); AttemptSnap(potential_snaps, screen_pt, playhead_pos, start_times, playhead_abs_time); } diff --git a/app/widget/timebased/timebasedwidget.h b/app/widget/timebased/timebasedwidget.h index 347c079c7..9e152c7d3 100644 --- a/app/widget/timebased/timebasedwidget.h +++ b/app/widget/timebased/timebasedwidget.h @@ -41,8 +41,6 @@ class TimeBasedWidget : public TimelineScaledWidget public: TimeBasedWidget(bool ruler_text_visible = true, bool ruler_cache_status_visible = false, QWidget* parent = nullptr); - const rational &GetTime() const; - void ZoomIn(); void ZoomOut(); @@ -84,8 +82,6 @@ public: virtual bool Paste(); public slots: - void SetTime(const rational &time); - void SetTimebase(const rational& timebase); void SetScale(const double& scale); @@ -144,7 +140,7 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; - void ConnectTimelineView(TimeBasedView* base, bool connect_time_change_event = true); + void ConnectTimelineView(TimeBasedView* base); void PassWheelEventsToScrollBar(QObject* object); @@ -172,16 +168,12 @@ protected slots: static void PageScrollInternal(QScrollBar* bar, int maximum, int screen_position, bool whole_page_scroll); - void SetTimeAndSignal(const olive::rational& t); - void StopCatchUpScrollTimer() { StopCatchUpScrollTimer(scrollbar_); } signals: - void TimeChanged(const rational&); - void TimebaseChanged(const rational&); void ConnectedNodeChanged(ViewerOutput* old, ViewerOutput* now); @@ -271,6 +263,8 @@ private slots: void ConnectedNodeRemovedFromGraph(); + void PlayheadTimeChanged(const rational &time); + }; } diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 1bfea94a2..ed8dd84d8 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -83,7 +83,6 @@ TimelineWidget::TimelineWidget(QWidget *parent) : timecode_label_->SetDisplayType(RationalSlider::kTime); timecode_label_->setVisible(false); timecode_label_->SetMinimum(0); - connect(timecode_label_, &RationalSlider::ValueChanged, this, &TimelineWidget::SetTimeAndSignal); ruler_and_time_layout->addWidget(timecode_label_); ruler_and_time_layout->addWidget(ruler()); @@ -144,11 +143,10 @@ TimelineWidget::TimelineWidget(QWidget *parent) : view_splitter_->addWidget(tview); - ConnectTimelineView(view, false); + ConnectTimelineView(view); connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll); connect(view, &TimelineView::ScaleChanged, this, &TimelineWidget::SetScale); - connect(view, &TimelineView::TimeChanged, this, &TimelineWidget::SetTimeAndSignal); connect(view, &TimelineView::customContextMenuRequested, this, &TimelineWidget::ShowContextMenu); connect(scrollbar(), &QScrollBar::valueChanged, view->horizontalScrollBar(), &QScrollBar::setValue); connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, scrollbar(), &QScrollBar::setValue); @@ -244,15 +242,6 @@ void TimelineWidget::resizeEvent(QResizeEvent *event) UpdateTimecodeWidthFromSplitters(views_.first()->splitter()); } -void TimelineWidget::TimeChangedEvent(const rational &time) -{ - super::TimeChangedEvent(time); - - SetViewTime(time); - - timecode_label_->SetValue(time); -} - void TimelineWidget::ScaleChangedEvent(const double &scale) { super::ScaleChangedEvent(scale); @@ -271,6 +260,9 @@ void TimelineWidget::ConnectNodeEvent(ViewerOutput *n) connect(s, &Sequence::FrameRateChanged, this, &TimelineWidget::FrameRateChanged); connect(s, &Sequence::SampleRateChanged, this, &TimelineWidget::SampleRateChanged); + connect(timecode_label_, &RationalSlider::ValueChanged, s, &Sequence::SetPlayhead); + connect(s, &Sequence::PlayheadChanged, timecode_label_, &RationalSlider::SetValue); + ruler()->SetPlaybackCache(n->video_frame_cache()); SetTimebase(n->GetVideoParams().frame_rate_as_time_base()); @@ -301,6 +293,8 @@ void TimelineWidget::DisconnectNodeEvent(ViewerOutput *n) disconnect(s, &Sequence::FrameRateChanged, this, &TimelineWidget::FrameRateChanged); disconnect(s, &Sequence::SampleRateChanged, this, &TimelineWidget::SampleRateChanged); + disconnect(timecode_label_, &RationalSlider::ValueChanged, s, &Sequence::SetPlayhead); + DeselectAll(); foreach (Track* track, s->GetTracks()) { @@ -371,7 +365,7 @@ void TimelineWidget::SplitAtPlayhead() return; } - const rational &playhead_time = GetTime(); + const rational &playhead_time = GetConnectedNode()->GetPlayhead(); QVector selected_blocks = GetSelectedBlocks(); @@ -513,7 +507,7 @@ void TimelineWidget::DeleteSelected(bool ripple) ClearGhosts(); if (ripple_command && ripple_command->HasCommands() && new_playhead != RATIONAL_MAX) { - SetTimeAndSignal(new_playhead); + GetConnectedNode()->SetPlayhead(new_playhead); } } @@ -544,14 +538,14 @@ void TimelineWidget::DecreaseTrackHeight() void TimelineWidget::InsertFootageAtPlayhead(const QVector& footage) { auto command = new MultiUndoCommand(); - import_tool_->PlaceAt(footage, GetTime(), true, command); + import_tool_->PlaceAt(footage, GetConnectedNode()->GetPlayhead(), true, command); Core::instance()->undo_stack()->push(command); } void TimelineWidget::OverwriteFootageAtPlayhead(const QVector &footage) { auto command = new MultiUndoCommand(); - import_tool_->PlaceAt(footage, GetTime(), false, command); + import_tool_->PlaceAt(footage, GetConnectedNode()->GetPlayhead(), false, command); Core::instance()->undo_stack()->push(command); } @@ -714,7 +708,7 @@ void TimelineWidget::DeleteInToOut(bool ripple) false)); if (ripple) { - SetTimeAndSignal(GetConnectedNode()->GetWorkArea()->in()); + GetConnectedNode()->SetPlayhead(GetConnectedNode()->GetWorkArea()->in()); } Core::instance()->undo_stack()->push(command); @@ -1325,14 +1319,6 @@ void TimelineWidget::SetUseAudioTimeUnits(bool use) UpdateViewTimebases(); } -void TimelineWidget::SetViewTime(const rational &time) -{ - for (int i=0;iview()->SetTime(time); - } -} - void TimelineWidget::ToolChanged() { HideSnaps(); @@ -1618,7 +1604,7 @@ void TimelineWidget::MoveToPlayheadInternal(bool out) } foreach (Block *b, selected_blocks_) { - rational shift_amt = GetTime() - earliest_pts.value(b->track()); + rational shift_amt = GetConnectedNode()->GetPlayhead() - earliest_pts.value(b->track()); rational new_in = b->in() + shift_amt; bool can_shift = true; @@ -1641,7 +1627,7 @@ void TimelineWidget::MoveToPlayheadInternal(bool out) // Shift selections TimelineWidgetSelections new_sel = GetSelections(); for (auto it=new_sel.begin(); it!=new_sel.end(); it++) { - rational track_adj = GetTime() - earliest_pts.value(GetTrackFromReference(it.key()), GetTime()); + rational track_adj = GetConnectedNode()->GetPlayhead() - earliest_pts.value(GetTrackFromReference(it.key()), GetConnectedNode()->GetPlayhead()); if (!track_adj.isNull()) { it.value().shift(track_adj); } @@ -1794,7 +1780,7 @@ void TimelineWidget::RippleTo(Timeline::MovementMode mode) return; } - rational playhead_time = GetTime(); + rational playhead_time = GetConnectedNode()->GetPlayhead(); QVector tracks = GetEditToInfo(playhead_time, mode); @@ -1842,15 +1828,15 @@ void TimelineWidget::RippleTo(Timeline::MovementMode mode) // If we rippled, ump to where new cut is if applicable if (mode == Timeline::kTrimIn) { - SetTimeAndSignal(closest_point_to_playhead); - } else if (mode == Timeline::kTrimOut && closest_point_to_playhead == GetTime()) { - SetTimeAndSignal(playhead_time); + GetConnectedNode()->SetPlayhead(closest_point_to_playhead); + } else if (mode == Timeline::kTrimOut && closest_point_to_playhead == GetConnectedNode()->GetPlayhead()) { + GetConnectedNode()->SetPlayhead(playhead_time); } } void TimelineWidget::EditTo(Timeline::MovementMode mode) { - const rational playhead_time = GetTime(); + const rational playhead_time = GetConnectedNode()->GetPlayhead(); // Get list of unlocked tracks QVector tracks = GetEditToInfo(playhead_time, mode); @@ -1952,10 +1938,10 @@ bool TimelineWidget::PasteInternal(bool insert) command->add_child(new NodeAddCommand(GetConnectedNode()->project(), n)); } - rational paste_start = GetTime(); + rational paste_start = GetConnectedNode()->GetPlayhead(); if (insert) { - rational paste_end = GetTime(); + rational paste_end = paste_start; for (auto it=res.GetLoadData().properties.cbegin(); it!=res.GetLoadData().properties.cend(); it++) { rational length = static_cast(it.key())->length(); diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 5161f6d55..74cf4d896 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -291,7 +291,6 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; virtual void TimebaseChangedEvent(const rational &) override; - virtual void TimeChangedEvent(const rational &time) override; virtual void ScaleChangedEvent(const double &) override; virtual void ConnectNodeEvent(ViewerOutput* n) override; @@ -417,8 +416,6 @@ private slots: void SetUseAudioTimeUnits(bool use); - void SetViewTime(const rational &time); - void ToolChanged(); void AddableObjectChanged(); diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 5bad687f6..bcba5631d 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -64,15 +64,8 @@ void TimelineView::mousePressEvent(QMouseEvent *event) QPointF scene_pos = mapToScene(event->pos()); for (auto it=clip_marker_rects_.cbegin(); it!=clip_marker_rects_.cend(); it++) { if (it.value().contains(scene_pos)) { - QObject *p = this->parent(); - while (p) { - if (TimelineWidget *timeline = dynamic_cast(p)) { - timeline->SetTime(it.key()->time().in()); - break; - } - - p = p->parent(); - } + GetViewerNode()->SetPlayhead(it.key()->time().in()); + break; } } @@ -353,7 +346,7 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect) int x = TimeToScene(recording_coord_.GetFrame()); painter->drawRect(x, GetTrackY(recording_coord_.GetTrack().index()), - TimeToScene(GetTime()) - x, GetTrackHeight(recording_coord_.GetTrack().index())); + TimeToScene(GetViewerNode()->GetPlayhead()) - x, GetTrackHeight(recording_coord_.GetTrack().index())); } // Draw standard TimelineViewBase things (such as playhead) diff --git a/app/widget/timeruler/seekablewidget.cpp b/app/widget/timeruler/seekablewidget.cpp index 8dc21dace..750e1b67c 100644 --- a/app/widget/timeruler/seekablewidget.cpp +++ b/app/widget/timeruler/seekablewidget.cpp @@ -149,7 +149,7 @@ bool SeekableWidget::PasteMarkers() for (auto it=markers.cbegin(); it!=markers.cend(); it++) { min = std::min(min, (*it)->time().in()); } - min -= GetTime(); + min -= GetViewerNode()->GetPlayhead(); for (auto it=markers.cbegin(); it!=markers.cend(); it++) { TimelineMarker *m = *it; @@ -379,10 +379,8 @@ void SeekableWidget::SeekToScenePoint(qreal scene) playhead_time += movement; } - if (playhead_time != GetTime()) { - SetTime(playhead_time); - - emit TimeChanged(playhead_time); + if (playhead_time != GetViewerNode()->GetPlayhead()) { + GetViewerNode()->SetPlayhead(playhead_time); } } diff --git a/app/widget/timeruler/timeruler.cpp b/app/widget/timeruler/timeruler.cpp index fab83276a..603706a82 100644 --- a/app/widget/timeruler/timeruler.cpp +++ b/app/widget/timeruler/timeruler.cpp @@ -267,7 +267,7 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect) } // Draw the playhead if it's on screen at the moment - int playhead_pos = TimeToScene(GetTime()); + int playhead_pos = TimeToScene(GetViewerNode()->GetPlayhead()); p->setPen(Qt::NoPen); p->setBrush(PLAYHEAD_COLOR); DrawPlayhead(p, playhead_pos, line_bottom); diff --git a/app/widget/timetarget/timetarget.cpp b/app/widget/timetarget/timetarget.cpp index 3c98aa7df..3262b7a0a 100644 --- a/app/widget/timetarget/timetarget.cpp +++ b/app/widget/timetarget/timetarget.cpp @@ -28,16 +28,23 @@ TimeTargetObject::TimeTargetObject() : { } -Node *TimeTargetObject::GetTimeTarget() const +ViewerOutput *TimeTargetObject::GetTimeTarget() const { return time_target_; } -void TimeTargetObject::SetTimeTarget(Node *target) +void TimeTargetObject::SetTimeTarget(ViewerOutput *target) { - time_target_ = target; + if (time_target_) { + TimeTargetDisconnectEvent(time_target_); + } + time_target_ = target; TimeTargetChangedEvent(time_target_); + + if (time_target_) { + TimeTargetConnectEvent(time_target_); + } } void TimeTargetObject::SetPathIndex(int index) diff --git a/app/widget/timetarget/timetarget.h b/app/widget/timetarget/timetarget.h index c561f58b0..5f11fc0f1 100644 --- a/app/widget/timetarget/timetarget.h +++ b/app/widget/timetarget/timetarget.h @@ -21,7 +21,7 @@ #ifndef TIMETARGETOBJECT_H #define TIMETARGETOBJECT_H -#include "node/node.h" +#include "node/output/viewer/viewer.h" namespace olive { @@ -30,8 +30,8 @@ class TimeTargetObject public: TimeTargetObject(); - Node* GetTimeTarget() const; - void SetTimeTarget(Node* target); + ViewerOutput* GetTimeTarget() const; + void SetTimeTarget(ViewerOutput* target); void SetPathIndex(int index); @@ -41,10 +41,12 @@ public: //int GetNumberOfPathAdjustments(Node* from, NodeParam::Type direction) const; protected: - virtual void TimeTargetChangedEvent(Node* ){} + virtual void TimeTargetDisconnectEvent(ViewerOutput *){} + virtual void TimeTargetChangedEvent(ViewerOutput *){} + virtual void TimeTargetConnectEvent(ViewerOutput *){} private: - Node* time_target_; + ViewerOutput* time_target_; int path_index_; diff --git a/app/widget/viewer/audiowaveformview.cpp b/app/widget/viewer/audiowaveformview.cpp index 10a4c85eb..8ad081e6f 100644 --- a/app/widget/viewer/audiowaveformview.cpp +++ b/app/widget/viewer/audiowaveformview.cpp @@ -96,7 +96,7 @@ void AudioWaveformView::drawForeground(QPainter *p, const QRectF &rect) // Draw playhead p->setPen(PLAYHEAD_COLOR); - int playhead_x = TimeToScene(GetTime()); + int playhead_x = TimeToScene(GetViewerNode()->GetPlayhead()); p->drawLine(playhead_x, 0, playhead_x, height()); } diff --git a/app/widget/viewer/footageviewer.cpp b/app/widget/viewer/footageviewer.cpp index b643f6740..05373b0f2 100644 --- a/app/widget/viewer/footageviewer.cpp +++ b/app/widget/viewer/footageviewer.cpp @@ -56,25 +56,6 @@ void FootageViewerWidget::ResetWorkArea() } } -void FootageViewerWidget::ConnectNodeEvent(ViewerOutput *n) -{ - super::ConnectNodeEvent(n); - - IgnoreNextScrubEvent(); - SetTime(cached_timestamps_.value(n, 0)); -} - -void FootageViewerWidget::DisconnectNodeEvent(ViewerOutput *n) -{ - // Cache timestamp in case this footage is opened again later - cached_timestamps_.insert(n, GetTime()); - - super::DisconnectNodeEvent(n); - - IgnoreNextScrubEvent(); - SetTime(0); -} - void FootageViewerWidget::StartFootageDragInternal(bool enable_video, bool enable_audio) { if (!GetConnectedNode()) { diff --git a/app/widget/viewer/footageviewer.h b/app/widget/viewer/footageviewer.h index de98866c8..802e6e4d8 100644 --- a/app/widget/viewer/footageviewer.h +++ b/app/widget/viewer/footageviewer.h @@ -35,16 +35,9 @@ public: void OverrideWorkArea(const TimeRange &r); void ResetWorkArea(); -protected: - virtual void ConnectNodeEvent(ViewerOutput *) override; - - virtual void DisconnectNodeEvent(ViewerOutput *) override; - private: void StartFootageDragInternal(bool enable_video, bool enable_audio); - QHash cached_timestamps_; - TimelineWorkArea *override_workarea_; private slots: diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 3beb3f44e..ccb3d79d3 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -113,7 +113,7 @@ ViewerWidget::ViewerWidget(ViewerDisplayWidget *display, QWidget *parent) : // Create waveform view when audio is connected and video isn't waveform_view_ = new AudioWaveformView(); - ConnectTimelineView(waveform_view_, true); + ConnectTimelineView(waveform_view_); PassWheelEventsToScrollBar(waveform_view_); layout->addWidget(waveform_view_); @@ -135,7 +135,6 @@ ViewerWidget::ViewerWidget(ViewerDisplayWidget *display, QWidget *parent) : connect(controls_, &PlaybackControls::NextFrameClicked, this, &ViewerWidget::NextFrame); connect(controls_, &PlaybackControls::BeginClicked, this, &ViewerWidget::GoToStart); connect(controls_, &PlaybackControls::EndClicked, this, &ViewerWidget::GoToEnd); - connect(controls_, &PlaybackControls::TimeChanged, this, &ViewerWidget::SetTimeAndSignal); layout->addWidget(controls_); // FIXME: Magic number @@ -182,7 +181,6 @@ void ViewerWidget::TimeChangedEvent(const rational &time) } controls_->SetTime(time); - waveform_view_->SetTime(time); if (GetConnectedNode() && last_time_ != time) { if (!IsPlaying()) { @@ -216,6 +214,8 @@ void ViewerWidget::ConnectNodeEvent(ViewerOutput *n) connect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange); connect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateWaveformViewFromMode); + connect(controls_, &PlaybackControls::TimeChanged, n, &ViewerOutput::SetPlayhead); + VideoParams vp = n->GetVideoParams(); InterlacingChangedSlot(vp.interlacing()); @@ -260,6 +260,8 @@ void ViewerWidget::DisconnectNodeEvent(ViewerOutput *n) disconnect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange); disconnect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateWaveformViewFromMode); + disconnect(controls_, &PlaybackControls::TimeChanged, n, &ViewerOutput::SetPlayhead); + timeline_selected_blocks_.clear(); node_view_selected_.clear(); if (multicam_panel_) { @@ -417,7 +419,7 @@ void ViewerWidget::SetGizmos(Node *node) void ViewerWidget::StartCapture(TimelineWidget *source, const TimeRange &time, const Track::Reference &track) { - SetTimeAndSignal(time.in()); + GetConnectedNode()->SetPlayhead(time.in()); ArmForRecording(); recording_callback_ = source; @@ -480,7 +482,7 @@ void ViewerWidget::SetEmptyImage() void ViewerWidget::UpdateAutoCacher() { - auto_cacher_->SetPlayhead(GetTime()); + auto_cacher_->SetPlayhead(GetConnectedNode()->GetPlayhead()); } void ViewerWidget::DecrementPrequeuedAudio() @@ -523,7 +525,7 @@ void ViewerWidget::CreateAddableAt(const QRectF &f) Track::Type type = Track::kVideo; int track_index = -1; TrackList *list = s->track_list(type); - const rational &in = GetTime(); + const rational &in = GetConnectedNode()->GetPlayhead(); rational length = OLIVE_CONFIG("DefaultStillLength").value(); rational out = in + length; @@ -597,7 +599,7 @@ void ViewerWidget::RequestNextDryRun() if (IsPlaying()) { rational next_time = Timecode::timestamp_to_time(dry_run_next_frame_, timebase()); if (FrameExistsAtTime(next_time)) { - if (next_time > GetTime() + RenderManager::kDryRunInterval) { + if (next_time > GetConnectedNode()->GetPlayhead() + RenderManager::kDryRunInterval) { QTimer::singleShot(timebase().toDouble() / playback_speed_, this, &ViewerWidget::RequestNextDryRun); } else { RenderTicketWatcher *watcher = new RenderTicketWatcher(this); @@ -612,12 +614,12 @@ void ViewerWidget::RequestNextDryRun() void ViewerWidget::SaveFrameAsImage() { - Core::instance()->OpenExportDialogForViewer(GetConnectedNode(), GetTime(), true); + Core::instance()->OpenExportDialogForViewer(GetConnectedNode(), true); } void ViewerWidget::DetectMulticamNodeNow() { - DetectMulticamNode(GetTime()); + DetectMulticamNode(GetConnectedNode()->GetPlayhead()); } void ViewerWidget::CloseAudioProcessor() @@ -828,7 +830,7 @@ void ViewerWidget::QueueStarved() queue_starved_start_ = now; } else if (now > queue_starved_start_ + kMaximumWaitTimeMs) { if (first_requeue_watcher_) { - if (GetTime() + kMaximumWaitTime < first_requeue_watcher_->property("time").value()) { + if (GetConnectedNode()->GetPlayhead() + kMaximumWaitTime < first_requeue_watcher_->property("time").value()) { // We still have time return; } @@ -874,7 +876,7 @@ void ViewerWidget::UpdateTextureFromNode() return; } - rational time = GetTime(); + rational time = GetConnectedNode()->GetPlayhead(); bool frame_exists_at_time = FrameExistsAtTime(time); bool frame_might_be_still = ViewerMightBeAStill(); @@ -933,11 +935,11 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only) // If the playhead is beyond the end, restart at 0 if (!recording_) { rational last_frame = GetConnectedNode()->GetLength() - timebase(); - if (!in_to_out_only && GetTime() >= last_frame) { + if (!in_to_out_only && GetConnectedNode()->GetPlayhead() >= last_frame) { if (speed > 0) { - SetTimeAndSignal(0); + GetConnectedNode()->SetPlayhead(0); } else { - SetTimeAndSignal(last_frame); + GetConnectedNode()->SetPlayhead(last_frame); } } } @@ -977,7 +979,7 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only) static const int prequeue_count = 2; prequeuing_audio_ = prequeue_count; // Queue two buffers ahead of time - audio_playback_queue_time_ = GetTime(); + audio_playback_queue_time_ = GetConnectedNode()->GetPlayhead(); for (int i=0; iSetTicket(auto_cacher_->GetRangeOfAudio(TimeRange(GetTime(), GetTime() + interval))); + watcher->SetTicket(auto_cacher_->GetRangeOfAudio(TimeRange(GetConnectedNode()->GetPlayhead(), GetConnectedNode()->GetPlayhead() + interval))); } } } @@ -1173,7 +1175,7 @@ void ViewerWidget::FinishPlayPreprocess() prequeued_audio_.clear(); AudioMonitor::StartWaveformOnAll(GetConnectedNode()->GetConnectedWaveform(), - GetTime(), playback_speed_); + GetConnectedNode()->GetPlayhead(), playback_speed_); } display_widget_->ResetFPSTimer(); @@ -1522,7 +1524,7 @@ void ViewerWidget::Play(bool in_to_out_only) if (GetConnectedNode() && GetConnectedNode()->GetWorkArea()->enabled()) { // Jump to in point - SetTimeAndSignal(GetConnectedNode()->GetWorkArea()->in()); + GetConnectedNode()->SetPlayhead(GetConnectedNode()->GetWorkArea()->in()); } else { in_to_out_only = false; } @@ -1632,7 +1634,7 @@ void ViewerWidget::TimebaseChangedEvent(const rational &timebase) controls_->SetTimebase(timebase); - controls_->SetTime(ruler()->GetTime()); + controls_->SetTime(GetConnectedNode() ? GetConnectedNode()->GetPlayhead() : 0); LengthChangedSlot(GetConnectedNode() ? GetConnectedNode()->GetLength() : 0); } @@ -1717,7 +1719,7 @@ void ViewerWidget::PlaybackTimerUpdate() // pausing. Even if we pause it later with `end_of_line`, we prefer pausing after setting the time // so that an audio scrub event, etc. isn't sent. time_changed_from_timer_ = true; - SetTimeAndSignal(time_to_set); + GetConnectedNode()->SetPlayhead(time_to_set); time_changed_from_timer_ = false; if (end_of_line) { // Cache the current speed @@ -1767,7 +1769,7 @@ void ViewerWidget::LengthChangedSlot(const rational &length) controls_->SetEndTime(length); UpdateMinimumScale(); - if (length < last_length_ && GetTime() >= length) { + if (GetConnectedNode() && length < last_length_ && GetConnectedNode()->GetPlayhead() >= length) { UpdateTextureFromNode(); } @@ -1813,7 +1815,7 @@ void ViewerWidget::SetZoomFromMenu(QAction *action) void ViewerWidget::ViewerInvalidatedVideoRange(const TimeRange &range) { // If our current frame is within this range, we need to update - if (!IsPlaying() && GetTime() >= range.in() && (GetTime() < range.out() || range.in() == range.out())) { + if (!IsPlaying() && GetConnectedNode()->GetPlayhead() >= range.in() && (GetConnectedNode()->GetPlayhead() < range.out() || range.in() == range.out())) { QMetaObject::invokeMethod(this, &ViewerWidget::UpdateTextureFromNode, Qt::QueuedConnection); } } diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index e4f0d7289..de06b62e1 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -229,7 +229,7 @@ protected: private: int64_t GetTimestamp() const { - return Timecode::time_to_timestamp(GetTime(), timebase(), Timecode::kFloor); + return Timecode::time_to_timestamp(GetConnectedNode()->GetPlayhead(), timebase(), Timecode::kFloor); } void UpdateTimeInternal(int64_t i); diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 20adf7800..93049db33 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -107,12 +107,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(node_panel_, &NodePanel::NodeSelectionChanged, sequence_viewer_panel_, &ViewerPanel::SetNodeViewSelections); - // Connect time signals together - AddMainTimePanel(multicam_panel_); - AddMainTimePanel(curve_panel_); - AddMainTimePanel(param_panel_); - AddMainTimePanel(sequence_viewer_panel_); - + // Route play/pause/shuttle commands from these panels to the sequence viewer sequence_viewer_panel_->ConnectTimeBasedPanel(param_panel_); sequence_viewer_panel_->ConnectTimeBasedPanel(curve_panel_); sequence_viewer_panel_->ConnectTimeBasedPanel(multicam_panel_); @@ -526,7 +521,7 @@ void MainWindow::RevealViewerInFootageViewer(ViewerOutput *r, const TimeRange &r command->add_child(new WorkareaSetRangeCommand(r->GetWorkArea(), range)); Core::instance()->undo_stack()->push(command); - footage_viewer_panel_->SetTime(range.in()); + r->SetPlayhead(range.in()); } #ifdef Q_OS_LINUX @@ -557,7 +552,6 @@ void MainWindow::TimelineCloseRequested() { TimelinePanel *t = static_cast(sender()); RemoveTimelinePanel(t); - main_time_panels_.removeOne(t); } void MainWindow::ProjectCloseRequested() @@ -599,21 +593,6 @@ void MainWindow::FloatingPanelCloseRequested() panel->deleteLater(); } -void MainWindow::AddMainTimePanel(TimeBasedPanel *p) -{ - main_time_panels_.append(p); - connect(p, &TimeBasedPanel::TimeChanged, this, &MainWindow::UpdateMainTimePanels); -} - -void MainWindow::UpdateMainTimePanels(const rational &r) -{ - for (TimeBasedPanel *p : main_time_panels_) { - if (p != sender()) { - p->SetTime(r); - } - } -} - TimelinePanel* MainWindow::AppendTimelinePanel() { TimelinePanel* panel = AppendPanelInternal(timeline_panels_); @@ -624,8 +603,6 @@ TimelinePanel* MainWindow::AppendTimelinePanel() connect(panel, &TimelinePanel::RevealViewerInProject, this, &MainWindow::RevealViewerInProject); connect(panel, &TimelinePanel::RevealViewerInFootageViewer, this, &MainWindow::RevealViewerInFootageViewer); - AddMainTimePanel(panel); - sequence_viewer_panel_->ConnectTimeBasedPanel(panel); return panel; diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index 7f319e4b1..892d2ca54 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -147,8 +147,6 @@ private: void SelectFootageForProjectPanel(const QVector &e, ProjectPanel *p); - void AddMainTimePanel(TimeBasedPanel *p); - QByteArray premaximized_state_; // Standard panels @@ -176,8 +174,6 @@ private: bool first_show_; - QVector main_time_panels_; - private slots: void FocusedPanelChanged(PanelWidget* panel); @@ -208,8 +204,6 @@ private slots: void RevealViewerInProject(ViewerOutput *r); void RevealViewerInFootageViewer(ViewerOutput *r, const TimeRange &range); - void UpdateMainTimePanels(const rational &r); - }; }