From 8b8ea9395bdda4bb1404497ff654b82098084822 Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Sun, 18 Mar 2018 11:58:33 -0400 Subject: finally got bboxes working...i think --- src/data/graph.cpp | 23 +++++++++++------- src/data/graph.h | 14 +++++++++-- src/gui/tikzscene.cpp | 62 ++++++++++++++++++++++++++++++++---------------- src/gui/tikzscene.h | 3 ++- src/gui/undocommands.cpp | 7 ++++-- src/tikzit.h | 16 +++++++++++-- 6 files changed, 90 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/data/graph.cpp b/src/data/graph.cpp index 7a5fedc..208cd00 100644 --- a/src/data/graph.cpp +++ b/src/data/graph.cpp @@ -66,6 +66,19 @@ int Graph::maxIntName() return max; } +QRectF Graph::realBbox() +{ + float maxX = 0.0f; + QRectF rect = bbox(); + foreach (Node *n, _nodes) { + rect = rect.united(QRectF(n->point().x()-0.5f, + n->point().y()-0.5f, + 1.0f, 1.0f)); + } + + return rect; +} + QString Graph::freshNodeName() { return QString::number(maxIntName() + 1); @@ -228,14 +241,8 @@ Graph *Graph::copyOfSubgraphWithNodes(QSet nds) void Graph::insertGraph(Graph *graph) { QMap nodeTable; - foreach (Node *n, graph->nodes()) { - Node *n1 = n->copy(); - nodeTable.insert(n, n1); - addNode(n1); - } - foreach (Edge *e, graph->edges()) { - addEdge(e->copy(&nodeTable)); - } + foreach (Node *n, graph->nodes()) addNode(n); + foreach (Edge *e, graph->edges()) addEdge(e); } void Graph::setBbox(const QRectF &bbox) diff --git a/src/data/graph.h b/src/data/graph.h index 4d575e4..d00d2b2 100644 --- a/src/data/graph.h +++ b/src/data/graph.h @@ -48,6 +48,15 @@ public: bool hasBbox(); void clearBbox(); + /*! + * \brief realBbox computes the union of the user-defined + * bounding box, and the bounding boxes of the graph's + * contents. + * + * \return + */ + QRectF realBbox(); + QString tikz(); /*! @@ -59,9 +68,10 @@ public: Graph *copyOfSubgraphWithNodes(QSet nds); /*! - * \brief insertGraph inserts a copy of the given graph. Prior to calling this + * \brief insertGraph inserts the given graph into "this". Prior to calling this * method, the node names in the given graph should be made fresh via - * "renameApart". + * "renameApart". Note that the parameter "graph" relinquishes ownership of its + * nodes and edges, so it should be not be allowed to exist longer than "this". * \param graph */ void insertGraph(Graph *graph); diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp index 2ee3c50..59faa65 100644 --- a/src/gui/tikzscene.cpp +++ b/src/gui/tikzscene.cpp @@ -456,13 +456,15 @@ void TikzScene::pasteFromClipboard() // make sure names in the new subgraph are fresh g->renameApart(graph()); - // shift g to the right until there is some free space - QPointF p0 = toScreen(g->nodes()[0]->point()); - QPointF p = p0; - while (!items(p).isEmpty()) p.setX(p.x()+GLOBAL_SCALEF); - QPointF shift(roundf((p.x() - p0.x())/GLOBAL_SCALEF), 0.0f); - foreach (Node *n, g->nodes()) { - n->setPoint(n->point() + shift); + QRectF srcRect = g->realBbox(); + QRectF tgtRect = graph()->realBbox(); + QPointF shift(tgtRect.right() - srcRect.left(), 0.0f); + + // shift g to the right until it is in free space + if (shift.x() > 0) { + foreach (Node *n, g->nodes()) { + n->setPoint(n->point() + shift); + } } PasteCommand *cmd = new PasteCommand(this, g); @@ -507,6 +509,26 @@ void TikzScene::reloadStyles() } } +void TikzScene::refreshSceneBounds() +{ + if (!views().empty()) { + QGraphicsView *v = views().first(); + QRectF viewB = v->mapToScene(v->viewport()->rect()).boundingRect(); + //QPointF tl = v->mapToScene(viewB.topLeft()); + //viewB.setTopLeft(tl); + + QRectF bounds = viewB.united(rectToScreen(graph()->realBbox().adjusted(-1.0f, -1.0f, 1.0f, 1.0f))); + qDebug() << viewB; + + if (bounds != sceneRect()) { + QPointF c = viewB.center(); + setSceneRect(bounds); + v->centerOn(c); + } + } + //setBounds(graphB); +} + void TikzScene::refreshAdjacentEdges(QList nodes) { if (nodes.empty()) return; @@ -518,19 +540,19 @@ void TikzScene::refreshAdjacentEdges(QList nodes) } } -void TikzScene::setBounds(QRectF bounds) -{ - if (bounds != sceneRect()) { - if (!views().empty()) { - QGraphicsView *v = views().first(); - QPointF c = v->mapToScene(v->viewport()->rect().center()); - setSceneRect(bounds); - v->centerOn(c); - } else { - setSceneRect(bounds); - } - } -} +//void TikzScene::setBounds(QRectF bounds) +//{ +// if (bounds != sceneRect()) { +// if (!views().empty()) { +// QGraphicsView *v = views().first(); +// QPointF c = v->mapToScene(v->viewport()->rect().center()); +// setSceneRect(bounds); +// v->centerOn(c); +// } else { +// setSceneRect(bounds); +// } +// } +//} QMap &TikzScene::nodeItems() { diff --git a/src/gui/tikzscene.h b/src/gui/tikzscene.h index 5d3eec2..b551abd 100644 --- a/src/gui/tikzscene.h +++ b/src/gui/tikzscene.h @@ -30,11 +30,12 @@ public: QMap &nodeItems(); QMap &edgeItems(); void refreshAdjacentEdges(QList nodes); - void setBounds(QRectF bounds); +// void setBounds(QRectF bounds); TikzDocument *tikzDocument() const; void setTikzDocument(TikzDocument *tikzDocument); void reloadStyles(); + void refreshSceneBounds(); void applyActiveStyleToNodes(); void deleteSelectedItems(); void copyToClipboard(); diff --git a/src/gui/undocommands.cpp b/src/gui/undocommands.cpp index 0ebfd21..c9ca041 100644 --- a/src/gui/undocommands.cpp +++ b/src/gui/undocommands.cpp @@ -11,12 +11,14 @@ GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) : void GraphUpdateCommand::undo() { _scene->tikzDocument()->refreshTikz(); + _scene->refreshSceneBounds(); _scene->invalidate(); } void GraphUpdateCommand::redo() { _scene->tikzDocument()->refreshTikz(); + _scene->refreshSceneBounds(); _scene->invalidate(); } @@ -174,7 +176,7 @@ void AddNodeCommand::undo() _scene->graph()->removeNode(_node); - _scene->setBounds(_oldBounds); + //_scene->setBounds(_oldBounds); GraphUpdateCommand::undo(); } @@ -187,7 +189,8 @@ void AddNodeCommand::redo() _scene->nodeItems().insert(_node, ni); _scene->addItem(ni); - _scene->setBounds(_newBounds); + //_scene->setBounds(_newBounds); + GraphUpdateCommand::redo(); } diff --git a/src/tikzit.h b/src/tikzit.h index 51aea20..5b23083 100644 --- a/src/tikzit.h +++ b/src/tikzit.h @@ -51,13 +51,25 @@ // divisible by 8 to avoid rounding errors with e.g. grid-snapping. #define GLOBAL_SCALE 80 #define GLOBAL_SCALEF 80.0f +#define GLOBAL_SCALEF_INV 0.0125f inline QPointF toScreen(QPointF src) { src.setY(-src.y()); src *= GLOBAL_SCALEF; return src; } inline QPointF fromScreen(QPointF src) -{ src.setY(-src.y()); src /= GLOBAL_SCALEF; return src; } - +{ src.setY(-src.y()); src *= GLOBAL_SCALEF_INV; return src; } + +inline QRectF rectToScreen(QRectF src) +{ return QRectF(src.x() * GLOBAL_SCALEF, + -(src.y()+src.height()) * GLOBAL_SCALEF, + src.width() * GLOBAL_SCALEF, + src.height() * GLOBAL_SCALEF); } + +inline QRectF rectFromScreen(QRectF src) +{ return QRectF(src.x() * GLOBAL_SCALEF_INV, + -(src.y()+src.height()) * GLOBAL_SCALEF_INV, + src.width() * GLOBAL_SCALEF_INV, + src.height() * GLOBAL_SCALEF_INV); } class Tikzit : public QObject { Q_OBJECT -- cgit v1.2.3