summaryrefslogtreecommitdiff
path: root/src/gui/tikzscene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/tikzscene.cpp')
-rw-r--r--src/gui/tikzscene.cpp227
1 files changed, 193 insertions, 34 deletions
diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp
index 31d5bf6..4d14f43 100644
--- a/src/gui/tikzscene.cpp
+++ b/src/gui/tikzscene.cpp
@@ -29,6 +29,7 @@
#include <QInputDialog>
#include <cmath>
#include <delimitedstringvalidator.h>
+#include <QSettings>
TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools,
@@ -41,7 +42,8 @@ TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools,
_rubberBandItem = new QGraphicsRectItem();
_enabled = true;
//setSceneRect(-310,-230,620,450);
- setSceneRect(-1000,-1000,2000,2000);
+ //setSceneRect(-2000,-1500,4000,3000);
+ refreshSceneBounds();
QPen pen;
pen.setColor(QColor::fromRgbF(0.5, 0.0, 0.5));
@@ -106,6 +108,7 @@ void TikzScene::graphReplaced()
}
refreshZIndices();
+ refreshSceneBounds();
}
void TikzScene::extendSelectionUp()
@@ -225,6 +228,7 @@ void TikzScene::refreshZIndices()
void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
+ QSettings settings("tikzit", "tikzit");
if (!_enabled) return;
// current mouse position, in scene coordinates
@@ -232,14 +236,24 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
_draggingNodes = false;
- // disable rubber band drag, which will clear the selection. Only re-enable it
- // for the SELECT tool, and when no control point has been clicked.
- //views()[0]->setDragMode(QGraphicsView::NoDrag);
-
// radius of a control point for bezier edges, in scene coordinates
qreal cpR = GLOBAL_SCALEF * (0.1);
qreal cpR2 = cpR * cpR;
+ if (event->button() == Qt::RightButton &&
+ _tools->currentTool() == ToolPalette::SELECT &&
+ settings.value("smart-tool-enabled", true).toBool())
+ {
+ _smartTool = true;
+ if (!items(_mouseDownPos).isEmpty() &&
+ dynamic_cast<NodeItem*>(items(_mouseDownPos)[0]))
+ {
+ _tools->setCurrentTool(ToolPalette::EDGE);
+ } else {
+ _tools->setCurrentTool(ToolPalette::VERTEX);
+ }
+ }
+
switch (_tools->currentTool()) {
case ToolPalette::SELECT:
// check if we grabbed a control point of an edge
@@ -571,6 +585,12 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
break;
}
+ if (_smartTool) {
+ _tools->setCurrentTool(ToolPalette::SELECT);
+ }
+
+ _smartTool = false;
+
// clear artefacts from rubber band selection
invalidate(QRect(), QGraphicsScene::BackgroundLayer);
}
@@ -581,6 +601,18 @@ void TikzScene::keyReleaseEvent(QKeyEvent *event)
{
if (!_enabled) return;
+ // clear highlighting for edge bends (if there was any)
+ if (event->modifiers() & Qt::ControlModifier) {
+ // it could be the case the user has released shift and is still holding control
+ bool head = !(event->modifiers() & Qt::ShiftModifier);
+ _highlightHeads = head;
+ _highlightTails = !head;
+ } else {
+ _highlightHeads = false;
+ _highlightTails = false;
+ }
+
+
if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
deleteSelectedItems();
} else if (event->modifiers() == Qt::NoModifier) {
@@ -600,6 +632,8 @@ void TikzScene::keyReleaseEvent(QKeyEvent *event)
break;
}
}
+
+ foreach (QGraphicsItem *it, selectedItems()) it->update();
}
void TikzScene::keyPressEvent(QKeyEvent *event)
@@ -612,42 +646,129 @@ void TikzScene::keyPressEvent(QKeyEvent *event)
}
if (event->modifiers() & Qt::ControlModifier) {
- QPointF delta(0,0);
- qreal shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0 : 10.0;
- switch(event->key()) {
- case Qt::Key_Left:
- delta.setX(-0.025 * shift);
- break;
- case Qt::Key_Right:
- delta.setX(0.025 * shift);
- break;
- case Qt::Key_Up:
- delta.setY(0.025 * shift);
- break;
- case Qt::Key_Down:
- delta.setY(-0.025 * shift);
- break;
- }
+ QSet<Node*> selNodes;
+ QSet<Edge*> selEdges;
+ getSelection(selNodes, selEdges);
+
+ if (!selNodes.isEmpty()) {
+ QPointF delta(0,0);
+ qreal shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0 : 10.0;
+ switch(event->key()) {
+ case Qt::Key_Left:
+ delta.setX(-0.025 * shift);
+ break;
+ case Qt::Key_Right:
+ delta.setX(0.025 * shift);
+ break;
+ case Qt::Key_Up:
+ delta.setY(0.025 * shift);
+ break;
+ case Qt::Key_Down:
+ delta.setY(-0.025 * shift);
+ break;
+ }
- if (!delta.isNull()) {
- capture = true;
- QMap<Node*,QPointF> oldNodePositions;
- QMap<Node*,QPointF> newNodePositions;
- QPointF pos;
+ if (!delta.isNull()) {
+ capture = true;
+ QMap<Node*,QPointF> oldNodePositions;
+ QMap<Node*,QPointF> newNodePositions;
+ QPointF pos;
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
- pos = ni->node()->point();
- oldNodePositions.insert(ni->node(), pos);
- newNodePositions.insert(ni->node(), pos + delta);
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ pos = ni->node()->point();
+ oldNodePositions.insert(ni->node(), pos);
+ newNodePositions.insert(ni->node(), pos + delta);
+ }
}
+
+ MoveCommand *cmd = new MoveCommand(this, oldNodePositions, newNodePositions);
+ _tikzDocument->undoStack()->push(cmd);
}
+ } else if (!selEdges.isEmpty()) {
+ int deltaAngle = 0;
+ qreal deltaWeight = 0.0;
- MoveCommand *cmd = new MoveCommand(this, oldNodePositions, newNodePositions);
- _tikzDocument->undoStack()->push(cmd);
+ bool head = !(event->modifiers() & Qt::ShiftModifier);
+ _highlightHeads = head;
+ _highlightTails = !head;
+
+ switch(event->key()) {
+ case Qt::Key_Left:
+ deltaAngle = 15;
+ break;
+ case Qt::Key_Right:
+ deltaAngle = -15;
+ break;
+ case Qt::Key_Down:
+ deltaWeight = -0.1;
+ break;
+ case Qt::Key_Up:
+ deltaWeight = 0.1;
+ break;
+ }
+
+ if (deltaAngle != 0) {
+ capture = true;
+ _tikzDocument->undoStack()->beginMacro("Bend edges");
+
+ // shift bend by deltaAngle or -deltaAngle (see below)
+ int sign = 1;
+
+ foreach (Edge *e, selEdges) {
+ if (e->basicBendMode()) {
+ _tikzDocument->undoStack()->push(new ChangeEdgeModeCommand(this, e));
+ }
+
+ if (head) {
+ int oldInAngle = e->inAngle();
+ e->setInAngle(oldInAngle + sign * deltaAngle);
+ EdgeBendCommand *cmd = new EdgeBendCommand(this, e,
+ e->weight(),
+ e->bend(),
+ oldInAngle,
+ e->outAngle());
+ _tikzDocument->undoStack()->push(cmd);
+ } else {
+ int oldOutAngle = e->outAngle();
+ e->setOutAngle(oldOutAngle + sign * deltaAngle);
+ EdgeBendCommand *cmd = new EdgeBendCommand(this, e,
+ e->weight(),
+ e->bend(),
+ e->inAngle(),
+ oldOutAngle);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+
+ // in the special case where 2 edges are selected, bend in opposite directions
+ if (selEdges.size() == 2) sign *= -1;
+ }
+
+ _tikzDocument->undoStack()->endMacro();
+ } else if (!almostZero(deltaWeight)) {
+ capture = true;
+ _tikzDocument->undoStack()->beginMacro("Adjust edges");
+
+ foreach (Edge *e, selEdges) {
+ qreal oldWeight = e->weight();
+ // don't let weight drop below 0.1
+ if (oldWeight + deltaWeight > 0.099) {
+ e->setWeight(oldWeight + deltaWeight);
+ EdgeBendCommand *cmd = new EdgeBendCommand(this, e,
+ oldWeight,
+ e->bend(),
+ e->inAngle(),
+ e->outAngle());
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ }
+
+ _tikzDocument->undoStack()->endMacro();
+ }
}
}
+ foreach (QGraphicsItem *it, selectedItems()) it->update();
if (!capture) QGraphicsScene::keyPressEvent(event);
}
@@ -687,6 +808,16 @@ void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
}
}
+bool TikzScene::highlightTails() const
+{
+ return _highlightTails;
+}
+
+bool TikzScene::highlightHeads() const
+{
+ return _highlightHeads;
+}
+
bool TikzScene::enabled() const
{
return _enabled;
@@ -796,7 +927,13 @@ void TikzScene::selectAllNodes()
void TikzScene::deselectAll()
{
- selectedItems().clear();
+ foreach (NodeItem *ni, _nodeItems.values()) {
+ ni->setSelected(false);
+ }
+
+ foreach (EdgeItem *ei, _edgeItems.values()) {
+ ei->setSelected(false);
+ }
}
bool TikzScene::parseTikz(QString tikz)
@@ -870,6 +1007,28 @@ void TikzScene::reloadStyles()
}
}
+void TikzScene::refreshSceneBounds() {
+ qreal maxX = 30.0, maxY = 30.0;
+ qreal increment = 20.0;
+
+ foreach (Node *n, graph()->nodes()) {
+ while (n->point().x() - increment < -maxX || n->point().x() + increment > maxX) {
+ maxX += increment;
+ }
+
+ while (n->point().y() - increment < -maxY || n->point().y() + increment > maxY) {
+ maxY += increment;
+ }
+ }
+
+ QRectF rect(-GLOBAL_SCALEF * maxX, -GLOBAL_SCALEF * maxY, 2.0 * GLOBAL_SCALEF * maxX, 2.0 * GLOBAL_SCALEF * maxY);
+
+ if (rect != sceneRect()) {
+ setSceneRect(rect);
+ invalidate();
+ }
+}
+
// void TikzScene::refreshSceneBounds()
// {
// // if (!views().empty()) {