diff --git a/app/panel/viewer/viewerbase.h b/app/panel/viewer/viewerbase.h index 60122c262..16c733b35 100644 --- a/app/panel/viewer/viewerbase.h +++ b/app/panel/viewer/viewerbase.h @@ -77,6 +77,11 @@ public: GetViewerWidget()->SetTimelineSelectedBlocks(b); } + void SetNodeViewSelections(const QVector &n) + { + GetViewerWidget()->SetNodeViewSelections(n); + } + void ConnectMulticamWidget(MulticamWidget *p) { GetViewerWidget()->ConnectMulticamWidget(p); diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index fa8c2ac52..ef9d47390 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -260,6 +260,9 @@ void ViewerWidget::DisconnectNodeEvent(ViewerOutput *n) disconnect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange); disconnect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateWaveformViewFromMode); + timeline_selected_blocks_.clear(); + node_view_selected_.clear(); + CloseAudioProcessor(); audio_scrub_watchers_.clear(); @@ -621,12 +624,30 @@ void ViewerWidget::DetectMulticamNode(const rational &time) // Faster way to do this if (multicam_panel_ && multicam_panel_->isVisible()) { if (Sequence *s = dynamic_cast(GetConnectedNode())) { - // Prefer selected blocks - for (Block *b : timeline_selected_blocks_) { - if (b->range().Contains(time)) { - if ((clip = dynamic_cast(b))) { - if ((multicam = clip->FindMulticam())) { - break; + // Prefer selected nodes + for (Node *n : qAsConst(node_view_selected_)) { + if ((multicam = dynamic_cast(n))) { + // Found multicam, now try to find corresponding clip from selected timeline blocks + for (Block *b : qAsConst(timeline_selected_blocks_)) { + if (ClipBlock *c = dynamic_cast(b)) { + if (c->range().Contains(time) && c->ContextContainsNode(multicam)) { + clip = c; + break; + } + } + } + break; + } + } + + // Next, prefer multicam from selected block + if (!multicam) { + for (Block *b : qAsConst(timeline_selected_blocks_)) { + if (b->range().Contains(time)) { + if ((clip = dynamic_cast(b))) { + if ((multicam = clip->FindMulticam())) { + break; + } } } } diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index a5312eb3b..c465aabc9 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -122,6 +122,17 @@ public: } } + void SetNodeViewSelections(const QVector &n) + { + node_view_selected_ = n; + + if (!IsPlaying()) { + // If is playing, this will happen by the next frame automatically + DetectMulticamNode(GetTime()); + UpdateTextureFromNode(); + } + } + void ConnectMulticamWidget(MulticamWidget *p); public slots: @@ -340,6 +351,7 @@ private: int ignore_scrub_; QVector timeline_selected_blocks_; + QVector node_view_selected_; MulticamWidget *multicam_panel_; diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index dfb5e11a2..79b589901 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -105,6 +105,8 @@ MainWindow::MainWindow(QWidget *parent) : connect(param_panel_, &ParamPanel::FocusedNodeChanged, curve_panel_, &CurvePanel::SetNode); connect(param_panel_, &ParamPanel::SelectedNodesChanged, node_panel_, &NodePanel::Select); + connect(node_panel_, &NodePanel::NodeSelectionChanged, sequence_viewer_panel_, &ViewerPanel::SetNodeViewSelections); + // Connect time signals together AddMainTimePanel(multicam_panel_); AddMainTimePanel(curve_panel_);