diff --git a/app/node/value.cpp b/app/node/value.cpp index e2f9913c5..ef5ac05bd 100644 --- a/app/node/value.cpp +++ b/app/node/value.cpp @@ -44,7 +44,12 @@ void NodeValueDatabase::Insert(const NodeInput *key, const NodeValueTable &value NodeValueTable NodeValueDatabase::Merge() const { - return NodeValueTable::Merge(tables_.values()); + QHash copy = tables_; + + // Kinda hacky, but we don't need this table to slipstream + copy.remove(QStringLiteral("global")); + + return NodeValueTable::Merge(copy.values()); } NodeValue::NodeValue() : @@ -176,7 +181,6 @@ NodeValueTable NodeValueTable::Merge(QList tables) NodeValueTable merged_table; // Slipstreams all tables together - // FIXME: I don't actually know if this is the right approach... foreach (const NodeValueTable& t, tables) { if (row >= t.Count()) { continue; diff --git a/app/node/value.h b/app/node/value.h index 7efb8592a..448c1c54d 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -108,14 +108,21 @@ public: using const_iterator = QHash::const_iterator; - inline QHash::const_iterator begin() const { + inline QHash::const_iterator begin() const + { return tables_.cbegin(); } - inline QHash::const_iterator end() const { + inline QHash::const_iterator end() const + { return tables_.cend(); } + inline bool contains(const QString& s) const + { + return tables_.contains(s); + } + private: QHash tables_; diff --git a/app/panel/table/table.h b/app/panel/table/table.h index 0587cf51b..d08fe0de3 100644 --- a/app/panel/table/table.h +++ b/app/panel/table/table.h @@ -28,6 +28,7 @@ OLIVE_NAMESPACE_ENTER class NodeTablePanel : public TimeBasedPanel { + Q_OBJECT public: NodeTablePanel(QWidget* parent); diff --git a/app/widget/nodetableview/nodetableview.cpp b/app/widget/nodetableview/nodetableview.cpp index f876b82d5..9d6590cbc 100644 --- a/app/widget/nodetableview/nodetableview.cpp +++ b/app/widget/nodetableview/nodetableview.cpp @@ -29,7 +29,8 @@ OLIVE_NAMESPACE_ENTER NodeTableView::NodeTableView(QWidget* parent) : - QTreeWidget(parent) + QTreeWidget(parent), + last_set_node_(nullptr) { setColumnCount(3); setHeaderLabels({tr("Type"), @@ -42,11 +43,23 @@ NodeTableView::NodeTableView(QWidget* parent) : void NodeTableView::SetNode(Node *n, const rational &time) { - clear(); + if (last_set_node_ != n) { + // Clear everything if the node has changed + clear(); + } + last_set_node_ = n; NodeTableTraverser traverser; NodeValueDatabase db = traverser.GenerateDatabase(n, TimeRange(time, time)); + // Remove top items if necessary + for (int i=0;itopLevelItemCount();i++) { + if (!db.contains(this->topLevelItem(i)->data(0, Qt::UserRole).toString())) { + delete this->takeTopLevelItem(i); + i--; + } + } + NodeValueDatabase::const_iterator i; for (i=db.begin(); i!=db.end(); i++) { @@ -58,17 +71,40 @@ void NodeTableView::SetNode(Node *n, const rational &time) continue; } - QTreeWidgetItem* top_item = new QTreeWidgetItem(); - top_item->setText(0, input->name()); - top_item->setFirstColumnSpanned(true); - this->addTopLevelItem(top_item); + QTreeWidgetItem* top_item = nullptr; - for (int j=table.Count()-1; j>=0; j--) { - const NodeValue& value = table.at(j); + for (int j=0;jtopLevelItemCount();j++) { + QTreeWidgetItem* compare = this->topLevelItem(j); + + if (compare->data(0, Qt::UserRole).toString() == input->id()) { + top_item = compare; + break; + } + } + + if (!top_item) { + top_item = new QTreeWidgetItem(); + top_item->setText(0, input->name()); + top_item->setData(0, Qt::UserRole, input->id()); + top_item->setFirstColumnSpanned(true); + this->addTopLevelItem(top_item); + } + + // Create children if necessary + while (top_item->childCount() < table.Count()) { + top_item->addChild(new QTreeWidgetItem()); + } + + // Remove children if necessary + while (top_item->childCount() > table.Count()) { + delete top_item->takeChild(top_item->childCount() - 1); + } + + for (int j=0;jaddChild(sub_item); + QTreeWidgetItem* sub_item = top_item->child(j); // Set data type name sub_item->setText(0, NodeParam::GetPrettyDataTypeName(value.type())); diff --git a/app/widget/nodetableview/nodetableview.h b/app/widget/nodetableview/nodetableview.h index e453903b7..1ce906c09 100644 --- a/app/widget/nodetableview/nodetableview.h +++ b/app/widget/nodetableview/nodetableview.h @@ -36,6 +36,9 @@ public: void SetMultipleNodeMessage(); +private: + Node* last_set_node_; + }; OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodetableview/nodetablewidget.cpp b/app/widget/nodetableview/nodetablewidget.cpp index 20db058c2..0c50794ab 100644 --- a/app/widget/nodetableview/nodetablewidget.cpp +++ b/app/widget/nodetableview/nodetablewidget.cpp @@ -25,7 +25,8 @@ OLIVE_NAMESPACE_ENTER NodeTableWidget::NodeTableWidget(QWidget* parent) : - TimeBasedWidget(parent) + TimeBasedWidget(parent), + node_(nullptr) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setSpacing(0); @@ -37,13 +38,35 @@ NodeTableWidget::NodeTableWidget(QWidget* parent) : void NodeTableWidget::SetNodes(const QList &nodes) { + node_ = nullptr; + if (nodes.isEmpty()) { view_->clear(); } else if (nodes.size() == 1) { - view_->SetNode(nodes.first(), rational()); + node_ = nodes.first(); + + ViewerOutput* viewer = node_->FindOutputNode(); + if (viewer) { + qDebug() << "Found timebase"; + SetTimebase(viewer->video_params().time_base()); + } + + UpdateView(); } else { view_->SetMultipleNodeMessage(); } } +void NodeTableWidget::TimeChangedEvent(const int64_t &) +{ + UpdateView(); +} + +void NodeTableWidget::UpdateView() +{ + if (node_) { + view_->SetNode(node_, GetTime()); + } +} + OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodetableview/nodetablewidget.h b/app/widget/nodetableview/nodetablewidget.h index ae0c82cc4..bc05d768d 100644 --- a/app/widget/nodetableview/nodetablewidget.h +++ b/app/widget/nodetableview/nodetablewidget.h @@ -33,9 +33,16 @@ public: void SetNodes(const QList& nodes); +protected: + virtual void TimeChangedEvent(const int64_t& ts) override; + private: + void UpdateView(); + NodeTableView* view_; + Node* node_; + }; OLIVE_NAMESPACE_EXIT diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index a917143f6..09286c316 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -86,7 +86,9 @@ MainWindow::MainWindow(QWidget *parent) : connect(node_panel_, &NodePanel::SelectionChanged, table_panel_, &NodeTablePanel::SetNodes); connect(param_panel_, &ParamPanel::RequestSelectNode, node_panel_, &NodePanel::Select); connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp); + connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp); connect(param_panel_, &ParamPanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp); + connect(param_panel_, &ParamPanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp); connect(param_panel_, &ParamPanel::FoundGizmos, sequence_viewer_panel_, &SequenceViewerPanel::SetGizmos); connect(PanelManager::instance(), &PanelManager::FocusedPanelChanged, this, &MainWindow::FocusedPanelChanged); @@ -518,6 +520,7 @@ TimelinePanel* MainWindow::AppendTimelinePanel() connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::TimelineCloseRequested); connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp); + connect(panel, &TimelinePanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp); connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp); connect(panel, &TimelinePanel::SelectionChanged, node_panel_, &NodePanel::SelectBlocks); connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);