From 2c29725dc80511d3a4787dcdb658859e196d83b0 Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Mon, 7 Mar 2022 14:42:47 -0600 Subject: [PATCH 01/17] csi cmake changes --- CMakeLists.txt | 57 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed54c86a7..245450b55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,29 +71,34 @@ endif() # We'll have to manually specify some files set(CMAKE_AUTOMOC ON) -set(CPP_SOURCE_FILES - src/Connection.cpp - src/ConnectionBlurEffect.cpp - src/ConnectionGeometry.cpp - src/ConnectionGraphicsObject.cpp - src/ConnectionPainter.cpp - src/ConnectionState.cpp - src/ConnectionStyle.cpp - src/DataModelRegistry.cpp - src/FlowScene.cpp - src/FlowView.cpp - src/FlowViewStyle.cpp - src/Node.cpp - src/NodeConnectionInteraction.cpp - src/NodeDataModel.cpp - src/NodeGeometry.cpp - src/NodeGraphicsObject.cpp - src/NodePainter.cpp - src/NodeState.cpp - src/NodeStyle.cpp - src/Properties.cpp - src/StyleCollection.cpp -) +file(GLOB_RECURSE CPP_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/nodes/internal/*.hpp) + +# qt5_wrap_cpp(qan_source_files, qan_header_files) + +# set(CPP_SOURCE_FILES +# src/Connection.cpp +# src/ConnectionBlurEffect.cpp +# src/ConnectionGeometry.cpp +# src/ConnectionGraphicsObject.cpp +# src/ConnectionPainter.cpp +# src/ConnectionState.cpp +# src/ConnectionStyle.cpp +# src/DataModelRegistry.cpp +# src/FlowScene.cpp +# src/FlowView.cpp +# src/FlowViewStyle.cpp +# src/Node.cpp +# src/NodeConnectionInteraction.cpp +# src/NodeDataModel.cpp +# src/NodeGeometry.cpp +# src/NodeGraphicsObject.cpp +# src/NodePainter.cpp +# src/NodeState.cpp +# src/NodeStyle.cpp +# src/Properties.cpp +# src/StyleCollection.cpp +# ) set(HPP_HEADER_FILES include/nodes/internal/Compiler.hpp @@ -129,6 +134,7 @@ set(HPP_HEADER_FILES # If we want to give the option to build a static library, # set BUILD_SHARED_LIBS option to OFF add_library(nodes + STATIC ${CPP_SOURCE_FILES} ${HPP_HEADER_FILES} ${RESOURCES} @@ -154,9 +160,10 @@ target_link_libraries(nodes target_compile_definitions(nodes PUBLIC - NODE_EDITOR_SHARED + NODE_EDITOR_STATIC + # NODE_EDITOR_SHARED PRIVATE - NODE_EDITOR_EXPORTS + # NODE_EDITOR_EXPORTS #NODE_DEBUG_DRAWING QT_NO_KEYWORDS ) From 6afbd5b1325a815681931172ad770632aa9977e5 Mon Sep 17 00:00:00 2001 From: Scott Selland Date: Thu, 21 Apr 2022 10:39:57 -0500 Subject: [PATCH 02/17] internal library changes QtNodeEditor --- .../internal/ConnectionGraphicsObject.hpp | 3 +++ include/nodes/internal/FlowScene.hpp | 6 ++++- include/nodes/internal/FlowView.hpp | 7 ++++-- include/nodes/internal/NodeDataModel.hpp | 16 ++++++++++-- src/ConnectionGraphicsObject.cpp | 7 ++++++ src/ConnectionPainter.cpp | 9 ++++--- src/FlowView.cpp | 4 +++ src/NodePainter.cpp | 25 ++++++++++++++++--- 8 files changed, 65 insertions(+), 12 deletions(-) diff --git a/include/nodes/internal/ConnectionGraphicsObject.hpp b/include/nodes/internal/ConnectionGraphicsObject.hpp index 7db498e48..ebed8681e 100644 --- a/include/nodes/internal/ConnectionGraphicsObject.hpp +++ b/include/nodes/internal/ConnectionGraphicsObject.hpp @@ -75,6 +75,9 @@ class ConnectionGraphicsObject void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override; + void + mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event); + private: void diff --git a/include/nodes/internal/FlowScene.hpp b/include/nodes/internal/FlowScene.hpp index 9303c442a..8dd656e49 100644 --- a/include/nodes/internal/FlowScene.hpp +++ b/include/nodes/internal/FlowScene.hpp @@ -102,6 +102,8 @@ class NODE_EDITOR_PUBLIC FlowScene Q_SIGNALS: + void nodePlacedNow(QtNodes::Node&n); + /** * @brief Node has been created but not on the scene yet. * @see nodePlaced() @@ -122,7 +124,7 @@ class NODE_EDITOR_PUBLIC FlowScene void nodeMoved(Node& n, const QPointF& newLocation); - void nodeDoubleClicked(Node& n); + void nodeDoubleClicked(QtNodes::Node& n); void nodeClicked(Node& n); @@ -132,6 +134,8 @@ class NODE_EDITOR_PUBLIC FlowScene void connectionHoverLeft(Connection& c); + void connectionDoubleClicked(QtNodes::Connection& c); + void nodeHoverLeft(Node& n); void nodeContextMenu(Node& n, const QPointF& pos); diff --git a/include/nodes/internal/FlowView.hpp b/include/nodes/internal/FlowView.hpp index 473af4d15..20f198e9c 100644 --- a/include/nodes/internal/FlowView.hpp +++ b/include/nodes/internal/FlowView.hpp @@ -27,6 +27,10 @@ class NODE_EDITOR_PUBLIC FlowView void setScene(FlowScene *scene); + void setBackgroundColor(QColor color) {_backgroundColor = color; } + + QPointF _clickPos; + public Q_SLOTS: void scaleUp(); @@ -62,8 +66,7 @@ public Q_SLOTS: QAction* _clearSelectionAction; QAction* _deleteSelectionAction; - QPointF _clickPos; - FlowScene* _scene; + QColor _backgroundColor; }; } diff --git a/include/nodes/internal/NodeDataModel.hpp b/include/nodes/internal/NodeDataModel.hpp index 57428dba5..e80c0739e 100644 --- a/include/nodes/internal/NodeDataModel.hpp +++ b/include/nodes/internal/NodeDataModel.hpp @@ -28,6 +28,8 @@ class Connection; class StyleCollection; +enum { NT_UNKNOWN = -1, NT_EXT_INLET = 0, NT_WSR = 1, NT_PFR = 2 }; + class NODE_EDITOR_PUBLIC NodeDataModel : public QObject , public Serializable @@ -45,6 +47,10 @@ class NODE_EDITOR_PUBLIC NodeDataModel virtual QString caption() const = 0; + //Can add parameter std::string requestedInfo which we can set to be "inlet_temperature", "reactor_type", "volume", etc.. + //this way if we need to show more info about the node we can just call this overridden method with what we need + virtual QString extraInfo(int reactorType) { return ""; } + /// It is possible to hide caption in GUI virtual bool captionVisible() const { return true; } @@ -61,6 +67,9 @@ class NODE_EDITOR_PUBLIC NodeDataModel virtual QString name() const = 0; + virtual int + nodeType() const { return NT_UNKNOWN; } + public: QJsonObject @@ -74,8 +83,7 @@ class NODE_EDITOR_PUBLIC NodeDataModel virtual NodeDataType dataType(PortType portType, PortIndex portIndex) const = 0; -public: - +public: enum class ConnectionPolicy { One, @@ -154,6 +162,9 @@ class NODE_EDITOR_PUBLIC NodeDataModel virtual NodePainterDelegate* painterDelegate() const { return nullptr; } + virtual + bool dataEdited() { return edited; } + public Q_SLOTS: virtual void @@ -197,5 +208,6 @@ public Q_SLOTS: private: NodeStyle _nodeStyle; + bool edited = false; }; } diff --git a/src/ConnectionGraphicsObject.cpp b/src/ConnectionGraphicsObject.cpp index 8fff26459..0b8ebbaf8 100644 --- a/src/ConnectionGraphicsObject.cpp +++ b/src/ConnectionGraphicsObject.cpp @@ -244,6 +244,13 @@ hoverLeaveEvent(QGraphicsSceneHoverEvent* event) event->accept(); } +void +ConnectionGraphicsObject:: +mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + QGraphicsItem::mouseDoubleClickEvent(event); + _scene.connectionDoubleClicked(connection()); +} void ConnectionGraphicsObject:: diff --git a/src/ConnectionPainter.cpp b/src/ConnectionPainter.cpp index c6da391be..3383465f5 100644 --- a/src/ConnectionPainter.cpp +++ b/src/ConnectionPainter.cpp @@ -307,7 +307,10 @@ paint(QPainter* painter, painter->setPen(connectionStyle.constructionColor()); painter->setBrush(connectionStyle.constructionColor()); - double const pointRadius = pointDiameter / 2.0; - painter->drawEllipse(source, pointRadius, pointRadius); - painter->drawEllipse(sink, pointRadius, pointRadius); + QLineF arrow1(sink.x(), sink.y(), sink.x()-15, sink.y()-10); + QLineF arrow2(sink.x(), sink.y(), sink.x()-15, sink.y()+10); + painter->setPen(QPen(Qt::white, 4)); + painter->drawLine(arrow1); + painter->drawLine(arrow2); + } diff --git a/src/FlowView.cpp b/src/FlowView.cpp index d7f768361..2b057fe24 100644 --- a/src/FlowView.cpp +++ b/src/FlowView.cpp @@ -49,6 +49,8 @@ FlowView(QWidget *parent) setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); //setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + + _backgroundColor = QColor::black(); } @@ -172,6 +174,7 @@ contextMenuEvent(QContextMenuEvent *event) node.nodeGraphicsObject().setPos(posView); _scene->nodePlaced(node); + _scene->nodePlacedNow(node); } else { @@ -344,6 +347,7 @@ void FlowView:: drawBackground(QPainter* painter, const QRectF& r) { + painter->setBrush(_backgroundColor); QGraphicsView::drawBackground(painter, r); auto drawGrid = diff --git a/src/NodePainter.cpp b/src/NodePainter.cpp index aa96d15a6..4881880a7 100644 --- a/src/NodePainter.cpp +++ b/src/NodePainter.cpp @@ -40,9 +40,9 @@ paint(QPainter* painter, drawNodeRect(painter, geom, model, graphicsObject); - drawConnectionPoints(painter, geom, state, model, scene); + //drawConnectionPoints(painter, geom, state, model, scene); - drawFilledConnectionPoints(painter, geom, state, model); + //drawFilledConnectionPoints(painter, geom, state, model); drawModelName(painter, geom, state, model); @@ -100,7 +100,17 @@ drawNodeRect(QPainter* painter, double const radius = 3.0; - painter->drawRoundedRect(boundary, radius, radius); + if(model->nodeType() == NT_WSR) { + painter->drawRoundedRect(boundary, radius, radius); + } + else if(model->nodeType() == NT_PFR) { + painter->setBrush(Qt::darkCyan); + painter->drawRoundedRect(boundary, radius, radius); + } + else { + painter->setBrush(Qt::yellow); + painter->drawEllipse(boundary); + } } @@ -264,7 +274,14 @@ drawModelName(QPainter * painter, painter->setFont(f); painter->setPen(nodeStyle.FontColor); - painter->drawText(position, name); + if(model->nodeType() != NT_EXT_INLET) { + painter->drawText(position, name); + } + else { + QPointF position2(geom.width() / 2.0 - 50, geom.height() / 2.0); + painter->drawText(position2, name); + } + f.setBold(false); painter->setFont(f); From f3ca470de7f08106d30629f612bed7d4e105ffe6 Mon Sep 17 00:00:00 2001 From: Scott Selland Date: Thu, 28 Apr 2022 13:04:21 -0500 Subject: [PATCH 03/17] fixing call to change background color --- src/FlowView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FlowView.cpp b/src/FlowView.cpp index 2b057fe24..242a8fc82 100644 --- a/src/FlowView.cpp +++ b/src/FlowView.cpp @@ -50,7 +50,7 @@ FlowView(QWidget *parent) //setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); - _backgroundColor = QColor::black(); + _backgroundColor = Qt::black; } From 2e6f7c83593ba3b5427939e58bcb0b661049d64f Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Thu, 28 Apr 2022 13:34:39 -0500 Subject: [PATCH 04/17] attempt to fix CI pipeline --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 245450b55..7eb5c6ec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ endif() # Unfortunately, as we have a split include/src, AUTOMOC doesn't work. # We'll have to manually specify some files -set(CMAKE_AUTOMOC ON) +# set(CMAKE_AUTOMOC ON) file(GLOB_RECURSE CPP_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/nodes/internal/*.hpp) From 7cd27bb7b2c9554058689cb8c49ec346c752a97b Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Thu, 28 Apr 2022 13:41:16 -0500 Subject: [PATCH 05/17] revert --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7eb5c6ec2..245450b55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ endif() # Unfortunately, as we have a split include/src, AUTOMOC doesn't work. # We'll have to manually specify some files -# set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOMOC ON) file(GLOB_RECURSE CPP_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/nodes/internal/*.hpp) From b638efc18235804beb761fda0cbd45fec5da6df3 Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Thu, 28 Apr 2022 14:11:33 -0500 Subject: [PATCH 06/17] fix CI --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 245450b55..aa2aabd5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ set(CMAKE_AUTOMOC ON) file(GLOB_RECURSE CPP_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/nodes/internal/*.hpp) +file(GLOB_RECURSE RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resources/*.qrc) # qt5_wrap_cpp(qan_source_files, qan_header_files) # set(CPP_SOURCE_FILES From 43f1edc7c5e9a279b56ebcc541611f3956d42773 Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Thu, 28 Apr 2022 14:24:42 -0500 Subject: [PATCH 07/17] revert --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa2aabd5f..245450b55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,6 @@ set(CMAKE_AUTOMOC ON) file(GLOB_RECURSE CPP_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/nodes/internal/*.hpp) -file(GLOB_RECURSE RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resources/*.qrc) # qt5_wrap_cpp(qan_source_files, qan_header_files) # set(CPP_SOURCE_FILES From cf01e2628f96d3e711940d602229aec6b1b9d0ff Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Thu, 28 Apr 2022 14:31:14 -0500 Subject: [PATCH 08/17] fix CI --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 245450b55..fc00ce5fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ set(NE_DEVELOPER_DEFAULTS "${is_root_project}" CACHE BOOL "Turns on default sett option(BUILD_TESTING "Build tests" "${NE_DEVELOPER_DEFAULTS}") option(BUILD_EXAMPLES "Build Examples" "${NE_DEVELOPER_DEFAULTS}") -option(BUILD_SHARED_LIBS "Build as shared library" ON) +option(BUILD_SHARED_LIBS "Build as shared library" OF) option(BUILD_DEBUG_POSTFIX_D "Append d suffix to debug libraries" OFF) option(NE_FORCE_TEST_COLOR "Force colorized unit test output" OFF) From 606715388542061471828fb5544d02b793e4722a Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Mon, 2 May 2022 15:01:21 -0500 Subject: [PATCH 09/17] set off by default --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc00ce5fb..65c4e819a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,11 +13,11 @@ else() set(is_root_project ON) endif() -set(NE_DEVELOPER_DEFAULTS "${is_root_project}" CACHE BOOL "Turns on default settings for development of NodeEditor") +set(NE_DEVELOPER_DEFAULTS "${is_root_project}" CACHE BOOL OFF "Turns on default settings for development of NodeEditor") option(BUILD_TESTING "Build tests" "${NE_DEVELOPER_DEFAULTS}") option(BUILD_EXAMPLES "Build Examples" "${NE_DEVELOPER_DEFAULTS}") -option(BUILD_SHARED_LIBS "Build as shared library" OF) +option(BUILD_SHARED_LIBS "Build as shared library" OFF) option(BUILD_DEBUG_POSTFIX_D "Append d suffix to debug libraries" OFF) option(NE_FORCE_TEST_COLOR "Force colorized unit test output" OFF) From 25e3ee43410242ea83021dc0ebb34383e09e3785 Mon Sep 17 00:00:00 2001 From: Paul Gruenbacher Date: Mon, 2 May 2022 15:07:56 -0500 Subject: [PATCH 10/17] outright disable testing/examples --- CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65c4e819a..c3f118106 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,17 +219,17 @@ target_sources(nodes PRIVATE ${nodes_moc}) # Examples ## -if(BUILD_EXAMPLES) - add_subdirectory(examples) -endif() +# if(BUILD_EXAMPLES) +# add_subdirectory(examples) +# endif() ################## # Automated Tests ## -if(BUILD_TESTING) - add_subdirectory(test) -endif() +# if(BUILD_TESTING) +# add_subdirectory(test) +# endif() ############### # Installation From 9e61936f70659023ef6a2e370861fbbcf7a57e78 Mon Sep 17 00:00:00 2001 From: Scott Selland Date: Thu, 16 Jun 2022 15:48:41 -0500 Subject: [PATCH 11/17] updating background color, style of connections/nodes & icons --- include/nodes/internal/FlowScene.hpp | 1 + src/ConnectionPainter.cpp | 15 +++++++++------ src/FlowScene.cpp | 1 + src/FlowView.cpp | 6 +++--- src/NodeGeometry.cpp | 8 ++++---- src/NodePainter.cpp | 23 +++++++++++++++-------- 6 files changed, 33 insertions(+), 21 deletions(-) diff --git a/include/nodes/internal/FlowScene.hpp b/include/nodes/internal/FlowScene.hpp index 8dd656e49..104a10990 100644 --- a/include/nodes/internal/FlowScene.hpp +++ b/include/nodes/internal/FlowScene.hpp @@ -121,6 +121,7 @@ class NODE_EDITOR_PUBLIC FlowScene void connectionCreated(Connection const &c); void connectionDeleted(Connection const &c); + void connectionDrawn(const QtNodes::Connection &c); void nodeMoved(Node& n, const QPointF& newLocation); diff --git a/src/ConnectionPainter.cpp b/src/ConnectionPainter.cpp index 3383465f5..f75170dbd 100644 --- a/src/ConnectionPainter.cpp +++ b/src/ConnectionPainter.cpp @@ -117,7 +117,7 @@ drawSketchLine(QPainter * painter, p.setColor(connectionStyle.constructionColor()); p.setStyle(Qt::DashLine); - painter->setPen(p); + painter->setPen(Qt::black); painter->setBrush(Qt::NoBrush); using QtNodes::ConnectionGeometry; @@ -271,7 +271,7 @@ drawNormalLine(QPainter * painter, p.setColor(selectedColor); } - painter->setPen(p); + painter->setPen(Qt::black); painter->setBrush(Qt::NoBrush); painter->drawPath(cubic); @@ -284,6 +284,9 @@ ConnectionPainter:: paint(QPainter* painter, Connection const &connection) { + painter->setPen(Qt::black); + painter->setBrush(Qt::black); + drawHoveredOrSelected(painter, connection); drawSketchLine(painter, connection); @@ -304,12 +307,12 @@ paint(QPainter* painter, QtNodes::StyleCollection::connectionStyle(); double const pointDiameter = connectionStyle.pointDiameter(); - - painter->setPen(connectionStyle.constructionColor()); - painter->setBrush(connectionStyle.constructionColor()); + painter->setBrush(Qt::black); + //painter->setPen(connectionStyle.constructionColor()); + //painter->setBrush(connectionStyle.constructionColor()); QLineF arrow1(sink.x(), sink.y(), sink.x()-15, sink.y()-10); QLineF arrow2(sink.x(), sink.y(), sink.x()-15, sink.y()+10); - painter->setPen(QPen(Qt::white, 4)); + painter->setPen(QPen(Qt::black, 4)); painter->drawLine(arrow1); painter->drawLine(arrow2); diff --git a/src/FlowScene.cpp b/src/FlowScene.cpp index dd4306df1..f1dea5b5f 100644 --- a/src/FlowScene.cpp +++ b/src/FlowScene.cpp @@ -91,6 +91,7 @@ createConnection(PortType connectedPort, this, [this](Connection const& c) { connectionCreated(c); + connectionDrawn(c); }); return connection; diff --git a/src/FlowView.cpp b/src/FlowView.cpp index 242a8fc82..b4dfba9a3 100644 --- a/src/FlowView.cpp +++ b/src/FlowView.cpp @@ -38,7 +38,7 @@ FlowView(QWidget *parent) auto const &flowViewStyle = StyleCollection::flowViewStyle(); - setBackgroundBrush(flowViewStyle.BackgroundColor); + setBackgroundBrush(Qt::white); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -387,12 +387,12 @@ drawBackground(QPainter* painter, const QRectF& r) QPen pfine(flowViewStyle.FineGridColor, 1.0); painter->setPen(pfine); - drawGrid(15); + //drawGrid(15); QPen p(flowViewStyle.CoarseGridColor, 1.0); painter->setPen(p); - drawGrid(150); + //drawGrid(150); } diff --git a/src/NodeGeometry.cpp b/src/NodeGeometry.cpp index 91d90dc66..c8d69309e 100644 --- a/src/NodeGeometry.cpp +++ b/src/NodeGeometry.cpp @@ -281,9 +281,9 @@ captionHeight() const if (!_dataModel->captionVisible()) return 0; - QString name = _dataModel->caption(); + //QString name = _dataModel->caption(); - return _boldFontMetrics.boundingRect(name).height(); + return 20;//_boldFontMetrics.boundingRect(name).height(); } @@ -294,9 +294,9 @@ captionWidth() const if (!_dataModel->captionVisible()) return 0; - QString name = _dataModel->caption(); + //QString name = _dataModel->caption(); - return _boldFontMetrics.boundingRect(name).width(); + return 175;//_boldFontMetrics.boundingRect(name).width(); } diff --git a/src/NodePainter.cpp b/src/NodePainter.cpp index 4881880a7..a6dc817ba 100644 --- a/src/NodePainter.cpp +++ b/src/NodePainter.cpp @@ -96,20 +96,21 @@ drawNodeRect(QPainter* painter, float diam = nodeStyle.ConnectionPointDiameter; - QRectF boundary( -diam, -diam, 2.0 * diam + geom.width(), 2.0 * diam + geom.height()); + QRect boundary( -diam, -diam, geom.width(), geom.height()); double const radius = 3.0; if(model->nodeType() == NT_WSR) { - painter->drawRoundedRect(boundary, radius, radius); + QPixmap wsrNode(":/images/plugFlowReactor.png"); + painter->drawPixmap(boundary, wsrNode); } else if(model->nodeType() == NT_PFR) { - painter->setBrush(Qt::darkCyan); - painter->drawRoundedRect(boundary, radius, radius); + QPixmap pfrNode(":/images/7_general-flow-a.svg"); + painter->drawPixmap(boundary, pfrNode); } else { - painter->setBrush(Qt::yellow); - painter->drawEllipse(boundary); + QPixmap inletNode(":/images/2_gas-turbines-d.svg"); + painter->drawPixmap(boundary, inletNode); } } @@ -274,11 +275,17 @@ drawModelName(QPainter * painter, painter->setFont(f); painter->setPen(nodeStyle.FontColor); - if(model->nodeType() != NT_EXT_INLET) { + if(model->nodeType() == NT_PFR) { painter->drawText(position, name); } + else if(model->nodeType() == NT_WSR) { + QPointF position2((geom.width() - rect.width()) / 2.0, + ((geom.spacing() + geom.entryHeight()) / 3.0) - 30); + painter->drawText(position2, name); + } else { - QPointF position2(geom.width() / 2.0 - 50, geom.height() / 2.0); + QPointF position2((geom.width() - rect.width()) / 2.0, + ((geom.spacing() + geom.entryHeight()) / 3.0) - 20); painter->drawText(position2, name); } From 497e4f30bb79c5f590ca449972c5fe33a38b96bf Mon Sep 17 00:00:00 2001 From: Scott Selland Date: Fri, 8 Jul 2022 15:57:50 -0500 Subject: [PATCH 12/17] fixing lack of multiple input connections, and fixing node sizing --- src/NodeConnectionInteraction.cpp | 4 ++-- src/NodeGeometry.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NodeConnectionInteraction.cpp b/src/NodeConnectionInteraction.cpp index 82689f4dc..fdf410e28 100644 --- a/src/NodeConnectionInteraction.cpp +++ b/src/NodeConnectionInteraction.cpp @@ -59,8 +59,8 @@ canConnect(PortIndex &portIndex, TypeConverter & converter) const // 3) Node port is vacant // port should be empty - if (!nodePortIsEmpty(requiredPort, portIndex)) - return false; + //if (!nodePortIsEmpty(requiredPort, portIndex)) + //return false; // 4) Connection type equals node port type, or there is a registered type conversion that can translate between the two diff --git a/src/NodeGeometry.cpp b/src/NodeGeometry.cpp index c8d69309e..f6c30e2af 100644 --- a/src/NodeGeometry.cpp +++ b/src/NodeGeometry.cpp @@ -88,7 +88,7 @@ recalculateSize() const { unsigned int maxNumOfEntries = std::max(_nSinks, _nSources); unsigned int step = _entryHeight + _spacing; - _height = step * maxNumOfEntries; + _height = step * maxNumOfEntries * 2; } if (auto w = _dataModel->embeddedWidget()) From 8bd9c918b0bde890c7e2daf5c2605c4e49c61552 Mon Sep 17 00:00:00 2001 From: Scott Selland Date: Mon, 12 Dec 2022 11:57:19 -0600 Subject: [PATCH 13/17] adding back connection point graphics --- src/NodePainter.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NodePainter.cpp b/src/NodePainter.cpp index a6dc817ba..d84454f34 100644 --- a/src/NodePainter.cpp +++ b/src/NodePainter.cpp @@ -40,9 +40,9 @@ paint(QPainter* painter, drawNodeRect(painter, geom, model, graphicsObject); - //drawConnectionPoints(painter, geom, state, model, scene); + drawConnectionPoints(painter, geom, state, model, scene); - //drawFilledConnectionPoints(painter, geom, state, model); + drawFilledConnectionPoints(painter, geom, state, model); drawModelName(painter, geom, state, model); @@ -128,7 +128,6 @@ drawConnectionPoints(QPainter* painter, float diameter = nodeStyle.ConnectionPointDiameter; auto reducedDiameter = diameter * 0.6; - for(PortType portType: {PortType::Out, PortType::In}) { size_t n = state.getEntries(portType).size(); @@ -189,11 +188,13 @@ drawConnectionPoints(QPainter* painter, { painter->setBrush(nodeStyle.ConnectionPointColor); } - painter->drawEllipse(p, reducedDiameter * r, reducedDiameter * r); } + if(model->nodeType() == 0) { + break; //ignore InPort if inlet node type + } }; } From fb694bfa351d7ed50c6e0e84c2d4cfd14a88a891 Mon Sep 17 00:00:00 2001 From: paul gruenbacher <71034156+paul-gruenbacher@users.noreply.github.com> Date: Tue, 15 Jul 2025 08:54:58 -0500 Subject: [PATCH 14/17] Update NodePainter.cpp icon --- src/NodePainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NodePainter.cpp b/src/NodePainter.cpp index d84454f34..d595074ab 100644 --- a/src/NodePainter.cpp +++ b/src/NodePainter.cpp @@ -109,7 +109,7 @@ drawNodeRect(QPainter* painter, painter->drawPixmap(boundary, pfrNode); } else { - QPixmap inletNode(":/images/2_gas-turbines-d.svg"); + QPixmap inletNode(":/images/browse_forward.png"); painter->drawPixmap(boundary, inletNode); } } From 958e712f202220c7263eb935397fd03592c193c1 Mon Sep 17 00:00:00 2001 From: Shivanshu Yadav Date: Mon, 24 Nov 2025 19:57:26 +0530 Subject: [PATCH 15/17] update for getting ui coordinates from canvas items --- include/nodes/internal/FlowScene.hpp | 2 +- include/nodes/internal/NodeGraphicsObject.hpp | 4 ++++ src/NodeGeometry.cpp | 6 +++--- src/NodeGraphicsObject.cpp | 6 ++++++ src/NodePainter.cpp | 16 +++++++--------- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/nodes/internal/FlowScene.hpp b/include/nodes/internal/FlowScene.hpp index 104a10990..8ba36fd73 100644 --- a/include/nodes/internal/FlowScene.hpp +++ b/include/nodes/internal/FlowScene.hpp @@ -123,7 +123,7 @@ class NODE_EDITOR_PUBLIC FlowScene void connectionDeleted(Connection const &c); void connectionDrawn(const QtNodes::Connection &c); - void nodeMoved(Node& n, const QPointF& newLocation); + void nodeMoved(QtNodes::Node& n, const QPointF& newLocation); void nodeDoubleClicked(QtNodes::Node& n); diff --git a/include/nodes/internal/NodeGraphicsObject.hpp b/include/nodes/internal/NodeGraphicsObject.hpp index ee717b5d5..b910fd808 100644 --- a/include/nodes/internal/NodeGraphicsObject.hpp +++ b/include/nodes/internal/NodeGraphicsObject.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "Connection.hpp" @@ -54,6 +55,9 @@ class NodeGraphicsObject : public QGraphicsObject void lock(bool locked); +Q_SIGNALS: + void nodeMoved(QtNodes::Node& node, const QPointF& newLocation); + protected: void paint(QPainter* painter, diff --git a/src/NodeGeometry.cpp b/src/NodeGeometry.cpp index f6c30e2af..94d2095e0 100644 --- a/src/NodeGeometry.cpp +++ b/src/NodeGeometry.cpp @@ -160,7 +160,7 @@ portScenePosition(PortIndex index, totalHeight += step * index; // TODO: why? - totalHeight += step / 2.0; + totalHeight += step; switch (portType) { @@ -168,13 +168,13 @@ portScenePosition(PortIndex index, { double x = _width + nodeStyle.ConnectionPointDiameter; - result = QPointF(x, totalHeight); + result = QPointF(x*0.9, totalHeight); break; } case PortType::In: { - double x = 0.0 - nodeStyle.ConnectionPointDiameter; + double x = 4.0 /*- nodeStyle.ConnectionPointDiameter*/; result = QPointF(x, totalHeight); break; diff --git a/src/NodeGraphicsObject.cpp b/src/NodeGraphicsObject.cpp index 7516d0bbd..4fd15ef0a 100644 --- a/src/NodeGraphicsObject.cpp +++ b/src/NodeGraphicsObject.cpp @@ -15,6 +15,7 @@ #include "Node.hpp" #include "NodeDataModel.hpp" #include "NodeConnectionInteraction.hpp" +#include #include "StyleCollection.hpp" @@ -37,6 +38,7 @@ NodeGraphicsObject(FlowScene &scene, setFlag(QGraphicsItem::ItemIsFocusable, true); setFlag(QGraphicsItem::ItemIsSelectable, true); setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); setCacheMode( QGraphicsItem::DeviceCoordinateCache ); @@ -192,6 +194,8 @@ itemChange(GraphicsItemChange change, const QVariant &value) moveConnections(); } + _scene.nodeMoved(node(),pos()); + return QGraphicsItem::itemChange(change, value); } @@ -321,6 +325,8 @@ mouseMoveEvent(QGraphicsSceneMouseEvent * event) r = r.united(mapToScene(boundingRect()).boundingRect()); + _scene.nodeMoved(_node,event->pos()); + scene()->setSceneRect(r); } diff --git a/src/NodePainter.cpp b/src/NodePainter.cpp index d595074ab..1001406b7 100644 --- a/src/NodePainter.cpp +++ b/src/NodePainter.cpp @@ -96,7 +96,7 @@ drawNodeRect(QPainter* painter, float diam = nodeStyle.ConnectionPointDiameter; - QRect boundary( -diam, -diam, geom.width(), geom.height()); + QRect boundary( diam, -diam*2.5, 150, 150); double const radius = 3.0; @@ -109,7 +109,7 @@ drawNodeRect(QPainter* painter, painter->drawPixmap(boundary, pfrNode); } else { - QPixmap inletNode(":/images/browse_forward.png"); + QPixmap inletNode(":/images/reactor_intlet-01.png"); painter->drawPixmap(boundary, inletNode); } } @@ -127,7 +127,7 @@ drawConnectionPoints(QPainter* painter, auto const &connectionStyle = StyleCollection::connectionStyle(); float diameter = nodeStyle.ConnectionPointDiameter; - auto reducedDiameter = diameter * 0.6; + auto reducedDiameter = diameter * 0.5; for(PortType portType: {PortType::Out, PortType::In}) { size_t n = state.getEntries(portType).size(); @@ -272,7 +272,7 @@ drawModelName(QPainter * painter, auto rect = metrics.boundingRect(name); QPointF position((geom.width() - rect.width()) / 2.0, - (geom.spacing() + geom.entryHeight()) / 3.0); + ((geom.spacing() + geom.entryHeight()) / 3.0) - 5); painter->setFont(f); painter->setPen(nodeStyle.FontColor); @@ -281,13 +281,11 @@ drawModelName(QPainter * painter, } else if(model->nodeType() == NT_WSR) { QPointF position2((geom.width() - rect.width()) / 2.0, - ((geom.spacing() + geom.entryHeight()) / 3.0) - 30); + ((geom.spacing() + geom.entryHeight()) / 3.0) - 40); painter->drawText(position2, name); } else { - QPointF position2((geom.width() - rect.width()) / 2.0, - ((geom.spacing() + geom.entryHeight()) / 3.0) - 20); - painter->drawText(position2, name); + painter->drawText(position, name); } @@ -336,7 +334,7 @@ drawEntryLabels(QPainter * painter, auto rect = metrics.boundingRect(s); - p.setY(p.y() + rect.height() / 4.0); + p.setY(p.y()*1.25 + rect.height()); switch (portType) { From f9be60529fd13e37177b89923db1875a5bcf61ee Mon Sep 17 00:00:00 2001 From: Shivanshu Yadav Date: Tue, 25 Nov 2025 20:22:29 +0530 Subject: [PATCH 16/17] virtual function entry for tooltips --- include/nodes/internal/NodeDataModel.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/nodes/internal/NodeDataModel.hpp b/include/nodes/internal/NodeDataModel.hpp index e80c0739e..ce2beff58 100644 --- a/include/nodes/internal/NodeDataModel.hpp +++ b/include/nodes/internal/NodeDataModel.hpp @@ -47,6 +47,8 @@ class NODE_EDITOR_PUBLIC NodeDataModel virtual QString caption() const = 0; + virtual QString tooltipText() = 0; + //Can add parameter std::string requestedInfo which we can set to be "inlet_temperature", "reactor_type", "volume", etc.. //this way if we need to show more info about the node we can just call this overridden method with what we need virtual QString extraInfo(int reactorType) { return ""; } From c55d0d609d848b356d2ed3a5a4d08bae4399e75a Mon Sep 17 00:00:00 2001 From: Shivanshu Yadav Date: Tue, 16 Dec 2025 21:06:30 +0530 Subject: [PATCH 17/17] Code for updated node drawing, icon change, icon resizing, and tooltip fixes. --- src/NodeGeometry.cpp | 25 +- src/NodePainter.cpp | 662 ++++++++++++++++++++++--------------------- src/NodePainter.hpp | 2 + 3 files changed, 367 insertions(+), 322 deletions(-) diff --git a/src/NodeGeometry.cpp b/src/NodeGeometry.cpp index 94d2095e0..357ec96b6 100644 --- a/src/NodeGeometry.cpp +++ b/src/NodeGeometry.cpp @@ -72,13 +72,20 @@ boundingRect() const double addon = 4 * nodeStyle.ConnectionPointDiameter; + if(_dataModel->nodeType()==NT_EXT_INLET){ + return (QRectF(0,0, _width, _height)); + }else if(_dataModel->nodeType()==NT_WSR){ + return (QRectF(0,(0 - (addon*1.8)), _width, _height+addon*1.8)); + }else if(_dataModel->nodeType()==NT_PFR){ + return (QRectF(0,0 - addon*0.5, _width, _height+addon*0.5)); + } + return QRectF(0 - addon, 0 - addon, _width + 2 * addon, _height + 2 * addon); } - void NodeGeometry:: recalculateSize() const @@ -149,11 +156,19 @@ portScenePosition(PortIndex index, { auto const &nodeStyle = StyleCollection::nodeStyle(); + //Calculate the area for node label + QPainter painter; + QFont f = painter.font(); + f.setBold(true); + QFontMetrics metrics(f); + auto labelRect = metrics.boundingRect(_dataModel->caption()); + unsigned int step = _entryHeight + _spacing; QPointF result; - double totalHeight = 0.0; + double totalHeight = boundingRect().height(); + double y = boundingRect().y() + totalHeight/2 + labelRect.height(); totalHeight += captionHeight(); @@ -168,15 +183,15 @@ portScenePosition(PortIndex index, { double x = _width + nodeStyle.ConnectionPointDiameter; - result = QPointF(x*0.9, totalHeight); + result = QPointF(x*0.85, y); break; } case PortType::In: { - double x = 4.0 /*- nodeStyle.ConnectionPointDiameter*/; + double x = nodeStyle.ConnectionPointDiameter; - result = QPointF(x, totalHeight); + result = QPointF(x*1.85, y); break; } diff --git a/src/NodePainter.cpp b/src/NodePainter.cpp index 1001406b7..ca58a6863 100644 --- a/src/NodePainter.cpp +++ b/src/NodePainter.cpp @@ -22,420 +22,448 @@ using QtNodes::NodeDataModel; using QtNodes::FlowScene; void -NodePainter:: -paint(QPainter* painter, - Node & node, - FlowScene const& scene) + NodePainter:: + paint(QPainter* painter, + Node & node, + FlowScene const& scene) { - NodeGeometry const& geom = node.nodeGeometry(); + NodeGeometry& geom = node.nodeGeometry(); + NodeState const& state = node.nodeState(); + NodeGraphicsObject const & graphicsObject = node.nodeGraphicsObject(); + + // FORCE SQUARE SHAPE - width = height + if(geom.width() != geom.height()) { + double size = std::max(geom.width(), geom.height()); + geom.setWidth(size); + geom.setHeight(size); + } + + geom.recalculateSize(painter->font()); - NodeState const& state = node.nodeState(); + //-------------------------------------------- + NodeDataModel const * model = node.nodeDataModel(); - NodeGraphicsObject const & graphicsObject = node.nodeGraphicsObject(); + drawNodeRect(painter, geom, model, graphicsObject); + drawConnectionPoints(painter, geom, state, model, scene); + drawFilledConnectionPoints(painter, geom, state, model); + drawModelName(painter, geom, state, model); + drawEntryLabels(painter, geom, state, model); + drawResizeRect(painter, geom, model); + drawValidationRect(painter, geom, model, graphicsObject); - geom.recalculateSize(painter->font()); + /// call custom painter + if (auto painterDelegate = model->painterDelegate()) + { + painterDelegate->paint(painter, geom, model); + } +} - //-------------------------------------------- - NodeDataModel const * model = node.nodeDataModel(); - drawNodeRect(painter, geom, model, graphicsObject); +void + NodePainter:: + drawNodeRect(QPainter* painter, + NodeGeometry const& geom, + NodeDataModel const* model, + NodeGraphicsObject const & graphicsObject) +{ + NodeStyle const& nodeStyle = model->nodeStyle(); - drawConnectionPoints(painter, geom, state, model, scene); + auto color = graphicsObject.isSelected() + ? nodeStyle.SelectedBoundaryColor + : nodeStyle.NormalBoundaryColor; - drawFilledConnectionPoints(painter, geom, state, model); + if (geom.hovered()) + { + QPen p(color, nodeStyle.HoveredPenWidth); + painter->setPen(p); + } + else + { + QPen p(color, nodeStyle.PenWidth); + painter->setPen(p); + } - drawModelName(painter, geom, state, model); + // Draw blue background to show bounding rect (for debugging) + // QBrush wBrush(Qt::blue); + // QRect fullBoundary(geom.boundingRect().x(), + // geom.boundingRect().y(), + // geom.boundingRect().width(), + // geom.boundingRect().height() + // ); + // painter->fillRect(fullBoundary, wBrush); + + // Load the pixmap + QPixmap pixmap; + if(model->nodeType() == NT_WSR) { + pixmap = QPixmap(":/images/plugFlowReactor.png"); + } + else if(model->nodeType() == NT_PFR) { + pixmap = QPixmap(":/images/7_general-flow-a.svg"); + } + else { + pixmap = QPixmap(":/images/reactor_intlet-01.png"); + } - drawEntryLabels(painter, geom, state, model); + if (!pixmap.isNull()) { + // CENTER THE PIXMAP in the bounding rect + double nodeSize = geom.width(); // Square, so width = height - drawResizeRect(painter, geom, model); + // Calculate scaled pixmap size (maintain aspect ratio, fit within node) + QSize pixmapSize = pixmap.size(); + pixmapSize.scale(nodeSize * 0.8, nodeSize * 0.8, Qt::KeepAspectRatio); - drawValidationRect(painter, geom, model, graphicsObject); + //Calculate the area for node label + QFont f = painter->font(); + f.setBold(true); + QFontMetrics metrics(f); + auto labelRect = metrics.boundingRect(model->caption()); - /// call custom painter - if (auto painterDelegate = model->painterDelegate()) - { - painterDelegate->paint(painter, geom, model); - } -} + // Calculate top-left position to center the pixmap + double x = (nodeSize - pixmapSize.width()) / 2.0; + double y = geom.boundingRect().center().y() - (pixmapSize.height()/2) + labelRect.height(); + QRectF targetRect(x, y, pixmapSize.width(), pixmapSize.height()); -void -NodePainter:: -drawNodeRect(QPainter* painter, - NodeGeometry const& geom, - NodeDataModel const* model, - NodeGraphicsObject const & graphicsObject) -{ - NodeStyle const& nodeStyle = model->nodeStyle(); - - auto color = graphicsObject.isSelected() - ? nodeStyle.SelectedBoundaryColor - : nodeStyle.NormalBoundaryColor; - - if (geom.hovered()) - { - QPen p(color, nodeStyle.HoveredPenWidth); - painter->setPen(p); - } - else - { - QPen p(color, nodeStyle.PenWidth); - painter->setPen(p); - } - - QLinearGradient gradient(QPointF(0.0, 0.0), - QPointF(2.0, geom.height())); - - gradient.setColorAt(0.0, nodeStyle.GradientColor0); - gradient.setColorAt(0.03, nodeStyle.GradientColor1); - gradient.setColorAt(0.97, nodeStyle.GradientColor2); - gradient.setColorAt(1.0, nodeStyle.GradientColor3); - - painter->setBrush(gradient); - - float diam = nodeStyle.ConnectionPointDiameter; - - QRect boundary( diam, -diam*2.5, 150, 150); - - double const radius = 3.0; - - if(model->nodeType() == NT_WSR) { - QPixmap wsrNode(":/images/plugFlowReactor.png"); - painter->drawPixmap(boundary, wsrNode); - } - else if(model->nodeType() == NT_PFR) { - QPixmap pfrNode(":/images/7_general-flow-a.svg"); - painter->drawPixmap(boundary, pfrNode); - } - else { - QPixmap inletNode(":/images/reactor_intlet-01.png"); - painter->drawPixmap(boundary, inletNode); - } + // Draw the centered pixmap + painter->drawPixmap(targetRect.toRect(), pixmap); + } } void -NodePainter:: -drawConnectionPoints(QPainter* painter, - NodeGeometry const& geom, - NodeState const& state, - NodeDataModel const * model, - FlowScene const & scene) + NodePainter:: + drawConnectionPoints(QPainter* painter, + NodeGeometry const& geom, + NodeState const& state, + NodeDataModel const * model, + FlowScene const & scene) { - NodeStyle const& nodeStyle = model->nodeStyle(); - auto const &connectionStyle = StyleCollection::connectionStyle(); + NodeStyle const& nodeStyle = model->nodeStyle(); + auto const &connectionStyle = StyleCollection::connectionStyle(); - float diameter = nodeStyle.ConnectionPointDiameter; - auto reducedDiameter = diameter * 0.5; - for(PortType portType: {PortType::Out, PortType::In}) - { - size_t n = state.getEntries(portType).size(); + float diameter = nodeStyle.ConnectionPointDiameter; + auto reducedDiameter = diameter * 0.5; - for (unsigned int i = 0; i < n; ++i) + for(PortType portType: {PortType::Out, PortType::In}) { - QPointF p = geom.portScenePosition(i, portType); - - auto const & dataType = - model->dataType(portType, static_cast(i)); - - bool canConnect = (state.getEntries(portType)[i].empty() || - (portType == PortType::Out && - model->portOutConnectionPolicy(i) == NodeDataModel::ConnectionPolicy::Many) ); + size_t n = state.getEntries(portType).size(); - double r = 1.0; - if (state.isReacting() && - canConnect && - portType == state.reactingPortType()) - { - - auto diff = geom.draggingPos() - p; - double dist = std::sqrt(QPointF::dotProduct(diff, diff)); - bool typeConvertable = false; - - { - if (portType == PortType::In) - { - typeConvertable = scene.registry().getTypeConverter(state.reactingDataType(), dataType) != nullptr; - } - else - { - typeConvertable = scene.registry().getTypeConverter(dataType, state.reactingDataType()) != nullptr; - } - } - - if (state.reactingDataType().id == dataType.id || typeConvertable) + for (unsigned int i = 0; i < n; ++i) { - double const thres = 40.0; - r = (dist < thres) ? - (2.0 - dist / thres ) : - 1.0; + QPointF p = geom.portScenePosition(i, portType); + auto const & dataType = + model->dataType(portType, static_cast(i)); + + bool canConnect = (state.getEntries(portType)[i].empty() || + (portType == PortType::Out && + model->portOutConnectionPolicy(i) == NodeDataModel::ConnectionPolicy::Many) ); + + double r = 1.0; + if (state.isReacting() && + canConnect && + portType == state.reactingPortType()) + { + + auto diff = geom.draggingPos() - p; + double dist = std::sqrt(QPointF::dotProduct(diff, diff)); + bool typeConvertable = false; + + { + if (portType == PortType::In) + { + typeConvertable = scene.registry().getTypeConverter(state.reactingDataType(), dataType) != nullptr; + } + else + { + typeConvertable = scene.registry().getTypeConverter(dataType, state.reactingDataType()) != nullptr; + } + } + + if (state.reactingDataType().id == dataType.id || typeConvertable) + { + double const thres = 40.0; + r = (dist < thres) ? + (2.0 - dist / thres ) : + 1.0; + } + else + { + double const thres = 80.0; + r = (dist < thres) ? + (dist / thres) : + 1.0; + } + } + + if (connectionStyle.useDataDefinedColors()) + { + painter->setBrush(connectionStyle.normalColor(dataType.id)); + } + else + { + painter->setBrush(nodeStyle.ConnectionPointColor); + } + painter->drawEllipse(p, + reducedDiameter * r, + reducedDiameter * r); } - else - { - double const thres = 80.0; - r = (dist < thres) ? - (dist / thres) : - 1.0; + if(model->nodeType() == 0) { + break; //ignore InPort if inlet node type } - } - - if (connectionStyle.useDataDefinedColors()) - { - painter->setBrush(connectionStyle.normalColor(dataType.id)); - } - else - { - painter->setBrush(nodeStyle.ConnectionPointColor); - } - painter->drawEllipse(p, - reducedDiameter * r, - reducedDiameter * r); - } - if(model->nodeType() == 0) { - break; //ignore InPort if inlet node type - } - }; + }; } void -NodePainter:: -drawFilledConnectionPoints(QPainter * painter, - NodeGeometry const & geom, - NodeState const & state, - NodeDataModel const * model) + NodePainter:: + drawFilledConnectionPoints(QPainter * painter, + NodeGeometry const & geom, + NodeState const & state, + NodeDataModel const * model) { - NodeStyle const& nodeStyle = model->nodeStyle(); - auto const & connectionStyle = StyleCollection::connectionStyle(); + NodeStyle const& nodeStyle = model->nodeStyle(); + auto const & connectionStyle = StyleCollection::connectionStyle(); - auto diameter = nodeStyle.ConnectionPointDiameter; + auto diameter = nodeStyle.ConnectionPointDiameter; - for(PortType portType: {PortType::Out, PortType::In}) - { - size_t n = state.getEntries(portType).size(); - for (size_t i = 0; i < n; ++i) + for(PortType portType: {PortType::Out, PortType::In}) { - QPointF p = geom.portScenePosition( - static_cast(i), - static_cast(portType)); + size_t n = state.getEntries(portType).size(); - if (!state.getEntries(portType)[i].empty()) - { - auto const & dataType = - model->dataType(portType, static_cast(i)); - - if (connectionStyle.useDataDefinedColors()) + for (size_t i = 0; i < n; ++i) { - QColor const c = connectionStyle.normalColor(dataType.id); - painter->setPen(c); - painter->setBrush(c); + QPointF p = geom.portScenePosition( + static_cast(i), + static_cast(portType)); + + if (!state.getEntries(portType)[i].empty()) + { + auto const & dataType = + model->dataType(portType, static_cast(i)); + + if (connectionStyle.useDataDefinedColors()) + { + QColor const c = connectionStyle.normalColor(dataType.id); + painter->setPen(c); + painter->setBrush(c); + } + else + { + painter->setPen(nodeStyle.FilledConnectionPointColor); + painter->setBrush(nodeStyle.FilledConnectionPointColor); + } + + painter->drawEllipse(p, + diameter * 0.4, + diameter * 0.4); + } } - else - { - painter->setPen(nodeStyle.FilledConnectionPointColor); - painter->setBrush(nodeStyle.FilledConnectionPointColor); - } - - painter->drawEllipse(p, - diameter * 0.4, - diameter * 0.4); - } } - } } void -NodePainter:: -drawModelName(QPainter * painter, - NodeGeometry const & geom, - NodeState const & state, - NodeDataModel const * model) + NodePainter:: + drawModelName(QPainter * painter, + NodeGeometry const & geom, + NodeState const & state, + NodeDataModel const * model) { - NodeStyle const& nodeStyle = model->nodeStyle(); - - Q_UNUSED(state); + NodeStyle const& nodeStyle = model->nodeStyle(); - if (!model->captionVisible()) - return; + Q_UNUSED(state); - QString const &name = model->caption(); + if (!model->captionVisible()) + return; - QFont f = painter->font(); + QString const &name = model->caption(); - f.setBold(true); + QFont f = painter->font(); - QFontMetrics metrics(f); + f.setBold(true); - auto rect = metrics.boundingRect(name); + QFontMetrics metrics(f); - QPointF position((geom.width() - rect.width()) / 2.0, - ((geom.spacing() + geom.entryHeight()) / 3.0) - 5); + auto rect = metrics.boundingRect(name); + auto nodeRect = geom.boundingRect(); - painter->setFont(f); - painter->setPen(nodeStyle.FontColor); - if(model->nodeType() == NT_PFR) { - painter->drawText(position, name); - } - else if(model->nodeType() == NT_WSR) { - QPointF position2((geom.width() - rect.width()) / 2.0, - ((geom.spacing() + geom.entryHeight()) / 3.0) - 40); - painter->drawText(position2, name); - } - else { - painter->drawText(position, name); - } + QPointF position((geom.width() - rect.width()) / 2.0, nodeRect.y()+rect.height()); + painter->setFont(f); + painter->setPen(nodeStyle.FontColor); + if(model->nodeType() == NT_PFR) { + painter->drawText(position, name); + } + else if(model->nodeType() == NT_WSR) { + painter->drawText(position, name); + } + else { + painter->drawText(position, name); + } - f.setBold(false); - painter->setFont(f); + f.setBold(false); + painter->setFont(f); } void -NodePainter:: -drawEntryLabels(QPainter * painter, - NodeGeometry const & geom, - NodeState const & state, - NodeDataModel const * model) + NodePainter:: + drawEntryLabels(QPainter * painter, + NodeGeometry const & geom, + NodeState const & state, + NodeDataModel const * model) { - QFontMetrics const & metrics = - painter->fontMetrics(); + QFontMetrics const & metrics = + painter->fontMetrics(); - for(PortType portType: {PortType::Out, PortType::In}) - { - auto const &nodeStyle = model->nodeStyle(); + for(PortType portType: {PortType::Out, PortType::In}) + { + auto const &nodeStyle = model->nodeStyle(); - auto& entries = state.getEntries(portType); + auto& entries = state.getEntries(portType); - size_t n = entries.size(); + size_t n = entries.size(); - for (size_t i = 0; i < n; ++i) - { - QPointF p = geom.portScenePosition(static_cast(i), portType); + for (size_t i = 0; i < n; ++i) + { + QPointF p = geom.portScenePosition(static_cast(i), portType); - if (entries[i].empty()) - painter->setPen(nodeStyle.FontColorFaded); - else - painter->setPen(nodeStyle.FontColor); + if (entries[i].empty()) + painter->setPen(nodeStyle.FontColorFaded); + else + painter->setPen(nodeStyle.FontColor); - QString s; + QString s; - if (model->portCaptionVisible(portType, static_cast(i))) - { - s = model->portCaption(portType, static_cast(i)); - } - else - { - s = model->dataType(portType, static_cast(i)).name; - } + if (model->portCaptionVisible(portType, static_cast(i))) + { + s = model->portCaption(portType, static_cast(i)); + } + else + { + s = model->dataType(portType, static_cast(i)).name; + } - auto rect = metrics.boundingRect(s); + auto rect = metrics.boundingRect(s); - p.setY(p.y()*1.25 + rect.height()); + p.setY(p.y() + rect.height() / 2.0); - switch (portType) - { - case PortType::In: - p.setX(5.0); - break; + switch (portType) + { + case PortType::In: + p.setX(5.0); + break; - case PortType::Out: - p.setX(geom.width() - 5.0 - rect.width()); - break; + case PortType::Out: + p.setX(geom.width() - 5.0 - rect.width()); + break; - default: - break; - } + default: + break; + } - painter->drawText(p, s); + painter->drawText(p, s); + } } - } } void -NodePainter:: -drawResizeRect(QPainter * painter, - NodeGeometry const & geom, - NodeDataModel const * model) + NodePainter:: + drawResizeRect(QPainter * painter, + NodeGeometry const & geom, + NodeDataModel const * model) { - if (model->resizable()) - { - painter->setBrush(Qt::gray); - - painter->drawEllipse(geom.resizeRect()); - } + if (model->resizable()) + { + painter->setBrush(Qt::gray); + painter->drawEllipse(geom.resizeRect()); + } } void -NodePainter:: -drawValidationRect(QPainter * painter, - NodeGeometry const & geom, - NodeDataModel const * model, - NodeGraphicsObject const & graphicsObject) + NodePainter:: + drawValidationRect(QPainter * painter, + NodeGeometry const & geom, + NodeDataModel const * model, + NodeGraphicsObject const & graphicsObject) { - auto modelValidationState = model->validationState(); + auto modelValidationState = model->validationState(); - if (modelValidationState != NodeValidationState::Valid) - { - NodeStyle const& nodeStyle = model->nodeStyle(); + if (modelValidationState != NodeValidationState::Valid) + { + NodeStyle const& nodeStyle = model->nodeStyle(); - auto color = graphicsObject.isSelected() - ? nodeStyle.SelectedBoundaryColor - : nodeStyle.NormalBoundaryColor; + auto color = graphicsObject.isSelected() + ? nodeStyle.SelectedBoundaryColor + : nodeStyle.NormalBoundaryColor; - if (geom.hovered()) - { - QPen p(color, nodeStyle.HoveredPenWidth); - painter->setPen(p); - } - else - { - QPen p(color, nodeStyle.PenWidth); - painter->setPen(p); - } + if (geom.hovered()) + { + QPen p(color, nodeStyle.HoveredPenWidth); + painter->setPen(p); + } + else + { + QPen p(color, nodeStyle.PenWidth); + painter->setPen(p); + } - //Drawing the validation message background - if (modelValidationState == NodeValidationState::Error) - { - painter->setBrush(nodeStyle.ErrorColor); - } - else - { - painter->setBrush(nodeStyle.WarningColor); - } + //Drawing the validation message background + if (modelValidationState == NodeValidationState::Error) + { + painter->setBrush(nodeStyle.ErrorColor); + } + else + { + painter->setBrush(nodeStyle.WarningColor); + } - double const radius = 3.0; + double const radius = 3.0; - float diam = nodeStyle.ConnectionPointDiameter; + // Draw validation rect at the bottom within bounds + QRectF boundary(0, + geom.height() - geom.validationHeight(), + geom.width(), + geom.validationHeight()); - QRectF boundary(-diam, - -diam + geom.height() - geom.validationHeight(), - 2.0 * diam + geom.width(), - 2.0 * diam + geom.validationHeight()); + painter->drawRoundedRect(boundary, radius, radius); - painter->drawRoundedRect(boundary, radius, radius); + painter->setBrush(Qt::gray); - painter->setBrush(Qt::gray); + //Drawing the validation message itself + QString const &errorMsg = model->validationMessage(); - //Drawing the validation message itself - QString const &errorMsg = model->validationMessage(); + QFont f = painter->font(); + QFontMetrics metrics(f); + auto rect = metrics.boundingRect(errorMsg); - QFont f = painter->font(); + QPointF position((geom.width() - rect.width()) / 2.0, + geom.height() - geom.validationHeight() / 2.0 + rect.height() / 2.0); - QFontMetrics metrics(f); + painter->setFont(f); + painter->setPen(nodeStyle.FontColor); + painter->drawText(position, errorMsg); + } +} - auto rect = metrics.boundingRect(errorMsg); - QPointF position((geom.width() - rect.width()) / 2.0, - geom.height() - (geom.validationHeight() - diam) / 2.0); +void NodePainter::resizeNodeByFactor(Node & node, double factor) +{ + NodeGeometry& geom = node.nodeGeometry(); - painter->setFont(f); - painter->setPen(nodeStyle.FontColor); - painter->drawText(position, errorMsg); - } + // Get current size + double currentSize = geom.width(); // Square, so width = height + + // Calculate new size + double newSize = currentSize * factor; + + // Apply new size (force square) + geom.setWidth(newSize); + geom.setHeight(newSize); + + // Trigger update + node.nodeGraphicsObject().update(); } diff --git a/src/NodePainter.hpp b/src/NodePainter.hpp index ba8c3c71b..8619b0e39 100644 --- a/src/NodePainter.hpp +++ b/src/NodePainter.hpp @@ -75,5 +75,7 @@ class NodePainter NodeGeometry const & geom, NodeDataModel const * model, NodeGraphicsObject const & graphicsObject); + + void resizeNodeByFactor(Node & node, double factor); }; }