refactor: fix file case
This commit is contained in:
73
src/Gui/Network/DisplayFlagButton.cpp
Normal file
73
src/Gui/Network/DisplayFlagButton.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "Gui/Network/DisplayFlagButton.h"
|
||||
#include "Gui/Network/NodeGraphic.h"
|
||||
#include <QPainter>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qnamespace.h>
|
||||
|
||||
DisplayFlagButton::DisplayFlagButton(QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent)
|
||||
{
|
||||
constexpr float width = 8;
|
||||
const float height = static_cast<NodeGraphic*>(parent)->getBodyRect().height()*0.8;
|
||||
baseRect_ = QRectF(-width/2.0f, -height/2.0f, width, height);
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
disabledBrush_ = QBrush(disabledColor_);
|
||||
enabledBrush_ = QBrush(enabledColor_);
|
||||
hoveredEnabledBrush_ = QBrush("#1391ff");
|
||||
hoveredDisabledBrush_ = QBrush(hoveredColor_);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DisplayFlagButton::setEnabled(bool enabled)
|
||||
{
|
||||
enabled_ = enabled;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void DisplayFlagButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
painter->setPen(Qt::NoPen);
|
||||
// painter->setBrush(QBrush(disabledColor_));
|
||||
QBrush usedBrush;
|
||||
if(enabled_)
|
||||
{
|
||||
if(hovered_) { usedBrush = hoveredEnabledBrush_; }
|
||||
else { usedBrush = enabledBrush_; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hovered_) { usedBrush = hoveredDisabledBrush_; }
|
||||
else { usedBrush = disabledBrush_; }
|
||||
}
|
||||
painter->setBrush(usedBrush);
|
||||
constexpr float roundRad = 3;
|
||||
painter->drawRoundedRect(baseRect_, roundRad, roundRad);
|
||||
}
|
||||
|
||||
QRectF DisplayFlagButton::boundingRect() const
|
||||
{
|
||||
return baseRect_;
|
||||
}
|
||||
|
||||
float DisplayFlagButton::getWidth()
|
||||
{
|
||||
return baseRect_.width();
|
||||
}
|
||||
|
||||
void DisplayFlagButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
hovered_ = true;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void DisplayFlagButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
hovered_ = false;
|
||||
update();
|
||||
}
|
||||
|
||||
29
src/Gui/Network/DisplayFlagButton.h
Normal file
29
src/Gui/Network/DisplayFlagButton.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <QGraphicsItem>
|
||||
#include <QBrush>
|
||||
|
||||
class DisplayFlagButton
|
||||
: public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
DisplayFlagButton(QGraphicsItem *parent = nullptr);
|
||||
float getWidth();
|
||||
void setEnabled(bool enabled);
|
||||
private:
|
||||
QRectF baseRect_;
|
||||
QColor disabledColor_=QColor("#373737");
|
||||
QColor enabledColor_=QColor("#00BFFF");
|
||||
QColor hoveredColor_=QColor("#666666");
|
||||
QBrush disabledBrush_;
|
||||
QBrush enabledBrush_;
|
||||
QBrush hoveredDisabledBrush_;
|
||||
QBrush hoveredEnabledBrush_;
|
||||
bool hovered_=false;
|
||||
bool enabled_=false;
|
||||
protected:
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
|
||||
};
|
||||
53
src/Gui/Network/FloatingEdgeGraphic.cpp
Normal file
53
src/Gui/Network/FloatingEdgeGraphic.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "Gui/Network/FloatingEdgeGraphic.h"
|
||||
#include <QTextDocument>
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include <iostream>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <algorithm>
|
||||
|
||||
FloatingEdgeGraphic::FloatingEdgeGraphic(SocketGraphic* socket1, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), socket1_{socket1}
|
||||
{
|
||||
floatPos_ = socket1_->scenePos();
|
||||
setZValue(-1);
|
||||
}
|
||||
|
||||
QRectF FloatingEdgeGraphic::boundingRect() const
|
||||
{
|
||||
auto boundRect = QRectF(socket1_->scenePos(), floatPos_).normalized();
|
||||
return boundRect;
|
||||
}
|
||||
|
||||
void FloatingEdgeGraphic::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
// auto pen = QPen("white");
|
||||
|
||||
QLinearGradient gradient(socket1_->scenePos(), floatPos_);
|
||||
gradient.setColorAt(0.0, QColor(255, 255, 255, 255));
|
||||
gradient.setColorAt(1.0, QColor(255, 255, 255, 50));
|
||||
|
||||
QPen pen(QBrush(gradient), 1);
|
||||
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter->setPen(pen);
|
||||
// painter->drawLine(socket1_->scenePos(),floatPos_);
|
||||
|
||||
QPointF pos1 = socket1_->getIO()==enzo::nt::SocketIOType::Input ? socket1_->scenePos() : floatPos_;
|
||||
QPointF pos2 = socket1_->getIO()==enzo::nt::SocketIOType::Input ? floatPos_ : socket1_->scenePos();
|
||||
float dist = std::sqrt(std::pow(pos1.x()-pos2.x(),2)+std::pow(pos1.y()-pos2.y(),2));
|
||||
float cubicStrength = dist*0.5;
|
||||
cubicStrength = std::clamp(cubicStrength, 0.0f, 40.0f);
|
||||
QPainterPath path;
|
||||
path.moveTo(pos1);
|
||||
path.cubicTo(pos1-QPoint(0,cubicStrength), pos2+QPoint(0,cubicStrength), pos2);
|
||||
painter->drawPath(path);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FloatingEdgeGraphic::setFloatPos(QPointF floatPos) {
|
||||
prepareGeometryChange();
|
||||
floatPos_ = floatPos;
|
||||
update();
|
||||
}
|
||||
|
||||
21
src/Gui/Network/FloatingEdgeGraphic.h
Normal file
21
src/Gui/Network/FloatingEdgeGraphic.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <QGraphicsItem>
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
class FloatingEdgeGraphic
|
||||
: public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
FloatingEdgeGraphic(SocketGraphic* socket1, QGraphicsItem *parent = nullptr);
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void setFloatPos(QPointF floatPos);
|
||||
|
||||
private:
|
||||
SocketGraphic* socket1_;
|
||||
QPointF floatPos_;
|
||||
};
|
||||
|
||||
392
src/Gui/Network/Network.cpp
Normal file
392
src/Gui/Network/Network.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
#include "Gui/Network/Network.h"
|
||||
#include "Engine/Operator/GeometryConnection.h"
|
||||
#include "Engine/Operator/GeometryOperator.h"
|
||||
#include "Engine/Types.h"
|
||||
#include "Gui/Network/DisplayFlagButton.h"
|
||||
#include "Gui/Network/NodeEdgeGraphic.h"
|
||||
#include "Gui/Network/NetworkGraphicsView.h"
|
||||
#include "Gui/Network/NetworkGraphicsScene.h"
|
||||
#include "Gui/Network/NodeGraphic.h"
|
||||
#include "Gui/Network/FloatingEdgeGraphic.h"
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include "Engine/Network/NetworkManager.h"
|
||||
#include <memory>
|
||||
#include <qboxlayout.h>
|
||||
#include <QPushButton>
|
||||
#include <QGraphicsItem>
|
||||
#include <QMouseEvent>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qnamespace.h>
|
||||
#include <QLine>
|
||||
|
||||
using namespace enzo;
|
||||
|
||||
Network::Network(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
|
||||
mainLayout_ = new QVBoxLayout(parent);
|
||||
// mainLayout_->setContentsMargins(0,0,0,0);
|
||||
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
|
||||
|
||||
this->setLayout(mainLayout_);
|
||||
|
||||
|
||||
scene_ = new NetworkGraphicsScene();
|
||||
view_ = new NetworkGraphicsView(this, this, scene_);
|
||||
|
||||
|
||||
mainLayout_->addWidget(view_);
|
||||
|
||||
}
|
||||
|
||||
void Network::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QPainterPath path;
|
||||
constexpr float radius = 10;
|
||||
path.addRoundedRect(mainLayout_->contentsRect(), radius, radius);
|
||||
QRegion region = QRegion(path.toFillPolygon().toPolygon());
|
||||
this->setMask(region);
|
||||
}
|
||||
|
||||
void Network::deleteEdge(QGraphicsItem* edge)
|
||||
{
|
||||
std::cout << "----\ndeleting edge\n";
|
||||
if(!edge) return;
|
||||
if(prevHoverItem_==edge)
|
||||
{
|
||||
prevHoverItem_=nullptr;
|
||||
}
|
||||
// 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;
|
||||
static_cast<NodeEdgeGraphic*>(edge)->cleanUp();
|
||||
std::cout << "finished deleting edge\n----\n";
|
||||
}
|
||||
|
||||
void Network::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if( event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
leftMousePressed(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Network::leftMousePressed(QMouseEvent *event)
|
||||
{
|
||||
std::cout << "LEFT MOUSE PRESSED\n";
|
||||
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)
|
||||
{
|
||||
deleteEdge(clickedEdge);
|
||||
}
|
||||
// socket logic
|
||||
else if(clickedSocket)
|
||||
{
|
||||
// find closest socket
|
||||
clickedSocket = closestItemOfType<SocketGraphic>(clickedItems, view_->mapToScene(event->pos()));
|
||||
if(clickedSocket)
|
||||
{
|
||||
socketClicked(static_cast<SocketGraphic*>(clickedSocket), event);
|
||||
}
|
||||
}
|
||||
// floating edge
|
||||
else if(floatingEdge_)
|
||||
{
|
||||
destroyFloatingEdge();
|
||||
}
|
||||
else if(QGraphicsItem* clickedNode = itemOfType<NodeGraphic>(clickedItems))
|
||||
{
|
||||
nodeMoveDelta_=clickedNode->pos()-view_->mapToScene(event->pos());
|
||||
std::cout << "move delta: " << nodeMoveDelta_.x() << " " << nodeMoveDelta_.y() << "\n";
|
||||
state_=State::MOVING_NODE;
|
||||
moveNodeBuffer.clear();
|
||||
moveNodeBuffer.push_back(clickedNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Network::socketClicked(SocketGraphic* socket, QMouseEvent *event)
|
||||
{
|
||||
std::cout << "socket clicked\n";
|
||||
// if first click
|
||||
if(!floatingEdge_)
|
||||
{
|
||||
startSocket_=socket;
|
||||
std::cout << "creating floating edge\n";
|
||||
floatingEdge_ = new FloatingEdgeGraphic(socket);
|
||||
scene_->addItem(floatingEdge_);
|
||||
floatingEdge_->setFloatPos(view_->mapToScene(event->pos()));
|
||||
}
|
||||
// second click
|
||||
// connect to opposite type
|
||||
else if (
|
||||
socket->getIO()!=startSocket_->getIO() &&
|
||||
startSocket_->getOpId()!=socket->getOpId()
|
||||
)
|
||||
{
|
||||
|
||||
// order sockets in relation to data flow
|
||||
// the input node is the node the data flows from
|
||||
auto inputNodeSocket = socket->getIO()==enzo::nt::SocketIOType::Output ? socket : startSocket_;
|
||||
// the output node is the node the data flows to
|
||||
auto outputNodeSocket = startSocket_->getIO()==enzo::nt::SocketIOType::Input ? startSocket_ : socket;
|
||||
|
||||
std::cout << "CONNECTING opid: " << inputNodeSocket->getOpId() << " -> " << outputNodeSocket->getOpId() << "\n";
|
||||
|
||||
|
||||
nt::connectOperators(inputNodeSocket->getOpId(), inputNodeSocket->getIndex(), outputNodeSocket->getOpId(), outputNodeSocket->getIndex());
|
||||
|
||||
|
||||
NodeEdgeGraphic* newEdge = new NodeEdgeGraphic(outputNodeSocket, inputNodeSocket);
|
||||
|
||||
newEdge->setPos(outputNodeSocket->scenePos(), inputNodeSocket->scenePos());
|
||||
scene_->addItem(newEdge);
|
||||
destroyFloatingEdge();
|
||||
}
|
||||
}
|
||||
|
||||
void Network::destroyFloatingEdge()
|
||||
{
|
||||
if(floatingEdge_)
|
||||
{
|
||||
scene_->removeItem(floatingEdge_);
|
||||
delete floatingEdge_;
|
||||
floatingEdge_=nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Network::mouseMoved(QMouseEvent *event)
|
||||
{
|
||||
// cache and reset prev hover item
|
||||
QGraphicsItem* prevHoverItem=prevHoverItem_;
|
||||
prevHoverItem_=nullptr;
|
||||
|
||||
// modifiers
|
||||
Qt::KeyboardModifiers mods = event->modifiers();
|
||||
bool ctrlMod = mods & Qt::ControlModifier;
|
||||
|
||||
QList<QGraphicsItem*> hoverItems = view_->items(event->pos());
|
||||
|
||||
if(state_==State::MOVING_NODE)
|
||||
{
|
||||
moveNodes(view_->mapToScene(event->pos())+nodeMoveDelta_);
|
||||
return;
|
||||
}
|
||||
|
||||
if(floatingEdge_)
|
||||
{
|
||||
if(
|
||||
SocketGraphic* hoverSocket = static_cast<SocketGraphic*>(closestItemOfType<SocketGraphic>(hoverItems, view_->mapToScene(event->pos())));
|
||||
hoverSocket &&
|
||||
hoverSocket!=startSocket_ &&
|
||||
hoverSocket->getIO()!=startSocket_->getIO() &&
|
||||
hoverSocket->getOpId()!=startSocket_->getOpId()
|
||||
|
||||
)
|
||||
{
|
||||
floatingEdge_->setFloatPos(hoverSocket->scenePos());
|
||||
}
|
||||
else
|
||||
{
|
||||
floatingEdge_->setFloatPos(view_->mapToScene(event->pos()));
|
||||
}
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QGraphicsItem* hoverEdge = itemOfType<NodeEdgeGraphic>(hoverItems);
|
||||
|
||||
// set node edge color
|
||||
if(ctrlMod && hoverEdge)
|
||||
{
|
||||
if(event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
deleteEdge(hoverEdge);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "highlighting\n";
|
||||
highlightEdge(hoverEdge, true);
|
||||
}
|
||||
}
|
||||
// reset node edge color
|
||||
if(
|
||||
prevHoverItem &&
|
||||
(!ctrlMod || hoverEdge!=prevHoverItem)
|
||||
)
|
||||
{
|
||||
std::cout << "unhighlighting\n";
|
||||
highlightEdge(prevHoverItem, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Network::moveNodes(QPointF pos)
|
||||
{
|
||||
|
||||
for(auto node : moveNodeBuffer)
|
||||
{
|
||||
node->setPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Network::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
// modifiers
|
||||
Qt::KeyboardModifiers mods = event->modifiers();
|
||||
bool ctrlMod = mods & Qt::ControlModifier;
|
||||
|
||||
// get pos
|
||||
QPoint globalPos = QCursor::pos();
|
||||
QPoint widgetPos = mapFromGlobal(globalPos);
|
||||
QPointF viewPos = view_->mapToScene(widgetPos);
|
||||
|
||||
|
||||
QList<QGraphicsItem*> hoverItems = view_->items(widgetPos);
|
||||
|
||||
// edge detection
|
||||
switch(event->key())
|
||||
{
|
||||
|
||||
case( Qt::Key_Control):
|
||||
{
|
||||
QGraphicsItem* hoverItem = itemOfType<NodeEdgeGraphic>(hoverItems);
|
||||
if(hoverItem!=nullptr)
|
||||
{
|
||||
highlightEdge(hoverItem, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(Qt::Key_Escape):
|
||||
{
|
||||
destroyFloatingEdge();
|
||||
break;
|
||||
}
|
||||
case(Qt::Key_Tab):
|
||||
{
|
||||
if(auto newNode = createNode())
|
||||
{
|
||||
newNode->setPos(viewPos);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodeGraphic* Network::createNode()
|
||||
{
|
||||
if(nt::OpId id = nt::NetworkManager::addOperator())
|
||||
{
|
||||
NodeGraphic* newNode = new NodeGraphic(id);
|
||||
scene_->addItem(newNode);
|
||||
nodeStore_.emplace(id, newNode);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Network::highlightEdge(QGraphicsItem* edge, bool state)
|
||||
{
|
||||
if(!edge || !isType<NodeEdgeGraphic>(edge)) return;
|
||||
if(state)
|
||||
{
|
||||
static_cast<NodeEdgeGraphic*>(edge)->setDeleteHighlight(true);
|
||||
prevHoverItem_=edge;
|
||||
// NOTE: sloppy fix for color not updating
|
||||
view_->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<NodeEdgeGraphic*>(edge)->setDeleteHighlight(false);
|
||||
// NOTE: sloppy fix for color not updating
|
||||
view_->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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<NodeEdgeGraphic>(prevHoverItem_)
|
||||
)
|
||||
{
|
||||
highlightEdge(prevHoverItem_, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Network::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
// std::cout << "----\nMOUSE RELEASED\n---\n";
|
||||
QList<QGraphicsItem*> hoverItems = view_->items(event->pos());
|
||||
QGraphicsItem* hoverSocket = itemOfType<SocketGraphic>(hoverItems);
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
// display flag
|
||||
if(
|
||||
QGraphicsItem* clickedDisplayFlag = itemOfType<DisplayFlagButton>(hoverItems);
|
||||
clickedDisplayFlag &&
|
||||
QLineF(event->pos(), leftMouseStart).length()<5.0f
|
||||
)
|
||||
{
|
||||
enzo::nt::NetworkManager* nm = enzo::nt::NetworkManager::getInstance();
|
||||
NodeGraphic* clickedNode = static_cast<NodeGraphic*>(itemOfType<NodeGraphic>(hoverItems));
|
||||
enzo::nt::OpId opId = clickedNode->getOpId();
|
||||
if(auto prevDisplayOpId = nt::NetworkManager::getDisplayOp(); prevDisplayOpId)
|
||||
{
|
||||
NodeGraphic* prevDisplayNode = nodeStore_.at(*prevDisplayOpId);
|
||||
prevDisplayNode->setDisplayFlag(false);
|
||||
}
|
||||
nm->setDisplayOp(opId);
|
||||
static_cast<DisplayFlagButton*>(clickedDisplayFlag)->setEnabled(true);
|
||||
}
|
||||
if(state_==State::MOVING_NODE)
|
||||
{
|
||||
moveNodeBuffer.clear();
|
||||
state_=State::DEFAULT;
|
||||
}
|
||||
else if(floatingEdge_ && hoverSocket)
|
||||
{
|
||||
hoverSocket = closestItemOfType<SocketGraphic>(hoverItems, view_->mapToScene(event->pos()));
|
||||
if(hoverSocket)
|
||||
{
|
||||
socketClicked(static_cast<SocketGraphic*>(hoverSocket), event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
121
src/Gui/Network/Network.h
Normal file
121
src/Gui/Network/Network.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qpoint.h>
|
||||
#include <typeinfo>
|
||||
#include "Engine/Network/NetworkManager.h"
|
||||
#include "Engine/Types.h"
|
||||
#include "Gui/Network/NetworkGraphicsView.h"
|
||||
#include "Gui/Network/NodeEdgeGraphic.h"
|
||||
#include "Gui/Network/NetworkGraphicsScene.h"
|
||||
#include "Gui/Network/NodeGraphic.h"
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include "Gui/Network/FloatingEdgeGraphic.h"
|
||||
#include <iostream>
|
||||
#include <QPointer>
|
||||
#include <unordered_map>
|
||||
|
||||
class Network
|
||||
: public QWidget
|
||||
{
|
||||
public:
|
||||
Network(QWidget* parent = nullptr);
|
||||
void socketClicked(SocketGraphic* socket, QMouseEvent *event);
|
||||
void mouseMoved(QMouseEvent *event);
|
||||
QSize sizeHint() const override { return QSize(-1, -1); }
|
||||
|
||||
enum class State
|
||||
{
|
||||
DEFAULT,
|
||||
MOVING_NODE
|
||||
};
|
||||
|
||||
private:
|
||||
QLayout* mainLayout_;
|
||||
NetworkGraphicsScene* scene_;
|
||||
NetworkGraphicsView* view_;
|
||||
|
||||
std::unordered_map<enzo::nt::OpId, NodeGraphic*> nodeStore_;
|
||||
|
||||
FloatingEdgeGraphic* floatingEdge_=nullptr;
|
||||
SocketGraphic* startSocket_=nullptr;
|
||||
|
||||
QGraphicsItem* prevHoverItem_=nullptr;
|
||||
// nodes currently being moved
|
||||
std::vector<QGraphicsItem*> moveNodeBuffer;
|
||||
QPointF nodeMoveDelta_;
|
||||
|
||||
State state_=State::DEFAULT;
|
||||
QPointF leftMouseStart;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void keyReleaseEvent(QKeyEvent *event) override;
|
||||
void destroyFloatingEdge();
|
||||
void deleteEdge(QGraphicsItem* edge);
|
||||
|
||||
NodeGraphic* createNode();
|
||||
|
||||
void highlightEdge(QGraphicsItem* edge, bool state);
|
||||
void leftMousePressed(QMouseEvent* event);
|
||||
|
||||
void moveNodes(QPointF pos);
|
||||
|
||||
template<typename T>
|
||||
bool isType(QGraphicsItem* item)
|
||||
{
|
||||
return item && typeid(*item)==typeid(T);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QGraphicsItem* itemOfType(QList<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)
|
||||
{
|
||||
std::vector <QGraphicsItem*> filteredItems;
|
||||
for(QGraphicsItem* item : items)
|
||||
{
|
||||
if(item && typeid(*item)==typeid(T))
|
||||
{
|
||||
filteredItems.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
if(filteredItems.size()==0) return nullptr;
|
||||
if(filteredItems.size()==1) return filteredItems.at(0);
|
||||
|
||||
QGraphicsItem* closestItem=filteredItems.at(0);
|
||||
float closestDist=QLineF(closestItem->scenePos(), centerPos).length();
|
||||
|
||||
for(size_t i=1; i<filteredItems.size(); ++i)
|
||||
{
|
||||
QGraphicsItem* item = filteredItems.at(i);
|
||||
auto currentDist = QLineF(item->scenePos(), centerPos).length();
|
||||
if(currentDist < closestDist)
|
||||
{
|
||||
closestItem = item;
|
||||
closestDist = currentDist;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return closestItem;
|
||||
}
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
};
|
||||
54
src/Gui/Network/NetworkGraphicsScene.cpp
Normal file
54
src/Gui/Network/NetworkGraphicsScene.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "Gui/Network/NetworkGraphicsScene.h"
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneWheelEvent>
|
||||
#include <iostream>
|
||||
#include <qgraphicsview.h>
|
||||
#include <QPainterPath>
|
||||
|
||||
NetworkGraphicsScene::NetworkGraphicsScene()
|
||||
: QGraphicsScene()
|
||||
{
|
||||
sceneWidth_ = 64000;
|
||||
sceneHeight_ = 64000;
|
||||
gridSize_ = 40;
|
||||
|
||||
setSceneRect(sceneWidth_/-2.0f, sceneHeight_/-2.0f, sceneWidth_, sceneHeight_);
|
||||
|
||||
setBackgroundBrush(QColor("#282828"));
|
||||
}
|
||||
|
||||
void NetworkGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
|
||||
// QPainterPath path;
|
||||
// path.addRoundedRect(rect, 15, 15);
|
||||
// painter->setClipPath(path);
|
||||
|
||||
QGraphicsScene::drawBackground(painter, rect);
|
||||
|
||||
|
||||
|
||||
int top = ceil(rect.top());
|
||||
int bottom = floor(rect.bottom());
|
||||
int left = floor(rect.left());
|
||||
int right = ceil(rect.right());
|
||||
|
||||
QPen gridPen(QColor("#323232"));
|
||||
|
||||
painter->setPen(gridPen);
|
||||
|
||||
QList<QLine> lines;
|
||||
|
||||
for (int y = top - (top % gridSize_); y <= bottom; y += gridSize_) {
|
||||
lines.append(QLine(left, y, right, y));
|
||||
}
|
||||
|
||||
for (int x = left - (left % gridSize_); x <= right; x += gridSize_) {
|
||||
lines.append(QLine(x, bottom, x, top));
|
||||
}
|
||||
|
||||
painter->drawLines(lines);
|
||||
|
||||
}
|
||||
|
||||
|
||||
16
src/Gui/Network/NetworkGraphicsScene.h
Normal file
16
src/Gui/Network/NetworkGraphicsScene.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
||||
class NetworkGraphicsScene
|
||||
: public QGraphicsScene
|
||||
{
|
||||
public:
|
||||
NetworkGraphicsScene();
|
||||
private:
|
||||
uint sceneWidth_;
|
||||
uint sceneHeight_;
|
||||
uint gridSize_;
|
||||
protected:
|
||||
void drawBackground(QPainter *painter, const QRectF &rect) override;
|
||||
};
|
||||
132
src/Gui/Network/NetworkGraphicsView.cpp
Normal file
132
src/Gui/Network/NetworkGraphicsView.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include "Gui/Network/NetworkGraphicsView.h"
|
||||
#include <QGraphicsItem>
|
||||
#include "Gui/Network/Network.h"
|
||||
#include "Gui/Network/NetworkGraphicsScene.h"
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include <iostream>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qobject.h>
|
||||
#include <typeinfo>
|
||||
|
||||
NetworkGraphicsView::NetworkGraphicsView(QWidget *parent, Network* network, QGraphicsScene* scene)
|
||||
: QGraphicsView(parent), scene_{scene}, network_{network}
|
||||
{
|
||||
setScene(scene_);
|
||||
setMouseTracking(true);
|
||||
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
initUI();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void NetworkGraphicsView::initUI()
|
||||
{
|
||||
// zoom from mouse
|
||||
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
// disable scroll bars
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
|
||||
//
|
||||
setViewportUpdateMode(ViewportUpdateMode::FullViewportUpdate);
|
||||
}
|
||||
|
||||
void NetworkGraphicsView::mouseReleaseEvent(QMouseEvent *event) {
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
|
||||
// pass event to parent
|
||||
if (parentWidget()) {
|
||||
QMouseEvent *eventCopy = new QMouseEvent(
|
||||
event->type(),
|
||||
event->position(),
|
||||
event->scenePosition(),
|
||||
event->globalPosition(),
|
||||
event->button(),
|
||||
event->buttons(),
|
||||
event->modifiers()
|
||||
);
|
||||
QCoreApplication::postEvent(parentWidget(), eventCopy);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkGraphicsView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if(
|
||||
event->button() == Qt::MiddleButton
|
||||
)
|
||||
{
|
||||
panStartPos = event->pos();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
|
||||
// pass event to parent
|
||||
// if (parentWidget()) {
|
||||
// QMouseEvent *eventCopy = new QMouseEvent(
|
||||
// event->type(),
|
||||
// event->position(),
|
||||
// event->scenePosition(),
|
||||
// event->globalPosition(),
|
||||
// event->button(),
|
||||
// event->buttons(),
|
||||
// event->modifiers()
|
||||
// );
|
||||
// QCoreApplication::postEvent(parentWidget(), eventCopy);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// void NetworkView::mouseReleaseEvent(QMouseEvent *event)
|
||||
// {
|
||||
// if(
|
||||
// event->button() & Qt::MiddleButton
|
||||
// )
|
||||
// {
|
||||
// panStartPos = QPointF(0,0);
|
||||
// }
|
||||
// }
|
||||
|
||||
void NetworkGraphicsView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
network_->mouseMoved(event);
|
||||
|
||||
// pan view
|
||||
if( event->buttons() & Qt::MiddleButton)
|
||||
{
|
||||
QPointF pos = event->pos();
|
||||
QPointF delta = pos-panStartPos;
|
||||
|
||||
float speed = 1.0f;
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());
|
||||
panStartPos = event->pos();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void NetworkGraphicsView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
int delta = event->angleDelta().y();
|
||||
if(delta > 0)
|
||||
{
|
||||
scale(1.1, 1.1);
|
||||
}
|
||||
else if(delta < 0)
|
||||
{
|
||||
scale(0.9, 0.9);
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
29
src/Gui/Network/NetworkGraphicsView.h
Normal file
29
src/Gui/Network/NetworkGraphicsView.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qwidget.h>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
class Network;
|
||||
|
||||
class NetworkGraphicsView
|
||||
: public QGraphicsView
|
||||
{
|
||||
public:
|
||||
NetworkGraphicsView(QWidget *parent = nullptr, Network* network=nullptr, QGraphicsScene* scene = nullptr);
|
||||
QSize sizeHint() const override { return QSize(-1, -1); }
|
||||
private:
|
||||
QPointF panStartPos;
|
||||
void initUI();
|
||||
QGraphicsScene* scene_;
|
||||
Network* network_;
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *mouseEvent) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
QGraphicsItem* getItemAtClick(QMouseEvent *event);
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
// void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
};
|
||||
140
src/Gui/Network/NodeEdgeGraphic.cpp
Normal file
140
src/Gui/Network/NodeEdgeGraphic.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include "Gui/Network/NodeEdgeGraphic.h"
|
||||
#include <QTextDocument>
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include <iostream>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
|
||||
NodeEdgeGraphic::NodeEdgeGraphic(SocketGraphic* socket1, SocketGraphic* socket2, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), socket1_{socket1}, socket2_{socket2}, defaultColor_{QColor("white")}
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
setZValue(-1);
|
||||
color_=defaultColor_;
|
||||
defaultPen_=QPen(defaultColor_);
|
||||
defaultPen_.setCapStyle(Qt::RoundCap);
|
||||
|
||||
deleteHighlightPen_.setCapStyle(Qt::RoundCap);
|
||||
deleteHighlightPen_.setWidth(2);
|
||||
updateDeleteHighlightPen();
|
||||
|
||||
|
||||
socket1_->addEdge(this);
|
||||
socket2_->addEdge(this);
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::updateDeleteHighlightPen()
|
||||
{
|
||||
QLinearGradient gradient(pos1_, hoverPos_);
|
||||
gradient.setColorAt(0.0, QColor(255, 74, 74, 200));
|
||||
gradient.setColorAt(1, QColor(255, 74, 74, 50));
|
||||
// gradient.setColorAt(1.0, QColor(255, 74, 74, 200));
|
||||
|
||||
deleteHighlightPen_.setBrush(QBrush(gradient));
|
||||
}
|
||||
|
||||
NodeEdgeGraphic::~NodeEdgeGraphic()
|
||||
{
|
||||
std::cout << "edge destructor\n";
|
||||
cleanUp();
|
||||
std::cout << "destructor finished\n";
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
hoverPos_ = event->scenePos();
|
||||
if(deleteHighlight_)
|
||||
{
|
||||
updateDeleteHighlightPen();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::updatePath()
|
||||
{
|
||||
qreal cubicStrength = 40;
|
||||
path_.clear();
|
||||
path_.moveTo(pos1_);
|
||||
path_.cubicTo(pos1_-QPoint(0,cubicStrength), pos2_+QPoint(0,cubicStrength), pos2_);
|
||||
updateDeleteHighlightPen();
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::setPos(QPointF pos1, QPointF pos2)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
pos1_ = pos1;
|
||||
pos2_ = pos2;
|
||||
updatePath();
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::setDeleteHighlight(bool enable)
|
||||
{
|
||||
deleteHighlight_=enable;
|
||||
update();
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::setStartPos(QPointF pos)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
pos1_ = pos;
|
||||
updatePath();
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::setEndPos(QPointF pos)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
pos2_ = pos;
|
||||
updatePath();
|
||||
}
|
||||
|
||||
QRectF NodeEdgeGraphic::boundingRect() const
|
||||
{
|
||||
// std::cout << "bounds set" << socket1_->scenePos().x() << " " << socket1_->scenePos().y() << " " << socket2_->scenePos().x() << " " << socket2_->scenePos().y() << "\n";
|
||||
// QRectF boundRect_ = QRectF(socket1_->scenePos(), socket1_->scenePos()).normalized();
|
||||
QRectF boundRect_ = QRectF(pos1_, pos2_).normalized();
|
||||
boundRect_.adjust(-padding_,-padding_,padding_,padding_);
|
||||
return boundRect_;
|
||||
}
|
||||
|
||||
QPainterPath NodeEdgeGraphic::shape() const{
|
||||
QPainterPathStroker stroker;
|
||||
stroker.setWidth(padding_);
|
||||
return stroker.createStroke(path_);
|
||||
}
|
||||
|
||||
// void NodeEdgeGraphic::setColor(QColor color)
|
||||
// {
|
||||
// std::cout << "color set to: " << color.name().toStdString() << "\n";
|
||||
// color_ = color;
|
||||
// pen_.setColor(color_);
|
||||
// update();
|
||||
// }
|
||||
|
||||
// void NodeEdgeGraphic::useDefaultColor()
|
||||
// {
|
||||
// setColor(defaultColor_);
|
||||
// }
|
||||
|
||||
void NodeEdgeGraphic::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
// std::cout << "painting\n";
|
||||
painter->setPen(deleteHighlight_ ? deleteHighlightPen_ : defaultPen_);
|
||||
painter->drawPath(path_);
|
||||
|
||||
}
|
||||
|
||||
void NodeEdgeGraphic::cleanUp()
|
||||
{
|
||||
// these probably aren't necessary but i'm trying to fix a bug
|
||||
prepareGeometryChange();
|
||||
update();
|
||||
scene()->update();
|
||||
|
||||
scene()->removeItem(this);
|
||||
socket1_->removeEdge(this);
|
||||
socket2_->removeEdge(this);
|
||||
}
|
||||
46
src/Gui/Network/NodeEdgeGraphic.h
Normal file
46
src/Gui/Network/NodeEdgeGraphic.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <QGraphicsItem>
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
class NodeEdgeGraphic
|
||||
: public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
NodeEdgeGraphic(SocketGraphic* socket1, SocketGraphic* socket2, QGraphicsItem *parent = nullptr);
|
||||
~NodeEdgeGraphic();
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
QPainterPath shape() const override;
|
||||
// void setColor(QColor color);
|
||||
// void useDefaultColor();
|
||||
void updateDeleteHighlightPen();
|
||||
void setPos(QPointF pos1, QPointF pos2);
|
||||
void setStartPos(QPointF pos);
|
||||
void setEndPos(QPointF pos);
|
||||
void cleanUp();
|
||||
void setDeleteHighlight(bool enable);
|
||||
QPen deleteHighlightPen_;
|
||||
QPen defaultPen_;
|
||||
|
||||
bool deleteHighlight_=false;
|
||||
|
||||
private:
|
||||
SocketGraphic* socket1_;
|
||||
SocketGraphic* socket2_;
|
||||
QColor color_;
|
||||
QColor defaultColor_;
|
||||
QPointF pos1_;
|
||||
QPointF pos2_;
|
||||
QPainterPath path_;
|
||||
QRectF boundRect_;
|
||||
qreal padding_=40;
|
||||
QPointF hoverPos_;
|
||||
|
||||
void updatePath();
|
||||
protected:
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
};
|
||||
|
||||
249
src/Gui/Network/NodeGraphic.cpp
Normal file
249
src/Gui/Network/NodeGraphic.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
#include "Gui/Network/NodeGraphic.h"
|
||||
#include <QTextDocument>
|
||||
#include <iostream>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qnamespace.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "Engine/Network/NetworkManager.h"
|
||||
#include "Engine/Operator/GeometryOperator.h"
|
||||
#include "Engine/Types.h"
|
||||
#include "Gui/Network/DisplayFlagButton.h"
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QGraphicsSvgItem>
|
||||
#include "Gui/Network/NodeIconGraphic.h"
|
||||
|
||||
NodeGraphic::NodeGraphic(enzo::nt::OpId id, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), opId_{id}
|
||||
{
|
||||
socketSize_ = 3;
|
||||
titlePadding_=1;
|
||||
titleText_ = "Attr_Del_1";
|
||||
subTitleText_ = "Attribute Delete";
|
||||
constexpr int height = 27;
|
||||
constexpr int width = 100;
|
||||
bodyRect_ = QRect(-width*0.5f, -height*0.5f, width, height);
|
||||
iconScale_=height*0.55;
|
||||
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges);
|
||||
|
||||
initFonts();
|
||||
initIcon();
|
||||
initSockets();
|
||||
initFlagButtons();
|
||||
|
||||
}
|
||||
|
||||
void NodeGraphic::initFonts()
|
||||
{
|
||||
// declare fonts
|
||||
titleFont_ = QFont();
|
||||
titleFont_.setPixelSize(8);
|
||||
|
||||
subTitleFont_ = QFont();
|
||||
subTitleFont_.setPixelSize(5);
|
||||
|
||||
// compute text positions
|
||||
QRectF titleBounds = QFontMetricsF(titleFont_).boundingRect(titleText_.c_str());
|
||||
QRectF subTitleBounds = QFontMetricsF(subTitleFont_).boundingRect(subTitleText_.c_str());
|
||||
float titleOffsetX = (titleBounds.width()-bodyRect_.width()-iconScale_)*0.5f;
|
||||
float titleOffsetY = subTitleBounds.height()*0.5f+titlePadding_+(-(subTitleBounds.height()*0.5+titleBounds.height()+titlePadding_)+bodyRect_.height())*0.5f;
|
||||
// float titleOffsetY = (bodyRect_.height())*0.5f;
|
||||
// titleOffsetY -= subTitleBounds.height()*0.5f;
|
||||
float subTitleOffsetX = titleOffsetX;
|
||||
float subTitleOffsetY = (-(subTitleBounds.height()*0.5+titleBounds.height()+titlePadding_)+bodyRect_.height())*0.5f;
|
||||
|
||||
titleRect_ = bodyRect_.adjusted(-titleOffsetX, titleOffsetY, -titleOffsetX, titleOffsetY);
|
||||
subTitleRect_ = bodyRect_.adjusted(-subTitleOffsetX, subTitleOffsetY, -subTitleOffsetX, subTitleOffsetY);
|
||||
|
||||
}
|
||||
|
||||
void NodeGraphic::initIcon()
|
||||
{
|
||||
icon_ = new NodeIconGraphic(":/node-icons/grid.svg", this);
|
||||
// icon_ = new NodeIconGraphic("/home/parker/MyRepos/masters/static/icons/icon-main-white.svg", this);
|
||||
|
||||
icon_->setScale(1.0f/icon_->boundingRect().width()*iconScale_);
|
||||
// icon_->setScale(0.01);
|
||||
icon_->setPos(titleRect_.left()-iconScale_-iconPadding_, -iconScale_*0.5f);
|
||||
}
|
||||
|
||||
void NodeGraphic::initFlagButtons()
|
||||
{
|
||||
displayFlagButton_ = new DisplayFlagButton(this);
|
||||
float padding = 2;
|
||||
displayFlagButton_->setPos(QPointF(bodyRect_.right()-displayFlagButton_->getWidth()/2.0f-padding, bodyRect_.center().y()));
|
||||
}
|
||||
|
||||
void NodeGraphic::initSockets()
|
||||
{
|
||||
enzo::nt::GeometryOperator& op = enzo::nt::NetworkManager::getGeoOperator(opId_);
|
||||
for(int i=0, max=op.getMaxInputs(); i<max; ++i)
|
||||
{
|
||||
auto* socketInput = new SocketGraphic(enzo::nt::SocketIOType::Input, opId_, i, this);
|
||||
socketInput->setPos(getSocketPosition(i, enzo::nt::SocketIOType::Input));
|
||||
inputs_.push_back(socketInput);
|
||||
}
|
||||
|
||||
for(int i=0, max=op.getMaxOutputs(); i<max; ++i)
|
||||
{
|
||||
auto* socketOutput = new SocketGraphic(enzo::nt::SocketIOType::Output, opId_, i, this);
|
||||
socketOutput->setPos(getSocketPosition(i, enzo::nt::SocketIOType::Output));
|
||||
outputs_.push_back(socketOutput);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// void setInputEdge(NodeEdgeGraphic* edge, int indx)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// void setOutputEdge(NodeEdgeGraphic* edge, int indx)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// void NodeGraphic::addEdge(NodeEdgeGraphic* edge)
|
||||
// {
|
||||
// edges_.push_back(edge);
|
||||
// }
|
||||
|
||||
SocketGraphic* NodeGraphic::getInput(int indx) const
|
||||
{
|
||||
if(inputs_.size()==0)
|
||||
{
|
||||
throw std::out_of_range("Can't access inputs when node has no inputs: " + std::to_string(indx));
|
||||
}
|
||||
else if(indx>inputs_.size()-1)
|
||||
{
|
||||
throw std::out_of_range("Can't access input: " + std::to_string(indx));
|
||||
}
|
||||
return inputs_.at(indx);
|
||||
}
|
||||
SocketGraphic* NodeGraphic::getOutput(int indx) const
|
||||
{
|
||||
if(outputs_.size()==0)
|
||||
{
|
||||
throw std::out_of_range("Can't access outputs when node has no outputs: " + std::to_string(indx));
|
||||
}
|
||||
else if(indx>inputs_.size()-1)
|
||||
{
|
||||
throw std::out_of_range("Can't access input: " + std::to_string(indx));
|
||||
}
|
||||
return outputs_.at(indx);
|
||||
}
|
||||
|
||||
QRectF NodeGraphic::boundingRect() const
|
||||
{
|
||||
QRectF boundRect = bodyRect_;
|
||||
float padding = 0;
|
||||
boundRect.adjust(-padding, -padding, padding, padding);
|
||||
return boundRect;
|
||||
}
|
||||
|
||||
void NodeGraphic::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
// default outline
|
||||
QPen defaultPen = Qt::NoPen;
|
||||
defaultPen.setWidth(1);
|
||||
// outline when selected
|
||||
QPen selectedPen = QPen("#edd044");
|
||||
// choose outline
|
||||
if(isSelected()) painter->setPen(selectedPen);
|
||||
else painter->setPen(defaultPen);
|
||||
|
||||
// set fill
|
||||
QBrush whiteBrush = QBrush("white");
|
||||
painter->setBrush(QBrush(QColor("#1b1b1b")));
|
||||
|
||||
painter->drawRoundedRect(bodyRect_, 5, 5);
|
||||
|
||||
painter->setPen(QPen(QColor("white")));
|
||||
|
||||
painter->setFont(titleFont_);
|
||||
// painter->setPen(QPen(QColor("#d2d2d2")));
|
||||
painter->setPen(QPen(QColor("white")));
|
||||
|
||||
painter->drawText(titleRect_, Qt::AlignLeft, titleText_.c_str());
|
||||
|
||||
painter->setFont(subTitleFont_);
|
||||
painter->drawText(subTitleRect_, Qt::AlignLeft, subTitleText_.c_str());
|
||||
|
||||
|
||||
}
|
||||
|
||||
// void NodeGraphic::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
// {
|
||||
// QGraphicsItem::mouseMoveEvent(event);
|
||||
// updatePositions(event->scenePos());
|
||||
// }
|
||||
|
||||
// void NodeGraphic::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
// {
|
||||
// updatePositions(event->scenePos());
|
||||
// QGraphicsItem::mouseReleaseEvent(event);
|
||||
// }
|
||||
|
||||
void NodeGraphic::updatePositions()
|
||||
{
|
||||
for(int socketIndex=0; socketIndex<inputs_.size(); ++socketIndex)
|
||||
{
|
||||
inputs_[socketIndex]->posChanged(getSocketScenePosition(socketIndex, enzo::nt::SocketIOType::Input));
|
||||
}
|
||||
for(int socketIndex=0; socketIndex<outputs_.size(); ++socketIndex)
|
||||
{
|
||||
outputs_[socketIndex]->posChanged(getSocketScenePosition(socketIndex, enzo::nt::SocketIOType::Output));
|
||||
}
|
||||
}
|
||||
|
||||
QPointF NodeGraphic::getSocketPosition(int socketIndex, enzo::nt::SocketIOType socketType)
|
||||
{
|
||||
enzo::nt::GeometryOperator& op = enzo::nt::NetworkManager::getGeoOperator(opId_);
|
||||
int maxSocketNumber = socketType==enzo::nt::SocketIOType::Input ? op.getMaxInputs() : op.getMaxOutputs();
|
||||
float socketSpread = socketSize_*1.5*maxSocketNumber;
|
||||
|
||||
float xPos, yPos;
|
||||
xPos = bodyRect_.center().x();
|
||||
yPos = socketType == enzo::nt::SocketIOType::Input ? bodyRect_.top() : bodyRect_.bottom();
|
||||
|
||||
xPos += ((socketIndex/static_cast<float>(maxSocketNumber-1))-0.5)*2*socketSpread;
|
||||
|
||||
return QPointF(xPos, yPos);
|
||||
}
|
||||
QPointF NodeGraphic::getSocketScenePosition(int socketIndex, enzo::nt::SocketIOType socketType)
|
||||
{
|
||||
return this->pos()+getSocketPosition(socketIndex, socketType);
|
||||
}
|
||||
|
||||
enzo::nt::OpId NodeGraphic::getOpId() const
|
||||
{
|
||||
return opId_;
|
||||
}
|
||||
|
||||
void NodeGraphic::setDisplayFlag(bool state)
|
||||
{
|
||||
displayFlagButton_->setEnabled(state);
|
||||
}
|
||||
|
||||
|
||||
QRectF NodeGraphic::getBodyRect()
|
||||
{
|
||||
return bodyRect_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QVariant NodeGraphic::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
QVariant returnVal = QGraphicsItem::itemChange(change, value);
|
||||
|
||||
if (change == ItemPositionHasChanged) {
|
||||
updatePositions();
|
||||
};
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
76
src/Gui/Network/NodeGraphic.h
Normal file
76
src/Gui/Network/NodeGraphic.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
#include "Engine/Types.h"
|
||||
#include "Gui/Network/DisplayFlagButton.h"
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include "Gui/Network/NodeIconGraphic.h"
|
||||
#include "Gui/Network/NodeEdgeGraphic.h"
|
||||
#include <iostream>
|
||||
|
||||
class NodeGraphic
|
||||
: public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
NodeGraphic(enzo::nt::OpId id, QGraphicsItem *parent = nullptr);
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
SocketGraphic* getInput(int indx) const;
|
||||
SocketGraphic* getOutput(int indx) const;
|
||||
enzo::nt::OpId getOpId() const;
|
||||
QPointF getSocketPosition(int socketIndex, enzo::nt::SocketIOType socketType);
|
||||
QPointF getSocketScenePosition(int socketIndex, enzo::nt::SocketIOType socketType);
|
||||
QRectF getBodyRect();
|
||||
void setDisplayFlag(bool state);
|
||||
|
||||
// void addEdge(NodeEdgeGraphic* edge);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
// void setInputEdge(NodeEdgeGraphic* edge, int indx);
|
||||
// void setOutputEdge(NodeEdgeGraphic* edge, int indx);
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
void initSockets();
|
||||
void initFlagButtons();
|
||||
void initIcon();
|
||||
void initFonts();
|
||||
|
||||
enzo::nt::OpId opId_;
|
||||
std::vector<SocketGraphic*> inputs_;
|
||||
std::vector<SocketGraphic*> outputs_;
|
||||
|
||||
// std::vector<NodeEdgeGraphic*> edges_;
|
||||
|
||||
std::string titleText_="";
|
||||
std::string subTitleText_="";
|
||||
int maxTitleLen_=10;
|
||||
QRectF bodyRect_;
|
||||
int socketSize_ = 1;
|
||||
int inputSocketCnt_=0;
|
||||
int outputSocketCnt_=0;
|
||||
NodeIconGraphic* icon_;
|
||||
int iconScale_;
|
||||
float iconPadding_ = 5;
|
||||
QGraphicsItem* test_;
|
||||
|
||||
QFont titleFont_;
|
||||
QFont subTitleFont_;
|
||||
int titlePadding_;
|
||||
|
||||
QRectF titleRect_;
|
||||
QRectF subTitleRect_;
|
||||
|
||||
DisplayFlagButton* displayFlagButton_;
|
||||
|
||||
void updatePositions();
|
||||
protected:
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||
// void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
// void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
};
|
||||
|
||||
17
src/Gui/Network/NodeIconGraphic.cpp
Normal file
17
src/Gui/Network/NodeIconGraphic.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "Gui/Network/NodeIconGraphic.h"
|
||||
#include <qgraphicssvgitem.h>
|
||||
#include <QBrush>
|
||||
#include <QPainter>
|
||||
|
||||
NodeIconGraphic::NodeIconGraphic(const QString &fileName, QGraphicsItem *parent)
|
||||
: QGraphicsSvgItem(fileName, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// void NodeIconGraphic::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
// {
|
||||
//
|
||||
// this->setProperty("color", QColor("red"));
|
||||
// QGraphicsSvgItem::paint(painter, option, widget);
|
||||
// }
|
||||
12
src/Gui/Network/NodeIconGraphic.h
Normal file
12
src/Gui/Network/NodeIconGraphic.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <QGraphicsSvgItem>
|
||||
|
||||
class NodeIconGraphic
|
||||
: public QGraphicsSvgItem
|
||||
{
|
||||
public:
|
||||
NodeIconGraphic(const QString &fileName, QGraphicsItem *parent = nullptr);
|
||||
protected:
|
||||
// void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||
|
||||
};
|
||||
116
src/Gui/Network/SocketGraphic.cpp
Normal file
116
src/Gui/Network/SocketGraphic.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "Gui/Network/SocketGraphic.h"
|
||||
#include <QTextDocument>
|
||||
#include <iostream>
|
||||
#include <qgraphicsitem.h>
|
||||
#include "Gui/Network/NodeEdgeGraphic.h"
|
||||
|
||||
SocketGraphic::SocketGraphic(enzo::nt::SocketIOType type, enzo::nt::OpId opId, unsigned int socketIndex, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), type_{type}, opId_{opId}, socketIndex_{socketIndex}
|
||||
{
|
||||
brushActive_ = QBrush("white");
|
||||
brushInactive_ = QBrush("#9f9f9f");
|
||||
socketSize_ = 3;
|
||||
setAcceptHoverEvents(true);
|
||||
initBoundingBox();
|
||||
}
|
||||
|
||||
unsigned int SocketGraphic::getIndex() const
|
||||
{
|
||||
return socketIndex_;
|
||||
}
|
||||
|
||||
|
||||
void SocketGraphic::addEdge(NodeEdgeGraphic* edge)
|
||||
{
|
||||
std::cout << "adding edge\n";
|
||||
edges_.insert(edge);
|
||||
}
|
||||
|
||||
void SocketGraphic::removeEdge(NodeEdgeGraphic* edge)
|
||||
{
|
||||
std::cout << "removing edge\n";
|
||||
std::cout << "before size: " << edges_.size() << "\n";
|
||||
edges_.erase(edge);
|
||||
std::cout << "after size: " << edges_.size() << "\n";
|
||||
// auto it = find(edges_.begin(), edges_.end(), edge);
|
||||
// if(it!=edges_.end())
|
||||
// {
|
||||
// edges_.erase(it);
|
||||
// }
|
||||
}
|
||||
|
||||
void SocketGraphic::initBoundingBox()
|
||||
{
|
||||
boundRect_ = QRect(
|
||||
-socketSize_/2.0f*paddingScale_,
|
||||
-socketSize_/2.0f*paddingScale_,
|
||||
socketSize_*paddingScale_,
|
||||
socketSize_*paddingScale_
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void SocketGraphic::posChanged(QPointF pos)
|
||||
{
|
||||
for(auto* edge : edges_)
|
||||
{
|
||||
// edge->setPos(startSocket_->scenePos(), socket->scenePos());
|
||||
if(type_==enzo::nt::SocketIOType::Input)
|
||||
{
|
||||
edge->setStartPos(pos);
|
||||
}
|
||||
else if(type_==enzo::nt::SocketIOType::Output)
|
||||
{
|
||||
edge->setEndPos(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enzo::nt::OpId SocketGraphic::getOpId() const
|
||||
{
|
||||
return opId_;
|
||||
}
|
||||
|
||||
QRectF SocketGraphic::boundingRect() const
|
||||
{
|
||||
return boundRect_;
|
||||
}
|
||||
|
||||
QPainterPath SocketGraphic::shape() const{
|
||||
QPainterPath path;
|
||||
QPointF startPt(boundRect_.center().x(), type_==enzo::nt::SocketIOType::Input ? boundRect_.top() : boundRect_.bottom());
|
||||
path.moveTo(startPt);
|
||||
path.arcTo(boundRect_, 0, type_==enzo::nt::SocketIOType::Input ? 180 : -180);
|
||||
path.lineTo(boundRect_.right(), boundRect_.center().y());
|
||||
path.closeSubpath();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
enzo::nt::SocketIOType SocketGraphic::getIO() { return type_; }
|
||||
|
||||
|
||||
void SocketGraphic::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(hovered_ ? brushActive_ : brushInactive_);
|
||||
painter->drawEllipse(QPoint(0,0), socketSize_, socketSize_);
|
||||
|
||||
// painter->drawRect(boundRect_);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SocketGraphic::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
hovered_ = true;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void SocketGraphic::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
hovered_ = false;
|
||||
update();
|
||||
}
|
||||
46
src/Gui/Network/SocketGraphic.h
Normal file
46
src/Gui/Network/SocketGraphic.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include "Engine/Types.h"
|
||||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
class NodeEdgeGraphic;
|
||||
|
||||
class SocketGraphic
|
||||
: public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
|
||||
SocketGraphic(enzo::nt::SocketIOType type, enzo::nt::OpId opId, unsigned int socketIndex, QGraphicsItem *parent = nullptr);
|
||||
enzo::nt::SocketIOType getIO();
|
||||
void addEdge(NodeEdgeGraphic* edge);
|
||||
void removeEdge(NodeEdgeGraphic* edge);
|
||||
void posChanged(QPointF pos);
|
||||
QPainterPath shape() const override;
|
||||
enzo::nt::OpId getOpId() const;
|
||||
|
||||
unsigned int getIndex() const;
|
||||
|
||||
private:
|
||||
int socketSize_ = 1;
|
||||
unsigned int socketIndex_;
|
||||
QBrush brushInactive_;
|
||||
QBrush brushActive_;
|
||||
bool hovered_=false;
|
||||
enzo::nt::SocketIOType type_;
|
||||
std::unordered_set<NodeEdgeGraphic*> edges_;
|
||||
qreal paddingScale_=20;
|
||||
QRectF boundRect_;
|
||||
enzo::nt::OpId opId_;
|
||||
|
||||
void initBoundingBox();
|
||||
protected:
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user