From 854ca0a7a9f77a42211a6fd826645b77f01b5752 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Fri, 12 Nov 2021 11:51:13 -0800 Subject: [PATCH] reimplemented edge connect/disconnect --- app/widget/nodeview/nodeview.cpp | 35 +++++------ app/widget/nodeview/nodeviewedge.cpp | 23 +------ app/widget/nodeview/nodeviewedge.h | 11 ---- app/widget/nodeview/nodeviewitem.cpp | 61 ++++++++++++------- app/widget/nodeview/nodeviewitem.h | 11 ++-- app/widget/nodeview/nodeviewitemconnector.cpp | 5 +- app/widget/nodeview/nodeviewitemconnector.h | 11 +++- 7 files changed, 75 insertions(+), 82 deletions(-) diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index d5e85fcfb..31be310c6 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -473,30 +473,27 @@ void NodeView::mousePressEvent(QMouseEvent *event) { if (HandPress(event)) return; + QGraphicsItem* item = itemAt(event->pos()); + if (event->button() == Qt::LeftButton) { - // See if we're dragging the arrow of an edge - QPointF scene_pt = mapToScene(event->pos()); - - for (NodeViewEdge *edge_item : scene_.edges()) { - if (edge_item->arrow_bounding_rect().contains(scene_pt)) { - create_edge_src_ = scene_.NodeToUIObject(edge_item->output()); - create_edge_ = edge_item; - create_edge_already_exists_ = true; + // Determine if user clicked on a connector + if (NodeViewItemConnector *connector = dynamic_cast(item)) { + NodeViewItem *attached_item = static_cast(connector->parentItem()); + if (connector->IsOutput()) { + CreateNewEdge(attached_item, event->pos()); return; - } - } - - // See if we're dragging the arrow of a node - for (NodeViewItem *node_item : scene_.item_map()) { - if (node_item->GetOutputTriangle().boundingRect().translated(node_item->pos()).contains(scene_pt)) { - CreateNewEdge(node_item, event->pos()); + } else { + NodeViewEdge *edge_item = attached_item->GetEdgeFromInputConnector(connector); + if (edge_item) { + create_edge_src_ = edge_item->from_item(); + create_edge_ = edge_item; + create_edge_already_exists_ = true; + } return; } } } - QGraphicsItem* item = itemAt(event->pos()); - if (event->button() == Qt::RightButton) { if (!item || !item->isSelected()) { // Qt doesn't do this by default for some reason @@ -668,13 +665,13 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event) } // Update contexts - if (!removed_edges.empty()) { + /*if (!removed_edges.empty()) { UpdateContextsFromEdgeRemove(command, removed_edges); } if (added_edge.first) { UpdateContextsFromEdgeAdd(command, added_edge, removed_edges); - } + }*/ Core::instance()->undo_stack()->pushIfHasChildren(command); return; diff --git a/app/widget/nodeview/nodeviewedge.cpp b/app/widget/nodeview/nodeviewedge.cpp index f6df8ce73..977b88cbd 100644 --- a/app/widget/nodeview/nodeviewedge.cpp +++ b/app/widget/nodeview/nodeviewedge.cpp @@ -126,13 +126,6 @@ void NodeViewEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti painter->setPen(QPen(edge_color, edge_width_)); painter->setBrush(Qt::NoBrush); painter->drawPath(path()); - - // Draw arrow - if (!connected_) { - painter->setPen(Qt::NoPen); - painter->setBrush(edge_color); - painter->drawPolygon(arrow_); - } } void NodeViewEdge::Init() @@ -149,7 +142,6 @@ void NodeViewEdge::Init() // Use font metrics to set edge width for basic high DPI support edge_width_ = QFontMetrics(QFont()).height() / 12; - arrow_size_ = QFontMetrics(QFont()).height() / 2; } void NodeViewEdge::UpdateCurve() @@ -185,7 +177,7 @@ void NodeViewEdge::UpdateCurve() path.cubicTo(cp1, cp2, end); if (!qFuzzyCompare(start.x(), end.x())) { - double continue_x = end.x() - qCos(angle)*arrow_size_; + double continue_x = end.x() - qCos(angle); double x1 = start.x(); double x2 = cp1.x(); @@ -215,18 +207,7 @@ void NodeViewEdge::UpdateCurve() } - setPath(path); - - const double arrow_angle = 150.0 * M_PI / 180.0; - QVector arrow_points(4); - arrow_points[0] = end; - arrow_points[1] = end + QPointF(qCos(angle + arrow_angle) * arrow_size_, qSin(angle + arrow_angle) * arrow_size_); - arrow_points[2] = end + QPointF(qCos(angle - arrow_angle) * arrow_size_, qSin(angle - arrow_angle) * arrow_size_); - arrow_points[3] = end; - - arrow_ = QPolygonF(arrow_points); - arrow_bounding_rect_ = arrow_.boundingRect(); - arrow_bounding_rect_.adjust(-arrow_size_, -arrow_size_, arrow_size_, arrow_size_); + setPath(mapFromScene(path)); } } diff --git a/app/widget/nodeview/nodeviewedge.h b/app/widget/nodeview/nodeviewedge.h index 6240aeb64..de8d10720 100644 --- a/app/widget/nodeview/nodeviewedge.h +++ b/app/widget/nodeview/nodeviewedge.h @@ -70,11 +70,6 @@ public: return to_item_; } - const QRectF arrow_bounding_rect() const - { - return arrow_bounding_rect_; - } - void Adjust(); /** @@ -144,12 +139,6 @@ private: bool curved_; - QPolygonF arrow_; - - int arrow_size_; - - QRectF arrow_bounding_rect_; - QPointF cached_start_; QPointF cached_end_; bool cached_input_is_expanded_; diff --git a/app/widget/nodeview/nodeviewitem.cpp b/app/widget/nodeview/nodeviewitem.cpp index 520d2c961..b3e4ee4e9 100644 --- a/app/widget/nodeview/nodeviewitem.cpp +++ b/app/widget/nodeview/nodeviewitem.cpp @@ -67,7 +67,7 @@ NodeViewItem::NodeViewItem(QGraphicsItem *parent) : title_bar_rect_ = QRectF(-widget_width/2, -widget_height/2, widget_width, widget_height); setRect(title_bar_rect_); - output_connector_ = new NodeViewItemConnector(this); + output_connector_ = new NodeViewItemConnector(true, this); } QPointF NodeViewItem::GetNodePosition() const @@ -196,7 +196,7 @@ void NodeViewItem::RemoveEdge(NodeViewEdge *edge) int NodeViewItem::GetIndexAt(QPointF pt) const { - pt -= pos(); + pt -= this->scenePos(); for (int i=0; iRetranslate(); @@ -473,6 +472,17 @@ void NodeViewItem::DrawNodeTitle(QPainter* painter, QString text, const QRectF& text); } +NodeViewEdge *NodeViewItem::GetEdgeFromInputIndex(int index) +{ + foreach (NodeViewEdge *edge, edges_) { + if (edge->input().input() == node_inputs_.at(index)) { + return edge; + } + } + + return nullptr; +} + void NodeViewItem::SetHighlightedIndex(int index) { if (highlighted_index_ == index) { @@ -491,6 +501,23 @@ void NodeViewItem::SetLabelAsOutput(bool e) update(); } +NodeViewEdge *NodeViewItem::GetEdgeFromInputConnector(NodeViewItemConnector *connector) +{ + ssize_t index = -1; + for (ssize_t i=0; ipos(); + return input_connectors_[index]->scenePos(); } QPointF NodeViewItem::GetOutputPoint() const { - QPointF p = pos() + output_connector_->pos(); + QPointF p = output_connector_->scenePos(); QRectF r = output_connector_->boundingRect(); switch (flow_dir_) { @@ -563,15 +590,10 @@ void NodeViewItem::UpdateInputConnectors() input_connectors_.resize(node_inputs_.size()); for (size_t i=old_sz; i(this); + input_connectors_[i] = std::make_unique(false, this); } } -void NodeViewItem::ClearInputConnectors() -{ - input_connectors_.clear(); -} - void NodeViewItem::UpdateConnectorPositions() { UpdateInputConnectorPositions(); @@ -627,16 +649,13 @@ NodeViewCommon::FlowDirection NodeViewItem::GetFlowDirectionForInput(int index) if (!expanded_ || NodeViewCommon::IsFlowHorizontal(flow_dir_)) { return flow_dir_; } else { - foreach (NodeViewEdge *edge, edges_) { - if (edge->input().input() == node_inputs_.at(index)) { - if (edge->from_item()->x() < this->x()) { - return NodeViewCommon::kLeftToRight; - } else { - return NodeViewCommon::kRightToLeft; - } - } + NodeViewEdge *edge = GetEdgeFromInputIndex(index); + + if (!edge || edge->from_item()->x() < this->x()) { + return NodeViewCommon::kLeftToRight; + } else { + return NodeViewCommon::kRightToLeft; } - return NodeViewCommon::kLeftToRight; } } diff --git a/app/widget/nodeview/nodeviewitem.h b/app/widget/nodeview/nodeviewitem.h index c1ff35387..0f11574ed 100644 --- a/app/widget/nodeview/nodeviewitem.h +++ b/app/widget/nodeview/nodeviewitem.h @@ -127,13 +127,10 @@ public: return prevent_removing_; } - QPolygonF GetOutputTriangle() const - { - return output_connector_->polygon(); - } - void SetLabelAsOutput(bool e); + NodeViewEdge *GetEdgeFromInputConnector(NodeViewItemConnector *connector); + protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; @@ -151,6 +148,8 @@ private: void DrawNodeTitle(QPainter *painter, QString text, const QRectF &rect, Qt::Alignment vertical_align, int icon_size, bool draw_arrow); + NodeViewEdge *GetEdgeFromInputIndex(int index); + /** * @brief Returns local rect of a NodeInput in array node_inputs_[index] */ @@ -163,8 +162,6 @@ private: void UpdateInputConnectors(); - void ClearInputConnectors(); - void UpdateConnectorPositions(); void UpdateInputConnectorPositions(); diff --git a/app/widget/nodeview/nodeviewitemconnector.cpp b/app/widget/nodeview/nodeviewitemconnector.cpp index 650c33ccf..2ab919d77 100644 --- a/app/widget/nodeview/nodeviewitemconnector.cpp +++ b/app/widget/nodeview/nodeviewitemconnector.cpp @@ -29,8 +29,9 @@ namespace olive { -NodeViewItemConnector::NodeViewItemConnector(QGraphicsItem *parent) : - QGraphicsPolygonItem(parent) +NodeViewItemConnector::NodeViewItemConnector(bool is_output, QGraphicsItem *parent) : + QGraphicsPolygonItem(parent), + output_(is_output) { QColor c = qApp->palette().text().color(); setPen(QPen(c, NodeViewItem::DefaultItemBorder())); diff --git a/app/widget/nodeview/nodeviewitemconnector.h b/app/widget/nodeview/nodeviewitemconnector.h index 6dfc7d9d3..4da1e2fca 100644 --- a/app/widget/nodeview/nodeviewitemconnector.h +++ b/app/widget/nodeview/nodeviewitemconnector.h @@ -30,9 +30,18 @@ namespace olive { class NodeViewItemConnector : public QGraphicsPolygonItem { public: - NodeViewItemConnector(QGraphicsItem *parent = nullptr); + NodeViewItemConnector(bool is_output, QGraphicsItem *parent = nullptr); void SetFlowDirection(NodeViewCommon::FlowDirection dir); + + bool IsOutput() const + { + return output_; + } + +private: + bool output_; + }; }