summaryrefslogtreecommitdiff
path: root/tikzit/src/gui/tikzscene.cpp
diff options
context:
space:
mode:
authorAleks Kissinger <aleks0@gmail.com>2017-12-21 16:34:58 +0000
committerAleks Kissinger <aleks0@gmail.com>2017-12-21 16:34:58 +0000
commit9d8317cd593d47911bb6b2e6fb8ef0077e24ae36 (patch)
tree6f2d44782c37f8eaa36f2bb1de625343af65649e /tikzit/src/gui/tikzscene.cpp
parent82bdd42a475d240bb08e201a47b0972d0b2862a6 (diff)
edge bending working
Diffstat (limited to 'tikzit/src/gui/tikzscene.cpp')
-rw-r--r--tikzit/src/gui/tikzscene.cpp184
1 files changed, 161 insertions, 23 deletions
diff --git a/tikzit/src/gui/tikzscene.cpp b/tikzit/src/gui/tikzscene.cpp
index b12b769..b502f84 100644
--- a/tikzit/src/gui/tikzscene.cpp
+++ b/tikzit/src/gui/tikzscene.cpp
@@ -1,4 +1,5 @@
#include "tikzit.h"
+#include "util.h"
#include "tikzscene.h"
#include "undocommands.h"
@@ -10,6 +11,7 @@
TikzScene::TikzScene(TikzDocument *tikzDocument, QObject *parent) :
QGraphicsScene(parent), _tikzDocument(tikzDocument)
{
+ _modifyEdgeItem = 0;
}
TikzScene::~TikzScene() {
@@ -49,23 +51,59 @@ void TikzScene::graphReplaced()
void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
+ // current mouse position, in scene coordinates
QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(),
event->buttonDownScenePos(Qt::LeftButton).y());
+ // radius of a control point for bezier edges, in scene coordinates
+ qreal cpR = GLOBAL_SCALEF * (0.05);
+ qreal cpR2 = cpR * cpR;
switch (tikzit->toolPalette()->currentTool()) {
case ToolPalette::SELECT:
- // TODO: check if we grabbed a control point
- QGraphicsScene::mousePressEvent(event);
- if (!selectedItems().empty() && !items(mousePos).empty()) {
+ // check if we grabbed a control point of an edge
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
+ qreal dx, dy;
+
+ dx = ei->cp1Item()->pos().x() - mousePos.x();
+ dy = ei->cp1Item()->pos().y() - mousePos.y();
+
+ if (dx*dx + dy*dy <= cpR2) {
+ _modifyEdgeItem = ei;
+ _firstControlPoint = true;
+ break;
+ }
+
+ dx = ei->cp2Item()->pos().x() - mousePos.x();
+ dy = ei->cp2Item()->pos().y() - mousePos.y();
+
+ if (dx*dx + dy*dy <= cpR2) {
+ _modifyEdgeItem = ei;
+ _firstControlPoint = false;
+ break;
+ }
+ }
+ }
+
+ if (_modifyEdgeItem != 0) {
+ // disable rubber band drag, which will clear the selection
+ views()[0]->setDragMode(QGraphicsView::NoDrag);
+ qDebug() << "Got a control point";
+ } else {
+ // since we are not dragging a control point, process the click normally
+ views()[0]->setDragMode(QGraphicsView::RubberBandDrag);
+ QGraphicsScene::mousePressEvent(event);
+
+ // save current node positions for undo support
_oldNodePositions.clear();
foreach (QGraphicsItem *gi, selectedItems()) {
if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
_oldNodePositions.insert(ni->node(), ni->node()->point());
}
}
- qDebug() << "I am dragging";
}
+
break;
case ToolPalette::VERTEX:
break;
@@ -78,9 +116,96 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
+ // current mouse position, in scene coordinates
+
+ QPointF mousePos = event->scenePos();
+
switch (tikzit->toolPalette()->currentTool()) {
case ToolPalette::SELECT:
- QGraphicsScene::mouseMoveEvent(event);
+ if (_modifyEdgeItem != 0) {
+ Edge *e = _modifyEdgeItem->edge();
+ // dragging a control point
+ QPointF src = toScreen(e->source()->point());
+ QPointF targ = toScreen(e->target()->point());
+ float dx1 = targ.x() - src.x();
+ float dy1 = targ.y() - src.y();
+ float dx2, dy2;
+ if (_firstControlPoint) {
+ dx2 = mousePos.x() - src.x();
+ dy2 = mousePos.y() - src.y();
+ } else {
+ dx2 = mousePos.x() - targ.x();
+ dy2 = mousePos.y() - targ.y();
+ }
+
+ float baseDist = sqrt(dx1*dx1 + dy1*dy1);
+ float handleDist = sqrt(dx2*dx2 + dy2*dy2);
+ float wcoarseness = 0.1f;
+
+ if (!e->isSelfLoop()) {
+ if (baseDist != 0) {
+ e->setWeight(roundToNearest(wcoarseness, handleDist/baseDist));
+ } else {
+ e->setWeight(roundToNearest(wcoarseness, handleDist/GLOBAL_SCALEF));
+ }
+ }
+
+ float control_angle = atan2(-dy2, dx2);
+
+ int bcoarseness = 15;
+
+ if(e->basicBendMode()) {
+ float bnd;
+ float base_angle = atan2(-dy1, dx1);
+ if (_firstControlPoint) {
+ bnd = base_angle - control_angle;
+ } else {
+ bnd = control_angle - base_angle + M_PI;
+ if (bnd > M_PI) bnd -= 2*M_PI;
+ }
+
+ e->setBend(round(bnd * (180.0f / M_PI) * (1.0f / (float)bcoarseness)) * bcoarseness);
+
+ } else {
+ int bnd = round(control_angle * (180.0f / M_PI) *
+ (1.0f / (float)bcoarseness)) *
+ bcoarseness;
+ if (_firstControlPoint) {
+ // TODO: enable moving both control points
+// if ([theEvent modifierFlags] & NSAlternateKeyMask) {
+// if ([modifyEdge isSelfLoop]) {
+// [modifyEdge setInAngle:[modifyEdge inAngle] +
+// (bnd - [modifyEdge outAngle])];
+// } else {
+// [modifyEdge setInAngle:[modifyEdge inAngle] -
+// (bnd - [modifyEdge outAngle])];
+// }
+// }
+
+ e->setOutAngle(bnd);
+ } else {
+// if (theEvent.modifierFlags & NSAlternateKeyMask) {
+// if ([modifyEdge isSelfLoop]) {
+// [modifyEdge setOutAngle:[modifyEdge outAngle] +
+// (bnd - [modifyEdge inAngle])];
+// } else {
+// [modifyEdge setOutAngle:[modifyEdge outAngle] -
+// (bnd - [modifyEdge inAngle])];
+// }
+// }
+
+ e->setInAngle(bnd);
+ }
+ }
+
+ _modifyEdgeItem->readPos();
+
+ } else {
+ // otherwise, process mouse move normally
+ QGraphicsScene::mouseMoveEvent(event);
+ refreshAdjacentEdges(_oldNodePositions.keys());
+ }
+
break;
case ToolPalette::VERTEX:
break;
@@ -89,35 +214,37 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
case ToolPalette::CROP:
break;
}
-
- // TODO: only sync edges that change
- foreach (EdgeItem *ei, _edgeItems) {
- ei->edge()->updateControls();
- ei->syncPos();
- }
}
void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
switch (tikzit->toolPalette()->currentTool()) {
case ToolPalette::SELECT:
- QGraphicsScene::mouseReleaseEvent(event);
+ if (_modifyEdgeItem != 0) {
+ // finished dragging a control point
+ // TODO
- if (!_oldNodePositions.empty()) {
- QMap<Node*,QPointF> newNodePositions;
+ _modifyEdgeItem = 0;
+ } else {
+ // otherwise, process mouse move normally
+ QGraphicsScene::mouseReleaseEvent(event);
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
- ni->writePos();
- newNodePositions.insert(ni->node(), ni->node()->point());
+ if (!_oldNodePositions.empty()) {
+ QMap<Node*,QPointF> newNodePositions;
+
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ ni->writePos();
+ newNodePositions.insert(ni->node(), ni->node()->point());
+ }
}
- }
- //qDebug() << _oldNodePositions;
- //qDebug() << newNodePositions;
+ //qDebug() << _oldNodePositions;
+ //qDebug() << newNodePositions;
- _tikzDocument->undoStack()->push(new MoveCommand(this, _oldNodePositions, newNodePositions));
- _oldNodePositions.clear();
+ _tikzDocument->undoStack()->push(new MoveCommand(this, _oldNodePositions, newNodePositions));
+ _oldNodePositions.clear();
+ }
}
break;
@@ -146,6 +273,17 @@ QVector<EdgeItem *> TikzScene::edgeItems() const
return _edgeItems;
}
+void TikzScene::refreshAdjacentEdges(QList<Node*> nodes)
+{
+ if (nodes.empty()) return;
+ foreach (EdgeItem *ei, _edgeItems) {
+ if (nodes.contains(ei->edge()->source()) || nodes.contains(ei->edge()->target())) {
+ ei->edge()->updateControls();
+ ei->readPos();
+ }
+ }
+}
+
QVector<NodeItem *> TikzScene::nodeItems() const
{
return _nodeItems;