From 708011ca445e6096d693bde77b63b43b9de78e54 Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Mon, 18 Dec 2017 17:59:56 +0000 Subject: adding node position tracking for undo --- tikzit/src/gui/nodeitem.cpp | 14 +++++++++-- tikzit/src/gui/nodeitem.h | 5 +++- tikzit/src/gui/tikzscene.cpp | 52 +++++++++++++++++++++++++++++------------ tikzit/src/gui/tikzscene.h | 15 +++++++++--- tikzit/src/gui/undocommands.cpp | 21 +++++++++++++---- tikzit/src/gui/undocommands.h | 7 +++++- 6 files changed, 88 insertions(+), 26 deletions(-) (limited to 'tikzit/src/gui') diff --git a/tikzit/src/gui/nodeitem.cpp b/tikzit/src/gui/nodeitem.cpp index bf4830b..40b4de9 100644 --- a/tikzit/src/gui/nodeitem.cpp +++ b/tikzit/src/gui/nodeitem.cpp @@ -17,14 +17,19 @@ NodeItem::NodeItem(Node *node) setFlag(QGraphicsItem::ItemIsSelectable); setFlag(QGraphicsItem::ItemIsMovable); setFlag(QGraphicsItem::ItemSendsGeometryChanges); - syncPos(); + readPos(); } -void NodeItem::syncPos() +void NodeItem::readPos() { setPos(toScreen(_node->point())); } +void NodeItem::writePos() +{ + _node->setPoint(fromScreen(pos())); +} + QRectF NodeItem::labelRect() const { QString label = _node->label(); //QFont f("Courier", 9); @@ -99,6 +104,11 @@ QRectF NodeItem::boundingRect() const return r.united(shape().boundingRect()).adjusted(-4,-4,4,4); } +Node *NodeItem::node() const +{ + return _node; +} + QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange) { diff --git a/tikzit/src/gui/nodeitem.h b/tikzit/src/gui/nodeitem.h index 2228874..d0f1e62 100644 --- a/tikzit/src/gui/nodeitem.h +++ b/tikzit/src/gui/nodeitem.h @@ -16,11 +16,14 @@ class NodeItem : public QGraphicsItem { public: NodeItem(Node *node); - void syncPos(); + void readPos(); + void writePos(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QVariant itemChange(GraphicsItemChange change, const QVariant &value); QPainterPath shape() const; QRectF boundingRect() const; + Node *node() const; + private: Node *_node; QRectF labelRect() const; diff --git a/tikzit/src/gui/tikzscene.cpp b/tikzit/src/gui/tikzscene.cpp index cd88f4e..5722d0d 100644 --- a/tikzit/src/gui/tikzscene.cpp +++ b/tikzit/src/gui/tikzscene.cpp @@ -1,8 +1,3 @@ -/** - * Manage the scene, which contains a single Graph, and respond to user input. This serves as - * the controller for the MVC (Graph, TikzView, TikzScene). - */ - #include "tikzit.h" #include "tikzscene.h" @@ -32,27 +27,27 @@ void TikzScene::setGraph(Graph *graph) void TikzScene::graphReplaced() { - foreach (NodeItem *ni, nodeItems) { + foreach (NodeItem *ni, _nodeItems) { removeItem(ni); delete ni; } - nodeItems.clear(); + _nodeItems.clear(); - foreach (EdgeItem *ei, edgeItems) { + foreach (EdgeItem *ei, _edgeItems) { removeItem(ei); delete ei; } - edgeItems.clear(); + _edgeItems.clear(); foreach (Edge *e, _graph->edges()) { EdgeItem *ei = new EdgeItem(e); - edgeItems << ei; + _edgeItems << ei; addItem(ei); } foreach (Node *n, _graph->nodes()) { NodeItem *ni = new NodeItem(n); - nodeItems << ni; + _nodeItems << ni; addItem(ni); } } @@ -68,10 +63,10 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event) // TODO: check if we grabbed a control point QGraphicsScene::mousePressEvent(event); if (!selectedItems().empty() && !items(mousePos).empty()) { - _oldNodePositions = new QHash(); - for (QGraphicsItem *gi : selectedItems()) { + _oldNodePositions.clear(); + foreach (QGraphicsItem *gi, selectedItems()) { if (NodeItem *ni = dynamic_cast(gi)) { - _oldNodePositions-> + _oldNodePositions.insert(ni->node(), ni->node()->point()); } } qDebug() << "I am dragging"; @@ -101,7 +96,7 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } // TODO: only sync edges that change - foreach (EdgeItem *ei, edgeItems) { + foreach (EdgeItem *ei, _edgeItems) { ei->edge()->updateControls(); ei->syncPos(); } @@ -112,6 +107,23 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) switch (tikzit->toolPalette()->currentTool()) { case ToolPalette::SELECT: QGraphicsScene::mouseReleaseEvent(event); + + if (!_oldNodePositions.empty()) { + QMap newNodePositions; + + foreach (QGraphicsItem *gi, selectedItems()) { + if (NodeItem *ni = dynamic_cast(gi)) { + ni->writePos(); + newNodePositions.insert(ni->node(), ni->node()->point()); + } + } + + qDebug() << _oldNodePositions; + qDebug() << newNodePositions; + + _oldNodePositions.clear(); + } + break; case ToolPalette::VERTEX: break; @@ -121,3 +133,13 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) break; } } + +QVector TikzScene::edgeItems() const +{ + return _edgeItems; +} + +QVector TikzScene::nodeItems() const +{ + return _nodeItems; +} diff --git a/tikzit/src/gui/tikzscene.h b/tikzit/src/gui/tikzscene.h index e0e75c1..b12c749 100644 --- a/tikzit/src/gui/tikzscene.h +++ b/tikzit/src/gui/tikzscene.h @@ -1,3 +1,8 @@ +/** + * Manage the scene, which contains a single Graph, and respond to user input. This serves as + * the controller for the MVC (Graph, TikzView, TikzScene). + */ + #ifndef TIKZSCENE_H #define TIKZSCENE_H @@ -21,6 +26,10 @@ public: ~TikzScene(); Graph *graph() const; void setGraph(Graph *graph); + QVector nodeItems() const; + + QVector edgeItems() const; + public slots: void graphReplaced(); protected: @@ -29,9 +38,9 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: Graph *_graph; - QVector nodeItems; - QVector edgeItems; - QHash *_oldNodePositions; + QVector _nodeItems; + QVector _edgeItems; + QMap _oldNodePositions; }; #endif // TIKZSCENE_H diff --git a/tikzit/src/gui/undocommands.cpp b/tikzit/src/gui/undocommands.cpp index 38f7569..6d48fc4 100644 --- a/tikzit/src/gui/undocommands.cpp +++ b/tikzit/src/gui/undocommands.cpp @@ -1,16 +1,29 @@ #include "undocommands.h" -MoveCommand::MoveCommand(TikzScene *scene, QUndoCommand *parent) : QUndoCommand(parent) +MoveCommand::MoveCommand(TikzScene *scene, + QMap oldNodePositions, + QMap newNodePositions, + QUndoCommand *parent) : + QUndoCommand(parent), + _scene(scene), + _oldNodePositions(oldNodePositions), + _newNodePositions(newNodePositions) { - _scene = scene; } + void MoveCommand::undo() { - + foreach (NodeItem *ni, _scene->nodeItems()) { + if (_oldNodePositions.contains(ni->node())) + ni->node()->setPoint(_oldNodePositions.value(ni->node())); + } } void MoveCommand::redo() { - + foreach (NodeItem *ni, _scene->nodeItems()) { + if (_newNodePositions.contains(ni->node())) + ni->node()->setPoint(_newNodePositions.value(ni->node())); + } } diff --git a/tikzit/src/gui/undocommands.h b/tikzit/src/gui/undocommands.h index bbdf6c3..bdf9ad2 100644 --- a/tikzit/src/gui/undocommands.h +++ b/tikzit/src/gui/undocommands.h @@ -12,11 +12,16 @@ class MoveCommand : public QUndoCommand { public: - explicit MoveCommand(TikzScene *scene, QUndoCommand *parent = 0); + explicit MoveCommand(TikzScene *scene, + QMap oldNodePositions, + QMap newNodePositions, + QUndoCommand *parent = 0); void undo() override; void redo() override; private: TikzScene *_scene; + QMap _oldNodePositions; + QMap _newNodePositions; }; #endif // UNDOCOMMANDS_H -- cgit v1.2.3