summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGard Spreemann <gspreemann@gmail.com>2019-01-12 08:36:56 +0100
committerGard Spreemann <gspreemann@gmail.com>2019-01-12 08:36:56 +0100
commit6bf0bd3d1bce15acded6b83edabbdc329686cd7e (patch)
tree12569b7d18e006bb52dd72c649d5832e8ff6939a
parent7bf0645fc8c7fd95889b7dca289fb20b4212df85 (diff)
parent579c8118f8538a7adb8c70e1909734431ecf0d10 (diff)
Merge tag 'v2.1.1' into debian/sid
-rw-r--r--src/data/edge.cpp8
-rw-r--r--src/gui/edgeitem.cpp20
-rw-r--r--src/gui/nodeitem.cpp10
-rw-r--r--src/gui/tikzscene.cpp227
-rw-r--r--src/gui/tikzscene.h9
-rw-r--r--src/gui/tikzview.cpp2
-rw-r--r--src/gui/undocommands.cpp6
-rw-r--r--src/tikzit.h2
-rw-r--r--tikzit.pro2
9 files changed, 236 insertions, 50 deletions
diff --git a/src/data/edge.cpp b/src/data/edge.cpp
index 864d5ed..fcd9959 100644
--- a/src/data/edge.cpp
+++ b/src/data/edge.cpp
@@ -169,8 +169,10 @@ void Edge::updateControls() {
qreal bnd = static_cast<qreal>(_bend) * (M_PI / 180.0);
outAngleR = angle - bnd;
inAngleR = M_PI + angle + bnd;
- _outAngle = static_cast<int>(round(outAngleR * (180.0 / M_PI)));
- _inAngle = static_cast<int>(round(inAngleR * (180.0 / M_PI)));
+
+ // keep _inAngle and _outAngle snapped to increments of 15 degrees
+ _outAngle = static_cast<int>(roundToNearest(15.0, outAngleR * (180.0 / M_PI)));
+ _inAngle = static_cast<int>(roundToNearest(15.0, inAngleR * (180.0 / M_PI)));
} else {
outAngleR = static_cast<qreal>(_outAngle) * (M_PI / 180.0);
inAngleR = static_cast<qreal>(_inAngle) * (M_PI / 180.0);
@@ -409,7 +411,7 @@ QPointF Edge::bezierTangent(qreal start, qreal end) const
// normalise
qreal len = sqrt(dx*dx + dy*dy);
- if (almostZero(len)) {
+ if (!almostZero(len)) {
dx = (dx / len) * 0.1;
dy = (dy / len) * 0.1;
}
diff --git a/src/gui/edgeitem.cpp b/src/gui/edgeitem.cpp
index 48f321e..454a276 100644
--- a/src/gui/edgeitem.cpp
+++ b/src/gui/edgeitem.cpp
@@ -149,7 +149,7 @@ void EdgeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge
painter->setPen(QPen(draw1));
- float r = GLOBAL_SCALEF * _edge->cpDist();
+ qreal r = GLOBAL_SCALEF * _edge->cpDist();
painter->drawEllipse(toScreen(_edge->source()->point()), r, r);
painter->drawEllipse(toScreen(_edge->target()->point()), r, r);
@@ -159,6 +159,24 @@ void EdgeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge
painter->drawLine(toScreen(_edge->tail()), toScreen(_edge->cp1()));
painter->drawLine(toScreen(_edge->head()), toScreen(_edge->cp2()));
+ if (scene()) {
+ TikzScene *sc = static_cast<TikzScene*>(scene());
+
+ painter->setFont(Tikzit::LABEL_FONT);
+ QFontMetrics fm(Tikzit::LABEL_FONT);
+ QRectF rect = fm.boundingRect("<>");
+
+ if (sc->highlightHeads()) {
+ QPointF headMark(_edge->head().x(), _edge->head().y() + _edge->cpDist() - 0.25);
+ rect.moveCenter(toScreen(headMark));
+ painter->drawText(rect, Qt::AlignCenter, "<>");
+ } else if (sc->highlightTails()) {
+ QPointF tailMark(_edge->tail().x(), _edge->tail().y() + _edge->cpDist() - 0.25);
+ rect.moveCenter(toScreen(tailMark));
+ painter->drawText(rect, Qt::AlignCenter, "<>");
+ }
+ }
+
//painter->drawEllipse(toScreen(_edge->cp1()), r, r);
//painter->drawEllipse(toScreen(_edge->cp2()), r, r);
diff --git a/src/gui/nodeitem.cpp b/src/gui/nodeitem.cpp
index 18ff43c..8907573 100644
--- a/src/gui/nodeitem.cpp
+++ b/src/gui/nodeitem.cpp
@@ -72,7 +72,7 @@ void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge
QVector<qreal> p;
p << 1.0 << 2.0;
pen.setDashPattern(p);
- pen.setWidthF(2.0f);
+ pen.setWidthF(2.0);
painter->setPen(pen);
painter->setBrush(Qt::NoBrush);
painter->drawPath(shape());
@@ -135,10 +135,10 @@ void NodeItem::updateBounds()
prepareGeometryChange();
QString label = _node->label();
if (label != "") {
- QFontMetrics fm(Tikzit::LABEL_FONT);
- QRectF labelRect = fm.boundingRect(label);
- labelRect.moveCenter(QPointF(0, 0));
- _boundingRect = labelRect.united(shape().boundingRect()).adjusted(-4, -4, 4, 4);
+ //QFontMetrics fm(Tikzit::LABEL_FONT);
+ //QRectF labelRect = fm.boundingRect(label);
+ //labelRect.moveCenter(QPointF(0, 0));
+ _boundingRect = labelRect().united(shape().boundingRect()).adjusted(-4, -4, 4, 4);
} else {
_boundingRect = shape().boundingRect().adjusted(-4, -4, 4, 4);
}
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()) {
diff --git a/src/gui/tikzscene.h b/src/gui/tikzscene.h
index e8ea2c6..3e46f6d 100644
--- a/src/gui/tikzscene.h
+++ b/src/gui/tikzscene.h
@@ -80,6 +80,11 @@ public:
void getSelection(QSet<Node*> &selNodes, QSet<Edge*> &selEdges);
QSet<Node*> getSelectedNodes();
+ void refreshSceneBounds();
+
+ bool highlightHeads() const;
+
+ bool highlightTails() const;
public slots:
void graphReplaced();
@@ -113,6 +118,10 @@ private:
int _oldInAngle;
int _oldOutAngle;
bool _enabled;
+
+ bool _highlightHeads;
+ bool _highlightTails;
+ bool _smartTool;
};
#endif // TIKZSCENE_H
diff --git a/src/gui/tikzview.cpp b/src/gui/tikzview.cpp
index 5b0f09c..ddbc404 100644
--- a/src/gui/tikzview.cpp
+++ b/src/gui/tikzview.cpp
@@ -49,7 +49,7 @@ void TikzView::zoomOut()
void TikzView::setScene(QGraphicsScene *scene)
{
QGraphicsView::setScene(scene);
- centerOn(QPointF(0.0f,0.0f));
+ centerOn(QPointF(0.0,0.0));
}
void TikzView::drawBackground(QPainter *painter, const QRectF &rect)
diff --git a/src/gui/undocommands.cpp b/src/gui/undocommands.cpp
index 8a00536..82b9455 100644
--- a/src/gui/undocommands.cpp
+++ b/src/gui/undocommands.cpp
@@ -29,16 +29,14 @@ GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) :
void GraphUpdateCommand::undo()
{
_scene->tikzDocument()->refreshTikz();
- //refreshSceneBounds does nothing
- //_scene->refreshSceneBounds();
+ _scene->refreshSceneBounds();
_scene->invalidate();
}
void GraphUpdateCommand::redo()
{
_scene->tikzDocument()->refreshTikz();
- //refreshSceneBounds does nothing
- //_scene->refreshSceneBounds();
+ _scene->refreshSceneBounds();
_scene->invalidate();
}
diff --git a/src/tikzit.h b/src/tikzit.h
index 3dcbbd1..743e3f0 100644
--- a/src/tikzit.h
+++ b/src/tikzit.h
@@ -49,7 +49,7 @@
#ifndef TIKZIT_H
#define TIKZIT_H
-#define TIKZIT_VERSION "2.1.0"
+#define TIKZIT_VERSION "2.1.1"
#include "mainwindow.h"
#include "mainmenu.h"
diff --git a/tikzit.pro b/tikzit.pro
index 692433d..b7b155d 100644
--- a/tikzit.pro
+++ b/tikzit.pro
@@ -2,7 +2,7 @@
QT += core gui widgets network
-VERSION = 2.1
+VERSION = 2.1.1
test {
CONFIG += testcase