diff --git a/app/panel/curve/curve.cpp b/app/panel/curve/curve.cpp index d67972a7e..233b637f5 100644 --- a/app/panel/curve/curve.cpp +++ b/app/panel/curve/curve.cpp @@ -32,9 +32,16 @@ CurvePanel::CurvePanel(QWidget *parent) : Retranslate(); } +NodeInput *CurvePanel::GetInput() const +{ + return static_cast(GetTimeBasedWidget())->GetInput(); +} + void CurvePanel::SetInput(NodeInput *input) { static_cast(GetTimeBasedWidget())->SetInput(input); + + Retranslate(); } void CurvePanel::SetTimeTarget(Node *target) @@ -59,6 +66,13 @@ void CurvePanel::Retranslate() TimeBasedPanel::Retranslate(); SetTitle(tr("Curve Editor")); + + NodeInput* connected_input = static_cast(GetTimeBasedWidget())->GetInput(); + if (connected_input) { + SetSubtitle(connected_input->name()); + } else { + SetSubtitle(QString()); + } } OLIVE_NAMESPACE_EXIT diff --git a/app/panel/curve/curve.h b/app/panel/curve/curve.h index 36a3ba564..761b00a0f 100644 --- a/app/panel/curve/curve.h +++ b/app/panel/curve/curve.h @@ -32,6 +32,8 @@ class CurvePanel : public TimeBasedPanel public: CurvePanel(QWidget* parent); + NodeInput* GetInput() const; + public slots: void SetInput(NodeInput* input); diff --git a/app/panel/panelmanager.cpp b/app/panel/panelmanager.cpp index a76d65093..f85e6824f 100644 --- a/app/panel/panelmanager.cpp +++ b/app/panel/panelmanager.cpp @@ -144,7 +144,10 @@ void PanelManager::FocusChanged(QWidget *old, QWidget *now) void PanelManager::SetPanelsLocked(bool locked) { foreach (PanelWidget* panel, focus_history_) { - panel->SetMovementLocked(locked); + // Only affect panels actually in our layout + if (!panel->isFloating()) { + panel->SetMovementLocked(locked); + } } locked_ = locked; diff --git a/app/panel/param/param.cpp b/app/panel/param/param.cpp index e714f8d05..bdbb8e8e0 100644 --- a/app/panel/param/param.cpp +++ b/app/panel/param/param.cpp @@ -20,15 +20,19 @@ #include "param.h" +#include "window/mainwindow/mainwindow.h" + OLIVE_NAMESPACE_ENTER ParamPanel::ParamPanel(QWidget* parent) : TimeBasedPanel(QStringLiteral("ParamPanel"), parent) { NodeParamView* view = new NodeParamView(); - connect(view, &NodeParamView::SelectedInputChanged, this, &ParamPanel::SelectedInputChanged); + connect(view, &NodeParamView::InputDoubleClicked, this, &ParamPanel::CreateCurvePanel); connect(view, &NodeParamView::TimeTargetChanged, this, &ParamPanel::TimeTargetChanged); connect(view, &NodeParamView::RequestSelectNode, this, &ParamPanel::RequestSelectNode); + connect(view, &NodeParamView::OpenedNode, this, &ParamPanel::OpeningNode); + connect(view, &NodeParamView::ClosedNode, this, &ParamPanel::ClosingNode); SetTimeBasedWidget(view); Retranslate(); @@ -41,6 +45,20 @@ void ParamPanel::SetNodes(QList nodes) Retranslate(); } +void ParamPanel::SetTimestamp(const int64_t ×tamp) +{ + TimeBasedPanel::SetTimestamp(timestamp); + + // Ensure all CurvePanels are updated with this time too + QHash::const_iterator i; + + for (i=open_curve_panels_.begin(); i!=open_curve_panels_.end(); i++) { + if (i.value() && i.value() != sender()) { + i.value()->SetTimestamp(timestamp); + } + } +} + void ParamPanel::Retranslate() { SetTitle(tr("Parameter Editor")); @@ -56,4 +74,67 @@ void ParamPanel::Retranslate() } } +void ParamPanel::CreateCurvePanel(NodeInput *input) +{ + if (!input->is_keyframable()) { + return; + } + + CurvePanel* panel = open_curve_panels_.value(input); + + if (panel) { + panel->raise(); + return; + } + + NodeParamView* view = static_cast(GetTimeBasedWidget()); + + panel = Core::instance()->main_window()->AppendCurvePanel(); + + panel->SetInput(input); + panel->SetTimebase(view->timebase()); + panel->SetTimestamp(view->GetTimestamp()); + + connect(view, &NodeParamView::TimebaseChanged, panel, &CurvePanel::SetTimebase); + connect(view, &NodeParamView::TimeChanged, panel, &CurvePanel::SetTimestamp); + connect(panel, &CurvePanel::TimeChanged, view, &NodeParamView::SetTimestamp); + connect(panel, &CurvePanel::TimeChanged, view, &NodeParamView::TimeChanged); + connect(panel, &CurvePanel::CloseRequested, this, &ParamPanel::ClosingCurvePanel); + + open_curve_panels_.insert(input, panel); +} + +void ParamPanel::OpeningNode(Node *n) +{ + QList inputs = n->GetInputsIncludingArrays(); + + foreach (NodeInput* i, inputs) { + if (open_curve_panels_.contains(i)) { + // We had a CurvePanel open for this input that was closed in ClosingNode(), re-open it + CreateCurvePanel(i); + } + } +} + +void ParamPanel::ClosingNode(Node *n) +{ + QList inputs = n->GetInputsIncludingArrays(); + + foreach (NodeInput* i, inputs) { + CurvePanel* panel = open_curve_panels_.value(i); + + // Close the panel (this also destroys it), but keep a reference in the hash + if (panel) { + panel->close(); + open_curve_panels_.insert(i, nullptr); + } + } +} + +void ParamPanel::ClosingCurvePanel() +{ + CurvePanel* panel = static_cast(sender()); + open_curve_panels_.remove(panel->GetInput()); +} + OLIVE_NAMESPACE_EXIT diff --git a/app/panel/param/param.h b/app/panel/param/param.h index 7d78aab64..0ad5523c4 100644 --- a/app/panel/param/param.h +++ b/app/panel/param/param.h @@ -21,6 +21,7 @@ #ifndef PARAM_H #define PARAM_H +#include "panel/curve/curve.h" #include "panel/timebased/timebased.h" #include "widget/nodeparamview/nodeparamview.h" @@ -35,9 +36,9 @@ public: public slots: void SetNodes(QList nodes); -signals: - void SelectedInputChanged(NodeInput* input); + virtual void SetTimestamp(const int64_t& timestamp) override; +signals: void TimeTargetChanged(Node* node); void RequestSelectNode(const QList& target); @@ -45,6 +46,18 @@ signals: protected: virtual void Retranslate() override; +private slots: + void CreateCurvePanel(NodeInput* input); + + void OpeningNode(Node* n); + + void ClosingNode(Node* n); + + void ClosingCurvePanel(); + +private: + QHash open_curve_panels_; + }; OLIVE_NAMESPACE_EXIT diff --git a/app/panel/timebased/timebased.cpp b/app/panel/timebased/timebased.cpp index 4da1e95c0..37a0959fa 100644 --- a/app/panel/timebased/timebased.cpp +++ b/app/panel/timebased/timebased.cpp @@ -68,7 +68,7 @@ void TimeBasedPanel::SetTimebase(const rational &timebase) widget_->SetTimebase(timebase); } -void TimeBasedPanel::SetTime(const int64_t ×tamp) +void TimeBasedPanel::SetTimestamp(const int64_t ×tamp) { widget_->SetTimestamp(timestamp); } diff --git a/app/panel/timebased/timebased.h b/app/panel/timebased/timebased.h index 9c68567b3..90fb83723 100644 --- a/app/panel/timebased/timebased.h +++ b/app/panel/timebased/timebased.h @@ -89,7 +89,7 @@ public: public slots: void SetTimebase(const rational& timebase); - void SetTime(const int64_t& timestamp); + virtual void SetTimestamp(const int64_t& timestamp); signals: void TimeChanged(const int64_t& time); diff --git a/app/panel/viewer/viewerbase.cpp b/app/panel/viewer/viewerbase.cpp index da1726540..a8d4d55b8 100644 --- a/app/panel/viewer/viewerbase.cpp +++ b/app/panel/viewer/viewerbase.cpp @@ -98,9 +98,6 @@ void ViewerPanelBase::CreateScopePanel(ScopePanel::Type type) p->SetType(type); - // We treat our scope panels as kind of children, and destroy them if we're ever destroyed - connect(this, &ViewerPanelBase::destroyed, p, &ScopePanel::deleteLater); - // If the scope closes, reduce the count (we do this because if no scopes are open, we can optimize the viewer slightly) connect(p, &ScopePanel::CloseRequested, this, &ViewerPanelBase::ScopePanelClosed); diff --git a/app/widget/curvewidget/curvewidget.cpp b/app/widget/curvewidget/curvewidget.cpp index a16e0a726..71c742619 100644 --- a/app/widget/curvewidget/curvewidget.cpp +++ b/app/widget/curvewidget/curvewidget.cpp @@ -108,6 +108,11 @@ CurveWidget::~CurveWidget() view_->Clear(); } +NodeInput *CurveWidget::GetInput() const +{ + return input_; +} + void CurveWidget::SetInput(NodeInput *input) { if (bridge_) { diff --git a/app/widget/curvewidget/curvewidget.h b/app/widget/curvewidget/curvewidget.h index 551825028..b0276bb7f 100644 --- a/app/widget/curvewidget/curvewidget.h +++ b/app/widget/curvewidget/curvewidget.h @@ -41,6 +41,7 @@ public: virtual ~CurveWidget() override; + NodeInput* GetInput() const; void SetInput(NodeInput* input); const double& GetVerticalScale(); diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index 6b57f2c14..b9d1e7366 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -126,6 +126,8 @@ void NodeParamView::SetNodes(QList nodes) // If we already have item widgets, delete them all now foreach (NodeParamViewItem* item, items_) { + emit ClosedNode(item->GetNode()); + delete item; } items_.clear(); @@ -149,12 +151,14 @@ void NodeParamView::SetNodes(QList nodes) 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); + connect(item, &NodeParamViewItem::InputDoubleClicked, this, &NodeParamView::InputDoubleClicked); connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::RequestSelectNode); items_.append(item); QTimer::singleShot(1, item, &NodeParamViewItem::SignalAllKeyframes); + + emit OpenedNode(node); } ViewerOutput* viewer = nodes_.first()->FindOutputNode(); diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index 5188469fe..097fcd4ae 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -41,12 +41,16 @@ public: const QList& nodes(); signals: - void SelectedInputChanged(NodeInput* input); + void InputDoubleClicked(NodeInput* input); void TimeTargetChanged(Node* target); void RequestSelectNode(const QList& target); + void OpenedNode(Node* n); + + void ClosedNode(Node* n); + protected: virtual void resizeEvent(QResizeEvent *event) override; diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index b464e3135..6d7a2f0ee 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -46,7 +46,6 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) : QHBoxLayout* title_bar_layout = new QHBoxLayout(title_bar_); title_bar_collapse_btn_ = new CollapseButton(); - connect(title_bar_collapse_btn_, &QPushButton::toggled, this, &NodeParamViewItemBody::setVisible); title_bar_layout->addWidget(title_bar_collapse_btn_); title_bar_lbl_ = new QLabel(title_bar_); @@ -66,11 +65,12 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) : } body_ = new NodeParamViewItemBody(inputs); - connect(body_, &NodeParamViewItemBody::InputClicked, this, &NodeParamViewItem::InputClicked); + connect(body_, &NodeParamViewItemBody::InputDoubleClicked, this, &NodeParamViewItem::InputDoubleClicked); connect(body_, &NodeParamViewItemBody::RequestSelectNode, this, &NodeParamViewItem::RequestSelectNode); connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime); connect(body_, &NodeParamViewItemBody::KeyframeAdded, this, &NodeParamViewItem::KeyframeAdded); connect(body_, &NodeParamViewItemBody::KeyframeRemoved, this, &NodeParamViewItem::KeyframeRemoved); + connect(title_bar_collapse_btn_, &QPushButton::toggled, body_, &NodeParamViewItemBody::setVisible); main_layout->addWidget(body_); Retranslate(); @@ -88,6 +88,11 @@ void NodeParamViewItem::SetTime(const rational &time) body_->SetTime(time_); } +Node *NodeParamViewItem::GetNode() const +{ + return node_; +} + void NodeParamViewItem::SignalAllKeyframes() { body_->SignalAllKeyframes(); @@ -142,7 +147,7 @@ NodeParamViewItemBody::NodeParamViewItemBody(const QVector &inputs, // Add descriptor label ui_objects.main_label = new ClickableLabel(); - connect(ui_objects.main_label, &ClickableLabel::MouseClicked, this, &NodeParamViewItemBody::LabelClicked); + connect(ui_objects.main_label, &ClickableLabel::MouseDoubleClicked, this, &NodeParamViewItemBody::LabelDoubleClicked); if (input->IsArray()) { QHBoxLayout* array_label_layout = new QHBoxLayout(); @@ -164,7 +169,7 @@ NodeParamViewItemBody::NodeParamViewItemBody(const QVector &inputs, connect(sub_body, &NodeParamViewItemBody::KeyframeAdded, this, &NodeParamViewItemBody::KeyframeAdded); connect(sub_body, &NodeParamViewItemBody::KeyframeRemoved, this, &NodeParamViewItemBody::KeyframeRemoved); connect(sub_body, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItemBody::RequestSetTime); - connect(sub_body, &NodeParamViewItemBody::InputClicked, this, &NodeParamViewItemBody::InputClicked); + connect(sub_body, &NodeParamViewItemBody::InputDoubleClicked, this, &NodeParamViewItemBody::InputDoubleClicked); connect(sub_body, &NodeParamViewItemBody::RequestSelectNode, this, &NodeParamViewItemBody::RequestSelectNode); } else { content_layout->addWidget(ui_objects.main_label, row_count, 0); @@ -330,12 +335,13 @@ void NodeParamViewItemBody::InputAddedKeyframe(NodeKeyframePtr key) InputAddedKeyframeInternal(input, key); } -void NodeParamViewItemBody::LabelClicked() +void NodeParamViewItemBody::LabelDoubleClicked() { QMap::const_iterator iterator; + for (iterator=input_ui_map_.begin(); iterator!=input_ui_map_.end(); iterator++) { - if (iterator.value().connected_label == sender()) { - emit InputClicked(iterator.key()); + if (iterator.value().main_label == sender()) { + emit InputDoubleClicked(iterator.key()); return; } } diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h index 5963391ba..5209d68ed 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.h +++ b/app/widget/nodeparamview/nodeparamviewitem.h @@ -64,7 +64,7 @@ signals: void RequestSetTime(const rational& time); - void InputClicked(NodeInput* input); + void InputDoubleClicked(NodeInput* input); void RequestSelectNode(const QList& node); @@ -93,7 +93,7 @@ private slots: void InputAddedKeyframe(NodeKeyframePtr key); - void LabelClicked(); + void LabelDoubleClicked(); void ConnectionClicked(); @@ -109,6 +109,8 @@ public: void SetTime(const rational& time); + Node* GetNode() const; + public slots: void SignalAllKeyframes(); @@ -119,7 +121,7 @@ signals: void RequestSetTime(const rational& time); - void InputClicked(NodeInput* input); + void InputDoubleClicked(NodeInput* input); void RequestSelectNode(const QList& node); diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 1a83578e5..4c192af99 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -73,27 +73,17 @@ MainWindow::MainWindow(QWidget *parent) : AppendProjectPanel(); tool_panel_ = PanelManager::instance()->CreatePanel(this); task_man_panel_ = PanelManager::instance()->CreatePanel(this); - curve_panel_ = PanelManager::instance()->CreatePanel(this); AppendTimelinePanel(); audio_monitor_panel_ = PanelManager::instance()->CreatePanel(this); // Make connections to sequence viewer connect(node_panel_, &NodePanel::SelectionChanged, param_panel_, &ParamPanel::SetNodes); - connect(param_panel_, &ParamPanel::SelectedInputChanged, curve_panel_, &CurvePanel::SetInput); - connect(param_panel_, &ParamPanel::TimebaseChanged, curve_panel_, &CurvePanel::SetTimebase); - connect(param_panel_, &ParamPanel::TimeTargetChanged, curve_panel_, &CurvePanel::SetTimeTarget); connect(param_panel_, &ParamPanel::RequestSelectNode, node_panel_, &NodePanel::Select); - connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, param_panel_, &ParamPanel::SetTime); - connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, curve_panel_, &CurvePanel::SetTime); - connect(param_panel_, &ParamPanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime); - connect(param_panel_, &ParamPanel::TimeChanged, curve_panel_, &CurvePanel::SetTime); - connect(curve_panel_, &CurvePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime); - connect(curve_panel_, &CurvePanel::TimeChanged, param_panel_, &ParamPanel::SetTime); - + connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp); + connect(param_panel_, &ParamPanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp); connect(PanelManager::instance(), &PanelManager::FocusedPanelChanged, this, &MainWindow::FocusedPanelChanged); sequence_viewer_panel_->ConnectTimeBasedPanel(param_panel_); - sequence_viewer_panel_->ConnectTimeBasedPanel(curve_panel_); footage_viewer_panel_->ConnectPixelSamplerPanel(pixel_sampler_panel_); sequence_viewer_panel_->ConnectPixelSamplerPanel(pixel_sampler_panel_); @@ -239,24 +229,35 @@ void MainWindow::FolderOpen(Project* p, Item *i, bool floating) // If the panel is closed, just destroy it panel->SetSignalInsteadOfClose(true); - connect(panel, &ProjectPanel::CloseRequested, this, &MainWindow::FolderCloseRequested); + panel->setProperty("parent_list", reinterpret_cast(&folder_panels_)); + connect(panel, &ProjectPanel::CloseRequested, this, &MainWindow::FloatingPanelCloseRequested); folder_panels_.append(panel); } ScopePanel *MainWindow::AppendScopePanel() { - ScopePanel* panel = PanelManager::instance()->CreatePanel(this); + return AppendFloatingPanelInternal(scope_panels_); +} - SetUniquePanelID(panel, scope_panels_); +CurvePanel *MainWindow::AppendCurvePanel() +{ + CurvePanel* p = AppendFloatingPanelInternal(curve_panels_); - panel->setFloating(true); - panel->show(); + sequence_viewer_panel_->ConnectTimeBasedPanel(p); - panel->SetSignalInsteadOfClose(true); - connect(panel, &ScopePanel::CloseRequested, this, &MainWindow::ScopeCloseRequested); + return p; - return panel; + /*connect(panel, &TimelinePanel::TimeChanged, curve_panel_, &CurvePanel::SetTime); + connect(curve_panel_, &CurvePanel::TimeChanged, panel, &TimelinePanel::SetTime); + connect(param_panel_, &ParamPanel::SelectedInputChanged, curve_panel_, &CurvePanel::SetInput); + connect(param_panel_, &ParamPanel::TimebaseChanged, curve_panel_, &CurvePanel::SetTimebase); + connect(param_panel_, &ParamPanel::TimeTargetChanged, curve_panel_, &CurvePanel::SetTimeTarget); + connect(param_panel_, &ParamPanel::TimeChanged, curve_panel_, &CurvePanel::SetTime); + connect(curve_panel_, &CurvePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime); + connect(curve_panel_, &CurvePanel::TimeChanged, param_panel_, &ParamPanel::SetTime); + sequence_viewer_panel_->ConnectTimeBasedPanel(curve_panel_); + connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, curve_panel_, &CurvePanel::SetTime);*/ } void MainWindow::SetFullscreen(bool fullscreen) @@ -413,19 +414,14 @@ void MainWindow::ProjectCloseRequested() Core::instance()->CloseProject(Core::instance()->GetSharedPtrFromProject(p), true); } -void MainWindow::FolderCloseRequested() +void MainWindow::FloatingPanelCloseRequested() { - ProjectPanel* panel = static_cast(sender()); + PanelWidget* panel = static_cast(sender()); - folder_panels_.removeOne(panel); - panel->deleteLater(); -} + quintptr list_ptr = panel->property("parent_list").value(); + QList* list = reinterpret_cast< QList* >(list_ptr); -void MainWindow::ScopeCloseRequested() -{ - ScopePanel* panel = static_cast(sender()); - - scope_panels_.removeOne(panel); + list->removeOne(panel); panel->deleteLater(); } @@ -481,13 +477,11 @@ TimelinePanel* MainWindow::AppendTimelinePanel() TimelinePanel* panel = AppendPanelInternal(timeline_panels_); connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::TimelineCloseRequested); - connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTime); - connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime); - connect(panel, &TimelinePanel::TimeChanged, curve_panel_, &CurvePanel::SetTime); + connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp); + connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp); connect(panel, &TimelinePanel::SelectionChanged, node_panel_, &NodePanel::SelectWithDependencies); - connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTime); - connect(curve_panel_, &CurvePanel::TimeChanged, panel, &TimelinePanel::SetTime); - connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, panel, &TimelinePanel::SetTime); + connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp); + connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp); connect(sequence_viewer_panel_->video_renderer(), &VideoRenderBackend::CachedTimeReady, panel->ruler(), &TimeRuler::CacheTimeReady); connect(sequence_viewer_panel_->video_renderer(), &VideoRenderBackend::RangeInvalidated, panel->ruler(), &TimeRuler::CacheInvalidatedRange); @@ -588,10 +582,6 @@ void MainWindow::SetDefaultLayout() timeline_panels_.first()->show(); addDockWidget(Qt::BottomDockWidgetArea, timeline_panels_.first()); - curve_panel_->hide(); - curve_panel_->setFloating(true); - addDockWidget(Qt::BottomDockWidgetArea, curve_panel_); - task_man_panel_->hide(); task_man_panel_->setFloating(true); addDockWidget(Qt::BottomDockWidgetArea, task_man_panel_); @@ -642,4 +632,22 @@ void MainWindow::SetUniquePanelID(T *panel, const QList &list) panel->setObjectName(panel->objectName().append(QString::number(list.size()))); } +template +T *MainWindow::AppendFloatingPanelInternal(QList &list) +{ + T* panel = PanelManager::instance()->CreatePanel(this); + + SetUniquePanelID(panel, list); + + panel->setFloating(true); + panel->show(); + + panel->SetSignalInsteadOfClose(true); + connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::FloatingPanelCloseRequested); + + panel->setProperty("parent_list", reinterpret_cast(&list)); + + return panel; +} + OLIVE_NAMESPACE_EXIT diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index 4f2d52c6e..cbf2ccc26 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -68,6 +68,8 @@ public: ScopePanel* AppendScopePanel(); + CurvePanel* AppendCurvePanel(); + #ifdef Q_OS_WINDOWS void SetTaskbarButtonState(TBPFLAG flags); @@ -100,6 +102,9 @@ private: template T* AppendPanelInternal(QList& list); + template + T* AppendFloatingPanelInternal(QList& list); + template void SetUniquePanelID(T* panel, const QList& list); @@ -122,7 +127,7 @@ private: QList timeline_panels_; AudioMonitorPanel* audio_monitor_panel_; TaskManagerPanel* task_man_panel_; - CurvePanel* curve_panel_; + QList curve_panels_; PixelSamplerPanel* pixel_sampler_panel_; QList scope_panels_; @@ -141,9 +146,7 @@ private slots: void ProjectCloseRequested(); - void FolderCloseRequested(); - - void ScopeCloseRequested(); + void FloatingPanelCloseRequested(); void LoadLayoutInternal(QXmlStreamReader* reader, XMLNodeData *xml_data);