diff --git a/app/panel/param/param.cpp b/app/panel/param/param.cpp index 5fa076690..2b9df7f4c 100644 --- a/app/panel/param/param.cpp +++ b/app/panel/param/param.cpp @@ -30,6 +30,7 @@ ParamPanel::ParamPanel(QWidget* parent) : NodeParamView* view = new NodeParamView(); connect(view, &NodeParamView::RequestSelectNode, this, &ParamPanel::RequestSelectNode); connect(view, &NodeParamView::NodeOrderChanged, this, &ParamPanel::NodeOrderChanged); + connect(view, &NodeParamView::FocusedNodeChanged, this, &ParamPanel::FocusedNodeChanged); SetTimeBasedWidget(view); Retranslate(); diff --git a/app/panel/param/param.h b/app/panel/param/param.h index f74bce63a..3c4f15354 100644 --- a/app/panel/param/param.h +++ b/app/panel/param/param.h @@ -44,6 +44,8 @@ signals: void NodeOrderChanged(const QList& nodes); + void FocusedNodeChanged(Node* n); + protected: virtual void Retranslate() override; diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index 159c8d64d..b07031ea6 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -20,6 +20,7 @@ #include "nodeparamview.h" +#include #include #include #include @@ -31,7 +32,8 @@ OLIVE_NAMESPACE_ENTER NodeParamView::NodeParamView(QWidget *parent) : TimeBasedWidget(true, false, parent), - last_scroll_val_(0) + last_scroll_val_(0), + focused_node_(nullptr) { // Create horizontal layout to place scroll area in (and keyframe editing eventually) QHBoxLayout* layout = new QHBoxLayout(this); @@ -125,6 +127,12 @@ NodeParamView::NodeParamView(QWidget *parent) : SetScale(120); SetMaximumScale(TimelineViewBase::kMaximumScale); + + // Pickup on widget focus changes + connect(qApp, + &QApplication::focusChanged, + this, + &NodeParamView::FocusChanged); } void NodeParamView::SelectNodes(const QList &nodes) @@ -157,6 +165,13 @@ void NodeParamView::SelectNodes(const QList &nodes) param_widget_area_->addDockWidget(Qt::LeftDockWidgetArea, item); changes_made = true; + + if (!focused_node_ && n->HasGizmos()) { + // We'll focus this node now + item->SetHighlighted(true); + focused_node_ = n; + emit FocusedNodeChanged(focused_node_); + } } } @@ -299,6 +314,11 @@ void NodeParamView::RemoveNode(Node *n) keyframe_view_->RemoveKeyframesOfNode(n); delete items_.take(n); + + if (focused_node_ == n) { + focused_node_ = nullptr; + emit FocusedNodeChanged(nullptr); + } } void NodeParamView::ItemRequestedTimeChanged(const rational &time) @@ -337,4 +357,36 @@ void NodeParamView::PinNode(bool pin) } } +void NodeParamView::FocusChanged(QWidget* old, QWidget* now) +{ + Q_UNUSED(old) + + QObject* parent = now; + NodeParamViewItem* item; + + while (parent) { + item = dynamic_cast(parent); + + if (item) { + // Found it! + if (item->GetNode() != focused_node_) { + if (focused_node_) { + // De-focus current node + items_.value(focused_node_)->SetHighlighted(false); + } + + focused_node_ = item->GetNode(); + + item->SetHighlighted(true); + + emit FocusedNodeChanged(focused_node_); + } + + break; + } + + parent = parent->parent(); + } +} + OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index a807b2171..f9fee45db 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -79,6 +79,8 @@ signals: void NodeOrderChanged(const QList& nodes); + void FocusedNodeChanged(Node* n); + protected: virtual void resizeEvent(QResizeEvent *event) override; @@ -117,6 +119,8 @@ private: QMap node_expanded_state_; + Node* focused_node_; + private slots: void ItemRequestedTimeChanged(const rational& time); @@ -126,6 +130,8 @@ private slots: void PinNode(bool pin); + void FocusChanged(QWidget *old, QWidget *now); + }; OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index 6fcb95b91..0f5a88e67 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -33,7 +33,8 @@ OLIVE_NAMESPACE_ENTER NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) : QDockWidget(parent), - node_(node) + node_(node), + highlighted_(false) { // Create title bar widget title_bar_ = new NodeParamViewItemTitleBar(this); @@ -75,6 +76,8 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) : setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + setFocusPolicy(Qt::ClickFocus); + Retranslate(); } @@ -109,6 +112,19 @@ void NodeParamViewItem::changeEvent(QEvent *e) QWidget::changeEvent(e); } +void NodeParamViewItem::paintEvent(QPaintEvent *event) +{ + QDockWidget::paintEvent(event); + + // Draw border if focused + if (highlighted_) { + QPainter p(this); + p.setBrush(Qt::NoBrush); + p.setPen(palette().highlight().color()); + p.drawRect(rect().adjusted(0, 0, -1, -1)); + } +} + void NodeParamViewItem::Retranslate() { node_->Retranslate(); diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h index e97a150fd..2bc8972fa 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.h +++ b/app/widget/nodeparamview/nodeparamviewitem.h @@ -138,9 +138,20 @@ public: bool IsExpanded() const; + void SetHighlighted(bool e) + { + highlighted_ = e; + + update(); + } + public slots: void SignalAllKeyframes(); + void SetExpanded(bool e); + + void ToggleExpanded(); + signals: void KeyframeAdded(NodeKeyframePtr key, int y); @@ -154,14 +165,11 @@ signals: void PinToggled(bool e); -public slots: - void SetExpanded(bool e); - - void ToggleExpanded(); - protected: virtual void changeEvent(QEvent *e) override; + virtual void paintEvent(QPaintEvent *event) override; + private: NodeParamViewItemTitleBar* title_bar_; @@ -171,6 +179,8 @@ private: rational time_; + bool highlighted_; + private slots: void Retranslate(); diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 983dcdba4..64f871781 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -82,12 +82,13 @@ MainWindow::MainWindow(QWidget *parent) : AppendTimelinePanel(); audio_monitor_panel_ = PanelManager::instance()->CreatePanel(this); - // Make connections to sequence viewer + // Make node-related connections connect(node_panel_, &NodePanel::NodesSelected, param_panel_, &ParamPanel::SelectNodes); connect(node_panel_, &NodePanel::NodesDeselected, param_panel_, &ParamPanel::DeselectNodes); connect(node_panel_, &NodePanel::NodesSelected, table_panel_, &NodeTablePanel::SelectNodes); connect(node_panel_, &NodePanel::NodesDeselected, table_panel_, &NodeTablePanel::DeselectNodes); connect(param_panel_, &ParamPanel::RequestSelectNode, node_panel_, &NodePanel::Select); + connect(param_panel_, &ParamPanel::FocusedNodeChanged, sequence_viewer_panel_, &ViewerPanel::SetGizmos); // Connect time signals together connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp);