fix: update edge hover to closest edge instead of add order
This commit is contained in:
@@ -57,13 +57,10 @@ void Network::deleteEdge(QGraphicsItem* edge)
|
|||||||
{
|
{
|
||||||
std::cout << "----\ndeleting edge\n";
|
std::cout << "----\ndeleting edge\n";
|
||||||
if(!edge) return;
|
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
|
// NOTE: deleting edge kept giving me segmentation faults
|
||||||
// I coundn't figure it out so I'm just leaving it for now
|
// I coundn't figure it out so I'm just leaving it for now
|
||||||
// delete edge;
|
// delete edge;
|
||||||
@@ -86,14 +83,15 @@ void Network::leftMousePressed(QMouseEvent *event)
|
|||||||
Qt::KeyboardModifiers mods = event->modifiers();
|
Qt::KeyboardModifiers mods = event->modifiers();
|
||||||
leftMouseStart = event->pos();
|
leftMouseStart = event->pos();
|
||||||
|
|
||||||
// QGraphicsItem* itemClicked = view_->itemAt(event->pos());
|
|
||||||
QList<QGraphicsItem*> clickedItems = view_->items(event->pos());
|
QList<QGraphicsItem*> clickedItems = view_->items(event->pos());
|
||||||
QGraphicsItem* clickedSocket = itemOfType<SocketGraphic>(clickedItems);
|
QGraphicsItem* clickedSocket = itemOfType<SocketGraphic>(clickedItems);
|
||||||
QGraphicsItem* clickedEdge = itemOfType<NodeEdgeGraphic>(clickedItems);
|
|
||||||
|
|
||||||
|
|
||||||
// delete edges
|
// delete edges
|
||||||
if(mods & Qt::ControlModifier && clickedEdge)
|
if(
|
||||||
|
QGraphicsItem* clickedEdge = closestItemOfType<NodeEdgeGraphic>(clickedItems, view_->mapToScene(event->pos()));
|
||||||
|
mods & Qt::ControlModifier && clickedEdge
|
||||||
|
)
|
||||||
{
|
{
|
||||||
deleteEdge(clickedEdge);
|
deleteEdge(clickedEdge);
|
||||||
}
|
}
|
||||||
@@ -180,9 +178,21 @@ void Network::destroyFloatingEdge()
|
|||||||
|
|
||||||
void Network::mouseMoved(QMouseEvent *event)
|
void Network::mouseMoved(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
// cache and reset prev hover item
|
// cache and reset prev hover items
|
||||||
QGraphicsItem* prevHoverItem=prevHoverItem_;
|
std::unordered_set<QGraphicsItem*> prevHoverItems = prevHoverItems_;
|
||||||
prevHoverItem_=nullptr;
|
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
|
// modifiers
|
||||||
Qt::KeyboardModifiers mods = event->modifiers();
|
Qt::KeyboardModifiers mods = event->modifiers();
|
||||||
@@ -190,15 +200,6 @@ void Network::mouseMoved(QMouseEvent *event)
|
|||||||
|
|
||||||
QList<QGraphicsItem*> hoverItems = view_->items(event->pos());
|
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)
|
if(state_==State::MOVING_NODE)
|
||||||
{
|
{
|
||||||
@@ -227,7 +228,7 @@ void Network::mouseMoved(QMouseEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QGraphicsItem* hoverEdge = itemOfType<NodeEdgeGraphic>(hoverItems);
|
QGraphicsItem* hoverEdge = closestItemOfType<NodeEdgeGraphic>(hoverItems, view_->mapToScene(event->pos()));
|
||||||
|
|
||||||
// set node edge color
|
// set node edge color
|
||||||
if(ctrlMod && hoverEdge)
|
if(ctrlMod && hoverEdge)
|
||||||
@@ -238,20 +239,13 @@ void Network::mouseMoved(QMouseEvent *event)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "highlighting\n";
|
static_cast<NodeEdgeGraphic*>(hoverEdge)->setDeleteHighlight(true);
|
||||||
highlightEdge(hoverEdge, true);
|
prevHoverItems_.insert(hoverEdge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reset node edge color
|
|
||||||
if(
|
// highlight hovered socket
|
||||||
prevHoverItem &&
|
else if(auto hoverSocket = closestItemOfType<SocketGraphic>(hoverItems, view_->mapToScene(event->pos())))
|
||||||
(!ctrlMod || hoverEdge!=prevHoverItem)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::cout << "unhighlighting\n";
|
|
||||||
highlightEdge(prevHoverItem, false);
|
|
||||||
}
|
|
||||||
if(auto hoverSocket = closestItemOfType<SocketGraphic>(hoverItems, view_->mapToScene(event->pos())))
|
|
||||||
{
|
{
|
||||||
static_cast<SocketGraphic*>(hoverSocket)->setHover(true);
|
static_cast<SocketGraphic*>(hoverSocket)->setHover(true);
|
||||||
prevHoverItems_.insert(hoverSocket);
|
prevHoverItems_.insert(hoverSocket);
|
||||||
@@ -291,7 +285,17 @@ void Network::keyPressEvent(QKeyEvent *event)
|
|||||||
QGraphicsItem* hoverItem = itemOfType<NodeEdgeGraphic>(hoverItems);
|
QGraphicsItem* hoverItem = itemOfType<NodeEdgeGraphic>(hoverItems);
|
||||||
if(hoverItem!=nullptr)
|
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;
|
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)
|
void Network::keyReleaseEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
// modifiers
|
// modifiers
|
||||||
Qt::KeyboardModifiers mods = event->modifiers();
|
Qt::KeyboardModifiers mods = event->modifiers();
|
||||||
bool ctrlMod = mods & Qt::ControlModifier;
|
bool ctrlMod = mods & Qt::ControlModifier;
|
||||||
|
|
||||||
// edge detection
|
// handle previous items
|
||||||
|
for(QGraphicsItem* item : prevHoverItems_)
|
||||||
|
{
|
||||||
if(
|
if(
|
||||||
prevHoverItem_ &&
|
|
||||||
event->key() == Qt::Key_Control &&
|
event->key() == Qt::Key_Control &&
|
||||||
isType<NodeEdgeGraphic>(prevHoverItem_)
|
isType<NodeEdgeGraphic>(item)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
highlightEdge(prevHoverItem_, false);
|
static_cast<NodeEdgeGraphic*>(item)->setDeleteHighlight(false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
class Network
|
class Network
|
||||||
: public QWidget
|
: public QWidget
|
||||||
@@ -42,7 +43,6 @@ private:
|
|||||||
FloatingEdgeGraphic* floatingEdge_=nullptr;
|
FloatingEdgeGraphic* floatingEdge_=nullptr;
|
||||||
SocketGraphic* startSocket_=nullptr;
|
SocketGraphic* startSocket_=nullptr;
|
||||||
|
|
||||||
QGraphicsItem* prevHoverItem_=nullptr;
|
|
||||||
std::unordered_set<QGraphicsItem*> prevHoverItems_;
|
std::unordered_set<QGraphicsItem*> prevHoverItems_;
|
||||||
// nodes currently being moved
|
// nodes currently being moved
|
||||||
std::vector<QGraphicsItem*> moveNodeBuffer;
|
std::vector<QGraphicsItem*> moveNodeBuffer;
|
||||||
@@ -58,7 +58,6 @@ private:
|
|||||||
|
|
||||||
NodeGraphic* createNode(enzo::nt::opConstructor ctorFunc);
|
NodeGraphic* createNode(enzo::nt::opConstructor ctorFunc);
|
||||||
|
|
||||||
void highlightEdge(QGraphicsItem* edge, bool state);
|
|
||||||
void leftMousePressed(QMouseEvent* event);
|
void leftMousePressed(QMouseEvent* event);
|
||||||
|
|
||||||
void moveNodes(QPointF pos);
|
void moveNodes(QPointF pos);
|
||||||
@@ -82,6 +81,19 @@ private:
|
|||||||
return nullptr;
|
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>
|
template<typename T>
|
||||||
QGraphicsItem* closestItemOfType(QList<QGraphicsItem*> items, QPointF centerPos)
|
QGraphicsItem* closestItemOfType(QList<QGraphicsItem*> items, QPointF centerPos)
|
||||||
{
|
{
|
||||||
@@ -97,13 +109,38 @@ private:
|
|||||||
if(filteredItems.size()==0) return nullptr;
|
if(filteredItems.size()==0) return nullptr;
|
||||||
if(filteredItems.size()==1) return filteredItems.at(0);
|
if(filteredItems.size()==1) return filteredItems.at(0);
|
||||||
|
|
||||||
|
std::cout << "\n\n new item " << filteredItems.size() << "\n";
|
||||||
QGraphicsItem* closestItem=filteredItems.at(0);
|
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)
|
for(size_t i=1; i<filteredItems.size(); ++i)
|
||||||
{
|
{
|
||||||
QGraphicsItem* item = filteredItems.at(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)
|
if(currentDist < closestDist)
|
||||||
{
|
{
|
||||||
closestItem = item;
|
closestItem = item;
|
||||||
|
|||||||
@@ -71,11 +71,16 @@ void NodeEdgeGraphic::setPos(QPointF pos1, QPointF pos2)
|
|||||||
updatePath();
|
updatePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeEdgeGraphic::setDeleteHighlight(bool enable)
|
void NodeEdgeGraphic::setDeleteHighlight(bool state)
|
||||||
|
{
|
||||||
|
bool stateChanged=deleteHighlight_!=state;
|
||||||
|
deleteHighlight_=state;
|
||||||
|
|
||||||
|
if(stateChanged)
|
||||||
{
|
{
|
||||||
deleteHighlight_=enable;
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NodeEdgeGraphic::setStartPos(QPointF pos)
|
void NodeEdgeGraphic::setStartPos(QPointF pos)
|
||||||
{
|
{
|
||||||
@@ -106,6 +111,22 @@ QPainterPath NodeEdgeGraphic::shape() const{
|
|||||||
return stroker.createStroke(path_);
|
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)
|
// void NodeEdgeGraphic::setColor(QColor color)
|
||||||
// {
|
// {
|
||||||
// std::cout << "color set to: " << color.name().toStdString() << "\n";
|
// std::cout << "color set to: " << color.name().toStdString() << "\n";
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ public:
|
|||||||
void setStartPos(QPointF pos);
|
void setStartPos(QPointF pos);
|
||||||
void setEndPos(QPointF pos);
|
void setEndPos(QPointF pos);
|
||||||
void cleanUp();
|
void cleanUp();
|
||||||
void setDeleteHighlight(bool enable);
|
void setDeleteHighlight(bool state);
|
||||||
QPen deleteHighlightPen_;
|
QPen deleteHighlightPen_;
|
||||||
QPen defaultPen_;
|
QPen defaultPen_;
|
||||||
|
|
||||||
bool deleteHighlight_=false;
|
bool deleteHighlight_=false;
|
||||||
|
|
||||||
|
QPointF closestPoint(QPointF startPos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SocketGraphic* socket1_;
|
SocketGraphic* socket1_;
|
||||||
SocketGraphic* socket2_;
|
SocketGraphic* socket2_;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ private:
|
|||||||
qreal paddingScale_=20;
|
qreal paddingScale_=20;
|
||||||
QRectF boundRect_;
|
QRectF boundRect_;
|
||||||
enzo::nt::OpId opId_;
|
enzo::nt::OpId opId_;
|
||||||
bool isHover_ = false;
|
|
||||||
|
|
||||||
void initBoundingBox();
|
void initBoundingBox();
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user