From 4e110b30c2194cc76745667bfc318f6df0e111d5 Mon Sep 17 00:00:00 2001 From: parker Date: Tue, 15 Jul 2025 02:36:39 +0100 Subject: [PATCH] fix: update edge hover to closest edge instead of add order --- src/Gui/Network/Network.cpp | 105 +++++++++++++--------------- src/Gui/Network/Network.h | 45 ++++++++++-- src/Gui/Network/NodeEdgeGraphic.cpp | 27 ++++++- src/Gui/Network/NodeEdgeGraphic.h | 4 +- src/Gui/Network/SocketGraphic.h | 1 - 5 files changed, 116 insertions(+), 66 deletions(-) diff --git a/src/Gui/Network/Network.cpp b/src/Gui/Network/Network.cpp index 5e07f06..980fa11 100644 --- a/src/Gui/Network/Network.cpp +++ b/src/Gui/Network/Network.cpp @@ -57,13 +57,10 @@ void Network::deleteEdge(QGraphicsItem* edge) { std::cout << "----\ndeleting edge\n"; if(!edge) return; - if(prevHoverItem_==edge) + if(auto it = prevHoverItems_.find(edge); it != prevHoverItems_.end()) { - prevHoverItem_=nullptr; + prevHoverItems_.erase(it); } - // scene_->removeItem(edge); - // scene_->update(); - // view_->update(); // NOTE: deleting edge kept giving me segmentation faults // I coundn't figure it out so I'm just leaving it for now // delete edge; @@ -86,14 +83,15 @@ void Network::leftMousePressed(QMouseEvent *event) Qt::KeyboardModifiers mods = event->modifiers(); leftMouseStart = event->pos(); - // QGraphicsItem* itemClicked = view_->itemAt(event->pos()); QList clickedItems = view_->items(event->pos()); QGraphicsItem* clickedSocket = itemOfType(clickedItems); - QGraphicsItem* clickedEdge = itemOfType(clickedItems); // delete edges - if(mods & Qt::ControlModifier && clickedEdge) + if( + QGraphicsItem* clickedEdge = closestItemOfType(clickedItems, view_->mapToScene(event->pos())); + mods & Qt::ControlModifier && clickedEdge + ) { deleteEdge(clickedEdge); } @@ -180,9 +178,21 @@ void Network::destroyFloatingEdge() void Network::mouseMoved(QMouseEvent *event) { - // cache and reset prev hover item - QGraphicsItem* prevHoverItem=prevHoverItem_; - prevHoverItem_=nullptr; + // cache and reset prev hover items + std::unordered_set prevHoverItems = prevHoverItems_; + prevHoverItems_.clear(); + // handle previous items + for(QGraphicsItem* item : prevHoverItems) + { + if(isType(item)) + { + static_cast(item)->setHover(false); + } + if(isType(item)) + { + static_cast(item)->setDeleteHighlight(false); + } + } // modifiers Qt::KeyboardModifiers mods = event->modifiers(); @@ -190,15 +200,6 @@ void Network::mouseMoved(QMouseEvent *event) QList hoverItems = view_->items(event->pos()); - // handle previous items - for(QGraphicsItem* item : prevHoverItems_) - { - if(isType(item)) - { - static_cast(item)->setHover(false); - } - } - prevHoverItems_.clear(); if(state_==State::MOVING_NODE) { @@ -227,7 +228,7 @@ void Network::mouseMoved(QMouseEvent *event) return; } - QGraphicsItem* hoverEdge = itemOfType(hoverItems); + QGraphicsItem* hoverEdge = closestItemOfType(hoverItems, view_->mapToScene(event->pos())); // set node edge color if(ctrlMod && hoverEdge) @@ -238,20 +239,13 @@ void Network::mouseMoved(QMouseEvent *event) } else { - std::cout << "highlighting\n"; - highlightEdge(hoverEdge, true); + static_cast(hoverEdge)->setDeleteHighlight(true); + prevHoverItems_.insert(hoverEdge); } } - // reset node edge color - if( - prevHoverItem && - (!ctrlMod || hoverEdge!=prevHoverItem) - ) - { - std::cout << "unhighlighting\n"; - highlightEdge(prevHoverItem, false); - } - if(auto hoverSocket = closestItemOfType(hoverItems, view_->mapToScene(event->pos()))) + + // highlight hovered socket + else if(auto hoverSocket = closestItemOfType(hoverItems, view_->mapToScene(event->pos()))) { static_cast(hoverSocket)->setHover(true); prevHoverItems_.insert(hoverSocket); @@ -291,7 +285,17 @@ void Network::keyPressEvent(QKeyEvent *event) QGraphicsItem* hoverItem = itemOfType(hoverItems); if(hoverItem!=nullptr) { - highlightEdge(hoverItem, true); + static_cast(hoverItem)->setDeleteHighlight(true); + + // deselect sockets + for(auto item : hoverItems) + { + if(isType(item)) + { + static_cast(item)->setHover(false); + } + } + prevHoverItems_.insert(hoverItem); } break; } @@ -338,36 +342,23 @@ NodeGraphic* Network::createNode(nt::opConstructor ctorFunc) } -void Network::highlightEdge(QGraphicsItem* edge, bool state) -{ - if(!edge || !isType(edge)) return; - if(state) - { - static_cast(edge)->setDeleteHighlight(true); - prevHoverItem_=edge; - } - else - { - static_cast(edge)->setDeleteHighlight(false); - } - -} - - void Network::keyReleaseEvent(QKeyEvent *event) { // modifiers Qt::KeyboardModifiers mods = event->modifiers(); bool ctrlMod = mods & Qt::ControlModifier; - // edge detection - if( - prevHoverItem_ && - event->key() == Qt::Key_Control && - isType(prevHoverItem_) - ) + // handle previous items + for(QGraphicsItem* item : prevHoverItems_) { - highlightEdge(prevHoverItem_, false); + if( + event->key() == Qt::Key_Control && + isType(item) + ) + { + static_cast(item)->setDeleteHighlight(false); + } + } } diff --git a/src/Gui/Network/Network.h b/src/Gui/Network/Network.h index 041dcaa..01e6376 100644 --- a/src/Gui/Network/Network.h +++ b/src/Gui/Network/Network.h @@ -16,6 +16,7 @@ #include #include #include +#include class Network : public QWidget @@ -42,7 +43,6 @@ private: FloatingEdgeGraphic* floatingEdge_=nullptr; SocketGraphic* startSocket_=nullptr; - QGraphicsItem* prevHoverItem_=nullptr; std::unordered_set prevHoverItems_; // nodes currently being moved std::vector moveNodeBuffer; @@ -58,7 +58,6 @@ private: NodeGraphic* createNode(enzo::nt::opConstructor ctorFunc); - void highlightEdge(QGraphicsItem* edge, bool state); void leftMousePressed(QMouseEvent* event); void moveNodes(QPointF pos); @@ -82,6 +81,19 @@ private: return nullptr; } + template + QGraphicsItem* itemOfType(std::unordered_set items) + { + for(QGraphicsItem* item : items) + { + if(item && typeid(*item)==typeid(T)) + { + return item; + } + } + return nullptr; + } + template QGraphicsItem* closestItemOfType(QList items, QPointF centerPos) { @@ -97,13 +109,38 @@ private: if(filteredItems.size()==0) return nullptr; if(filteredItems.size()==1) return filteredItems.at(0); + std::cout << "\n\n new item " << filteredItems.size() << "\n"; QGraphicsItem* closestItem=filteredItems.at(0); - float closestDist=QLineF(closestItem->scenePos(), centerPos).length(); + float closestDist; + { + QPointF itemPos; + if constexpr (std::is_base_of::value) + { + itemPos = static_cast(closestItem)->closestPoint(centerPos); + } + else + { + itemPos = closestItem->scenePos(); + } + closestDist = QLineF(itemPos, centerPos).length(); + } + std::cout << "currentDist: " << closestDist << "\n"; for(size_t i=1; iscenePos(), centerPos).length(); + + QPointF itemPos; + if constexpr (std::is_base_of::value) + { + itemPos = static_cast(item)->closestPoint(centerPos); + } + else + { + itemPos = item->scenePos(); + } + auto currentDist = QLineF(itemPos, centerPos).length(); + std::cout << "currentDist: " << currentDist << "\n"; if(currentDist < closestDist) { closestItem = item; diff --git a/src/Gui/Network/NodeEdgeGraphic.cpp b/src/Gui/Network/NodeEdgeGraphic.cpp index d10f3cd..3353cef 100644 --- a/src/Gui/Network/NodeEdgeGraphic.cpp +++ b/src/Gui/Network/NodeEdgeGraphic.cpp @@ -71,10 +71,15 @@ void NodeEdgeGraphic::setPos(QPointF pos1, QPointF pos2) updatePath(); } -void NodeEdgeGraphic::setDeleteHighlight(bool enable) +void NodeEdgeGraphic::setDeleteHighlight(bool state) { - deleteHighlight_=enable; - update(); + bool stateChanged=deleteHighlight_!=state; + deleteHighlight_=state; + + if(stateChanged) + { + update(); + } } void NodeEdgeGraphic::setStartPos(QPointF pos) @@ -106,6 +111,22 @@ QPainterPath NodeEdgeGraphic::shape() const{ return stroker.createStroke(path_); } +QPointF NodeEdgeGraphic::closestPoint(QPointF startPos) +{ + QPointF lineVec = pos2_ - pos1_; + QPointF pointVec = startPos - pos1_; + + double lineLenSquared = QPointF::dotProduct(lineVec, lineVec); + if (lineLenSquared == 0.0) + return pos1_; + + double t = QPointF::dotProduct(pointVec, lineVec) / lineLenSquared; + + QPointF closest = pos1_ + t * lineVec; + return closest; +} + + // void NodeEdgeGraphic::setColor(QColor color) // { // std::cout << "color set to: " << color.name().toStdString() << "\n"; diff --git a/src/Gui/Network/NodeEdgeGraphic.h b/src/Gui/Network/NodeEdgeGraphic.h index 05aa8ac..c5cc6e0 100644 --- a/src/Gui/Network/NodeEdgeGraphic.h +++ b/src/Gui/Network/NodeEdgeGraphic.h @@ -21,12 +21,14 @@ public: void setStartPos(QPointF pos); void setEndPos(QPointF pos); void cleanUp(); - void setDeleteHighlight(bool enable); + void setDeleteHighlight(bool state); QPen deleteHighlightPen_; QPen defaultPen_; bool deleteHighlight_=false; + QPointF closestPoint(QPointF startPos); + private: SocketGraphic* socket1_; SocketGraphic* socket2_; diff --git a/src/Gui/Network/SocketGraphic.h b/src/Gui/Network/SocketGraphic.h index 6997716..361c706 100644 --- a/src/Gui/Network/SocketGraphic.h +++ b/src/Gui/Network/SocketGraphic.h @@ -38,7 +38,6 @@ private: qreal paddingScale_=20; QRectF boundRect_; enzo::nt::OpId opId_; - bool isHover_ = false; void initBoundingBox(); protected: