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 16 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
3 changes: 2 additions & 1 deletion include/nodes/internal/Connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class NODE_EDITOR_PUBLIC Connection

QJsonObject
save() const override;


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

QUuid
Expand Down
25 changes: 25 additions & 0 deletions include/nodes/internal/FlowScene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ class Connection;
class ConnectionGraphicsObject;
class NodeStyle;

struct SceneHistory
{
QByteArray data;
};

/// Scene holds connections and nodes.
class NODE_EDITOR_PUBLIC FlowScene
: public QGraphicsScene
Expand Down Expand Up @@ -54,6 +59,10 @@ class NODE_EDITOR_PUBLIC FlowScene

Node&restoreNode(QJsonObject const& nodeJson);

QUuid pasteNode(QJsonObject &json);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it const reference


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

void removeNode(Node& node);

DataModelRegistry&registry() const;
Expand Down Expand Up @@ -89,7 +98,17 @@ class NODE_EDITOR_PUBLIC FlowScene

QByteArray saveToMemory() const;

void saveToClipBoard();

void loadFromMemory(const QByteArray& data);

void Undo();

void Redo();

void UpdateHistory();

void ResetHistory();

signals:

Expand All @@ -101,6 +120,8 @@ class NODE_EDITOR_PUBLIC FlowScene
void connectionDeleted(Connection &c);

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

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

void nodeDoubleClicked(Node& n);

Expand All @@ -122,6 +143,10 @@ class NODE_EDITOR_PUBLIC FlowScene
std::unordered_map<QUuid, SharedConnection> _connections;
std::unordered_map<QUuid, UniqueNode> _nodes;
std::shared_ptr<DataModelRegistry> _registry;

int historyInx;
bool writeToHistory;
std::vector< SceneHistory > history;
};

Node*
Expand Down
11 changes: 11 additions & 0 deletions include/nodes/internal/FlowView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ public slots:
void scaleDown();

void deleteSelectedNodes();

void duplicateSelectedNode();

void copySelectedNodes();

void pasteSelectedNodes();

protected:

Expand Down Expand Up @@ -61,6 +67,11 @@ public slots:

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

QPointF _clickPos;

Expand Down
11 changes: 11 additions & 0 deletions include/nodes/internal/Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,25 @@ class NODE_EDITOR_PUBLIC Node
QJsonObject
save() const override;


QJsonObject copyWithNewID(QUuid newId) const;


void
restore(QJsonObject const &json) override;

void
paste(QJsonObject const &json, QUuid ID);



public:

QUuid
id() const;

void setId(QUuid id);

void reactToPossibleConnection(PortType,
NodeDataType,
QPointF const & scenePoint);
Expand Down
9 changes: 9 additions & 0 deletions include/nodes/internal/NodeDataModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class NODE_EDITOR_PUBLIC NodeDataModel
/// Function creates instances of a model stored in DataModelRegistry
virtual std::unique_ptr<NodeDataModel>
clone() const = 0;

void setToolTipText(QString toolTipText);

public:

Expand Down Expand Up @@ -126,6 +128,8 @@ class NODE_EDITOR_PUBLIC NodeDataModel
virtual
NodePainterDelegate* painterDelegate() const { return nullptr; }

QString toolTipText();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be const and inline as other getters


signals:

void
Expand All @@ -139,9 +143,14 @@ class NODE_EDITOR_PUBLIC NodeDataModel

void
computingFinished();

void setToolTipTextSignal(QString text);


private:

QString _toolTipText;

NodeStyle _nodeStyle;
};
}
16 changes: 16 additions & 0 deletions src/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ save() const
}


QJsonObject Connection::copyWithNewID(QUuid in, QUuid out) {
QJsonObject connectionJson;

if (_inNode && _outNode)
{
connectionJson["in_id"] = in.toString();
connectionJson["in_index"] = _inPortIndex;

connectionJson["out_id"] = out.toString();
connectionJson["out_index"] = _outPortIndex;
}

return connectionJson;
}


QUuid
Connection::
id() const
Expand Down
124 changes: 119 additions & 5 deletions src/FlowScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ FlowScene(std::shared_ptr<DataModelRegistry> registry)
: _registry(registry)
{
setItemIndexMethod(QGraphicsScene::NoIndex);

ResetHistory();
UpdateHistory();

auto UpdateLamda = [this](Node& n, const QPointF& p)
{
UpdateHistory();
};
connect(this, &FlowScene::nodeMoveFinished, this, UpdateLamda);
}


Expand Down Expand Up @@ -102,7 +111,7 @@ createConnection(Node& nodeIn,
_connections[connection->id()] = connection;

connectionCreated(*connection);

return connection;
}

Expand All @@ -123,6 +132,20 @@ restoreConnection(QJsonObject const &connectionJson)
return createConnection(*nodeIn, portIndexIn, *nodeOut, portIndexOut);
}

void FlowScene::pasteConnection(QJsonObject const &connectionJson, QUuid newIn, QUuid newOut)
{
QUuid nodeInId = QUuid(connectionJson["in_id"].toString());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused nodeInId and nodeOutId

QUuid nodeOutId = QUuid(connectionJson["out_id"].toString());

PortIndex portIndexIn = connectionJson["in_index"].toInt();
PortIndex portIndexOut = connectionJson["out_index"].toInt();

auto nodeIn = _nodes[newIn].get();
auto nodeOut = _nodes[newOut].get();

createConnection(*nodeIn, portIndexIn, *nodeOut, portIndexOut);
}


void
FlowScene::
Expand All @@ -147,6 +170,7 @@ createNode(std::unique_ptr<NodeDataModel> && dataModel)
_nodes[node->id()] = std::move(node);

nodeCreated(*nodePtr);

return *nodePtr;
}

Expand All @@ -156,26 +180,46 @@ FlowScene::
restoreNode(QJsonObject const& nodeJson)
{
QString modelName = nodeJson["model"].toObject()["name"].toString();

auto dataModel = registry().create(modelName);

if (!dataModel)
throw std::logic_error(std::string("No registered model with name ") +
modelName.toLocal8Bit().data());

auto node = std::make_unique<Node>(std::move(dataModel));
auto ngo = std::make_unique<NodeGraphicsObject>(*this, *node);
node->setGraphicsObject(std::move(ngo));

node->restore(nodeJson);

auto nodePtr = node.get();
_nodes[node->id()] = std::move(node);

nodeCreated(*nodePtr);
return *nodePtr;
}

QUuid FlowScene::pasteNode(QJsonObject &nodeJson) {
QString modelName = nodeJson["model"].toObject()["name"].toString();
auto dataModel = registry().create(modelName);

if (!dataModel)
throw std::logic_error(std::string("No registered model with name ") +
modelName.toLocal8Bit().data());

auto node = std::make_unique<Node>(std::move(dataModel));
auto ngo = std::make_unique<NodeGraphicsObject>(*this, *node);


node->setGraphicsObject(std::move(ngo));

QUuid newId = QUuid::createUuid();
node->paste(nodeJson, newId);

auto nodePtr = node.get();
_nodes[node->id()] = std::move(node);
nodeCreated(*nodePtr);
return newId;
}



void
FlowScene::
Expand Down Expand Up @@ -491,6 +535,11 @@ saveToMemory() const
}


void FlowScene::saveToClipBoard()
{

}

void
FlowScene::
loadFromMemory(const QByteArray& data)
Expand All @@ -510,8 +559,73 @@ loadFromMemory(const QByteArray& data)
{
restoreConnection(connectionJsonArray[i].toObject());
}


}

void FlowScene::Undo()
{
std::cout << "Undo" << std::endl;
if(historyInx > 1)
{
writeToHistory = false;
clearScene();
historyInx--;
loadFromMemory(history[historyInx - 1].data);
writeToHistory = true;
}
}

void FlowScene::Redo()
{
std::cout << "Redo" << std::endl;
writeToHistory = false;
if(historyInx < history.size())
{
std::cout << "historyInx:" << historyInx << " history.size():" << history.size() << std::endl;
clearScene();
loadFromMemory(history[historyInx].data);
historyInx++;
}
else
{
std::cout << "Could not redo" << std::endl;
}
writeToHistory = true;
}

void FlowScene::UpdateHistory()
{
if(writeToHistory)
{
std::cout << "UpdateHistory" << std::endl;

SceneHistory sh;
sh.data = saveToMemory();

if(historyInx < history.size())
{
history.resize(historyInx);
history.push_back(sh);
}
else
{
history.push_back(sh);
}

historyInx++;
}
}

void FlowScene::ResetHistory()
{
historyInx = 0;
writeToHistory = true;
history.clear();
}




//------------------------------------------------------------------------------
namespace QtNodes
Expand Down
Loading