diff --git a/app/panel/CMakeLists.txt b/app/panel/CMakeLists.txt
index f93581c56..0b3f572b0 100644
--- a/app/panel/CMakeLists.txt
+++ b/app/panel/CMakeLists.txt
@@ -15,6 +15,7 @@
# along with this program. If not, see .
add_subdirectory(node)
+add_subdirectory(param)
add_subdirectory(project)
add_subdirectory(taskmanager)
add_subdirectory(timeline)
diff --git a/app/panel/node/node.cpp b/app/panel/node/node.cpp
index 54ba33beb..9caad412b 100644
--- a/app/panel/node/node.cpp
+++ b/app/panel/node/node.cpp
@@ -26,6 +26,9 @@ NodePanel::NodePanel(QWidget *parent) :
// Create NodeView widget
node_view_ = new NodeView(this);
+ // Connect node view signals to this panel
+ connect(node_view_, SIGNAL(SelectionChanged(QList)), this, SIGNAL(SelectionChanged(QList)));
+
// Set it as the main widget of this panel
setWidget(node_view_);
diff --git a/app/panel/node/node.h b/app/panel/node/node.h
index 28a59fd70..5e6c4b646 100644
--- a/app/panel/node/node.h
+++ b/app/panel/node/node.h
@@ -38,6 +38,12 @@ public:
protected:
virtual void changeEvent(QEvent* e) override;
+signals:
+ /**
+ * @brief Wrapper for NodeView::SelectionChanged()
+ */
+ void SelectionChanged(QList selected_nodes);
+
private:
void Retranslate();
diff --git a/app/panel/param/CMakeLists.txt b/app/panel/param/CMakeLists.txt
new file mode 100644
index 000000000..04e3682a5
--- /dev/null
+++ b/app/panel/param/CMakeLists.txt
@@ -0,0 +1,22 @@
+# 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 .
+
+set(OLIVE_SOURCES
+ ${OLIVE_SOURCES}
+ panel/param/param.h
+ panel/param/param.cpp
+ PARENT_SCOPE
+)
diff --git a/app/panel/param/param.cpp b/app/panel/param/param.cpp
new file mode 100644
index 000000000..5cf53fe85
--- /dev/null
+++ b/app/panel/param/param.cpp
@@ -0,0 +1,50 @@
+/***
+
+ 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 "param.h"
+
+ParamPanel::ParamPanel(QWidget* parent) :
+ PanelWidget(parent)
+{
+ view_ = new NodeParamView(this);
+
+ setWidget(view_);
+
+ Retranslate();
+}
+
+void ParamPanel::SetNodes(QList nodes)
+{
+ view_->SetNodes(nodes);
+}
+
+void ParamPanel::changeEvent(QEvent *e)
+{
+ if (e->type() == QEvent::LanguageChange) {
+ Retranslate();
+ }
+ QDockWidget::changeEvent(e);
+}
+
+void ParamPanel::Retranslate()
+{
+ SetTitle(tr("Parameter Editor"));
+ SetSubtitle(tr("(none)"));
+}
diff --git a/app/panel/param/param.h b/app/panel/param/param.h
new file mode 100644
index 000000000..6d1155840
--- /dev/null
+++ b/app/panel/param/param.h
@@ -0,0 +1,45 @@
+/***
+
+ 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 PARAM_H
+#define PARAM_H
+
+#include "widget/nodeparamview/nodeparamview.h"
+#include "widget/panel/panel.h"
+
+class ParamPanel : public PanelWidget
+{
+ Q_OBJECT
+public:
+ ParamPanel(QWidget* parent);
+
+public slots:
+ void SetNodes(QList nodes);
+
+protected:
+ virtual void changeEvent(QEvent* e);
+
+private:
+ void Retranslate();
+
+ NodeParamView* view_;
+};
+
+#endif // PARAM_H
diff --git a/app/widget/CMakeLists.txt b/app/widget/CMakeLists.txt
index 9092485ec..872fe3343 100644
--- a/app/widget/CMakeLists.txt
+++ b/app/widget/CMakeLists.txt
@@ -17,6 +17,7 @@
add_subdirectory(flowlayout)
add_subdirectory(menu)
add_subdirectory(nodeview)
+add_subdirectory(nodeparamview)
add_subdirectory(panel)
add_subdirectory(playbackcontrols)
add_subdirectory(projectexplorer)
diff --git a/app/widget/nodeparamview/CMakeLists.txt b/app/widget/nodeparamview/CMakeLists.txt
new file mode 100644
index 000000000..fa8e4a357
--- /dev/null
+++ b/app/widget/nodeparamview/CMakeLists.txt
@@ -0,0 +1,24 @@
+# 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 .
+
+set(OLIVE_SOURCES
+ ${OLIVE_SOURCES}
+ widget/nodeparamview/nodeparamview.h
+ widget/nodeparamview/nodeparamview.cpp
+ widget/nodeparamview/nodeparamviewitem.h
+ widget/nodeparamview/nodeparamviewitem.cpp
+ PARENT_SCOPE
+)
diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp
new file mode 100644
index 000000000..853690cad
--- /dev/null
+++ b/app/widget/nodeparamview/nodeparamview.cpp
@@ -0,0 +1,73 @@
+/***
+
+ 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 "nodeparamview.h"
+
+NodeParamView::NodeParamView(QWidget *parent) :
+ QWidget(parent)
+{
+ // Set new layout
+ layout_ = new QVBoxLayout(this);
+ layout_->setSpacing(0);
+ layout_->setMargin(0);
+
+ // Add a stretch to allow empty space at the bottom of the layout
+ layout_->addStretch();
+}
+
+void NodeParamView::SetNodes(QList nodes)
+{
+ // If we already have item widgets, delete them all now
+ foreach (NodeParamViewItem* item, items_) {
+ delete item;
+ }
+ items_.clear();
+
+ // Set the internal list to the one we've received
+ nodes_ = nodes;
+
+ // For each node, create a widget
+ foreach (Node* node, nodes_) {
+
+ // See if we already have an item for this node type
+
+ bool merged_node = false;
+
+ foreach (NodeParamViewItem* existing_item, items_) {
+ if (existing_item->CanAddNode(node)) {
+ existing_item->AttachNode(node);
+ merged_node = true;
+ break;
+ }
+ }
+
+ // If we couldn't merge this node into the existing item, create a new one
+ if (!merged_node) {
+ NodeParamViewItem* item = new NodeParamViewItem(this);
+
+ item->AttachNode(node);
+
+ // Insert the widget before the stretch
+ layout_->insertWidget(layout_->count() - 1, item);
+
+ items_.append(item);
+ }
+ }
+}
diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h
new file mode 100644
index 000000000..685599148
--- /dev/null
+++ b/app/widget/nodeparamview/nodeparamview.h
@@ -0,0 +1,45 @@
+/***
+
+ 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 NODEPARAMVIEW_H
+#define NODEPARAMVIEW_H
+
+#include
+#include
+
+#include "node/node.h"
+#include "nodeparamviewitem.h"
+
+class NodeParamView : public QWidget
+{
+public:
+ NodeParamView(QWidget* parent);
+
+ void SetNodes(QList nodes);
+
+private:
+ QVBoxLayout* layout_;
+
+ QList nodes_;
+
+ QList items_;
+};
+
+#endif // NODEPARAMVIEW_H
diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp
new file mode 100644
index 000000000..04f2a0e2c
--- /dev/null
+++ b/app/widget/nodeparamview/nodeparamviewitem.cpp
@@ -0,0 +1,142 @@
+/***
+
+ 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 "nodeparamviewitem.h"
+
+#include
+#include
+
+#include "ui/icons/icons.h"
+
+NodeParamViewItem::NodeParamViewItem(QWidget *parent) :
+ QWidget(parent)
+{
+ QVBoxLayout* main_layout = new QVBoxLayout(this);
+ main_layout->setSpacing(0);
+ main_layout->setMargin(0);
+
+ // Create title bar widget
+ title_bar_ = new NodeParamViewItemTitleBar(this);
+ title_bar_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+
+ QHBoxLayout* title_bar_layout = new QHBoxLayout(title_bar_);
+
+ title_bar_collapse_btn_ = new QPushButton();
+ title_bar_collapse_btn_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+ title_bar_collapse_btn_->setStyleSheet("border: none; background: none;");
+ title_bar_collapse_btn_->setCheckable(true);
+ title_bar_collapse_btn_->setChecked(true);
+ connect(title_bar_collapse_btn_, SIGNAL(clicked(bool)), this, SLOT(SetExpanded(bool)));
+ title_bar_layout->addWidget(title_bar_collapse_btn_);
+
+ title_bar_lbl_ = new QLabel(title_bar_);
+ title_bar_layout->addWidget(title_bar_lbl_);
+
+ // Add title bar to widget
+ main_layout->addWidget(title_bar_);
+
+ // Create and add contents widget
+ contents_ = new QWidget(this);
+ content_layout_ = new QGridLayout(contents_);
+ main_layout->addWidget(contents_);
+
+ // Set correct widget state
+ SetExpanded(title_bar_collapse_btn_->isChecked());
+}
+
+void NodeParamViewItem::AttachNode(Node *n)
+{
+ // Make sure we can attach this node (CanAddNode() should be run by the caller to make sure this node is valid)
+ Q_ASSERT(CanAddNode(n));
+
+ // Add node to the list
+ nodes_.append(n);
+
+ // If the added node was the first node, set up the UI
+ if (nodes_.size() == 1) {
+ SetupUI();
+ }
+}
+
+bool NodeParamViewItem::CanAddNode(Node* n)
+{
+ // Ensures that all Nodes have the same ID
+ return (nodes_.isEmpty() || nodes_.first()->id() == n->id());
+}
+
+void NodeParamViewItem::changeEvent(QEvent *e)
+{
+ // FIXME: Retranslate all UI elements
+
+ QWidget::changeEvent(e);
+}
+
+void NodeParamViewItem::SetupUI()
+{
+ Q_ASSERT(!nodes_.isEmpty());
+
+ Node* first_node = nodes_.first();
+
+ title_bar_lbl_->setText(first_node->Name());
+
+ int row_count = 0;
+
+ for (int i=0;iParameterCount();i++) {
+ NodeParam* param = first_node->ParamAt(i);
+
+ // This widget only needs to show input parameters
+ if (param->type() == NodeParam::kInput) {
+ QLabel* param_label = new QLabel(tr("%1:").arg(param->name()));
+
+ content_layout_->addWidget(param_label, row_count, 0);
+
+ row_count++;
+ }
+ }
+}
+
+void NodeParamViewItem::SetExpanded(bool e)
+{
+ expanded_ = e;
+
+ contents_->setVisible(e);
+
+ if (expanded_) {
+ title_bar_collapse_btn_->setIcon(olive::icon::TriDown);
+ } else {
+ title_bar_collapse_btn_->setIcon(olive::icon::TriRight);
+ }
+}
+
+NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) :
+ QWidget(parent)
+{
+}
+
+void NodeParamViewItemTitleBar::paintEvent(QPaintEvent *event)
+{
+ QWidget::paintEvent(event);
+
+ QPainter p(this);
+
+ // Draw bottom border using text color
+ p.setPen(palette().text().color());
+ p.drawLine(0, height() - 1, width(), height() - 1);
+}
diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h
new file mode 100644
index 000000000..dbddf7ddf
--- /dev/null
+++ b/app/widget/nodeparamview/nodeparamviewitem.h
@@ -0,0 +1,74 @@
+/***
+
+ 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 NODEPARAMVIEWITEM_H
+#define NODEPARAMVIEWITEM_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include "node/node.h"
+
+class NodeParamViewItemTitleBar : public QWidget {
+public:
+ NodeParamViewItemTitleBar(QWidget* parent = nullptr);
+
+protected:
+ virtual void paintEvent(QPaintEvent *event) override;
+};
+
+class NodeParamViewItem : public QWidget
+{
+ Q_OBJECT
+public:
+ NodeParamViewItem(QWidget* parent);
+
+ void AttachNode(Node* n);
+
+ bool CanAddNode(Node *n);
+
+protected:
+ void changeEvent(QEvent *e) override;
+
+private:
+ void SetupUI();
+
+ bool expanded_;
+
+ NodeParamViewItemTitleBar* title_bar_;
+
+ QLabel* title_bar_lbl_;
+
+ QPushButton* title_bar_collapse_btn_;
+
+ QWidget* contents_;
+
+ QGridLayout* content_layout_;
+
+ QList nodes_;
+
+private slots:
+ void SetExpanded(bool e);
+};
+
+#endif // NODEPARAMVIEWITEM_H
diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp
index e67e8f6a6..2828ac8e1 100644
--- a/app/widget/nodeview/nodeview.cpp
+++ b/app/widget/nodeview/nodeview.cpp
@@ -29,6 +29,7 @@ NodeView::NodeView(QWidget *parent) :
setDragMode(RubberBandDrag);
connect(&scene_, SIGNAL(changed(const QList&)), this, SLOT(ItemsChanged()));
+ connect(&scene_, SIGNAL(selectionChanged()), this, SLOT(SceneSelectionChangedSlot()));
}
void NodeView::SetGraph(NodeGraph *graph)
@@ -149,3 +150,22 @@ void NodeView::ItemsChanged()
}
}
}
+
+void NodeView::SceneSelectionChangedSlot()
+{
+ // Get the scene's selected items and convert it into a list of selected nodes
+ QList selected_items = scene_.selectedItems();
+
+ QList selected_nodes;
+
+ for (int i=0;i(selected_items.at(i));
+
+ if (item != nullptr) {
+ selected_nodes.append(item->node());
+ }
+ }
+
+ emit SelectionChanged(selected_nodes);
+}
diff --git a/app/widget/nodeview/nodeview.h b/app/widget/nodeview/nodeview.h
index f5a6b28b8..8cb50fd71 100644
--- a/app/widget/nodeview/nodeview.h
+++ b/app/widget/nodeview/nodeview.h
@@ -74,6 +74,12 @@ public:
*/
NodeViewEdge* EdgeToUIObject(NodeEdgePtr n);
+signals:
+ /**
+ * @brief Signal emitted when the selected nodes have changed
+ */
+ void SelectionChanged(QList selected_nodes);
+
private:
NodeGraph* graph_;
@@ -103,6 +109,11 @@ private slots:
*/
void ItemsChanged();
+ /**
+ * @brief Receiver for when the scene's selected items change
+ */
+ void SceneSelectionChangedSlot();
+
};
#endif // NODEVIEW_H
diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp
index c8f80e78c..32ccbbf0a 100644
--- a/app/window/mainwindow/mainwindow.cpp
+++ b/app/window/mainwindow/mainwindow.cpp
@@ -23,8 +23,9 @@
#include
// Panel objects
-#include "panel/project/project.h"
#include "panel/node/node.h"
+#include "panel/param/param.h"
+#include "panel/project/project.h"
#include "panel/timeline/timeline.h"
#include "panel/tool/tool.h"
#include "panel/viewer/viewer.h"
@@ -74,12 +75,17 @@ void olive::MainWindow::ProjectOpen(Project* p)
ToolPanel* tool_panel = new ToolPanel(this);
addDockWidget(Qt::BottomDockWidgetArea, tool_panel);
- NodePanel* task_panel = new NodePanel(this);
- addDockWidget(Qt::BottomDockWidgetArea, task_panel);
+ NodePanel* node_panel = new NodePanel(this);
+ addDockWidget(Qt::BottomDockWidgetArea, node_panel);
+
+ ParamPanel* param_panel = new ParamPanel(this);
+ addDockWidget(Qt::BottomDockWidgetArea, param_panel);
TimelinePanel* timeline_panel = new TimelinePanel(this);
addDockWidget(Qt::BottomDockWidgetArea, timeline_panel);
+ connect(node_panel, SIGNAL(SelectionChanged(QList)), param_panel, SLOT(SetNodes(QList)));
+
// FIXME: Test code
NodeGraph* graph = new NodeGraph();
graph->setParent(this);
@@ -92,6 +98,6 @@ void olive::MainWindow::ProjectOpen(Project* p)
graph->AddNode(sg);
ImageInput* ii = new ImageInput();
graph->AddNode(ii);
- task_panel->SetGraph(graph);
+ node_panel->SetGraph(graph);
// End test code
}