Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added duplicate selection (CTRL+D), undo and redo (CTRL+Z/Y) with scene history. #133

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
27433e0
Added duplicate action to the flow view. Removed shadow effect from n…
Nov 8, 2017
4b90d7d
Added duplicating connections, there is a bug to handle connections t…
Nov 8, 2017
c508028
added CTRL+D key sequence for duplicate
Nov 9, 2017
facd31b
Fixed node delete pointer error
Nov 9, 2017
a92ba58
Added very simple Undo Redo system
Nov 9, 2017
e42fe23
Added action context WidgetWithChildrenShortcut. Added duplication of…
Nov 14, 2017
b5f7310
added updating history for node movement
Nov 15, 2017
09a2681
Merge branch 'master' of https://github.com/paceholder/nodeeditor
Nov 15, 2017
d649c82
Added Fix for Mingw "invalid initialization of non-const reference of…
Nov 17, 2017
c073764
added setViewportUpdateMode(QGraphicsView::FullViewportUpdate); to fl…
Feb 7, 2018
243c382
Turn on/off the background grid render based on scale in viewport for…
Feb 19, 2018
7215528
Added the ability to set the tool tip for each node
Feb 20, 2018
7631c27
Merge branch 'master' of https://github.com/paceholder/nodeeditor
Feb 22, 2018
477d904
Made the signal and slot compatible for the setToolTip signal in the …
Feb 22, 2018
516ce86
Merge branch 'master' of https://github.com/paceholder/nodeeditor
Mar 14, 2018
bc9c58f
Added copy/paste between sheets
Jan 17, 2019
a0adb17
Started groups, added anchors, fixed position of nodes when pasting
jacquespillet Nov 1, 2019
02c5c7d
Added getter for history index, added resizing nodes
jacquespillet Nov 6, 2019
ddbe4a8
Started groups
jacquespillet Jan 6, 2020
4c2812f
continued groups
jacquespillet Apr 7, 2021
d341631
added deleted node
jacquespillet Apr 19, 2021
f6fb7b8
Added node templates
jacquespillet Aug 27, 2021
0eb037a
Fixes on groups
jacquespillet Sep 22, 2021
b91389b
Added snapping
jacquespillet Nov 15, 2021
51804f1
Added Collapsable group
jacquespillet Jan 26, 2022
d198287
Update view on geometry
jacquespillet Aug 8, 2022
a0318ec
Loading optimizations
jacquespillet Sep 22, 2022
54b5cf9
Optimized loading
jacquespillet Nov 21, 2022
410c823
started undoRedo
jacquespillet Nov 21, 2022
1c95c67
Merge branch 'master' of https://github.com/ScanLAB-Projects/nodeeditor
jacquespillet Nov 21, 2022
09d7926
progress on undo/redo system
jacquespillet Nov 22, 2022
8b041d4
UndoRedo for paste, duplicate and create connection
jacquespillet Dec 6, 2022
54c1f5b
fixed undo redo
jacquespillet Dec 9, 2022
c070645
added gotonode function
jacquespillet Nov 23, 2023
f5a177f
added go to node id
jacquespillet Jun 10, 2024
7e89261
added input colour to node
jacquespillet Sep 25, 2024
6f8c72d
fix crash
tomscanlab Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.py
*.pyc
CMakeLists.txt.user
/build
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ set(CPP_SOURCE_FILES
src/FlowView.cpp
src/FlowViewStyle.cpp
src/Node.cpp
src/Group.cpp
src/GroupGraphicsObject.cpp
src/NodeConnectionInteraction.cpp
src/NodeDataModel.cpp
src/NodeGeometry.cpp
Expand Down
23 changes: 21 additions & 2 deletions include/nodes/internal/Connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace QtNodes
class Node;
class NodeData;
class ConnectionGraphicsObject;
class Group;

///
class NODE_EDITOR_PUBLIC Connection
Expand All @@ -44,7 +45,8 @@ class NODE_EDITOR_PUBLIC Connection
Connection(Node& nodeIn,
PortIndex portIndexIn,
Node& nodeOut,
PortIndex portIndexOut);
PortIndex portIndexOut,
QUuid *id = nullptr);

Connection(const Connection&) = delete;
Connection operator=(const Connection&) = delete;
Expand All @@ -55,7 +57,8 @@ class NODE_EDITOR_PUBLIC Connection

QJsonObject
save() const override;


QJsonObject copyWithNewID(QUuid in, QUuid out);
public:

QUuid
Expand All @@ -78,6 +81,10 @@ class NODE_EDITOR_PUBLIC Connection
setNodeToPort(Node& node,
PortType portType,
PortIndex portIndex);
void
setGroup(Group* group,
PortType portType,
PortIndex portIndex);

void
removeFromNodes() const;
Expand All @@ -104,8 +111,14 @@ class NODE_EDITOR_PUBLIC Connection
Node*&
getNode(PortType portType);

Group*
getGroup(PortType portType) const;

PortIndex
getPortIndex(PortType portType) const;

PortIndex
getGroupPortIndex(PortType portType) const;

void
clearNode(PortType portType);
Expand All @@ -132,6 +145,12 @@ class NODE_EDITOR_PUBLIC Connection
PortIndex _outPortIndex;
PortIndex _inPortIndex;

Group* _outGroup = nullptr;
Group* _inGroup = nullptr;

PortIndex _outGroupPortIndex;
PortIndex _inGroupPortIndex;

private:

ConnectionState _connectionState;
Expand Down
22 changes: 21 additions & 1 deletion include/nodes/internal/DataModelRegistry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class NODE_EDITOR_PUBLIC DataModelRegistry
using RegisteredModelsCategoryMap = std::unordered_map<QString, QString>;
using CategoriesSet = std::set<QString>;

using RegisteredTemplatesMap = std::unordered_map<QString, QString>;

struct TypeConverterItem
{
RegistryItemPtr Model{};
Expand Down Expand Up @@ -82,10 +84,23 @@ class NODE_EDITOR_PUBLIC DataModelRegistry
converter->DestinationType = converter->Model->dataType(PortType::Out, 0);

auto typeConverterKey = std::make_pair(converter->SourceType.id, converter->DestinationType.id);
_registeredTypeConverters[typeConverterKey] = std::move(converter);
_registeredTypeConverters[typeConverterKey] = std::move(converter);
}
}

void
registerTemplate(QString templateName, QString templateFilePath)
{
_registeredTemplates[templateName] = templateFilePath;
}

void
removeTemplate(QString templateName)
{
_registeredTemplates.erase(templateName);
}


//Parameter order alias, so a category can be set without forcing to manually pass a model instance
template<typename ModelType, bool TypeConverter = false>
void
Expand All @@ -103,6 +118,9 @@ class NODE_EDITOR_PUBLIC DataModelRegistry
RegisteredModelsCategoryMap const &
registeredModelsCategoryAssociation() const;

RegisteredTemplatesMap &
RegisteredTemplates();

CategoriesSet const &
categories() const;

Expand All @@ -116,5 +134,7 @@ class NODE_EDITOR_PUBLIC DataModelRegistry
CategoriesSet _categories{};
RegisteredModelsMap _registeredModels{};
RegisteredTypeConvertersMap _registeredTypeConverters{};

RegisteredTemplatesMap _registeredTemplates{};
};
}
103 changes: 98 additions & 5 deletions include/nodes/internal/FlowScene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,40 @@
#include "QUuidStdHash.hpp"
#include "Export.hpp"
#include "DataModelRegistry.hpp"
#include <stack>

namespace QtNodes
{

class NodeDataModel;
class FlowItemInterface;
class Node;
class Group;
class NodeGraphicsObject;
class Connection;
class ConnectionGraphicsObject;
class NodeStyle;



struct UndoRedoAction {

std::function<int(void*)> undoAction;
std::function<int(void*)> redoAction;
std::string name;
UndoRedoAction(std::function<int(void*)> undoAction, std::function<int(void*)> redoAction, std::string name) {
this->undoAction = undoAction;
this->redoAction = redoAction;
this->name = name;
};
};


struct Anchor {
QPointF position;
double scale;
};

/// Scene holds connections and nodes.
class NODE_EDITOR_PUBLIC FlowScene
: public QGraphicsScene
Expand All @@ -35,6 +57,10 @@ class NODE_EDITOR_PUBLIC FlowScene

~FlowScene();

std::vector<UndoRedoAction> undoActions;
std::vector<UndoRedoAction> redoActions;
void PrintActions();
int historyInx;
public:

std::shared_ptr<Connection>createConnection(PortType connectedPort,
Expand All @@ -44,18 +70,37 @@ class NODE_EDITOR_PUBLIC FlowScene
std::shared_ptr<Connection>createConnection(Node& nodeIn,
PortIndex portIndexIn,
Node& nodeOut,
PortIndex portIndexOut);
PortIndex portIndexOut,
QUuid *id=nullptr);

std::shared_ptr<Connection>restoreConnection(QJsonObject const &connectionJson);

void deleteConnection(Connection& connection);
void deleteConnection(Connection* connection);
void deleteConnectionWithID(QUuid id);

Node&createNode(std::unique_ptr<NodeDataModel> && dataModel);

Node&createNodeWithID(std::unique_ptr<NodeDataModel> && dataModel, QUuid id);

Group& createGroup();

Group& pasteGroup(QJsonObject const& nodeJson, QPointF nodeGroupCentroid, QPointF mousePos);

Node&restoreNode(QJsonObject const& nodeJson);
Node&restoreNode(QJsonObject const& nodeJson, bool keepId=false);

Group& restoreGroup(QJsonObject const& nodeJson);

QUuid pasteNode(QJsonObject &json, QPointF nodeGroupCentroid, QPointF mousePos);

void pasteConnection(QJsonObject const &connectionJson, QUuid newIn, QUuid newOut);

void removeNode(Node& node);

void removeNodeWithID(QUuid id);

void removeGroup(Group& node);

DataModelRegistry&registry() const;

void setRegistry(std::shared_ptr<DataModelRegistry> registry);
Expand All @@ -71,13 +116,19 @@ class NODE_EDITOR_PUBLIC FlowScene
void setNodePosition(Node& node, const QPointF& pos) const;

QSizeF getNodeSize(const Node& node) const;

void resolveGroups(Group& node);

void resolveGroups(Node& n);

public:

std::unordered_map<QUuid, std::unique_ptr<Node> > const &nodes() const;
std::unordered_map<QUuid, std::shared_ptr<Node> > const &nodes() const;
std::unordered_map<QUuid, std::shared_ptr<Node> > &nodes();

std::unordered_map<QUuid, std::shared_ptr<Connection> > const &connections() const;

std::vector<Node*>selectedNodes() const;
std::vector<std::shared_ptr<Node>>selectedNodes() const;

public:

Expand All @@ -89,20 +140,45 @@ class NODE_EDITOR_PUBLIC FlowScene

QByteArray saveToMemory() const;

void saveToClipBoard();

void loadFromMemory(const QByteArray& data);

void AddAction(UndoRedoAction action);

void Undo();

void Redo();

void ResetHistory();

int GetHistoryIndex();

signals:

void nodeCreated(Node &n);

void groupCreated(Group &g);

void nodeDeleted(Node &n);

void connectionCreated(Connection &c);

void connectionDeleted(Connection &c);

void nodeMoved(Node& n, const QPointF& newLocation);

void groupMoved(Group& n, const QPointF& newLocation);

void nodeMoveFinished(Node& n, const QPointF& newLocation, const QPointF &oldLocation);

void groupMoveFinished(Group& g, const QPointF& newLocation, const QPointF& oldLocation);

void nodeClicked(Node& n);

void nodeDoubleClicked(Node& n);

void groupDoubleClicked(Group& g);

void connectionHovered(Connection& c, QPoint screenPos);

Expand All @@ -113,18 +189,35 @@ class NODE_EDITOR_PUBLIC FlowScene
void nodeHoverLeft(Node& n);

void nodeContextMenu(Node& n, const QPointF& pos);


public:

std::vector<Anchor> anchors;

int gridSize=1;
bool snapping=false;

private:

using SharedConnection = std::shared_ptr<Connection>;
using UniqueNode = std::unique_ptr<Node>;
using UniqueNode = std::shared_ptr<Node>;

std::unordered_map<QUuid, SharedConnection> _connections;
std::unordered_map<QUuid, UniqueNode> _nodes;
std::shared_ptr<DataModelRegistry> _registry;
std::unordered_map<QUuid, std::shared_ptr<Group>> _groups;

bool writeToHistory;


private:
};

Node*
locateNodeAt(QPointF scenePoint, FlowScene &scene,
QTransform viewTransform);
Group*
locateGroupAt(QPointF scenePoint, FlowScene &scene,
QTransform viewTransform);
}
31 changes: 29 additions & 2 deletions include/nodes/internal/FlowView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
#include <QtWidgets/QGraphicsView>

#include "Export.hpp"

namespace QtNodes
{

class FlowScene;
class NodeGraphicsObject;

class NODE_EDITOR_PUBLIC FlowView
: public QGraphicsView
Expand All @@ -27,13 +28,28 @@ class NODE_EDITOR_PUBLIC FlowView

void setScene(FlowScene *scene);

QJsonObject selectionToJson(bool includePartialConnections=false);
void jsonToScene(QJsonObject object);
void jsonToSceneMousePos(QJsonObject object);
void deleteJsonElements(const QJsonObject &object);

void goToNode(NodeGraphicsObject *node);
void goToNodeID(QUuid ID);


public slots:

void scaleUp();

void scaleDown();

void deleteSelectedNodes();

void duplicateSelectedNode();

void copySelectedNodes();

void pasteSelectedNodes();

protected:

Expand All @@ -53,6 +69,10 @@ public slots:

void showEvent(QShowEvent *event) override;

void addAnchor(int index);
void goToAnchor(int index);


protected:

FlowScene * scene();
Expand All @@ -61,6 +81,13 @@ public slots:

QAction* _clearSelectionAction;
QAction* _deleteSelectionAction;
QAction* _duplicateSelectionAction;
QAction* _copymultiplenodes;
QAction* _pastemultiplenodes;
QAction* _undoAction;
QAction* _redoAction;

std::vector<QAction*> anchorActions;

QPointF _clickPos;

Expand Down
Loading