summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2012-02-01 02:17:34 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2012-02-01 02:17:34 +0000
commit14625ba1f16c4d181d40358c2fd746e30715cb39 (patch)
tree1fa6c94c4c3284681ebc22a5948d6bd141da2707 /src
parentImplement cancellations of drags with ESC in the node tool (diff)
downloadinkscape-14625ba1f16c4d181d40358c2fd746e30715cb39.tar.gz
inkscape-14625ba1f16c4d181d40358c2fd746e30715cb39.zip
Additional fixes for drag cancellation in the node tool
(bzr r10926)
Diffstat (limited to 'src')
-rw-r--r--src/ui/tool/control-point.cpp29
-rw-r--r--src/ui/tool/control-point.h3
-rw-r--r--src/ui/tool/curve-drag-point.cpp15
-rw-r--r--src/ui/tool/curve-drag-point.h1
-rw-r--r--src/ui/tool/node.cpp15
5 files changed, 45 insertions, 18 deletions
diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp
index adad8611a..8ab7fe64f 100644
--- a/src/ui/tool/control-point.cpp
+++ b/src/ui/tool/control-point.cpp
@@ -21,6 +21,8 @@
#include "event-context.h"
#include "message-context.h"
#include "preferences.h"
+#include "snap-preferences.h"
+#include "sp-namedview.h"
#include "ui/tool/control-point.h"
#include "ui/tool/event-utils.h"
#include "ui/tool/transform-handle-set.h"
@@ -440,31 +442,32 @@ bool ControlPoint::_eventHandler(SPEventContext *event_context, GdkEvent *event)
{
case GDK_Escape: {
// ignore Escape if this is not a drag
- if (!_drag_initiated) return false;
+ if (!_drag_initiated) break;
- // Do not process delayed snap events - we might snap to a different place than we were initially
- delete _desktop->event_context->_delayed_snap_event;
- _desktop->event_context->_delayed_snap_event = NULL;
+ // temporarily disable snapping - we might snap to a different place than we were initially
+ sp_event_context_discard_delayed_snap_event(_desktop->event_context);
+ SnapPreferences &snapprefs = _desktop->namedview->snap_manager.snapprefs;
+ bool snap_save = snapprefs.getSnapEnabledGlobally();
+ snapprefs.setSnapEnabledGlobally(false);
Geom::Point new_pos = _drag_origin;
// make a fake event for dragging
// ASSUMPTION: dragging a point without modifiers will never prevent us from moving it
- // to its original position
- // TODO: pass correct values for x, y, x_root and y_root
+ // to its original position
GdkEventMotion fake;
fake.type = GDK_MOTION_NOTIFY;
fake.window = event->key.window;
fake.send_event = event->key.send_event;
fake.time = event->key.time;
- fake.x = 0; // not used in handlers atm
- fake.y = 0; // not used in handlers atm
+ fake.x = 0; // not used in handlers (and shouldn't be)
+ fake.y = 0; // not used in handlers (and shouldn't be)
fake.axes = NULL;
fake.state = 0; // unconstrained drag
fake.is_hint = FALSE;
fake.device = NULL;
- fake.x_root = 0; // not used in handlers atm
- fake.y_root = 0; // not used in handlers atm
+ fake.x_root = -1; // not used in handlers (and shouldn't be)
+ fake.y_root = -1; // can be used as a flag to check for cancelled drag
dragged(new_pos, &fake);
@@ -475,6 +478,7 @@ bool ControlPoint::_eventHandler(SPEventContext *event_context, GdkEvent *event)
_drag_initiated = false;
ungrabbed(NULL); // ungrabbed handlers can handle a NULL event
+ snapprefs.setSnapEnabledGlobally(snap_save);
} return true;
case GDK_Tab:
{// Downcast from ControlPoint to TransformHandle, if possible
@@ -624,6 +628,11 @@ void ControlPoint::_setColors(ColorEntry colors)
g_object_set(_canvas_item, "fill_color", colors.fill, "stroke_color", colors.stroke, NULL);
}
+bool ControlPoint::_is_drag_cancelled(GdkEventMotion *event)
+{
+ return !event || event->x_root == -1;
+}
+
// dummy implementations for handlers
// they are here to avoid unused param warnings
bool ControlPoint::grabbed(GdkEventMotion *) { return false; }
diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h
index 0719370f7..991d9123d 100644
--- a/src/ui/tool/control-point.h
+++ b/src/ui/tool/control-point.h
@@ -158,9 +158,10 @@ protected:
ColorSet *_cset; ///< Colors used to represent the point
State _state;
- static int const _grab_event_mask;
static Geom::Point const &_last_click_event_point() { return _drag_event_origin; }
static Geom::Point const &_last_drag_origin() { return _drag_origin; }
+ static bool _is_drag_cancelled(GdkEventMotion *event);
+ static int const _grab_event_mask;
private:
ControlPoint(ControlPoint const &other);
diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp
index 97e0ab7e7..3cc571585 100644
--- a/src/ui/tool/curve-drag-point.cpp
+++ b/src/ui/tool/curve-drag-point.cpp
@@ -34,6 +34,7 @@ namespace UI {
// to be declared as a friend
bool CurveDragPoint::_drags_stroke = false;
+bool CurveDragPoint::_segment_was_degenerate = false;
CurveDragPoint::CurveDragPoint(PathManipulator &pm)
: ControlPoint(pm._multi_path_manipulator._path_data.node_data.desktop, Geom::Point(),
@@ -61,6 +62,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/)
// move the handles to 1/3 the length of the segment for line segments
if (first->front()->isDegenerate() && second->back()->isDegenerate()) {
+ _segment_was_degenerate = true;
// delta is a vector equal 1/3 of distance from first to second
Geom::Point delta = (second->position() - first->position()) / 3.0;
@@ -68,13 +70,24 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/)
second->back()->move(second->back()->position() - delta);
_pm.update();
+ } else {
+ _segment_was_degenerate = false;
}
return false;
}
-void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *)
+void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
NodeList::iterator second = first.next();
+
+ // special cancel handling - retract handles when if the segment was degenerate
+ if (_is_drag_cancelled(event) && _segment_was_degenerate) {
+ first->front()->retract();
+ second->back()->retract();
+ _pm.update();
+ return;
+ }
+
// Magic Bezier Drag Equations follow!
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
diff --git a/src/ui/tool/curve-drag-point.h b/src/ui/tool/curve-drag-point.h
index 819b7dbe1..939047634 100644
--- a/src/ui/tool/curve-drag-point.h
+++ b/src/ui/tool/curve-drag-point.h
@@ -42,6 +42,7 @@ private:
PathManipulator &_pm;
NodeList::iterator first;
static bool _drags_stroke;
+ static bool _segment_was_degenerate;
static Geom::Point _stroke_drag_origin;
};
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index 2dc55e31c..4df4ba30e 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -351,13 +351,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
void Handle::ungrabbed(GdkEventButton *event)
{
// hide the handle if it's less than dragtolerance away from the node
- // TODO is this actually desired?
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- int drag_tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+ // however, never do this for cancelled drag / broken grab
+ // TODO is this actually a good idea?
+ if (event) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ int drag_tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
- Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position());
- if (dist.length() <= drag_tolerance) {
- move(_parent->position());
+ Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position());
+ if (dist.length() <= drag_tolerance) {
+ move(_parent->position());
+ }
}
// HACK: If the handle was dragged out, call parent's ungrabbed handler,