Skip to content

Commit aca8e43

Browse files
authored
Merge branch 'master' into upstream_progress_value
2 parents 878bb50 + 0d28130 commit aca8e43

28 files changed

Lines changed: 2229 additions & 91 deletions

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ set(CPP_SOURCE_FILES
8787
src/StyleCollection.cpp
8888
src/UndoCommands.cpp
8989
src/locateNode.cpp
90+
src/GroupGraphicsObject.cpp
91+
src/NodeGroup.cpp
9092
resources/resources.qrc
9193
)
9294

@@ -127,6 +129,8 @@ set(HPP_HEADER_FILES
127129
include/QtNodes/internal/DefaultVerticalNodeGeometry.hpp
128130
include/QtNodes/internal/NodeConnectionInteraction.hpp
129131
include/QtNodes/internal/UndoCommands.hpp
132+
include/QtNodes/internal/NodeGroup.hpp
133+
include/QtNodes/internal/GroupGraphicsObject.hpp
130134
)
131135

132136
# If we want to give the option to build a static library,

examples/calculator/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ int main(int argc, char *argv[])
112112
mainWidget.setWindowModified(true);
113113
});
114114

115+
if (scene->groupingEnabled()) {
116+
auto loadGroupAction = menu->addAction("Load Group...");
117+
QObject::connect(loadGroupAction, &QAction::triggered, [scene] { scene->loadGroupFile(); });
118+
}
119+
115120
mainWidget.setWindowTitle("[*]Data Flow: simplest calculator");
116121
mainWidget.resize(800, 600);
117122
// Center window.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "internal/GroupGraphicsObject.hpp"

include/QtNodes/NodeGroup

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "internal/NodeGroup.hpp"

include/QtNodes/internal/BasicGraphicsScene.hpp

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
#include "ConnectionIdHash.hpp"
66
#include "Definitions.hpp"
77
#include "Export.hpp"
8+
#include "GroupGraphicsObject.hpp"
9+
#include "NodeGroup.hpp"
10+
#include "UndoCommands.hpp"
811

9-
#include "QUuidStdHash.hpp"
10-
11-
#include <QtCore/QUuid>
12+
#include <QtCore/QJsonObject>
1213
#include <QtWidgets/QGraphicsScene>
1314
#include <QtWidgets/QMenu>
1415

@@ -27,6 +28,11 @@ class AbstractNodePainter;
2728
class ConnectionGraphicsObject;
2829
class NodeGraphicsObject;
2930
class NodeStyle;
31+
class DeleteCommand;
32+
class CopyCommand;
33+
class NodeGroup;
34+
class GroupGraphicsObject;
35+
struct ConnectionId;
3036

3137
/// An instance of QGraphicsScene, holds connections and nodes.
3238
class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
@@ -62,6 +68,17 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
6268

6369
QUndoStack &undoStack();
6470

71+
/**
72+
* @brief Setter for the _groupingEnabled flag.
73+
* @param boolean to set or not the flag.
74+
*/
75+
void setGroupingEnabled(bool enabled);
76+
77+
/**
78+
* @brief Getter for the _groupingEnabled flag.
79+
*/
80+
bool groupingEnabled() const { return _groupingEnabled; }
81+
6582
public:
6683
/**
6784
* @brief Creates a "draft" instance of ConnectionGraphicsObject.
@@ -87,6 +104,83 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
87104
/// Deletes all the nodes. Connections are removed automatically.
88105
void clearScene();
89106

107+
/**
108+
* @brief Creates a list of the connections that are incident only to nodes within a
109+
* given group.
110+
* @param groupID ID of the desired group.
111+
* @return List of (pointers of) connections whose both endpoints belong to members of
112+
* the specified group.
113+
*/
114+
std::vector<std::shared_ptr<ConnectionId>> connectionsWithinGroup(GroupId groupID);
115+
/**
116+
* @brief Creates a group in the scene containing the given nodes.
117+
* @param nodes Reference to the list of nodes to be included in the group.
118+
* @param name Group's name.
119+
* @param groupId Group's id.
120+
* @return Pointer to the newly-created group.
121+
*/
122+
std::weak_ptr<NodeGroup> createGroup(std::vector<NodeGraphicsObject *> &nodes,
123+
QString name = QStringLiteral(""),
124+
GroupId groupId = InvalidGroupId);
125+
126+
/**
127+
* @brief Creates a group in the scene containing the currently selected nodes.
128+
* @param name Group's name
129+
* @return Pointer to the newly-created group.
130+
*/
131+
std::weak_ptr<NodeGroup> createGroupFromSelection(QString groupName = QStringLiteral(""));
132+
133+
/**
134+
* @brief Restores a group from a JSON object.
135+
* @param groupJson JSON object containing the group data.
136+
* @return Pair consisting of a pointer to the newly-created group and the mapping
137+
* between old and new nodes.
138+
*/
139+
std::pair<std::weak_ptr<NodeGroup>, std::unordered_map<GroupId, GroupId>> restoreGroup(
140+
QJsonObject const &groupJson);
141+
142+
/**
143+
* @brief Returns a const reference to the mapping of existing groups.
144+
*/
145+
std::unordered_map<GroupId, std::shared_ptr<NodeGroup>> const &groups() const;
146+
147+
/**
148+
* @brief Loads a group from a file specified by the user.
149+
* @return Pointer to the newly-created group.
150+
*/
151+
std::weak_ptr<NodeGroup> loadGroupFile();
152+
153+
/**
154+
* @brief Saves a group in a .group file.
155+
* @param groupID Group's id.
156+
*/
157+
void saveGroupFile(GroupId groupID);
158+
159+
/**
160+
* @brief Calculates the selected nodes.
161+
* @return Vector containing the NodeGraphicsObject pointers related to the selected nodes.
162+
*/
163+
std::vector<NodeGraphicsObject *> selectedNodes() const;
164+
165+
/**
166+
* @brief Calculates the selected groups.
167+
* @return Vector containing the GroupGraphicsObject pointers related to the selected groups.
168+
*/
169+
std::vector<GroupGraphicsObject *> selectedGroups() const;
170+
171+
/**
172+
* @brief Adds a node to a group, if both node and group exists.
173+
* @param nodeId Node's id.
174+
* @param groupId Group's id.
175+
*/
176+
void addNodeToGroup(NodeId nodeId, GroupId groupId);
177+
178+
/**
179+
* @brief Removes a node from a group, if the node exists and is within a group.
180+
* @param nodeId Node's id.
181+
*/
182+
void removeNodeFromGroup(NodeId nodeId);
183+
90184
public:
91185
/**
92186
* @returns NodeGraphicsObject associated with the given nodeId.
@@ -111,6 +205,17 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
111205
*/
112206
virtual QMenu *createSceneMenu(QPointF const scenePos);
113207

208+
/**
209+
* @brief Creates the default menu when a node is selected.
210+
*/
211+
QMenu *createStdMenu(QPointF const scenePos);
212+
213+
/**
214+
* @brief Creates the menu when a group is selected.
215+
* @param groupGo reference to the GroupGraphicsObject related to the selected group.
216+
*/
217+
QMenu *createGroupMenu(QPointF const scenePos, GroupGraphicsObject *groupGo);
218+
114219
Q_SIGNALS:
115220
void modified(BasicGraphicsScene *);
116221
void nodeMoved(NodeId const nodeId, QPointF const &newLocation);
@@ -141,6 +246,24 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
141246
/// Redraws adjacent nodes for given `connectionId`
142247
void updateAttachedNodes(ConnectionId const connectionId, PortType const portType);
143248

249+
/**
250+
* @brief Loads a JSON object that represents a node, with the option
251+
* to keep the stored node id or generate a new one.
252+
* @param nodeJson The JSON object representing a node.
253+
* @param keepOriginalId If true, the loaded node will have the same id as the one stored in
254+
* the file; otherwise, a new id will be generated
255+
* @return A reference to the NodeGraphicsObject related to the loaded node.
256+
*/
257+
NodeGraphicsObject &loadNodeToMap(QJsonObject nodeJson, bool keepOriginalId = false);
258+
259+
/**
260+
* @brief Loads a connection between nodes from a JSON file.
261+
* @param connectionJson JSON object that stores the connection's endpoints.
262+
* @param nodeIdMap Map of nodes (i.e. all possible endpoints).
263+
*/
264+
void loadConnectionToMap(QJsonObject const &connectionJson,
265+
std::unordered_map<NodeId, NodeId> const &nodeIdMap);
266+
144267
public Q_SLOTS:
145268
/// Slot called when the `connectionId` is erased form the AbstractGraphModel.
146269
virtual void onConnectionDeleted(ConnectionId const connectionId);
@@ -155,21 +278,37 @@ public Q_SLOTS:
155278
virtual void onNodeClicked(NodeId const nodeId);
156279
virtual void onModelReset();
157280

281+
/**
282+
* @brief Slot called to trigger the copy command action.
283+
*/
284+
void onCopySelectedObjects() { undoStack().push(new CopyCommand(this)); }
285+
286+
/**
287+
* @brief Slot called to trigger the delete command action.
288+
*/
289+
void onDeleteSelectedObjects() { undoStack().push(new DeleteCommand(this)); }
290+
158291
private:
159292
AbstractGraphModel &_graphModel;
160293

161294
using UniqueNodeGraphicsObject = std::unique_ptr<NodeGraphicsObject>;
162295
using UniqueConnectionGraphicsObject = std::unique_ptr<ConnectionGraphicsObject>;
296+
using SharedGroup = std::shared_ptr<NodeGroup>;
163297

164298
std::unordered_map<NodeId, UniqueNodeGraphicsObject> _nodeGraphicsObjects;
165299
std::unordered_map<ConnectionId, UniqueConnectionGraphicsObject> _connectionGraphicsObjects;
300+
GroupId nextGroupId();
301+
302+
std::unordered_map<GroupId, SharedGroup> _groups{};
303+
GroupId _nextGroupId{0};
166304
std::unique_ptr<ConnectionGraphicsObject> _draftConnection;
167305
std::unique_ptr<AbstractNodeGeometry> _nodeGeometry;
168306
std::unique_ptr<AbstractNodePainter> _nodePainter;
169307
std::unique_ptr<AbstractConnectionPainter> _connectionPainter;
170308
bool _nodeDrag;
171309
QUndoStack *_undoStack;
172310
Qt::Orientation _orientation;
311+
bool _groupingEnabled;
173312
};
174313

175314
} // namespace QtNodes

include/QtNodes/internal/Definitions.hpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ Q_NAMESPACE_EXPORT(NODE_EDITOR_PUBLIC)
2121
/**
2222
* Constants used for fetching QVariant data from GraphModel.
2323
*/
24-
enum class NodeRole {
25-
Type = 0, ///< Type of the current node, usually a string.
26-
Position = 1, ///< `QPointF` positon of the node on the scene.
27-
Size = 2, ///< `QSize` for resizable nodes.
28-
CaptionVisible = 3, ///< `bool` for caption visibility.
29-
Caption = 4, ///< `QString` for node caption.
30-
Style = 5, ///< Custom NodeStyle as QJsonDocument
31-
InternalData = 6, ///< Node-stecific user data as QJsonObject
32-
InPortCount = 7, ///< `unsigned int`
33-
OutPortCount = 9, ///< `unsigned int`
34-
Widget = 10, ///< Optional `QWidget*` or `nullptr`
35-
ValidationState = 11, ///< Enum NodeValidationState of the node
36-
ProcessingStatus = 12, ///< Enum NodeProcessingStatus of the node
37-
ProgressValue = 13, ///< 'QString' for the progress value
38-
};
24+
enum class NodeRole {
25+
Type = 0, ///< Type of the current node, usually a string.
26+
Position = 1, ///< `QPointF` positon of the node on the scene.
27+
Size = 2, ///< `QSize` for resizable nodes.
28+
CaptionVisible = 3, ///< `bool` for caption visibility.
29+
Caption = 4, ///< `QString` for node caption.
30+
Style = 5, ///< Custom NodeStyle as QJsonDocument
31+
InternalData = 6, ///< Node-stecific user data as QJsonObject
32+
InPortCount = 7, ///< `unsigned int`
33+
OutPortCount = 9, ///< `unsigned int`
34+
Widget = 10, ///< Optional `QWidget*` or `nullptr`
35+
ValidationState = 11, ///< Enum NodeValidationState of the node
36+
ProcessingStatus = 12, ///< Enum NodeProcessingStatus of the node
37+
ProgressValue = 13, ///< 'QString' for the progress value
38+
};
3939
Q_ENUM_NS(NodeRole)
4040

4141
/**
@@ -95,6 +95,11 @@ using NodeId = unsigned int;
9595

9696
static constexpr NodeId InvalidNodeId = std::numeric_limits<NodeId>::max();
9797

98+
/// Unique Id associated with each node group.
99+
using GroupId = unsigned int;
100+
101+
static constexpr GroupId InvalidGroupId = std::numeric_limits<GroupId>::max();
102+
98103
/**
99104
* A unique connection identificator that stores
100105
* out `NodeId`, out `PortIndex`, in `NodeId`, in `PortIndex`

include/QtNodes/internal/GraphicsView.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public Q_SLOTS:
9191
private:
9292
QAction *_clearSelectionAction = nullptr;
9393
QAction *_deleteSelectionAction = nullptr;
94+
QAction *_cutSelectionAction = nullptr;
9495
QAction *_duplicateSelectionAction = nullptr;
9596
QAction *_copySelectionAction = nullptr;
9697
QAction *_pasteAction = nullptr;

0 commit comments

Comments
 (0)