summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 79cad9f)
raw | patch | inline | side by side (parent: 79cad9f)
author | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Wed, 30 Dec 2009 14:34:51 +0000 (15:34 +0100) | ||
committer | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Wed, 30 Dec 2009 14:34:51 +0000 (15:34 +0100) |
index c5c23a734bd919e7a04a39d6da88e286d90d9a8e..0fc9de9d0384ee0e99d98e0366012ed7851aa2ce 100644 (file)
@@ -625,7 +625,6 @@ sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, G
{
spcc_reset_colors(cc);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(event_context);
}
if (cc->state != SP_CONNECTOR_CONTEXT_IDLE) {
// Doing something else like rerouting.
@@ -757,7 +756,7 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
switch (cc->state) {
case SP_CONNECTOR_CONTEXT_STOP:
- /* This is allowed, if we just cancelled curve */
+ /* This is allowed, if we just canceled curve */
case SP_CONNECTOR_CONTEXT_IDLE:
{
if ( cc->npoints == 0 ) {
@@ -772,8 +771,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
// Test whether we clicked on a connection point
cc->sid = conn_pt_handle_test(cc, p);
-// sp_event_context_snap_window_open(event_context);
-
if (!cc->sid) {
// This is the first point, so just snap it to the grid
// as there's no other points to go off.
@@ -800,7 +797,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
}
cc_set_active_conn(cc, cc->newconn);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(event_context);
ret = TRUE;
break;
}
@@ -819,7 +815,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
cc_connector_rerouting_finish(cc, &p);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(event_context);
// Don't set ret to TRUE, so we drop through to the
// parent handler which will open the context menu.
@@ -827,7 +822,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
else if (cc->npoints != 0) {
spcc_connector_finish(cc);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(event_context);
ret = TRUE;
}
}
@@ -879,7 +873,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
if ( cc->selected_handle )
{
-// sp_event_context_snap_window_open(event_context);
cc->state = SP_CONNECTOR_CONTEXT_DRAGGING;
cc->selection->set( SP_OBJECT( cc->active_shape ) );
}
@@ -1047,7 +1040,6 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
}
cc_set_active_conn(cc, cc->newconn);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(event_context);
break;
}
case SP_CONNECTOR_CONTEXT_REROUTING:
@@ -1057,7 +1049,6 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
sp_document_ensure_up_to_date(doc);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(event_context);
return TRUE;
break;
}
@@ -1077,10 +1068,8 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
if (!cc->within_tolerance)
{
-// sp_event_context_snap_window_open(event_context);
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
sp_knot_set_position(cc->selected_handle, p, 0);
-// sp_event_context_snap_window_closed(event_context);
ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
cc->active_shape->avoidRef->updateConnectionPoint(cp);
@@ -1092,11 +1081,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
-// sp_event_context_snap_window_open( event_context );
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
sp_knot_set_position(cc->selected_handle, p, 0);
-// sp_event_context_snap_window_closed(event_context);
ConnectionPoint cp;
cp.type = ConnPointUserDefined;
if (cc->npoints != 0) {
spcc_connector_finish(cc);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(SP_EVENT_CONTEXT(cc));
ret = TRUE;
}
break;
sp_document_undo(doc);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-// sp_event_context_snap_window_closed(SP_EVENT_CONTEXT(cc));
desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
_("Connector endpoint drag cancelled."));
ret = TRUE;
else if (cc->npoints != 0) {
// if drawing, cancel, otherwise pass it up for deselecting
cc->state = SP_CONNECTOR_CONTEXT_STOP;
-// sp_event_context_snap_window_closed(SP_EVENT_CONTEXT(cc));
spcc_reset_colors(cc);
ret = TRUE;
}
if (!cc->within_tolerance)
{
-// sp_event_context_snap_window_open(event_context);
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
sp_knot_set_position(cc->selected_handle, p, 0);
-// sp_event_context_snap_window_closed(event_context);
ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
cc->active_shape->avoidRef->updateConnectionPoint(cp);
@@ -1229,13 +1211,10 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
Geom::Point p = cc->selected_handle->pos;
-// SPEventContext* event_context = SP_EVENT_CONTEXT( cc );
-// sp_event_context_snap_window_open( event_context );
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
sp_knot_set_position(cc->selected_handle, p, 0);
-// sp_event_context_snap_window_closed(event_context);
ConnectionPoint cp;
cp.type = ConnPointUserDefined;
cc->clickedhandle = cc->active_handle;
cc_clear_active_conn(cc);
cc->state = SP_CONNECTOR_CONTEXT_REROUTING;
-// sp_event_context_snap_window_open(SP_EVENT_CONTEXT(cc));
// Disconnect from attached shape
unsigned ind = (cc->active_handle == cc->endpt_handle[0]) ? 0 : 1;
index 20ea7d58cc5d3f6d9a0e4a2155193faaada73577..fdea9cbbfae1ecf3433bcbefee0c61e9f3664706 100644 (file)
g_assert(_desktop != NULL);
- /* Commented out for now, because this might hide any snapping bug!
if (!p.getSnapped()) {
- return; // If we haven't snapped, then it is of no use to draw a snapindicator
+ g_warning("No snapping took place, so no snap target will be displayed");
+ return; // If we haven't snapped, then it is of no use to draw a snapindicator
}
- */
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
bool value = prefs->getBool("/options/snapindicator/value", true);
diff --git a/src/event-context.cpp b/src/event-context.cpp
index 9b846f2b7e51a5f54e88c6e15363e33be52dcae8..918e3d4194cdb57baff49f51109aca5a7556e7fb 100644 (file)
--- a/src/event-context.cpp
+++ b/src/event-context.cpp
}
if (ec->_delayed_snap_event) {
- delete ec->_delayed_snap_event;
+ delete ec->_delayed_snap_event;
}
G_OBJECT_CLASS(parent_class)->dispose(object);
@@ -374,9 +374,9 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
switch (event->button.button) {
case 1:
if (event_context->space_panning) {
- // When starting panning, make sure there are no snap events pending because these might disable the panning again
- sp_event_context_discard_delayed_snap_event(event_context);
- panning = 1;
+ // When starting panning, make sure there are no snap events pending because these might disable the panning again
+ sp_event_context_discard_delayed_snap_event(event_context);
+ panning = 1;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK,
NULL, event->button.time-1);
@@ -387,9 +387,9 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
if (event->button.state & GDK_SHIFT_MASK) {
zoom_rb = 2;
} else {
- // When starting panning, make sure there are no snap events pending because these might disable the panning again
- sp_event_context_discard_delayed_snap_event(event_context);
- panning = 2;
+ // When starting panning, make sure there are no snap events pending because these might disable the panning again
+ sp_event_context_discard_delayed_snap_event(event_context);
+ panning = 2;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK,
NULL, event->button.time-1);
@@ -399,9 +399,9 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
case 3:
if (event->button.state & GDK_SHIFT_MASK
|| event->button.state & GDK_CONTROL_MASK) {
- // When starting panning, make sure there are no snap events pending because these might disable the panning again
- sp_event_context_discard_delayed_snap_event(event_context);
- panning = 3;
+ // When starting panning, make sure there are no snap events pending because these might disable the panning again
+ sp_event_context_discard_delayed_snap_event(event_context);
+ panning = 3;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK,
NULL, event->button.time);
@@ -421,7 +421,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
|| (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))
) {
/* Gdk seems to lose button release for us sometimes :-( */
- panning = 0;
+ panning = 0;
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
ret = TRUE;
@@ -514,11 +514,11 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
}
break;
case GDK_KEY_PRESS:
- {
- double const acceleration = prefs->getDoubleLimited("/options/scrollingacceleration/value", 0, 0, 6);
- int const key_scroll = prefs->getIntLimited("/options/keyscroll/value", 10, 0, 1000);
+ {
+ double const acceleration = prefs->getDoubleLimited("/options/scrollingacceleration/value", 0, 0, 6);
+ int const key_scroll = prefs->getIntLimited("/options/keyscroll/value", 10, 0, 1000);
- switch (get_group0_keyval(&event->key)) {
+ switch (get_group0_keyval(&event->key)) {
// GDK insists on stealing these keys (F1 for no idea what, tab for cycling widgets
// in the editing window). So we resteal them back and run our regular shortcut
// invoker on them.
@@ -545,11 +545,11 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
break;
case GDK_Q:
case GDK_q:
- if (desktop->quick_zoomed()) {
- ret = TRUE;
- }
+ if (desktop->quick_zoomed()) {
+ ret = TRUE;
+ }
if (!MOD__SHIFT && !MOD__CTRL && !MOD__ALT) {
- desktop->zoom_quick(true);
+ desktop->zoom_quick(true);
ret = TRUE;
}
break;
@@ -632,7 +632,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
default:
break;
}
- }
+ }
break;
case GDK_KEY_RELEASE:
switch (get_group0_keyval(&event->key)) {
@@ -651,8 +651,8 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context,
break;
case GDK_Q:
case GDK_q:
- if (desktop->quick_zoomed()) {
- desktop->zoom_quick(false);
+ if (desktop->quick_zoomed()) {
+ desktop->zoom_quick(false);
ret = TRUE;
}
break;
sp_event_context_root_handler(SPEventContext * event_context, GdkEvent * event)
{
switch (event->type) {
- case GDK_MOTION_NOTIFY:
- sp_event_context_snap_delay_handler(event_context, NULL, NULL, (GdkEventMotion *)event, DelayedSnapEvent::EVENTCONTEXT_ROOT_HANDLER);
- break;
- case GDK_BUTTON_RELEASE:
- if (event_context->_delayed_snap_event) {
- // If we have any pending snapping action, then invoke it now
- sp_event_context_snap_watchdog_callback(event_context->_delayed_snap_event);
- }
- break;
- case GDK_BUTTON_PRESS:
+ case GDK_MOTION_NOTIFY:
+ sp_event_context_snap_delay_handler(event_context, NULL, NULL, (GdkEventMotion *)event, DelayedSnapEvent::EVENTCONTEXT_ROOT_HANDLER);
+ break;
+ case GDK_BUTTON_RELEASE:
+ if (event_context->_delayed_snap_event) {
+ // If we have any pending snapping action, then invoke it now
+ sp_event_context_snap_watchdog_callback(event_context->_delayed_snap_event);
+ }
+ break;
+ case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
- // Snapping will be on hold if we're moving the mouse at high speeds. When starting
- // drawing a new shape we really should snap though.
- event_context->desktop->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
- break;
+ // Snapping will be on hold if we're moving the mouse at high speeds. When starting
+ // drawing a new shape we really should snap though.
+ event_context->desktop->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
+ break;
default:
- break;
+ break;
}
return sp_event_context_virtual_root_handler(event_context, event);
gint
sp_event_context_virtual_root_handler(SPEventContext * event_context, GdkEvent * event)
{
- gint ret = ((SPEventContextClass *) G_OBJECT_GET_CLASS(event_context))->root_handler(event_context, event);
- set_event_location(event_context->desktop, event);
- return ret;
+ gint ret = ((SPEventContextClass *) G_OBJECT_GET_CLASS(event_context))->root_handler(event_context, event);
+ set_event_location(event_context->desktop, event);
+ return ret;
}
/**
@@ -944,27 +944,27 @@ sp_event_context_virtual_root_handler(SPEventContext * event_context, GdkEvent *
gint
sp_event_context_item_handler(SPEventContext * event_context, SPItem * item, GdkEvent * event)
{
- switch (event->type) {
- case GDK_MOTION_NOTIFY:
- sp_event_context_snap_delay_handler(event_context, item, NULL, (GdkEventMotion *)event, DelayedSnapEvent::EVENTCONTEXT_ITEM_HANDLER);
- break;
- case GDK_BUTTON_RELEASE:
- if (event_context->_delayed_snap_event) {
- // If we have any pending snapping action, then invoke it now
- sp_event_context_snap_watchdog_callback(event_context->_delayed_snap_event);
- }
- break;
- /*case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- // Snapping will be on hold if we're moving the mouse at high speeds. When starting
- // drawing a new shape we really should snap though.
- event_context->desktop->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
- break;
- */
- default:
- break;
- }
+ switch (event->type) {
+ case GDK_MOTION_NOTIFY:
+ sp_event_context_snap_delay_handler(event_context, item, NULL, (GdkEventMotion *)event, DelayedSnapEvent::EVENTCONTEXT_ITEM_HANDLER);
+ break;
+ case GDK_BUTTON_RELEASE:
+ if (event_context->_delayed_snap_event) {
+ // If we have any pending snapping action, then invoke it now
+ sp_event_context_snap_watchdog_callback(event_context->_delayed_snap_event);
+ }
+ break;
+ /*case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ // Snapping will be on hold if we're moving the mouse at high speeds. When starting
+ // drawing a new shape we really should snap though.
+ event_context->desktop->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
+ break;
+ */
+ default:
+ break;
+ }
return sp_event_context_virtual_item_handler(event_context, item, event);
}
@@ -972,15 +972,15 @@ sp_event_context_item_handler(SPEventContext * event_context, SPItem * item, Gdk
gint
sp_event_context_virtual_item_handler(SPEventContext * event_context, SPItem * item, GdkEvent * event)
{
- gint ret = ((SPEventContextClass *) G_OBJECT_GET_CLASS(event_context))->item_handler(event_context, item, event);
+ gint ret = ((SPEventContextClass *) G_OBJECT_GET_CLASS(event_context))->item_handler(event_context, item, event);
- if (! ret) {
- ret = sp_event_context_virtual_root_handler(event_context, event);
- } else {
- set_event_location(event_context->desktop, event);
- }
+ if (! ret) {
+ ret = sp_event_context_virtual_root_handler(event_context, event);
+ } else {
+ set_event_location(event_context->desktop, event);
+ }
- return ret;
+ return ret;
}
/**
void sp_event_context_snap_delay_handler(SPEventContext *ec, SPItem* const item, SPKnot* const knot, GdkEventMotion *event, DelayedSnapEvent::DelayedSnapEventOrigin origin)
{
- static guint32 prev_time;
- static boost::optional<Geom::Point> prev_pos;
+ static guint32 prev_time;
+ static boost::optional<Geom::Point> prev_pos;
- // Snapping occurs when dragging with the left mouse button down, or when hovering e.g. in the pen tool with left mouse button up
+ // Snapping occurs when dragging with the left mouse button down, or when hovering e.g. in the pen tool with left mouse button up
bool const c1 = event->state & GDK_BUTTON2_MASK; // We shouldn't hold back any events when other mouse buttons have been
bool const c2 = event->state & GDK_BUTTON3_MASK; // pressed, e.g. when scrolling with the middle mouse button; if we do then
- // Inkscape will get stuck in an unresponsive state
+ // Inkscape will get stuck in an unresponsive state
bool const c3 = tools_isactive(ec->desktop, TOOLS_CALLIGRAPHIC);
// The snap delay will repeat the last motion event, which will lead to
// erroneous points in the calligraphy context. And because we don't snap
// in this context, we might just as well disable the snap delay all together
if (c1 || c2 || c3) {
- // Make sure that we don't send any pending snap events to a context if we know in advance
- // that we're not going to snap any way (e.g. while scrolling with middle mouse button)
- // Any motion event might affect the state of the context, leading to unexpected behavior
- sp_event_context_discard_delayed_snap_event(ec);
+ // Make sure that we don't send any pending snap events to a context if we know in advance
+ // that we're not going to snap any way (e.g. while scrolling with middle mouse button)
+ // Any motion event might affect the state of the context, leading to unexpected behavior
+ sp_event_context_discard_delayed_snap_event(ec);
} else if (ec->desktop && ec->desktop->namedview->snap_manager.snapprefs.getSnapEnabledGlobally()) {
- // Snap when speed drops below e.g. 0.02 px/msec, or when no motion events have occurred for some period.
- // i.e. snap when we're at stand still. A speed threshold enforces snapping for tablets, which might never
- // be fully at stand still and might keep spitting out motion events.
- ec->desktop->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); // put snapping on hold
-
- Geom::Point event_pos(event->x, event->y);
- guint32 event_t = gdk_event_get_time ( (GdkEvent *) event );
-
- if (prev_pos) {
- Geom::Coord dist = Geom::L2(event_pos - *prev_pos);
- guint32 delta_t = event_t - prev_time;
- gdouble speed = delta_t > 0 ? dist/delta_t : 1000;
- //std::cout << "Mouse speed = " << speed << " px/msec " << std::endl;
- if (speed > 0.02) { // Jitter threshold, might be needed for tablets
- // We're moving fast, so postpone any snapping until the next GDK_MOTION_NOTIFY event. We
- // will keep on postponing the snapping as long as the speed is high.
- // We must snap at some point in time though, so set a watchdog timer at some time from
- // now, just in case there's no future motion event that drops under the speed limit (when
- // stopping abruptly)
- delete ec->_delayed_snap_event;
- ec->_delayed_snap_event = new DelayedSnapEvent(ec, item, knot, event, origin); // watchdog is reset, i.e. pushed forward in time
- // If the watchdog expires before a new motion event is received, we will snap (as explained
- // above). This means however that when the timer is too short, we will always snap and that the
- // speed threshold is ineffective. In the extreme case the delay is set to zero, and snapping will
- // be immediate, as it used to be in the old days ;-).
- } else { // Speed is very low, so we're virtually at stand still
- // But if we're really standing still, then we should snap now. We could use some low-pass filtering,
- // otherwise snapping occurs for each jitter movement. For this filtering we'll leave the watchdog to expire,
- // snap, and set a new watchdog again.
- if (ec->_delayed_snap_event == NULL) { // no watchdog has been set
- // it might have already expired, so we'll set a new one; the snapping frequency will be limited by this
- ec->_delayed_snap_event = new DelayedSnapEvent(ec, item, knot, event, origin);
- } // else: watchdog has been set before and we'll wait for it to expire
- }
- } else {
- // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog
- g_assert(ec->_delayed_snap_event == NULL);
- ec->_delayed_snap_event = new DelayedSnapEvent(ec, item, knot, event, origin);
- }
-
- prev_pos = event_pos;
- prev_time = event_t;
+ // Snap when speed drops below e.g. 0.02 px/msec, or when no motion events have occurred for some period.
+ // i.e. snap when we're at stand still. A speed threshold enforces snapping for tablets, which might never
+ // be fully at stand still and might keep spitting out motion events.
+ ec->desktop->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); // put snapping on hold
+
+ Geom::Point event_pos(event->x, event->y);
+ guint32 event_t = gdk_event_get_time ( (GdkEvent *) event );
+
+ if (prev_pos) {
+ Geom::Coord dist = Geom::L2(event_pos - *prev_pos);
+ guint32 delta_t = event_t - prev_time;
+ gdouble speed = delta_t > 0 ? dist/delta_t : 1000;
+ //std::cout << "Mouse speed = " << speed << " px/msec " << std::endl;
+ if (speed > 0.02) { // Jitter threshold, might be needed for tablets
+ // We're moving fast, so postpone any snapping until the next GDK_MOTION_NOTIFY event. We
+ // will keep on postponing the snapping as long as the speed is high.
+ // We must snap at some point in time though, so set a watchdog timer at some time from
+ // now, just in case there's no future motion event that drops under the speed limit (when
+ // stopping abruptly)
+ delete ec->_delayed_snap_event;
+ ec->_delayed_snap_event = new DelayedSnapEvent(ec, item, knot, event, origin); // watchdog is reset, i.e. pushed forward in time
+ // If the watchdog expires before a new motion event is received, we will snap (as explained
+ // above). This means however that when the timer is too short, we will always snap and that the
+ // speed threshold is ineffective. In the extreme case the delay is set to zero, and snapping will
+ // be immediate, as it used to be in the old days ;-).
+ } else { // Speed is very low, so we're virtually at stand still
+ // But if we're really standing still, then we should snap now. We could use some low-pass filtering,
+ // otherwise snapping occurs for each jitter movement. For this filtering we'll leave the watchdog to expire,
+ // snap, and set a new watchdog again.
+ if (ec->_delayed_snap_event == NULL) { // no watchdog has been set
+ // it might have already expired, so we'll set a new one; the snapping frequency will be limited this way
+ ec->_delayed_snap_event = new DelayedSnapEvent(ec, item, knot, event, origin);
+ } // else: watchdog has been set before and we'll wait for it to expire
+ }
+ } else {
+ // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog
+ g_assert(ec->_delayed_snap_event == NULL);
+ ec->_delayed_snap_event = new DelayedSnapEvent(ec, item, knot, event, origin);
+ }
+
+ prev_pos = event_pos;
+ prev_time = event_t;
}
}
gboolean sp_event_context_snap_watchdog_callback(gpointer data)
{
- // Snap NOW! For this the "postponed" flag will be reset and the last motion event will be repeated
- DelayedSnapEvent *dse = reinterpret_cast<DelayedSnapEvent*>(data);
-
- if (dse == NULL) {
- // This might occur when this method is called directly, i.e. not through the timer
- // E.g. on GDK_BUTTON_RELEASE in sp_event_context_root_handler()
- return FALSE;
- }
-
- SPEventContext *ec = dse->getEventContext();
- if (ec == NULL || ec->desktop == NULL) {
- return false;
- }
-
- SPDesktop *dt = ec->desktop;
- dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
-
- switch (dse->getOrigin()) {
- case DelayedSnapEvent::EVENTCONTEXT_ROOT_HANDLER:
- sp_event_context_virtual_root_handler(ec, dse->getEvent());
- break;
- case DelayedSnapEvent::EVENTCONTEXT_ITEM_HANDLER:
- {
- SPItem* item = NULL;
- item = dse->getItem();
- if (item && SP_IS_ITEM(item)) {
- sp_event_context_virtual_item_handler(ec, item, dse->getEvent());
- }
- }
- break;
- case DelayedSnapEvent::KNOT_HANDLER:
- {
- SPKnot* knot = dse->getKnot();
- if (knot && SP_IS_KNOT(knot)) {
- sp_knot_handler_request_position(dse->getEvent(), knot);
- }
- }
- break;
- default:
- g_warning("Origin of snap-delay event has not been defined!;");
- break;
- }
-
- ec->_delayed_snap_event = NULL;
- delete dse;
-
- return FALSE; //Kills the timer and stops it from executing this callback over and over again.
+ // Snap NOW! For this the "postponed" flag will be reset and the last motion event will be repeated
+ DelayedSnapEvent *dse = reinterpret_cast<DelayedSnapEvent*>(data);
+
+ if (dse == NULL) {
+ // This might occur when this method is called directly, i.e. not through the timer
+ // E.g. on GDK_BUTTON_RELEASE in sp_event_context_root_handler()
+ return FALSE;
+ }
+
+ SPEventContext *ec = dse->getEventContext();
+ if (ec == NULL || ec->desktop == NULL) {
+ return false;
+ }
+
+ SPDesktop *dt = ec->desktop;
+ dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
+
+ switch (dse->getOrigin()) {
+ case DelayedSnapEvent::EVENTCONTEXT_ROOT_HANDLER:
+ sp_event_context_virtual_root_handler(ec, dse->getEvent());
+ break;
+ case DelayedSnapEvent::EVENTCONTEXT_ITEM_HANDLER:
+ {
+ SPItem* item = NULL;
+ item = dse->getItem();
+ if (item && SP_IS_ITEM(item)) {
+ sp_event_context_virtual_item_handler(ec, item, dse->getEvent());
+ }
+ }
+ break;
+ case DelayedSnapEvent::KNOT_HANDLER:
+ {
+ SPKnot* knot = dse->getKnot();
+ if (knot && SP_IS_KNOT(knot)) {
+ sp_knot_handler_request_position(dse->getEvent(), knot);
+ }
+ }
+ break;
+ default:
+ g_warning("Origin of snap-delay event has not been defined!;");
+ break;
+ }
+
+ ec->_delayed_snap_event = NULL;
+ delete dse;
+
+ return FALSE; //Kills the timer and stops it from executing this callback over and over again.
}
void sp_event_context_discard_delayed_snap_event(SPEventContext *ec)
{
- delete ec->_delayed_snap_event;
- ec->_delayed_snap_event = NULL;
+ delete ec->_delayed_snap_event;
+ ec->_delayed_snap_event = NULL;
}
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index 8f17ae0133122477bd60f9583553eed265fa15fb..1881dd72be73b6e2961041fd530782496f8470d7 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -1367,7 +1367,7 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
* must provide that information. */
// Build a list of the unselected nodes to which the snapper should snap
- std::vector<std::pair<Geom::Point, int> > unselected_nodes;
+ std::vector<std::pair<Geom::Point, int> > unselected_nodes;
for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) {
@@ -1388,39 +1388,39 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
Inkscape::NodePath::Node *closest_node = NULL;
Geom::Coord closest_dist = NR_HUGE;
- if (closest_only) {
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
- Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
- Geom::Coord dist = Geom::L2(nodepath->drag_origin_mouse - n->origin);
- if (dist < closest_dist) {
- closest_node = n;
- closest_dist = dist;
- }
- }
+ if (closest_only) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
+ Geom::Coord dist = Geom::L2(nodepath->drag_origin_mouse - n->origin);
+ if (dist < closest_dist) {
+ closest_node = n;
+ closest_dist = dist;
+ }
+ }
}
- // Iterate through all selected nodes
- m.setup(nodepath->desktop, false, nodepath->item, &unselected_nodes);
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ // Iterate through all selected nodes
+ m.setup(nodepath->desktop, false, nodepath->item, &unselected_nodes);
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
if (!closest_only || n == closest_node) { //try to snap either all selected nodes or only the closest one
- Inkscape::SnappedPoint s;
- Inkscape::SnapSourceType source_type = (n->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPSOURCE_NODE_SMOOTH : Inkscape::SNAPSOURCE_NODE_CUSP);
- if (constrained) {
- Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
- dedicated_constraint.setPoint(n->pos);
- s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type, dedicated_constraint, false);
- } else {
- s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type);
- }
-
- if (s.getSnapped()) {
- s.setPointerDistance(Geom::L2(nodepath->drag_origin_mouse - n->origin));
- if (!s.isOtherSnapBetter(best, true)) {
- best = s;
- best_pt = from_2geom(s.getPoint()) - n->pos;
- }
- }
+ Inkscape::SnappedPoint s;
+ Inkscape::SnapSourceType source_type = (n->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPSOURCE_NODE_SMOOTH : Inkscape::SNAPSOURCE_NODE_CUSP);
+ if (constrained) {
+ Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
+ dedicated_constraint.setPoint(n->pos);
+ s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type, dedicated_constraint, false);
+ } else {
+ s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type);
+ }
+
+ if (s.getSnapped()) {
+ s.setPointerDistance(Geom::L2(nodepath->drag_origin_mouse - n->origin));
+ if (!s.isOtherSnapBetter(best, true)) {
+ best = s;
+ best_pt = from_2geom(s.getPoint()) - n->pos;
+ }
+ }
}
}
@@ -3955,9 +3955,9 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
Inkscape::SnappedPoint s;
if ((state & GDK_SHIFT_MASK) != 0) {
- // We will not try to snap when the shift-key is pressed
- // so remove the old snap indicator and don't wait for it to time-out
- desktop->snapindicator->remove_snaptarget();
+ // We will not try to snap when the shift-key is pressed
+ // so remove the old snap indicator and don't wait for it to time-out
+ desktop->snapindicator->remove_snaptarget();
}
Inkscape::NodePath::Node *othernode = opposite->other;
diff --git a/src/selection.cpp b/src/selection.cpp
index 828a96968f6e1217f09335e96cfbe36894f5a829..7b936587c343513760684927f30be54e7179f00b 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -440,7 +440,7 @@ std::vector<std::pair<Geom::Point, int> > Selection::getSnapPoints(SnapPreferenc
//Include the transformation origin for snapping
//For a selection or group only the overall origin is considered
if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
- p.push_back(std::make_pair(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
+ p.push_back(std::make_pair(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
}
}
@@ -452,12 +452,12 @@ std::vector<std::pair<Geom::Point, int> > Selection::getSnapPointsConvexHull(Sna
std::vector<std::pair<Geom::Point, int> > p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
- sp_item_snappoints(SP_ITEM(iter->data), false, p, snapprefs);
+ sp_item_snappoints(SP_ITEM(iter->data), false, p, snapprefs);
}
std::vector<std::pair<Geom::Point, int> > pHull;
if (!p.empty()) {
- std::vector<std::pair<Geom::Point, int> >::iterator i;
+ std::vector<std::pair<Geom::Point, int> >::iterator i;
Geom::RectHull cvh((p.front()).first);
for (i = p.begin(); i != p.end(); i++) {
// these are the points we get back
diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp
index e4259e52ca9bb0f3adf9a8cc63f5d26f49975147..feb79cd9a75965fe85907ad462f3591d2bb0dfe0 100644 (file)
--- a/src/sp-flowtext.cpp
+++ b/src/sp-flowtext.cpp
#include "sp-rect.h"
#include "text-tag-attributes.h"
#include "text-chemistry.h"
-
+#include "text-editing.h"
#include "livarot/Shape.h"
static void sp_flowtext_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
static void sp_flowtext_print(SPItem *item, SPPrintContext *ctx);
static gchar *sp_flowtext_description(SPItem *item);
+static void sp_flowtext_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static NRArenaItem *sp_flowtext_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags);
static void sp_flowtext_hide(SPItem *item, unsigned key);
item_class->bbox = sp_flowtext_bbox;
item_class->print = sp_flowtext_print;
item_class->description = sp_flowtext_description;
+ item_class->snappoints = sp_flowtext_snappoints;
item_class->show = sp_flowtext_show;
item_class->hide = sp_flowtext_hide;
}
return g_strdup_printf(ngettext("<b>Linked flowed text</b> (%d character%s)", "<b>Linked flowed text</b> (%d characters%s)", nChars), nChars, trunc);
}
+static void sp_flowtext_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
+{
+ // Choose a point on the baseline for snapping from or to, with the horizontal position
+ // of this point depending on the text alignment (left vs. right)
+ Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item);
+ if (layout != NULL && layout->outputExists()) {
+ boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
+ if (pt) {
+ int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE);
+ p.push_back(std::make_pair((*pt) * sp_item_i2d_affine(item), type));
+ }
+ }
+}
+
static NRArenaItem *
sp_flowtext_show(SPItem *item, NRArena *arena, unsigned/* key*/, unsigned /*flags*/)
{
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 9f7157b995561f8e8b6aeef0765ce67841f1b391..1a5ca6f772a72f7ba94fd99c153062bdabf9502b 100644 (file)
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -962,11 +962,11 @@ static void sp_item_private_snappoints(SPItem const *item, bool const target, Sn
Geom::Point p1, p2;
p1 = bbox->min();
p2 = bbox->max();
- int type = target ? int(Inkscape::SNAPSOURCE_CONVEX_HULL_CORNER) : int(Inkscape::SNAPSOURCE_CONVEX_HULL_CORNER);
+ int type = target ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER);
p.push_back(std::make_pair(p1, type));
p.push_back(std::make_pair(Geom::Point(p1[Geom::X], p2[Geom::Y]), type));
p.push_back(std::make_pair(p2, type));
- p.push_back(std::make_pair(Geom::Point(p1[Geom::Y], p2[Geom::X]), type));
+ p.push_back(std::make_pair(Geom::Point(p2[Geom::X], p1[Geom::Y]), type));
}
}