diff --git a/panels/nodeeditor.cpp b/panels/nodeeditor.cpp index 387559a94..2d632ff5d 100644 --- a/panels/nodeeditor.cpp +++ b/panels/nodeeditor.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "global/global.h" @@ -11,23 +12,39 @@ NodeEditor::NodeEditor(QWidget *parent) : EffectsPanel(parent), view_(&scene_) -{ +{ setWindowTitle(tr("Node Editor")); resize(720, 480); QWidget* central_widget = new QWidget(); setWidget(central_widget); + QSplitter* splitter = new QSplitter(); + splitter->setOrientation(Qt::Horizontal); + splitter->setChildrenCollapsible(false); + + splitter->addWidget(&view_); + + QSizePolicy view_policy; + view_policy.setHorizontalStretch(1); + view_.setSizePolicy(view_policy); + view_.setInteractive(true); + view_.setDragMode(QGraphicsView::RubberBandDrag); + + prop_layout_ = new QVBoxLayout(&props_); + prop_layout_->setMargin(0); + prop_layout_->setSpacing(0); + prop_layout_->addStretch(); + splitter->addWidget(&props_); + QVBoxLayout* layout = new QVBoxLayout(central_widget); layout->setSpacing(0); layout->setMargin(0); - layout->addWidget(&view_); - - view_.setInteractive(true); - view_.setDragMode(QGraphicsView::RubberBandDrag); + layout->addWidget(splitter); connect(&scene_, SIGNAL(changed(const QList&)), this, SLOT(ItemsChanged())); + connect(&scene_, SIGNAL(selectionChanged()), this, SLOT(UpdateNodeProperties())); connect(&view_, SIGNAL(RequestContextMenu()), this, SLOT(ContextMenu())); } @@ -49,18 +66,21 @@ void NodeEditor::LoadEvent() for (int i=0;iGetEffect(); - if (effect_ui->GetEffect()->parent_clip == first_clip) { + if (node->parent_clip == first_clip) { NodeUI* node_ui = new NodeUI(); - effect_ui->SetNodeParent(node_ui); effect_ui->SetSelectable(false); - node_ui->SetWidget(effect_ui); + node_ui->SetNode(node); node_ui->AddToScene(&scene_); node_ui->setPos(effect_ui->GetEffect()->pos()); nodes_.append(node_ui); + + effect_ui->setVisible(false); + prop_layout_->insertWidget(prop_layout_->count()-1, effect_ui); } } } @@ -153,7 +173,7 @@ void NodeEditor::ItemsChanged() } foreach (NodeUI* node, nodes_) { - node->Widget()->GetEffect()->SetPos(node->pos()); + node->GetNode()->SetPos(node->pos()); } } @@ -170,3 +190,25 @@ void NodeEditor::ContextMenu() olive::Global->ShowEffectMenu(EFFECT_TYPE_EFFECT, c->type(), {c}); } } + +void NodeEditor::UpdateNodeProperties() +{ + // Find matching widget + for (int j=0;jsetVisible(false); + } + + QList sel = scene_.selectedItems(); + for (int i=0;i(sel.at(i)); + + if (node_ui != nullptr) { + for (int j=0;jGetEffect() == node_ui->GetNode()) { + open_effects_.at(j)->setVisible(true); + break; + } + } + } + } +} diff --git a/panels/nodeeditor.h b/panels/nodeeditor.h index b6cb01316..f38ff4ee9 100644 --- a/panels/nodeeditor.h +++ b/panels/nodeeditor.h @@ -23,9 +23,12 @@ protected: private: QGraphicsScene scene_; NodeView view_; + QWidget props_; QVector nodes_; QVector edges_; QVector connected_rows_; + QVBoxLayout* prop_layout_; + QVector nodes_open_in_props_; void ClearEdges(); void LoadEdges(); @@ -37,7 +40,7 @@ private slots: void ItemsChanged(); void ReloadEdges(); void ContextMenu(); - + void UpdateNodeProperties(); }; #endif // NODEEDITOR_H diff --git a/rendering/audio.cpp b/rendering/audio.cpp index 105524ab9..f16604edd 100644 --- a/rendering/audio.cpp +++ b/rendering/audio.cpp @@ -153,7 +153,8 @@ void clear_audio_ibuffer() { } int current_audio_freq() { - return olive::Global->is_exporting() ? audio_rendering_rate : audio_output->format().sampleRate(); + return olive::Global->is_exporting() + ? audio_rendering_rate : audio_output->format().sampleRate(); } qint64 get_buffer_offset_from_frame(double framerate, long frame) { diff --git a/ui/effectui.cpp b/ui/effectui.cpp index 62a1cdb35..cccf6b286 100644 --- a/ui/effectui.cpp +++ b/ui/effectui.cpp @@ -30,8 +30,7 @@ #include "panels/panels.h" EffectUI::EffectUI(Node* e) : - effect_(e), - node_parent_(nullptr) + effect_(e) { Q_ASSERT(e != nullptr); @@ -282,31 +281,6 @@ bool EffectUI::IsAttachedToClip(Clip *c) return false; } -void EffectUI::SetNodeParent(NodeUI *parent) -{ - node_parent_ = parent; -} - -void EffectUI::resizeEvent(QResizeEvent *event) -{ - if (node_parent_ != nullptr) { - node_parent_->Resize(event->size()); - } -} - -bool EffectUI::event(QEvent *event) -{ - if (node_parent_ != nullptr - && (event->type() == QEvent::MouseButtonPress - || event->type() == QEvent::MouseButtonRelease - || event->type() == QEvent::MouseMove - || event->type() == QEvent::MouseButtonDblClick) - && node_parent_->scene()->sendEvent(node_parent_, event)) { - return true; - } - return CollapsibleWidget::event(event); -} - QWidget *EffectUI::Widget(int row, int field) { return widgets_.at(row).at(field); diff --git a/ui/effectui.h b/ui/effectui.h index 9eb12201c..fe80c45e4 100644 --- a/ui/effectui.h +++ b/ui/effectui.h @@ -133,11 +133,7 @@ public: */ bool IsAttachedToClip(Clip* c); - void SetNodeParent(NodeUI* parent); - protected: - virtual void resizeEvent(QResizeEvent* event) override; - virtual bool event(QEvent* event) override; signals: /** @@ -203,11 +199,6 @@ private: */ QVector keyframe_navigators_; - /** - * @brief Internal reference to node parent - */ - NodeUI* node_parent_; - /** * @brief Attach a KeyframeNavigator object to an EffectRow. * diff --git a/ui/nodeedgeui.cpp b/ui/nodeedgeui.cpp index 61c0bde8c..a275af92f 100644 --- a/ui/nodeedgeui.cpp +++ b/ui/nodeedgeui.cpp @@ -26,7 +26,7 @@ void NodeEdgeUI::adjust() if (node != nullptr) { // Check if this node has the output row - int row_index = node->Widget()->GetEffect()->IndexOfRow(edge_->output()); + int row_index = node->GetNode()->IndexOfRow(edge_->output()); if (row_index > -1) { output_node_ = node; @@ -34,7 +34,7 @@ void NodeEdgeUI::adjust() } // Check if this node has the input row - row_index = node->Widget()->GetEffect()->IndexOfRow(edge_->input()); + row_index = node->GetNode()->IndexOfRow(edge_->input()); if (row_index > -1) { input_node_ = node; diff --git a/ui/nodeui.cpp b/ui/nodeui.cpp index e58906bad..14808ce3e 100644 --- a/ui/nodeui.cpp +++ b/ui/nodeui.cpp @@ -15,11 +15,11 @@ #include "ui/nodeedgeui.h" const int kRoundedRectRadius = 5; +const int kTextPadding = 4; const int kNodePlugSize = 12; NodeUI::NodeUI() : - central_widget_(nullptr), - proxy_(nullptr), + node_(nullptr), drag_destination_(nullptr), clicked_socket_(-1) { @@ -27,34 +27,23 @@ NodeUI::NodeUI() : setFlag(QGraphicsItem::ItemIsSelectable, true); } -NodeUI::~NodeUI() -{ - if (proxy_ != nullptr) { - proxy_->setParentItem(nullptr); - } -} - void NodeUI::AddToScene(QGraphicsScene *scene) { scene->addItem(this); - - if (central_widget_ != nullptr) { - proxy_ = scene->addWidget(central_widget_); - proxy_->setPos(pos() + QPoint(1 + kRoundedRectRadius, 1 + kRoundedRectRadius)); - proxy_->setParentItem(this); - } } -void NodeUI::Resize(const QSize &s) +void NodeUI::SetNode(Node *n) { + node_ = n; + QRectF rectangle; + rectangle.setTopLeft(pos()); - rectangle.setSize(s + 2 * QSize(kRoundedRectRadius, kRoundedRectRadius)); + rectangle.setSize(QSizeF(200, GetRowY(node_->row_count()))); QRectF inner_rect = rectangle; - inner_rect.translate(kNodePlugSize / 2, 0); - - rectangle.setWidth(rectangle.width() + kNodePlugSize); + inner_rect.setX(inner_rect.x() + kNodePlugSize/2); + inner_rect.setWidth(inner_rect.width() - kNodePlugSize/2); drag_path_ = QPainterPath(); drag_path_.addRoundedRect(inner_rect, kRoundedRectRadius, kRoundedRectRadius); @@ -62,20 +51,16 @@ void NodeUI::Resize(const QSize &s) setRect(rectangle); } -void NodeUI::SetWidget(EffectUI *widget) +Node *NodeUI::GetNode() { - central_widget_ = widget; -} - -EffectUI *NodeUI::Widget() -{ - return central_widget_; + return node_; } void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget) + // Draw node sockets QVector sockets = GetNodeSocketRects(); if (!sockets.isEmpty()) { painter->setPen(Qt::black); @@ -86,6 +71,7 @@ void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW } } + // Draw main background rounded rectangle QPalette palette = qApp->palette(); if (option->state & QStyle::State_Selected) { @@ -95,6 +81,34 @@ void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW } painter->setBrush(palette.window()); painter->drawPath(drag_path_); + + // Draw node title + painter->setPen(palette.text().color()); + int left_text_x = rect().x() + kNodePlugSize/2 + kTextPadding; + painter->drawText(left_text_x, + GetRowY(-1) + qApp->fontMetrics().ascent(), + node_->name()); + + // Draw node row names + for (int i=0;irow_count();i++) { + int text_x; + + if (node_->row(i)->IsNodeOutput()) { + // right alignment + text_x = rect().right() - kNodePlugSize/2 - qApp->fontMetrics().width(node_->row(i)->name()) - kTextPadding; + } else { + // left alignment + text_x = left_text_x; + } + + painter->drawText(text_x, + GetRowY(i) + qApp->fontMetrics().ascent(), + node_->row(i)->name()); + } + + // Draw title splitter line + int line_y = GetRowY(-1) + qApp->fontMetrics().height() + kTextPadding/2; + painter->drawLine(rect().x() + kNodePlugSize/2, line_y, rect().right() - kNodePlugSize/2, line_y); } void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event) @@ -114,8 +128,8 @@ void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event) if (clicked_socket_ > -1) { // See if this socket already has an edge connected - QVector edges = central_widget_->GetEffect()->row(clicked_socket_)->edges(); - if (!edges.isEmpty() && edges.last()->input()->GetParentEffect() == central_widget_->GetEffect()) { + QVector edges = node_->row(clicked_socket_)->edges(); + if (!edges.isEmpty() && edges.last()->input()->GetParentEffect() == node_) { NodeEdge* e = edges.last().get(); @@ -144,7 +158,7 @@ void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event) // Start a new edge here drag_line_start_ = pos() + sockets.at(clicked_socket_).center(); - drag_source_ = central_widget_->GetEffect()->row(clicked_socket_); + drag_source_ = node_->row(clicked_socket_); } @@ -254,18 +268,19 @@ QVector NodeUI::GetNodeSocketRects() { QVector rects; - if (proxy_ != nullptr) { - Node* e = central_widget_->GetEffect(); + if (node_ != nullptr) { + Node* e = node_; for (int i=0;irow_count();i++) { - EffectRow* row = e->row(i); - qreal x = (row->IsNodeOutput()) ? rect().right() - kNodePlugSize : rect().x(); - int y = central_widget_->GetRowY(i); + EffectRow* row = e->row(i); if (row->IsNodeInput() || row->IsNodeOutput()) { + qreal x = (row->IsNodeOutput()) ? rect().right() - kNodePlugSize : rect().x(); + int y = GetRowY(i) + qApp->fontMetrics().height()/2; + rects.append(QRectF(x, - proxy_->pos().y() + y - kNodePlugSize/2, + rect().y() + y - kNodePlugSize/2, kNodePlugSize, kNodePlugSize)); } @@ -277,11 +292,8 @@ QVector NodeUI::GetNodeSocketRects() EffectRow *NodeUI::GetRowFromIndex(int i) { - if (central_widget_ != nullptr) { - Node* e = central_widget_->GetEffect(); - if (i < e->row_count()) { - return e->row(i); - } + if (node_ != nullptr && i < node_->row_count()) { + return node_->row(i); } return nullptr; } @@ -296,7 +308,7 @@ NodeUI *NodeUI::FindUIFromNode(Node* n) // Check if this node has the specified - if (node->Widget()->GetEffect() == n) { + if (node->node_ == n) { return node; } } @@ -304,3 +316,8 @@ NodeUI *NodeUI::FindUIFromNode(Node* n) return nullptr; } + +int NodeUI::GetRowY(int index) +{ + return (qApp->fontMetrics().height() + kTextPadding) * (index + 1) + kTextPadding; +} diff --git a/ui/nodeui.h b/ui/nodeui.h index b8cd53c5a..0558bbe01 100644 --- a/ui/nodeui.h +++ b/ui/nodeui.h @@ -12,12 +12,11 @@ class Node; class NodeUI : public QGraphicsRectItem { public: NodeUI(); - virtual ~NodeUI() override; void AddToScene(QGraphicsScene* scene); - void Resize(const QSize& s); - void SetWidget(EffectUI* widget); - EffectUI* Widget(); + //void Resize(const QSize& s); + void SetNode(Node* n); + Node* GetNode(); QVector GetNodeSocketRects(); @@ -31,9 +30,9 @@ protected: private: EffectRow *GetRowFromIndex(int i); NodeUI* FindUIFromNode(Node* n); + int GetRowY(int index); - EffectUI* central_widget_; - QGraphicsProxyWidget* proxy_; + Node* node_; QGraphicsPathItem* drag_line_; QPointF drag_line_start_;