diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c9285ba9..d9aace751 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,21 +75,21 @@ set(CPP_SOURCE_FILES src/AbstractNodeGeometry.cpp src/BasicGraphicsScene.cpp src/ConnectionGraphicsObject.cpp - src/ConnectionPainter.cpp src/ConnectionState.cpp src/ConnectionStyle.cpp src/DataFlowGraphModel.cpp src/DataFlowGraphicsScene.cpp + src/DefaultConnectionPainter.cpp src/DefaultHorizontalNodeGeometry.cpp + src/DefaultNodePainter.cpp src/DefaultVerticalNodeGeometry.cpp src/Definitions.cpp src/GraphicsView.cpp src/GraphicsViewStyle.cpp - src/NodeDelegateModelRegistry.cpp src/NodeConnectionInteraction.cpp src/NodeDelegateModel.cpp + src/NodeDelegateModelRegistry.cpp src/NodeGraphicsObject.cpp - src/DefaultNodePainter.cpp src/NodeState.cpp src/NodeStyle.cpp src/StyleCollection.cpp @@ -98,6 +98,7 @@ set(CPP_SOURCE_FILES ) set(HPP_HEADER_FILES + include/QtNodes/internal/AbstractConnectionPainter.hpp include/QtNodes/internal/AbstractGraphModel.hpp include/QtNodes/internal/AbstractNodeGeometry.hpp include/QtNodes/internal/AbstractNodePainter.hpp @@ -110,7 +111,6 @@ set(HPP_HEADER_FILES include/QtNodes/internal/ConnectionStyle.hpp include/QtNodes/internal/DataFlowGraphicsScene.hpp include/QtNodes/internal/DataFlowGraphModel.hpp - include/QtNodes/internal/DefaultNodePainter.hpp include/QtNodes/internal/Definitions.hpp include/QtNodes/internal/Export.hpp include/QtNodes/internal/GraphicsView.hpp @@ -128,8 +128,9 @@ set(HPP_HEADER_FILES include/QtNodes/internal/Serializable.hpp include/QtNodes/internal/Style.hpp include/QtNodes/internal/StyleCollection.hpp - src/ConnectionPainter.hpp + src/DefaultConnectionPainter.hpp src/DefaultHorizontalNodeGeometry.hpp + src/DefaultNodePainter.hpp src/DefaultVerticalNodeGeometry.hpp src/NodeConnectionInteraction.hpp src/UndoCommands.hpp diff --git a/include/QtNodes/AbstractConnectionPainter b/include/QtNodes/AbstractConnectionPainter new file mode 100644 index 000000000..9e1434044 --- /dev/null +++ b/include/QtNodes/AbstractConnectionPainter @@ -0,0 +1 @@ +#include "internal/AbstractConnectionPainter.hpp" diff --git a/include/QtNodes/internal/AbstractConnectionPainter.hpp b/include/QtNodes/internal/AbstractConnectionPainter.hpp new file mode 100644 index 000000000..f838a0b99 --- /dev/null +++ b/include/QtNodes/internal/AbstractConnectionPainter.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "Export.hpp" + +class QPainter; + +namespace QtNodes { + +class ConnectionGraphicsObject; + +/// Class enables custom painting for connections. +class NODE_EDITOR_PUBLIC AbstractConnectionPainter +{ +public: + virtual ~AbstractConnectionPainter() = default; + + /** + * Reimplement this function in order to have a custom connection painting. + */ + virtual void paint(QPainter *painter, ConnectionGraphicsObject const &cgo) const = 0; + + virtual QPainterPath getPainterStroke(ConnectionGraphicsObject const &cgo) const = 0; +}; +} // namespace QtNodes diff --git a/include/QtNodes/internal/BasicGraphicsScene.hpp b/include/QtNodes/internal/BasicGraphicsScene.hpp index 94f94823f..59544980d 100644 --- a/include/QtNodes/internal/BasicGraphicsScene.hpp +++ b/include/QtNodes/internal/BasicGraphicsScene.hpp @@ -21,6 +21,7 @@ class QUndoStack; namespace QtNodes { +class AbstractConnectionPainter; class AbstractGraphModel; class AbstractNodePainter; class ConnectionGraphicsObject; @@ -49,8 +50,12 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene AbstractNodePainter &nodePainter(); + AbstractConnectionPainter &connectionPainter(); + void setNodePainter(std::unique_ptr newPainter); + void setConnectionPainter(std::unique_ptr newPainter); + QUndoStack &undoStack(); public: @@ -170,6 +175,8 @@ public Q_SLOTS: std::unique_ptr _nodePainter; + std::unique_ptr _connectionPainter; + bool _nodeDrag; QUndoStack *_undoStack; diff --git a/src/BasicGraphicsScene.cpp b/src/BasicGraphicsScene.cpp index feda81811..3e7e9a86c 100644 --- a/src/BasicGraphicsScene.cpp +++ b/src/BasicGraphicsScene.cpp @@ -3,6 +3,7 @@ #include "AbstractNodeGeometry.hpp" #include "ConnectionGraphicsObject.hpp" #include "ConnectionIdUtils.hpp" +#include "DefaultConnectionPainter.hpp" #include "DefaultHorizontalNodeGeometry.hpp" #include "DefaultNodePainter.hpp" #include "DefaultVerticalNodeGeometry.hpp" @@ -36,6 +37,7 @@ BasicGraphicsScene::BasicGraphicsScene(AbstractGraphModel &graphModel, QObject * , _graphModel(graphModel) , _nodeGeometry(std::make_unique(_graphModel)) , _nodePainter(std::make_unique()) + , _connectionPainter(std::make_unique()) , _nodeDrag(false) , _undoStack(new QUndoStack(this)) , _orientation(Qt::Horizontal) @@ -101,11 +103,21 @@ AbstractNodePainter &BasicGraphicsScene::nodePainter() return *_nodePainter; } +AbstractConnectionPainter &BasicGraphicsScene::connectionPainter() +{ + return *_connectionPainter; +} + void BasicGraphicsScene::setNodePainter(std::unique_ptr newPainter) { _nodePainter = std::move(newPainter); } +void BasicGraphicsScene::setConnectionPainter(std::unique_ptr newPainter) +{ + _connectionPainter = std::move(newPainter); +} + QUndoStack &BasicGraphicsScene::undoStack() { return *_undoStack; diff --git a/src/ConnectionGraphicsObject.cpp b/src/ConnectionGraphicsObject.cpp index 6a871c0ed..05ae46b34 100644 --- a/src/ConnectionGraphicsObject.cpp +++ b/src/ConnectionGraphicsObject.cpp @@ -1,10 +1,10 @@ #include "ConnectionGraphicsObject.hpp" +#include "AbstractConnectionPainter.hpp" #include "AbstractGraphModel.hpp" #include "AbstractNodeGeometry.hpp" #include "BasicGraphicsScene.hpp" #include "ConnectionIdUtils.hpp" -#include "ConnectionPainter.hpp" #include "ConnectionState.hpp" #include "ConnectionStyle.hpp" #include "NodeConnectionInteraction.hpp" @@ -128,7 +128,7 @@ QPainterPath ConnectionGraphicsObject::shape() const //return path; #else - return ConnectionPainter::getPainterStroke(*this); + return nodeScene()->connectionPainter().getPainterStroke(*this); #endif } @@ -198,7 +198,7 @@ void ConnectionGraphicsObject::paint(QPainter *painter, painter->setClipRect(option->exposedRect); - ConnectionPainter::paint(painter, *this); + nodeScene()->connectionPainter().paint(painter, *this); } void ConnectionGraphicsObject::mousePressEvent(QGraphicsSceneMouseEvent *event) diff --git a/src/ConnectionPainter.hpp b/src/ConnectionPainter.hpp deleted file mode 100644 index 8db24d8e6..000000000 --- a/src/ConnectionPainter.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -#include "Definitions.hpp" - -namespace QtNodes { - -class ConnectionGeometry; -class ConnectionGraphicsObject; - -class ConnectionPainter -{ -public: - static void paint(QPainter *painter, ConnectionGraphicsObject const &cgo); - - static QPainterPath getPainterStroke(ConnectionGraphicsObject const &cgo); -}; - -} // namespace QtNodes diff --git a/src/ConnectionPainter.cpp b/src/DefaultConnectionPainter.cpp similarity index 87% rename from src/ConnectionPainter.cpp rename to src/DefaultConnectionPainter.cpp index 97002ef79..b83ed87d3 100644 --- a/src/ConnectionPainter.cpp +++ b/src/DefaultConnectionPainter.cpp @@ -1,4 +1,4 @@ -#include "ConnectionPainter.hpp" +#include "DefaultConnectionPainter.hpp" #include @@ -11,7 +11,7 @@ namespace QtNodes { -static QPainterPath cubicPath(ConnectionGraphicsObject const &connection) +QPainterPath DefaultConnectionPainter::cubicPath(ConnectionGraphicsObject const &connection) const { QPointF const &in = connection.endPoint(PortType::In); QPointF const &out = connection.endPoint(PortType::Out); @@ -26,59 +26,7 @@ static QPainterPath cubicPath(ConnectionGraphicsObject const &connection) return cubic; } -QPainterPath ConnectionPainter::getPainterStroke(ConnectionGraphicsObject const &connection) -{ - auto cubic = cubicPath(connection); - - QPointF const &out = connection.endPoint(PortType::Out); - QPainterPath result(out); - - unsigned segments = 20; - - for (auto i = 0ul; i < segments; ++i) { - double ratio = double(i + 1) / segments; - result.lineTo(cubic.pointAtPercent(ratio)); - } - - QPainterPathStroker stroker; - stroker.setWidth(10.0); - - return stroker.createStroke(result); -} - -#ifdef NODE_DEBUG_DRAWING -static void debugDrawing(QPainter *painter, ConnectionGraphicsObject const &cgo) -{ - Q_UNUSED(painter); - - { - QPointF const &in = cgo.endPoint(PortType::In); - QPointF const &out = cgo.endPoint(PortType::Out); - - auto const points = cgo.pointsC1C2(); - - painter->setPen(Qt::red); - painter->setBrush(Qt::red); - - painter->drawLine(QLineF(out, points.first)); - painter->drawLine(QLineF(points.first, points.second)); - painter->drawLine(QLineF(points.second, in)); - painter->drawEllipse(points.first, 3, 3); - painter->drawEllipse(points.second, 3, 3); - - painter->setBrush(Qt::NoBrush); - painter->drawPath(cubicPath(cgo)); - } - - { - painter->setPen(Qt::yellow); - painter->drawRect(cgo.boundingRect()); - } -} - -#endif - -static void drawSketchLine(QPainter *painter, ConnectionGraphicsObject const &cgo) +void DefaultConnectionPainter::drawSketchLine(QPainter *painter, ConnectionGraphicsObject const &cgo) const { ConnectionState const &state = cgo.connectionState(); @@ -86,7 +34,7 @@ static void drawSketchLine(QPainter *painter, ConnectionGraphicsObject const &cg auto const &connectionStyle = QtNodes::StyleCollection::connectionStyle(); QPen pen; - pen.setWidth(connectionStyle.constructionLineWidth()); + pen.setWidth(static_cast(connectionStyle.constructionLineWidth())); pen.setColor(connectionStyle.constructionColor()); pen.setStyle(Qt::DashLine); @@ -100,7 +48,7 @@ static void drawSketchLine(QPainter *painter, ConnectionGraphicsObject const &cg } } -static void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject const &cgo) +void DefaultConnectionPainter::drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject const &cgo) const { bool const hovered = cgo.connectionState().hovered(); bool const selected = cgo.isSelected(); @@ -112,7 +60,7 @@ static void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject co double const lineWidth = connectionStyle.lineWidth(); QPen pen; - pen.setWidth(2 * lineWidth); + pen.setWidth(static_cast(2 * lineWidth)); pen.setColor(selected ? connectionStyle.selectedHaloColor() : connectionStyle.hoveredColor()); @@ -125,7 +73,7 @@ static void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject co } } -static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cgo) +void DefaultConnectionPainter::drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cgo) const { ConnectionState const &state = cgo.connectionState(); @@ -227,7 +175,7 @@ static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cg } } -void ConnectionPainter::paint(QPainter *painter, ConnectionGraphicsObject const &cgo) +void DefaultConnectionPainter::paint(QPainter *painter, ConnectionGraphicsObject const &cgo) const { drawHoveredOrSelected(painter, cgo); @@ -251,4 +199,55 @@ void ConnectionPainter::paint(QPainter *painter, ConnectionGraphicsObject const painter->drawEllipse(cgo.in(), pointRadius, pointRadius); } +QPainterPath DefaultConnectionPainter::getPainterStroke(ConnectionGraphicsObject const &connection) const +{ + auto cubic = cubicPath(connection); + + QPointF const &out = connection.endPoint(PortType::Out); + QPainterPath result(out); + + unsigned segments = 20; + + for (auto i = 0ul; i < segments; ++i) { + double ratio = double(i + 1) / segments; + result.lineTo(cubic.pointAtPercent(ratio)); + } + + QPainterPathStroker stroker; + stroker.setWidth(10.0); + + return stroker.createStroke(result); +} + +#ifdef NODE_DEBUG_DRAWING +void DefaultConnectionPainter::debugDrawing(QPainter *painter, ConnectionGraphicsObject const &cgo) +{ + Q_UNUSED(painter); + + { + QPointF const &in = cgo.endPoint(PortType::In); + QPointF const &out = cgo.endPoint(PortType::Out); + + auto const points = cgo.pointsC1C2(); + + painter->setPen(Qt::red); + painter->setBrush(Qt::red); + + painter->drawLine(QLineF(out, points.first)); + painter->drawLine(QLineF(points.first, points.second)); + painter->drawLine(QLineF(points.second, in)); + painter->drawEllipse(points.first, 3, 3); + painter->drawEllipse(points.second, 3, 3); + + painter->setBrush(Qt::NoBrush); + painter->drawPath(cubicPath(cgo)); + } + + { + painter->setPen(Qt::yellow); + painter->drawRect(cgo.boundingRect()); + } +} +#endif + } // namespace QtNodes diff --git a/src/DefaultConnectionPainter.hpp b/src/DefaultConnectionPainter.hpp new file mode 100644 index 000000000..b2c44d102 --- /dev/null +++ b/src/DefaultConnectionPainter.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#include "AbstractConnectionPainter.hpp" +#include "Definitions.hpp" + +namespace QtNodes { + +class ConnectionGeometry; +class ConnectionGraphicsObject; + +class DefaultConnectionPainter : public AbstractConnectionPainter +{ +public: + void paint(QPainter *painter, ConnectionGraphicsObject const &cgo) const override; + QPainterPath getPainterStroke(ConnectionGraphicsObject const &cgo) const override; +private: + QPainterPath cubicPath(ConnectionGraphicsObject const &connection) const; + void drawSketchLine(QPainter *painter, ConnectionGraphicsObject const &cgo) const; + void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject const &cgo) const; + void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cgo) const; +#ifdef NODE_DEBUG_DRAWING + void debugDrawing(QPainter *painter, ConnectionGraphicsObject const &cgo) const; +#endif +}; + +} // namespace QtNodes diff --git a/include/QtNodes/internal/DefaultNodePainter.hpp b/src/DefaultNodePainter.hpp similarity index 100% rename from include/QtNodes/internal/DefaultNodePainter.hpp rename to src/DefaultNodePainter.hpp