forked from paceholder/nodeeditor
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBasicGraphicsScene.hpp
More file actions
176 lines (137 loc) · 5.7 KB
/
BasicGraphicsScene.hpp
File metadata and controls
176 lines (137 loc) · 5.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#pragma once
#include "AbstractGraphModel.hpp"
#include "AbstractNodeGeometry.hpp"
#include "ConnectionIdHash.hpp"
#include "Definitions.hpp"
#include "Export.hpp"
#include "QUuidStdHash.hpp"
#include <QtCore/QUuid>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QMenu>
#include <functional>
#include <memory>
#include <tuple>
#include <unordered_map>
class QUndoStack;
namespace QtNodes {
class AbstractConnectionPainter;
class AbstractGraphModel;
class AbstractNodePainter;
class ConnectionGraphicsObject;
class NodeGraphicsObject;
class NodeStyle;
/// An instance of QGraphicsScene , holds connections and nodes.
class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
BasicGraphicsScene(AbstractGraphModel &graphModel, QObject *parent = nullptr);
// Scenes without models are not supported
BasicGraphicsScene() = delete;
~BasicGraphicsScene();
public:
/// @returns associated AbstractGraphModel.
AbstractGraphModel const &graphModel() const;
AbstractGraphModel &graphModel();
AbstractNodeGeometry const &nodeGeometry() const;
AbstractNodeGeometry &nodeGeometry();
AbstractNodePainter &nodePainter();
AbstractConnectionPainter &connectionPainter();
void setNodePainter(std::unique_ptr<AbstractNodePainter> newPainter);
void setConnectionPainter(std::unique_ptr<AbstractConnectionPainter> newPainter);
void setNodeGeometry(std::unique_ptr<AbstractNodeGeometry> newGeom);
QUndoStack &undoStack();
public:
/**
* @brief Creates a "draft" instance of ConnectionGraphicsObject.
*
* The scene caches a "draft" connection which has one loose end.
* After attachment the "draft" instance is deleted and instead a
* normal "full" connection is created.
* Function @returns the "draft" instance for further geometry
* manipulations.
*/
std::unique_ptr<ConnectionGraphicsObject> const &makeDraftConnection(
ConnectionId const newConnectionId);
/**
* @brief Deletes "draft" connection.
*
* The function is called when user releases the mouse button during
* the construction of the new connection without attaching it to any
* node.
*/
void resetDraftConnection();
/// Deletes all the nodes. Connections are removed automatically.
void clearScene();
public:
/**
* @returns NodeGraphicsObject associated with the given nodeId.
* @returns nullptr when the object is not found.
*/
NodeGraphicsObject *nodeGraphicsObject(NodeId nodeId);
/**
* @returns ConnectionGraphicsObject corresponding to `connectionId`.
* @returns `nullptr` when the object is not found.
*/
ConnectionGraphicsObject *connectionGraphicsObject(ConnectionId connectionId);
Qt::Orientation orientation() const { return _orientation; }
void setOrientation(Qt::Orientation const orientation);
public:
/**
* Can @return an instance of the scene context menu in subclass.
* Default implementation returns `nullptr`.
*/
virtual QMenu *createSceneMenu(QPointF const scenePos);
void freezeModelAndConnections(bool isFreeze);
Q_SIGNALS:
void modified(BasicGraphicsScene *);
void nodeMoved(NodeId const nodeId, QPointF const &newLocation);
void nodeClicked(NodeId const nodeId);
void nodeSelected(NodeId const nodeId);
void nodeDoubleClicked(NodeId const nodeId);
void nodeHovered(NodeId const nodeId, QPoint const screenPos);
void nodeHoverLeft(NodeId const nodeId);
void connectionHovered(ConnectionId const connectionId, QPoint const screenPos);
void connectionHoverLeft(ConnectionId const connectionId);
/// Signal allows showing custom context menu upon clicking a node.
void nodeContextMenu(NodeId const nodeId, QPointF const pos);
/// Signals to call Graphics View's zoomFit methods
void zoomFitAllClicked();
void zoomFitSelectedClicked();
private:
/**
* @brief Creates Node and Connection graphics objects.
*
* Function is used to populate an empty scene in the constructor. We
* perform depth-first AbstractGraphModel traversal. The connections are
* created by checking non-empty node `Out` ports.
*/
void traverseGraphAndPopulateGraphicsObjects();
/// Redraws adjacent nodes for given `connectionId`
void updateAttachedNodes(ConnectionId const connectionId, PortType const portType);
public Q_SLOTS:
/// Slot called when the `connectionId` is erased form the AbstractGraphModel.
virtual void onConnectionDeleted(ConnectionId const connectionId);
/// Slot called when the `connectionId` is created in the AbstractGraphModel.
virtual void onConnectionCreated(ConnectionId const connectionId);
virtual void onNodeDeleted(NodeId const nodeId);
virtual void onNodeCreated(NodeId const nodeId);
virtual void onNodePositionUpdated(NodeId const nodeId);
virtual void onNodeUpdated(NodeId const nodeId);
virtual void onNodeClicked(NodeId const nodeId);
virtual void onModelReset();
private:
AbstractGraphModel &_graphModel;
using UniqueNodeGraphicsObject = std::unique_ptr<NodeGraphicsObject>;
using UniqueConnectionGraphicsObject = std::unique_ptr<ConnectionGraphicsObject>;
std::unordered_map<NodeId, UniqueNodeGraphicsObject> _nodeGraphicsObjects;
std::unordered_map<ConnectionId, UniqueConnectionGraphicsObject> _connectionGraphicsObjects;
std::unique_ptr<ConnectionGraphicsObject> _draftConnection;
std::unique_ptr<AbstractNodeGeometry> _nodeGeometry;
std::unique_ptr<AbstractNodePainter> _nodePainter;
std::unique_ptr<AbstractConnectionPainter> _connectionPainter;
bool _nodeDrag;
QUndoStack *_undoStack;
Qt::Orientation _orientation;
};
} // namespace QtNodes