diff --git a/effects/effectrow.cpp b/effects/effectrow.cpp index e60bea8b1..274ce3479 100644 --- a/effects/effectrow.cpp +++ b/effects/effectrow.cpp @@ -74,9 +74,17 @@ void EffectRow::AddAcceptedNodeInput(olive::nodes::DataType type) void EffectRow::ConnectEdge(EffectRow *output, EffectRow *input) { - Q_ASSERT(output->IsNodeOutput()); - Q_ASSERT(input->IsNodeInput()); + // Make sure one is an output and one is an input + Q_ASSERT(output->IsNodeInput() != input->IsNodeInput()); + // Swap them if necessary + if (input->IsNodeOutput()) { + EffectRow* temp = output; + output = input; + input = temp; + } + + // Inputs can only have one edge, so we disconnect it here if there is one if (!input->node_edges_.isEmpty()) { DisconnectEdge(input->node_edges_.first()); } @@ -87,7 +95,6 @@ void EffectRow::ConnectEdge(EffectRow *output, EffectRow *input) input->node_edges_.append(edge); emit output->EdgesChanged(); - emit input->EdgesChanged(); } void EffectRow::DisconnectEdge(NodeEdgePtr edge) @@ -99,18 +106,11 @@ void EffectRow::DisconnectEdge(NodeEdgePtr edge) input->node_edges_.removeAll(edge); emit output->EdgesChanged(); - emit input->EdgesChanged(); } -QVector EffectRow::edges() +QVector EffectRow::edges() { - QVector edges; - - for (int i=0;i edges(); + QVector edges(); protected: /** diff --git a/nodes/node.cpp b/nodes/node.cpp index a2d6b7d9b..8f2d95deb 100644 --- a/nodes/node.cpp +++ b/nodes/node.cpp @@ -196,9 +196,9 @@ int Node::gizmo_count() { return gizmos.size(); } -QVector Node::GetAllEdges() +QVector Node::GetAllEdges() { - QVector edges; + QVector edges; for (int i=0;iedges()); diff --git a/nodes/node.h b/nodes/node.h index b58fa1d78..2acf02ef9 100644 --- a/nodes/node.h +++ b/nodes/node.h @@ -135,7 +135,7 @@ public: EffectGizmo* gizmo(int i); int gizmo_count(); - QVector GetAllEdges(); + QVector GetAllEdges(); bool IsEnabled(); bool IsExpanded(); diff --git a/panels/nodeeditor.cpp b/panels/nodeeditor.cpp index af7a1c89d..7c5eebeba 100644 --- a/panels/nodeeditor.cpp +++ b/panels/nodeeditor.cpp @@ -53,12 +53,58 @@ void NodeEditor::LoadEvent() node_ui->setPos(effect_ui->GetEffect()->pos()); nodes_.append(node_ui); + } + } + } + + LoadEdges(); +} + +void NodeEditor::ClearEvent() +{ + foreach (NodeUI* node, nodes_) { + scene_.removeItem(node); + } + + nodes_.clear(); + + ClearEdges(); +} + +void NodeEditor::ClearEdges() +{ + foreach (NodeEdgeUI* edge, edges_) { + scene_.removeItem(edge); + } + + edges_.clear(); + + DisconnectAllRows(); +} + +void NodeEditor::LoadEdges() +{ + if (!open_effects_.isEmpty()) { + QVector added_edges; + + Clip* first_clip = open_effects_.first()->GetEffect()->parent_clip; + + for (int i=0;iGetEffect(); + + if (n->parent_clip == first_clip) { + + // Connect all rows to this + for (int j=0;jrow_count();j++) { + ConnectRow(n->row(j)); + } // Get node edges - QVector edges = open_effects_.at(i)->GetEffect()->GetAllEdges(); + QVector edges = n->GetAllEdges(); for (int j=0;jWidget()->GetEffect()->SetPos(node->pos()); } } + +void NodeEditor::ReloadEdges() +{ + qDebug() << "reload edges called"; + + ClearEdges(); + LoadEdges(); +} diff --git a/panels/nodeeditor.h b/panels/nodeeditor.h index fd3ed0967..4de6d70de 100644 --- a/panels/nodeeditor.h +++ b/panels/nodeeditor.h @@ -24,9 +24,17 @@ private: NodeView view_; QVector nodes_; QVector edges_; + QVector connected_rows_; + + void ClearEdges(); + void LoadEdges(); + + void ConnectRow(EffectRow* row); + void DisconnectAllRows(); private slots: void ItemsChanged(); + void ReloadEdges(); }; diff --git a/ui/nodeui.cpp b/ui/nodeui.cpp index 6b433bf84..17180ec3f 100644 --- a/ui/nodeui.cpp +++ b/ui/nodeui.cpp @@ -112,9 +112,47 @@ void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event) } if (clicked_socket_ > -1) { - drag_line_start_ = pos() + sockets.at(clicked_socket_).center(); + + // See if this socket already has an edge connected + QVector edges = central_widget_->GetEffect()->row(clicked_socket_)->edges(); + if (!edges.isEmpty()) { + + NodeEdge* e = edges.last().get(); + + EffectRow* other_row = (e->input()->GetParentEffect() == central_widget_->GetEffect()) ? + e->output() : e->input(); + + Node* other_node = other_row->GetParentEffect(); + + int other_row_index = other_node->IndexOfRow(other_row); + + NodeUI* other_node_ui = FindUIFromNode(other_node); + + // Start an edge at the opposite end + drag_line_start_ = other_node_ui->pos() + other_node_ui->GetNodeSocketRects().at(other_row_index).center(); + + drag_source_ = other_row; + + // Disconnect the existing edge, and treat our dynamic one as an edit of that one + EffectRow::DisconnectEdge(edges.last()); + + } else { + + // Start a new edge here + drag_line_start_ = pos() + sockets.at(clicked_socket_).center(); + + drag_source_ = central_widget_->GetEffect()->row(clicked_socket_); + + } + drag_line_ = scene()->addPath(NodeEdgeUI::GetEdgePath(drag_line_start_, event->scenePos())); + if (!edges.isEmpty()) { + drag_line_->setPen(QPen(Qt::white, 2)); + } else { + drag_line_->setPen(QPen(Qt::gray, 2)); + } + event->accept(); } else { QGraphicsItem::mousePressEvent(event); @@ -135,8 +173,8 @@ void NodeUI::mouseMoveEvent(QGraphicsSceneMouseEvent *event) // See if the graphics item here is a node NodeUI* mouse_node = dynamic_cast(mouse_items.at(j)); - if (mouse_node != nullptr) { + // If so, get this node's sockets and loop through them QVector mouse_nodes_sockets = mouse_node->GetNodeSocketRects(); for (int i=0;iGetEffect()->row(clicked_socket_); + EffectRow* local_row = drag_source_; EffectRow* remote_row = mouse_node->GetRowFromIndex(i); // Ensure one is an input and one is an output and whether their data types are compatible @@ -199,7 +237,7 @@ void NodeUI::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) event->accept(); if (drag_destination_ != nullptr) { - EffectRow::ConnectEdge(central_widget_->GetEffect()->row(clicked_socket_), drag_destination_); + EffectRow::ConnectEdge(drag_source_, drag_destination_); } } else { QGraphicsItem::mouseReleaseEvent(event); @@ -241,3 +279,22 @@ EffectRow *NodeUI::GetRowFromIndex(int i) } return nullptr; } + +NodeUI *NodeUI::FindUIFromNode(Node* n) +{ + QList all_items = scene()->items(); + + for (int j=0;j(all_items.at(j)); + if (node != nullptr) { + + // Check if this node has the specified + + if (node->Widget()->GetEffect() == n) { + return node; + } + } + } + + return nullptr; +} diff --git a/ui/nodeui.h b/ui/nodeui.h index 2b1f30696..b8cd53c5a 100644 --- a/ui/nodeui.h +++ b/ui/nodeui.h @@ -7,6 +7,7 @@ class EffectUI; class EffectRow; class NodeEdge; +class Node; class NodeUI : public QGraphicsRectItem { public: @@ -29,12 +30,14 @@ protected: private: EffectRow *GetRowFromIndex(int i); + NodeUI* FindUIFromNode(Node* n); EffectUI* central_widget_; QGraphicsProxyWidget* proxy_; QGraphicsPathItem* drag_line_; QPointF drag_line_start_; + EffectRow* drag_source_; EffectRow* drag_destination_; QPainterPath drag_path_;