From df5b66c3c779bd9b11532303750405f511e0bd0d Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 17 Apr 2020 01:07:13 +1000 Subject: [PATCH] nodeparamview: show connections in the param view --- app/panel/param/param.cpp | 1 + app/panel/param/param.h | 2 + app/widget/nodeparamview/CMakeLists.txt | 2 + app/widget/nodeparamview/nodeparamview.cpp | 1 + app/widget/nodeparamview/nodeparamview.h | 2 + .../nodeparamviewconnectedlabel.cpp | 70 +++++++++++++++++++ .../nodeparamviewconnectedlabel.h | 49 +++++++++++++ .../nodeparamview/nodeparamviewitem.cpp | 70 ++++++++++++++----- app/widget/nodeparamview/nodeparamviewitem.h | 19 +++-- app/window/mainwindow/mainwindow.cpp | 1 + 10 files changed, 196 insertions(+), 21 deletions(-) create mode 100644 app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp create mode 100644 app/widget/nodeparamview/nodeparamviewconnectedlabel.h diff --git a/app/panel/param/param.cpp b/app/panel/param/param.cpp index d89c91780..24ebc1ea6 100644 --- a/app/panel/param/param.cpp +++ b/app/panel/param/param.cpp @@ -31,6 +31,7 @@ ParamPanel::ParamPanel(QWidget* parent) : NodeParamView* view = new NodeParamView(); connect(view, &NodeParamView::SelectedInputChanged, this, &ParamPanel::SelectedInputChanged); connect(view, &NodeParamView::TimeTargetChanged, this, &ParamPanel::TimeTargetChanged); + connect(view, &NodeParamView::RequestSelectNode, this, &ParamPanel::RequestSelectNode); SetTimeBasedWidget(view); Retranslate(); diff --git a/app/panel/param/param.h b/app/panel/param/param.h index 4894d5b42..7d78aab64 100644 --- a/app/panel/param/param.h +++ b/app/panel/param/param.h @@ -40,6 +40,8 @@ signals: void TimeTargetChanged(Node* node); + void RequestSelectNode(const QList& target); + protected: virtual void Retranslate() override; diff --git a/app/widget/nodeparamview/CMakeLists.txt b/app/widget/nodeparamview/CMakeLists.txt index 087779a3d..393759ba4 100644 --- a/app/widget/nodeparamview/CMakeLists.txt +++ b/app/widget/nodeparamview/CMakeLists.txt @@ -18,6 +18,8 @@ set(OLIVE_SOURCES ${OLIVE_SOURCES} widget/nodeparamview/nodeparamview.h widget/nodeparamview/nodeparamview.cpp + widget/nodeparamview/nodeparamviewconnectedlabel.h + widget/nodeparamview/nodeparamviewconnectedlabel.cpp widget/nodeparamview/nodeparamviewitem.h widget/nodeparamview/nodeparamviewitem.cpp widget/nodeparamview/nodeparamviewkeyframecontrol.h diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index 897e03cfc..3660a2ba5 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -150,6 +150,7 @@ void NodeParamView::SetNodes(QList nodes) 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::RequestSelectNode, this, &NodeParamView::RequestSelectNode); items_.append(item); diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index d5eda57af..5188469fe 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -45,6 +45,8 @@ signals: void TimeTargetChanged(Node* target); + void RequestSelectNode(const QList& target); + protected: virtual void resizeEvent(QResizeEvent *event) override; diff --git a/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp b/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp new file mode 100644 index 000000000..9c48bc888 --- /dev/null +++ b/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp @@ -0,0 +1,70 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "nodeparamviewconnectedlabel.h" + +#include + +#include "common/qtutils.h" +#include "node/node.h" + +OLIVE_NAMESPACE_ENTER + +NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(NodeInput *input, QWidget *parent) : + QWidget(parent), + input_(input) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setSpacing(QFontMetricsWidth(fontMetrics(), QStringLiteral(" "))); + layout->setMargin(0); + + layout->addWidget(new QLabel(tr("Connected to"))); + + connected_to_lbl_ = new ClickableLabel(); + connected_to_lbl_->setCursor(Qt::PointingHandCursor); + connect(connected_to_lbl_, &ClickableLabel::MouseClicked, this, &NodeParamViewConnectedLabel::ConnectionClicked); + layout->addWidget(connected_to_lbl_); + + // Set up "link" font + QFont link_font = connected_to_lbl_->font(); + link_font.setUnderline(true); + connected_to_lbl_->setForegroundRole(QPalette::Link); + connected_to_lbl_->setFont(link_font); + + UpdateConnected(); + + connect(input_, &NodeInput::EdgeAdded, this, &NodeParamViewConnectedLabel::UpdateConnected); + connect(input_, &NodeInput::EdgeRemoved, this, &NodeParamViewConnectedLabel::UpdateConnected); +} + +void NodeParamViewConnectedLabel::UpdateConnected() +{ + QString connection_str; + + if (input_->IsConnected()) { + connection_str = input_->get_connected_node()->Name(); + } else { + connection_str = tr("Nothing"); + } + + connected_to_lbl_->setText(connection_str); +} + +OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodeparamview/nodeparamviewconnectedlabel.h b/app/widget/nodeparamview/nodeparamviewconnectedlabel.h new file mode 100644 index 000000000..161bf2a0d --- /dev/null +++ b/app/widget/nodeparamview/nodeparamviewconnectedlabel.h @@ -0,0 +1,49 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef NODEPARAMVIEWCONNECTEDLABEL_H +#define NODEPARAMVIEWCONNECTEDLABEL_H + +#include "node/input.h" +#include "widget/clickablelabel/clickablelabel.h" + +OLIVE_NAMESPACE_ENTER + +class NodeParamViewConnectedLabel : public QWidget { + Q_OBJECT +public: + NodeParamViewConnectedLabel(NodeInput* input, QWidget* parent = nullptr); + +signals: + void ConnectionClicked(); + +private slots: + void UpdateConnected(); + +private: + ClickableLabel* connected_to_lbl_; + + NodeInput* input_; + +}; + +OLIVE_NAMESPACE_EXIT + +#endif // NODEPARAMVIEWCONNECTEDLABEL_H diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index 52d5cb342..7c29567f8 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -102,14 +102,10 @@ void NodeParamViewItem::SetTime(const rational &time) void NodeParamViewItem::SignalAllKeyframes() { - foreach (NodeParam* param, node_->parameters()) { - if (param->type() == NodeParam::kInput) { - NodeInput* input = static_cast(param); - - foreach (const NodeInput::KeyframeTrack& track, input->keyframe_tracks()) { - foreach (NodeKeyframePtr key, track) { - InputAddedKeyframeInternal(input, key); - } + foreach (NodeInput* input, node_->GetInputsIncludingArrays()) { + foreach (const NodeInput::KeyframeTrack& track, input->keyframe_tracks()) { + foreach (NodeKeyframePtr key, track) { + InputAddedKeyframeInternal(input, key); } } } @@ -150,7 +146,7 @@ void NodeParamViewItem::SetupUI() // Add descriptor label ClickableLabel* param_label = new ClickableLabel(); connect(param_label, &ClickableLabel::MouseClicked, this, &NodeParamViewItem::LabelClicked); - param_lbls_.append(param_label); + param_lbls_.insert(input, param_label); label_map_.insert(input, param_label); @@ -158,7 +154,7 @@ void NodeParamViewItem::SetupUI() // Create a widget/input bridge for this input NodeParamViewWidgetBridge* bridge = new NodeParamViewWidgetBridge(input, this); - bridges_.append(bridge); + bridges_.insert(input, bridge); // Add widgets for this parameter to the layout const QList& widgets_for_param = bridge->widgets(); @@ -166,6 +162,19 @@ void NodeParamViewItem::SetupUI() content_layout_->addWidget(widgets_for_param.at(i), row_count, i + 1); } + if (input->IsConnectable()) { + // Create clickable label used when an input is connected + NodeParamViewConnectedLabel* connected_lbl = new NodeParamViewConnectedLabel(input); + connected_.insert(input, connected_lbl); + connect(connected_lbl, &NodeParamViewConnectedLabel::ConnectionClicked, this, &NodeParamViewItem::ConnectionClicked); + content_layout_->addWidget(connected_lbl, row_count, 1); + + UpdateUIForEdgeConnection(input); + + connect(input, &NodeInput::EdgeAdded, this, &NodeParamViewItem::EdgeChanged); + connect(input, &NodeInput::EdgeRemoved, this, &NodeParamViewItem::EdgeChanged); + } + // Add keyframe control to this layout if parameter is keyframable if (input->is_keyframable()) { // Hacky but effective way to make sure this widget is always as far right as possible @@ -182,6 +191,8 @@ void NodeParamViewItem::SetupUI() connect(input, &NodeInput::KeyframeRemoved, this, &NodeParamViewItem::KeyframeRemoved); } + + row_count++; } } @@ -195,18 +206,25 @@ void NodeParamViewItem::Retranslate() title_bar_lbl_->setText(node_->Name()); - int row_count = 0; - foreach (NodeParam* param, node_->parameters()) { - // This widget only needs to show input parameters - if (param->type() == NodeParam::kInput) { - param_lbls_.at(row_count)->setText(tr("%1:").arg(param->name())); + QMap::const_iterator i; - row_count++; - } + for (i=param_lbls_.begin(); i!=param_lbls_.end(); i++) { + i.value()->setText(tr("%1:").arg(i.key()->name())); } } +void NodeParamViewItem::UpdateUIForEdgeConnection(NodeInput *input) +{ + // Show/hide bridge widgets + foreach (QWidget* w, bridges_.value(input)->widgets()) { + w->setVisible(!input->IsConnected()); + } + + // Show/hide connection label + connected_.value(input)->setVisible(input->IsConnected()); +} + NodeParamViewKeyframeControl *NodeParamViewItem::KeyframeControlFromInput(NodeInput *input) const { foreach (NodeParamViewKeyframeControl* key_control, key_control_list_) { @@ -267,6 +285,24 @@ void NodeParamViewItem::LabelClicked() } } +void NodeParamViewItem::EdgeChanged() +{ + UpdateUIForEdgeConnection(static_cast(sender())); +} + +void NodeParamViewItem::ConnectionClicked() +{ + NodeParamViewConnectedLabel* src = static_cast(sender()); + + NodeInput* input = connected_.key(src); + + Node* connected = input->get_connected_node(); + + if (connected) { + emit RequestSelectNode({connected}); + } +} + NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) : QWidget(parent) { diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h index c2561e31e..98c243072 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.h +++ b/app/widget/nodeparamview/nodeparamviewitem.h @@ -28,6 +28,7 @@ #include #include "node/node.h" +#include "nodeparamviewconnectedlabel.h" #include "nodeparamviewkeyframecontrol.h" #include "nodeparamviewwidgetbridge.h" #include "widget/clickablelabel/clickablelabel.h" @@ -64,6 +65,8 @@ signals: void InputClicked(NodeInput* input); + void RequestSelectNode(const QList& node); + protected: virtual void changeEvent(QEvent *e) override; @@ -74,6 +77,8 @@ private: void Retranslate(); + void UpdateUIForEdgeConnection(NodeInput* input); + NodeParamViewKeyframeControl* KeyframeControlFromInput(NodeInput* input) const; bool expanded_; @@ -82,8 +87,6 @@ private: QLabel* title_bar_lbl_; - QVector param_lbls_; - QPushButton* title_bar_collapse_btn_; QWidget* contents_; @@ -92,10 +95,14 @@ private: Node* node_; - QList bridges_; - rational time_; + QMap param_lbls_; + + QMap bridges_; + + QMap connected_; + QMap label_map_; QList key_control_list_; @@ -109,6 +116,10 @@ private slots: void LabelClicked(); + void EdgeChanged(); + + void ConnectionClicked(); + }; OLIVE_NAMESPACE_EXIT diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index d2d8ba8b8..a119c29bd 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -82,6 +82,7 @@ MainWindow::MainWindow(QWidget *parent) : 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);