fix: update edge hover to closest edge instead of add order

This commit is contained in:
parker
2025-07-15 02:36:39 +01:00
parent e3f66ea81a
commit 4e110b30c2
5 changed files with 116 additions and 66 deletions

View File

@@ -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<QGraphicsItem*> clickedItems = view_->items(event->pos());
QGraphicsItem* clickedSocket = itemOfType<SocketGraphic>(clickedItems);
QGraphicsItem* clickedEdge = itemOfType<NodeEdgeGraphic>(clickedItems);
// delete edges
if(mods & Qt::ControlModifier && clickedEdge)
if(
QGraphicsItem* clickedEdge = closestItemOfType<NodeEdgeGraphic>(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<QGraphicsItem*> prevHoverItems = prevHoverItems_;
prevHoverItems_.clear();
// handle previous items
for(QGraphicsItem* item : prevHoverItems)
{
if(isType<SocketGraphic>(item))
{
static_cast<SocketGraphic*>(item)->setHover(false);
}
if(isType<NodeEdgeGraphic>(item))
{
static_cast<NodeEdgeGraphic*>(item)->setDeleteHighlight(false);
}
}
// modifiers
Qt::KeyboardModifiers mods = event->modifiers();
@@ -190,15 +200,6 @@ void Network::mouseMoved(QMouseEvent *event)
QList<QGraphicsItem*> hoverItems = view_->items(event->pos());
// handle previous items
for(QGraphicsItem* item : prevHoverItems_)
{
if(isType<SocketGraphic>(item))
{
static_cast<SocketGraphic*>(item)->setHover(false);
}
}
prevHoverItems_.clear();
if(state_==State::MOVING_NODE)
{
@@ -227,7 +228,7 @@ void Network::mouseMoved(QMouseEvent *event)
return;
}
QGraphicsItem* hoverEdge = itemOfType<NodeEdgeGraphic>(hoverItems);
QGraphicsItem* hoverEdge = closestItemOfType<NodeEdgeGraphic>(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<NodeEdgeGraphic*>(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<SocketGraphic>(hoverItems, view_->mapToScene(event->pos())))
// highlight hovered socket
else if(auto hoverSocket = closestItemOfType<SocketGraphic>(hoverItems, view_->mapToScene(event->pos())))
{
static_cast<SocketGraphic*>(hoverSocket)->setHover(true);
prevHoverItems_.insert(hoverSocket);
@@ -291,7 +285,17 @@ void Network::keyPressEvent(QKeyEvent *event)
QGraphicsItem* hoverItem = itemOfType<NodeEdgeGraphic>(hoverItems);
if(hoverItem!=nullptr)
{
highlightEdge(hoverItem, true);
static_cast<NodeEdgeGraphic*>(hoverItem)->setDeleteHighlight(true);
// deselect sockets
for(auto item : hoverItems)
{
if(isType<SocketGraphic>(item))
{
static_cast<SocketGraphic*>(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<NodeEdgeGraphic>(edge)) return;
if(state)
{
static_cast<NodeEdgeGraphic*>(edge)->setDeleteHighlight(true);
prevHoverItem_=edge;
}
else
{
static_cast<NodeEdgeGraphic*>(edge)->setDeleteHighlight(false);
}
}
void Network::keyReleaseEvent(QKeyEvent *event)
{
// modifiers
Qt::KeyboardModifiers mods = event->modifiers();
bool ctrlMod = mods & Qt::ControlModifier;
// edge detection
// handle previous items
for(QGraphicsItem* item : prevHoverItems_)
{
if(
prevHoverItem_ &&
event->key() == Qt::Key_Control &&
isType<NodeEdgeGraphic>(prevHoverItem_)
isType<NodeEdgeGraphic>(item)
)
{
highlightEdge(prevHoverItem_, false);
static_cast<NodeEdgeGraphic*>(item)->setDeleteHighlight(false);
}
}
}

View File

@@ -16,6 +16,7 @@
#include <iostream>
#include <QPointer>
#include <unordered_map>
#include <unordered_set>
class Network
: public QWidget
@@ -42,7 +43,6 @@ private:
FloatingEdgeGraphic* floatingEdge_=nullptr;
SocketGraphic* startSocket_=nullptr;
QGraphicsItem* prevHoverItem_=nullptr;
std::unordered_set<QGraphicsItem*> prevHoverItems_;
// nodes currently being moved
std::vector<QGraphicsItem*> 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<typename T>
QGraphicsItem* itemOfType(std::unordered_set<QGraphicsItem*> items)
{
for(QGraphicsItem* item : items)
{
if(item && typeid(*item)==typeid(T))
{
return item;
}
}
return nullptr;
}
template<typename T>
QGraphicsItem* closestItemOfType(QList<QGraphicsItem*> 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<NodeEdgeGraphic, T>::value)
{
itemPos = static_cast<NodeEdgeGraphic*>(closestItem)->closestPoint(centerPos);
}
else
{
itemPos = closestItem->scenePos();
}
closestDist = QLineF(itemPos, centerPos).length();
}
std::cout << "currentDist: " << closestDist << "\n";
for(size_t i=1; i<filteredItems.size(); ++i)
{
QGraphicsItem* item = filteredItems.at(i);
auto currentDist = QLineF(item->scenePos(), centerPos).length();
QPointF itemPos;
if constexpr (std::is_base_of<NodeEdgeGraphic, T>::value)
{
itemPos = static_cast<NodeEdgeGraphic*>(item)->closestPoint(centerPos);
}
else
{
itemPos = item->scenePos();
}
auto currentDist = QLineF(itemPos, centerPos).length();
std::cout << "currentDist: " << currentDist << "\n";
if(currentDist < closestDist)
{
closestItem = item;

View File

@@ -71,10 +71,15 @@ void NodeEdgeGraphic::setPos(QPointF pos1, QPointF pos2)
updatePath();
}
void NodeEdgeGraphic::setDeleteHighlight(bool enable)
void NodeEdgeGraphic::setDeleteHighlight(bool state)
{
deleteHighlight_=enable;
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";

View File

@@ -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_;

View File

@@ -38,7 +38,6 @@ private:
qreal paddingScale_=20;
QRectF boundRect_;
enzo::nt::OpId opId_;
bool isHover_ = false;
void initBoundingBox();
protected: