summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4385257)
raw | patch | inline | side by side (parent: 4385257)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Sun, 25 Jan 2009 13:35:08 +0000 (13:35 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Sun, 25 Jan 2009 13:35:08 +0000 (13:35 +0000) |
- Creating single dots now snaps
23 files changed:
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index 3c8a50192fc2c3124ee5fa0c51a9aca5ce4602e2..da236ae8730672f7b1278afed563edd3a4538b39 100644 (file)
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
SPEventContext *ec = SP_EVENT_CONTEXT(ac);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
- SPItem *item = selection->singleItem();
+ SPItem *item = selection->singleItem();
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}
if (event->button.button == 1 && !event_context->space_panning) {
dragging = true;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
ac->center = Inkscape::setup_for_drag_start(desktop, event_context, event);
-
+
/* Snap center */
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
Geom::Point const motion_w(event->motion.x, event->motion.y);
Geom::Point motion_dt(desktop->w2d(motion_w));
-
+
sp_arc_drag(ac, motion_dt, event->motion.state);
gobble_motion_events(GDK_BUTTON1_MASK);
event_context->xp = event_context->yp = 0;
if (event->button.button == 1 && !event_context->space_panning) {
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the arc
sp_arc_finish(ac);
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the rect
sp_arc_finish(ac);
SP_OBJECT(ac->item)->updateRepr();
sp_canvas_end_forced_full_redraws(desktop->canvas);
-
+
sp_desktop_selection(desktop)->set(ac->item);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC,
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC,
_("Create ellipse"));
ac->item = NULL;
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index 2d20318e36cd5bae58bfb56612adbd5c21b953d7..2b76233f5c5cdf3d88a1eb62ec01bfef760081d4 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
box3d_context->ctrl_dragged = false;
box3d_context->extruded = false;
-
+
box3d_context->_vpdrag = NULL;
new (&box3d_context->sel_changed_connection) sigc::connection();
@@ -157,7 +157,7 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g
SPEventContext *ec = SP_EVENT_CONTEXT(bc);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
- SPItem *item = selection->singleItem();
+ SPItem *item = selection->singleItem();
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
if (selection->perspList().size() == 1) {
@@ -167,7 +167,7 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g
}
/* create a default perspective in document defs if none is present
- (can happen after 'vacuum defs' or when a pre-0.46 file is opened) */
+ (can happen after 'vacuum defs' or when a pre-0.46 file is opened) */
static void sp_box3d_context_check_for_persp_in_defs(SPDocument *document) {
SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
@@ -271,12 +271,13 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
event_context->xp = (gint) button_w[Geom::X];
event_context->yp = (gint) button_w[Geom::Y];
event_context->within_tolerance = true;
-
+
// remember clicked item, *not* disregarding groups (since a 3D box is a group), honoring Alt
event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, event->button.state & GDK_CONTROL_MASK);
dragging = true;
-
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
+
/* */
Geom::Point button_dt(desktop->w2d(button_w));
bc->drag_origin = from_2geom(button_dt);
@@ -372,6 +373,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
event_context->xp = event_context->yp = 0;
if ( event->button.button == 1 && !event_context->space_panning) {
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the box
@@ -504,6 +506,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the box
sp_box3d_finish(bc);
index 372918b80b4626461857773c202364ad79379698..6fa709b18915437322ef9827a8daacbb0e2786d9 100644 (file)
// Make sure we see all enter events for canvas items,
// even if a mouse button is depressed.
dt->canvas->gen_all_enter_events = true;
+
+ sp_canvas_set_snap_delay_active(dt->canvas, true);
}
// Restore the default event generating behaviour.
SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(ec);
desktop->canvas->gen_all_enter_events = false;
+
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
}
@@ -525,7 +529,7 @@ 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);
-
+
Geom::Point pt2g = to_2geom(p);
if (!cc->sid) {
@@ -568,12 +572,12 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
}
} else if (bevent.button == 3) {
if (cc->state == SP_CONNECTOR_CONTEXT_REROUTING) {
- // A context menu is going to be triggered here,
+ // A context menu is going to be triggered here,
// so end the rerouting operation.
cc_connector_rerouting_finish(cc, &p);
-
+
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
-
+
// Don't set ret to TRUE, so we drop through to the
// parent handler which will open the context menu.
}
@@ -705,7 +709,7 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
case SP_CONNECTOR_CONTEXT_REROUTING:
{
cc_connector_rerouting_finish(cc, &p);
-
+
sp_document_ensure_up_to_date(doc);
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
return TRUE;
break;
case GDK_Escape:
if (cc->state == SP_CONNECTOR_CONTEXT_REROUTING) {
-
+
SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
SPDocument *doc = sp_desktop_document(desktop);
cc_connector_rerouting_finish(cc, NULL);
-
+
sp_document_undo(doc);
-
+
cc->state = SP_CONNECTOR_CONTEXT_IDLE;
desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
_("Connector endpoint drag cancelled."));
@@ -771,7 +775,7 @@ cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p
{
SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
SPDocument *doc = sp_desktop_document(desktop);
-
+
// Clear the temporary path:
cc->red_curve->reset();
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
@@ -796,7 +800,7 @@ cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p
cc->clickeditem->setHidden(false);
sp_conn_adjust_path(SP_PATH(cc->clickeditem));
cc->clickeditem->updateRepr();
- sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR,
+ sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR,
_("Reroute connector"));
cc_set_active_conn(cc, cc->clickeditem);
}
cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
{
g_assert (knot != NULL);
-
+
g_object_ref(knot);
SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(
switch (event->type) {
case GDK_ENTER_NOTIFY:
sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
-
+
cc->active_handle = knot;
if (knot->tip)
knot->desktop->event_context->defaultMessageContext()->set(
Inkscape::NORMAL_MESSAGE, knot->tip);
}
-
+
consumed = TRUE;
break;
case GDK_LEAVE_NOTIFY:
sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE);
cc->active_handle = NULL;
-
+
if (knot->tip) {
knot->desktop->event_context->defaultMessageContext()->clear();
}
-
+
consumed = TRUE;
break;
default:
break;
}
-
+
g_object_unref(knot);
return consumed;
// Set center connection point.
if ( cc->connpthandle == NULL ) {
- SPKnot *knot = sp_knot_new(cc->desktop,
+ SPKnot *knot = sp_knot_new(cc->desktop,
_("<b>Connection point</b>: click or drag to create a new connector"));
knot->setShape(SP_KNOT_SHAPE_SQUARE);
// Create the handle if it doesn't exist
if ( cc->endpt_handle[i] == NULL ) {
- SPKnot *knot = sp_knot_new(cc->desktop,
+ SPKnot *knot = sp_knot_new(cc->desktop,
_("<b>Connector endpoint</b>: drag to reroute or connect to new shapes"));
knot->setShape(SP_KNOT_SHAPE_SQUARE);
diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp
index e2c3ba40eb4900d69c5084943a059370641be782..fbbbfee197d3e045adf249ade89da14a63c562ec 100644 (file)
--- a/src/desktop-events.cpp
+++ b/src/desktop-events.cpp
case GDK_BUTTON_PRESS:
if (event->button.button == 1) {
dragging = true;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
Geom::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win));
Geom::Point const event_dt(desktop->w2d(event_w));
@@ -142,14 +143,14 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge
if (dragging) {
Geom::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win));
Geom::Point event_dt(desktop->w2d(event_w));
-
+
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
m.guideSnap(event_dt, normal);
-
+
sp_guideline_set_position(SP_GUIDELINE(guide), from_2geom(event_dt));
desktop->set_coordinate_status(to_2geom(event_dt));
- desktop->setPosition(to_2geom(event_dt));
+ desktop->setPosition(to_2geom(event_dt));
}
break;
case GDK_BUTTON_RELEASE:
@@ -157,12 +158,13 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge
gdk_pointer_ungrab(event->button.time);
Geom::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win));
Geom::Point event_dt(desktop->w2d(event_w));
-
+
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
m.guideSnap(event_dt, normal);
-
+
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
gtk_object_destroy(GTK_OBJECT(guide));
guide = NULL;
if ((horiz ? wy : wx) >= 0) {
@@ -172,7 +174,7 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge
sp_repr_set_point(repr, "position", from_2geom(event_dt));
SP_OBJECT_REPR(desktop->namedview)->appendChild(repr);
Inkscape::GC::release(repr);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_NONE,
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_NONE,
_("Create guide"));
}
desktop->set_coordinate_status(from_2geom(event_dt));
case GDK_2BUTTON_PRESS:
if (event->button.button == 1) {
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
sp_canvas_item_ungrab(item, event->button.time);
Inkscape::UI::Dialogs::GuidelinePropertiesDialog::showDialog(guide, desktop);
ret = TRUE;
break;
}
dragging = true;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
sp_canvas_item_grab(item,
( GDK_BUTTON_RELEASE_MASK |
GDK_BUTTON_PRESS_MASK |
Geom::Point const motion_w(event->motion.x,
event->motion.y);
Geom::Point motion_dt(to_2geom(desktop->w2d(from_2geom(motion_w))));
-
- // This is for snapping while dragging existing guidelines. New guidelines,
+
+ // This is for snapping while dragging existing guidelines. New guidelines,
// which are dragged off the ruler, are being snapped in sp_dt_ruler_event
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
m.guideSnap(motion_dt, to_2geom(guide->normal_to_line));
-
+
sp_guide_moveto(*guide, from_2geom(motion_dt), false);
moved = true;
desktop->set_coordinate_status(from_2geom(motion_dt));
desktop->setPosition (from_2geom(event_dt));
}
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
sp_canvas_item_ungrab(item, event->button.time);
ret=TRUE;
}
// device shows up.
it->second = tools_active(desktop);
}
-
+
it = toolToUse.find(name);
if (it != toolToUse.end() ) {
tools_switch(desktop, it->second);
index e5ef2c80d5bc92c4b9a92784cb69e6e4890ac271..edd64f021b5fcdc29ba6b0a993f5a5c16a5fd896 100644 (file)
@@ -946,8 +946,8 @@ static void sp_canvas_dirty_rect(SPCanvas* canvas, int nl, int nt, int nr, int n
static void sp_canvas_mark_rect(SPCanvas* canvas, int nl, int nt, int nr, int nb, uint8_t val);
static int do_update (SPCanvas *canvas);
-static gboolean sp_canvas_snap_watchdog_callback(gpointer data);
-static void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event);
+static gboolean sp_canvas_snap_watchdog_callback(gpointer data);
+static void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event);
static void sp_canvas_snap_watchdog_kill(SPCanvas *canvas);
/**
canvas->watchdog_id = 0;
canvas->watchdog_event = NULL;
+ canvas->context_snap_delay_active = false;
}
/**
}
widget->allocation = *allocation;
-
+
if (GTK_WIDGET_REALIZED (widget)) {
gdk_window_move_resize (widget->window,
widget->allocation.x, widget->allocation.y,
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
- if (dt) {
+ if (dt) {
// 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.
+ // drawing a new shape we really should snap though.
dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
}
-
+
/* Pick the current item as if the button were not pressed, and
* then process the event.
*/
break;
case GDK_BUTTON_RELEASE:
- sp_canvas_snap_watchdog_callback(canvas); // If we have any pending snapping action, then invoke it now
-
+ sp_canvas_snap_watchdog_callback(canvas); // If we have any pending snapping action, then invoke it now
+
/* Process the event as if the button were pressed, then repick
* after the button has been released
*/
canvas->state = event->state;
pick_current_item (canvas, (GdkEvent *) event);
event->state ^= mask;
-
+
break;
default:
{
static guint32 prev_time;
static boost::optional<Geom::Point> prev_pos;
-
+
int status;
SPCanvas *canvas = SP_CANVAS (widget);
if (canvas->pixmap_gc == NULL) // canvas being deleted
return FALSE;
-
+
SPDesktop *dt = SP_ACTIVE_DESKTOP;
-
+
// Snap when speed drops below e.g. 0.02 px/msec, or when no motion events have occured 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.
- if (dt) {
- bool const c1 = event->type == GDK_MOTION_NOTIFY;
- bool const c21 = event->state & GDK_BUTTON1_MASK; // Snapping only occurs when dragging with the left mouse button down
- bool const c22 = event->state & GDK_BUTTON2_MASK; // We shouldn't hold back any events when other mouse buttons have been
- bool const c23 = 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
- bool const c3 = dt->namedview->snap_manager.snapprefs.getSnapEnabledGlobally();
- if (c1 && c21 && (!c22) && (!c23) && c3) {
- Geom::Point event_pos(event->x, event->y);
- guint32 event_t = gdk_event_get_time ( (GdkEvent *) event );
-
- dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); // put snapping on hold
-
- 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 << "speed = " << speed << " px/msec " << "| time passed = " << delta_t << " 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
- // stoppping abruptly)
- sp_canvas_snap_watchdog_kill(canvas);
- sp_canvas_snap_watchdog_set(canvas, event); // 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 (canvas->watchdog_id == 0) { // 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
- sp_canvas_snap_watchdog_set(canvas, event);
- } // 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
- sp_canvas_snap_watchdog_set(canvas, event);
+ if (canvas->context_snap_delay_active && dt && dt->namedview->snap_manager.snapprefs.getSnapEnabledGlobally()) {
+ Geom::Point event_pos(event->x, event->y);
+ guint32 event_t = gdk_event_get_time ( (GdkEvent *) event );
+
+ dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); // put snapping on hold
+
+ 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 << "speed = " << speed << " px/msec " << "| time passed = " << delta_t << " 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)
+ sp_canvas_snap_watchdog_kill(canvas);
+ sp_canvas_snap_watchdog_set(canvas, event); // 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 (canvas->watchdog_id == 0) { // 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
+ sp_canvas_snap_watchdog_set(canvas, event);
+ } // else: watchdog has been set before and we'll wait for it to expire
}
-
- prev_pos = event_pos;
- prev_time = event_t;
- }
+ } else {
+ // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog
+ sp_canvas_snap_watchdog_set(canvas, event);
+ }
+
+ prev_pos = event_pos;
+ prev_time = event_t;
}
-
+
canvas->state = event->state;
pick_current_item (canvas, (GdkEvent *) event);
return status;
}
-gboolean sp_canvas_snap_watchdog_callback(gpointer data)
+gboolean sp_canvas_snap_watchdog_callback(gpointer data)
{
- // Snap NOW! For this the "postponed" flag will be reset and an the last motion event will be repeated
+ // Snap NOW! For this the "postponed" flag will be reset and an the last motion event will be repeated
SPCanvas *canvas = reinterpret_cast<SPCanvas *>(data);
if (!canvas->watchdog_event) {
return FALSE;
- }
-
+ }
+
SPDesktop *dt = SP_ACTIVE_DESKTOP;
if (dt) {
dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false);
}
-
+
emit_event(canvas, canvas->watchdog_event);
gdk_event_free(canvas->watchdog_event);
canvas->watchdog_event = NULL;
canvas->watchdog_id = 0;
-
+
return FALSE;
}
-void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event)
+void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double value = prefs->getDoubleLimited("/options/snapdelay/value", 0, 0, 1000);
g_assert(canvas->watchdog_id == 0);
canvas->watchdog_id = g_timeout_add(value, &sp_canvas_snap_watchdog_callback, canvas);
g_assert(canvas->watchdog_event == NULL);
- canvas->watchdog_event = gdk_event_copy( (GdkEvent *) event);
+ canvas->watchdog_event = gdk_event_copy( (GdkEvent *) event);
}
-void sp_canvas_snap_watchdog_kill(SPCanvas *canvas)
+void sp_canvas_snap_watchdog_kill(SPCanvas *canvas)
{
- if (canvas->watchdog_id) {
+ if (canvas->watchdog_id) {
g_source_remove(canvas->watchdog_id); // Kill the watchdog
canvas->watchdog_id = 0;
}
-
+
if (canvas->watchdog_event) {
gdk_event_free(canvas->watchdog_event);
canvas->watchdog_event = NULL;
}
}
-
+
+void sp_canvas_set_snap_delay_active(SPCanvas *canvas, bool snapping)
+{
+ // Only when canvas->context_snap_delay_active has been set, Inkscape will know that snapping is active
+ // and will delay any snapping events (but only when asked to through the preferences)
+
+ // When snapping is being delayed, then that will also mean that at some point the last event
+ // might be re-triggered. This should only occur when Inkscape is still in the same tool or context,
+ // and even more specifically, the tool should even be in the same state. If for example snapping is being delayed while
+ // creating a rectangle, then the rect-context will be active and it will be in the "dragging" state
+ // (see the static boolean variable "dragging" in the sp_rect_context_root_handler). The procedure is
+ // as follows: call sp_canvas_set_snap_delay_active(*, TRUE) when entering the "dragging" state, which will delay
+ // snapping from that moment on, and call sp_canvas_set_snap_delay_active(*, FALSE) when leaving the "dragging"
+ // state. This last call will also make sure that any pending snap events will be canceled.
+
+ if (!canvas) {
+ g_warning("sp_canvas_set_snap_delay_active() has been called without providing a canvas!");
+ return;
+ }
+
+ if (canvas->context_snap_delay_active == snapping) {
+ g_warning("Snapping was already allowed or disallowed! This is a bug, please report it.");
+ }
+
+ canvas->context_snap_delay_active = snapping;
+
+ if (snapping == false) {
+ sp_canvas_snap_watchdog_kill(canvas); // kill any pending snapping events
+ }
+}
+
static void
sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, int draw_x1, int draw_y1, int draw_x2, int draw_y2, int sw)
{
@@ -1731,7 +1754,7 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1,
// Mark the region clean
sp_canvas_mark_rect(canvas, x0, y0, x1, y1, 0);
- buf.buf_rowstride = sw * 4;
+ buf.buf_rowstride = sw * 4;
buf.rect.x0 = x0;
buf.rect.y0 = y0;
buf.rect.x1 = x1;
} else {
// paths only, so 1M works faster
// 1M is the cached buffer and we need 4 channels
- setup.max_pixels = 262144;
+ setup.max_pixels = 262144;
}
// Start the clock
@@ -2282,7 +2305,7 @@ sp_canvas_scroll_to (SPCanvas *canvas, double cx, double cy, unsigned int clear,
int ix = (int) round(cx); // ix and iy are the new canvas coordinates (integer screen pixels)
int iy = (int) round(cy); // cx might be negative, so (int)(cx + 0.5) will not do!
- int dx = ix - canvas->x0; // dx and dy specify the displacement (scroll) of the
+ int dx = ix - canvas->x0; // dx and dy specify the displacement (scroll) of the
int dy = iy - canvas->y0; // canvas w.r.t its previous position
canvas->dx0 = cx; // here the 'd' stands for double, not delta!
index 2c416b8a759049c28090aebc2270816dc8d88c95..cb63374e1f1f500d3875fc88f30effb78aafe270 100644 (file)
--- a/src/display/sp-canvas.h
+++ b/src/display/sp-canvas.h
Geom::Rect getViewbox() const;
NR::IRect getViewboxIntegers() const;
-
+
guint watchdog_id;
GdkEvent *watchdog_event;
+ bool context_snap_delay_active;
};
GtkWidget *sp_canvas_new_aa();
@@ -217,6 +218,8 @@ void sp_canvas_world_to_window(SPCanvas const *canvas, double worldx, double wor
Geom::Point sp_canvas_window_to_world(SPCanvas const *canvas, Geom::Point const win);
Geom::Point sp_canvas_world_to_window(SPCanvas const *canvas, Geom::Point const world);
+void sp_canvas_set_snap_delay_active(SPCanvas *canvas, bool snapping);
+
#endif // SEEN_SP_CANVAS_H
/*
diff --git a/src/draw-context.cpp b/src/draw-context.cpp
index 98fee29bf4bff9449b27ab296248b04179f7a319..5e3ff82dc4539154b6379478f8c0e370297d4db0 100644 (file)
--- a/src/draw-context.cpp
+++ b/src/draw-context.cpp
item->updateRepr();
}
- sp_document_done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL,
+ sp_document_done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL,
_("Draw path"));
// When quickly drawing several subpaths with Shift, the next subpath may be finished and
@@ -834,7 +834,7 @@ void spdc_create_single_dot(SPEventContext *ec, Geom::Point const &pt, char cons
/* put the circle where the mouse click occurred and set the diameter to the
current stroke width, multiplied by the amount specified in the preferences */
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-
+
Geom::Matrix const i2d (sp_item_i2d_affine (item));
Geom::Point pp = pt * i2d;
double rad = 0.5 * prefs->getDouble(tool_path + "/dot-size", 3.0);
index 1f6842a5ca34236cd5304338b36188b28a572639..985e3ac5153cecf1194f03502a2d4db8bacbdbc5 100644 (file)
--- a/src/dropper-context.cpp
+++ b/src/dropper-context.cpp
{
SPDropperContext *dc = SP_DROPPER_CONTEXT(ec);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-
+
int pick = prefs->getInt("/tools/dropper/pick",
SP_DROPPER_PICK_VISIBLE);
bool setalpha = prefs->getBool("/tools/dropper/setalpha", true);
-
+
return SP_RGBA32_F_COMPOSE(dc->R, dc->G, dc->B,
(pick == SP_DROPPER_PICK_ACTUAL && setalpha) ? dc->alpha : 1.0);
}
@@ -324,7 +324,7 @@ static gint sp_dropper_context_root_handler(SPEventContext *event_context, GdkEv
if (!(sp_desktop_selection(desktop)->isEmpty())) {
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_DROPPER,
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_DROPPER,
_("Set picked color"));
}
index 8cab1690b5778ff48c3c9be53f4e29b1ebe50478..75aef13ef28a25b87211e28385673340f362f49a 100644 (file)
// If force is below the absolute threshold DYNA_EPSILON,
// or we haven't yet reached DYNA_VEL_START (i.e. at the beginning of stroke)
// _and_ the force is below the (higher) DYNA_EPSILON_START threshold,
- // discard this move.
+ // discard this move.
// This prevents flips, blobs, and jerks caused by microscopic tremor of the tablet pen,
// especially bothersome at the start of the stroke where we don't yet have the inertia to
// smooth them out.
// get the real brush point, not the same as pointer (affected by hatch tracking and/or mass
// drag)
Geom::Point brush = sp_dyna_draw_get_vpoint(dc, dc->cur);
- Geom::Point brush_w = SP_EVENT_CONTEXT(dc)->desktop->d2w(brush);
+ Geom::Point brush_w = SP_EVENT_CONTEXT(dc)->desktop->d2w(brush);
double trace_thick = 1;
if (dc->trace_bg) {
} else {
dc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Select a guide path</b> to track with <b>Ctrl</b>"));
}
- }
+ }
if ( dc->is_drawing && (event->motion.state & GDK_BUTTON1_MASK) && !event_context->space_panning) {
dc->dragging = TRUE;
} else {
// looks like we're starting to lose speed,
// so _gradually_ let go attraction to prevent jerks
- target = (dc->hatch_spacing * speed + hatch_dist * (SPEED_NORMAL - speed))/SPEED_NORMAL;
+ target = (dc->hatch_spacing * speed + hatch_dist * (SPEED_NORMAL - speed))/SPEED_NORMAL;
}
if (!IS_NAN(dot) && dot < -0.5) {// flip
target = -target;
}
} else {
- // this is the first motion event, set the dist
+ // this is the first motion event, set the dist
dc->hatch_spacing = hatch_dist;
}
}
// Draw the hatching circle if necessary
- if (event->motion.state & GDK_CONTROL_MASK) {
- if (dc->hatch_spacing == 0 && hatch_dist != 0) {
+ if (event->motion.state & GDK_CONTROL_MASK) {
+ if (dc->hatch_spacing == 0 && hatch_dist != 0) {
// Haven't set spacing yet: gray, center free, update radius live
Geom::Point c = desktop->w2d(motion_w);
Geom::Matrix const sm (Geom::Scale(hatch_dist, hatch_dist) * Geom::Translate(c));
dc->hatch_livarot_path = NULL;
dc->just_started_drawing = false;
- if (dc->hatch_spacing != 0 && !dc->keep_selected) {
+ if (dc->hatch_spacing != 0 && !dc->keep_selected) {
// we do not select the newly drawn path, so increase spacing by step
if (dc->hatch_spacing_step == 0) {
dc->hatch_spacing_step = dc->hatch_spacing;
} else {
if (dc->keep_selected) {
sp_desktop_selection(desktop)->set(dc->repr);
- }
+ }
}
} else {
dc->repr = NULL;
}
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC,
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC,
_("Draw calligraphic stroke"));
}
static void
add_cap(SPCurve *curve,
Geom::Point const &from,
- Geom::Point const &to,
+ Geom::Point const &to,
double rounding)
{
if (Geom::L2( to - from ) > DYNA_EPSILON) {
dc->cal1->is_empty() ||
dc->cal2->is_empty() ||
(dc->cal1->get_segment_count() <= 0) ||
- dc->cal1->first_path()->closed()
+ dc->cal1->first_path()->closed()
) {
dc->cal1->reset();
dc->cal2->reset();
SPCurve *rev_cal2 = dc->cal2->create_reverse();
if (
(rev_cal2->get_segment_count() <= 0) ||
- rev_cal2->first_path()->closed()
+ rev_cal2->first_path()->closed()
) {
rev_cal2->unref();
dc->cal1->reset();
!dc_cal1_firstseg ||
!rev_cal2_firstseg ||
!dc_cal1_lastseg ||
- !rev_cal2_lastseg
+ !rev_cal2_lastseg
) {
rev_cal2->unref();
dc->cal1->reset();
index b4f52a7c9bf7fa909564ca540d335badf1d677fd..e9b46a2c29df5e3275d09c8a3d0af12665c68f79 100644 (file)
--- a/src/gradient-context.cpp
+++ b/src/gradient-context.cpp
SPGradientContext *rc = SP_GRADIENT_CONTEXT(object);
SPEventContext *ec = SP_EVENT_CONTEXT(object);
+ sp_canvas_set_snap_delay_active(ec->desktop->canvas, false);
+
ec->enableGrDrag(false);
if (rc->_message_context) {
N_("Radial gradient <b>mid stop</b>")
};
-static void
+static void
gradient_selection_changed (Inkscape::Selection *, gpointer data)
{
SPGradientContext *rc = (SPGradientContext *) data;
rc->selcon = new sigc::connection (selection->connectChanged( sigc::bind (sigc::ptr_fun(&gradient_selection_changed), rc)));
rc->subselcon = new sigc::connection (ec->desktop->connectToolSubselectionChanged(sigc::bind (sigc::ptr_fun(&gradient_subselection_changed), rc)));
gradient_selection_changed(selection, rc);
+
+ sp_canvas_set_snap_delay_active(ec->desktop->canvas, true);
}
void
@@ -271,7 +275,7 @@ sp_gradient_context_get_stop_intervals (GrDrag *drag, GSList **these_stops, GSLi
// remember the coord of the dragger to reselect it later
coords.push_back(dragger->point);
// for all draggables of dragger
- for (GSList const* j = dragger->draggables; j != NULL; j = j->next) {
+ for (GSList const* j = dragger->draggables; j != NULL; j = j->next) {
GrDraggable *d = (GrDraggable *) j->data;
// find the gradient
@@ -279,9 +283,9 @@ sp_gradient_context_get_stop_intervals (GrDrag *drag, GSList **these_stops, GSLi
SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (gradient, false);
// these draggable types cannot have a next draggabe to insert a stop between them
- if (d->point_type == POINT_LG_END ||
- d->point_type == POINT_RG_FOCUS ||
- d->point_type == POINT_RG_R1 ||
+ if (d->point_type == POINT_LG_END ||
+ d->point_type == POINT_RG_FOCUS ||
+ d->point_type == POINT_RG_R1 ||
d->point_type == POINT_RG_R2) {
continue;
}
@@ -299,7 +303,7 @@ sp_gradient_context_get_stop_intervals (GrDrag *drag, GSList **these_stops, GSLi
// if there's a next stop,
if (next_stop) {
GrDragger *dnext = NULL;
- // find its dragger
+ // find its dragger
// (complex because it may have different types, and because in radial,
// more than one dragger may correspond to a stop, so we must distinguish)
if (type == POINT_LG_BEGIN || type == POINT_LG_MID) {
@@ -311,14 +315,14 @@ sp_gradient_context_get_stop_intervals (GrDrag *drag, GSList **these_stops, GSLi
if (type == POINT_RG_CENTER || type == POINT_RG_MID1) {
if (next_stop == last_stop)
dnext = drag->getDraggerFor (item, POINT_RG_R1, p_i+1, fs);
- else
+ else
dnext = drag->getDraggerFor (item, POINT_RG_MID1, p_i+1, fs);
- }
- if ((type == POINT_RG_MID2) ||
+ }
+ if ((type == POINT_RG_MID2) ||
(type == POINT_RG_CENTER && dnext && !dnext->isSelected())) {
if (next_stop == last_stop)
dnext = drag->getDraggerFor (item, POINT_RG_R2, p_i+1, fs);
- else
+ else
dnext = drag->getDraggerFor (item, POINT_RG_MID2, p_i+1, fs);
}
}
if (g_slist_length(these_stops) == 0 && drag->numSelected() == 1) {
// if a single stop is selected, add between that stop and the next one
GrDragger *dragger = (GrDragger *) drag->selected->data;
- for (GSList const* j = dragger->draggables; j != NULL; j = j->next) {
+ for (GSList const* j = dragger->draggables; j != NULL; j = j->next) {
GrDraggable *d = (GrDraggable *) j->data;
SPGradient *gradient = sp_item_gradient (d->item, d->fill_or_stroke);
SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (gradient, false);
guint32 const c0 = sp_stop_get_rgba32(stop0);
guint32 const c2 = sp_stop_get_rgba32(stop2);
guint32 const c1r = sp_stop_get_rgba32(stop1);
- guint32 c1 = average_color (c0, c2,
+ guint32 c1 = average_color (c0, c2,
(stop1->offset - stop0->offset) / (stop2->offset - stop0->offset));
- double diff =
+ double diff =
sqr(SP_RGBA32_R_F(c1) - SP_RGBA32_R_F(c1r)) +
sqr(SP_RGBA32_G_F(c1) - SP_RGBA32_G_F(c1r)) +
sqr(SP_RGBA32_B_F(c1) - SP_RGBA32_B_F(c1r)) +
@@ -630,7 +634,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
} else {
dragging = false;
- // unless clicked with Ctrl (to enable Ctrl+doubleclick).
+ // unless clicked with Ctrl (to enable Ctrl+doubleclick).
if (event->button.state & GDK_CONTROL_MASK) {
ret = TRUE;
break;
@@ -667,7 +671,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
event_context->item_to_select = NULL;
ret = TRUE;
}
- Inkscape::Rubberband::get(desktop)->stop();
+ Inkscape::Rubberband::get(desktop)->stop();
}
break;
case GDK_KEY_PRESS:
diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index 0cb9fc423e410469a33994f2364ba0d5a17391ec..eaf5658f803dc5cb3db25637b366875dfece1846 100644 (file)
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
#include "sp-pattern.h"
#include "style.h"
#include "live_effects/lpeobject.h"
+#include "desktop.h"
+#include "display/sp-canvas.h"
#include "xml/repr.h" // for debugging only
this->repr = repr;
this->local_change = FALSE;
+
+ this->dragging = false;
}
KnotHolder::~KnotHolder() {
void
KnotHolder::knot_clicked_handler(SPKnot *knot, guint state)
{
- KnotHolder *knot_holder = this;
+ KnotHolder *knot_holder = this;
for(std::list<KnotHolderEntity *>::iterator i = knot_holder->entity.begin(); i != knot_holder->entity.end(); ++i) {
KnotHolderEntity *e = *i;
void
KnotHolder::knot_moved_handler(SPKnot *knot, Geom::Point const &p, guint state)
{
- // this was a local change and the knotholder does not need to be recreated:
+ if (this->dragging == false) {
+ this->dragging = true;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
+ }
+
+ // this was a local change and the knotholder does not need to be recreated:
this->local_change = TRUE;
for(std::list<KnotHolderEntity *>::iterator i = this->entity.begin(); i != this->entity.end(); ++i) {
@@ -155,7 +164,10 @@ KnotHolder::knot_moved_handler(SPKnot *knot, Geom::Point const &p, guint state)
void
KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/)
{
- if (this->released) {
+ this->dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
+
+ if (this->released) {
this->released(this->item);
} else {
SPObject *object = (SPObject *) this->item;
diff --git a/src/knotholder.h b/src/knotholder.h
index 310adab6192b15e87d1ee81fb08056c947333b53..fa1abd071efd4e226efdfcc5fb470f803b8c3184 100644 (file)
--- a/src/knotholder.h
+++ b/src/knotholder.h
SPKnotHolderReleasedFunc released;
gboolean local_change; ///< if true, no need to recreate knotholder if repr was changed.
+
+ bool dragging;
};
/**
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index add070d1f8b31571bc70ef390278eaa5911911dc..cc38acbe5183210d5bb599b2a182625523b6ddcc 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
Inkscape::LivePathEffect::Effect *lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(object));
if (lpe && lpe->isVisible() && lpe->showOrigPath()) {
np->show_helperpath = true;
- }
+ }
}
np->straight_path = false;
if (IS_LIVEPATHEFFECT(object) && item) {
} else {
np->item = SP_ITEM(object);
}
-
+
np->drag_origin_mouse = Geom::Point(NR_HUGE, NR_HUGE);
// we need to update item's transform from the repr here,
@@ -1064,7 +1064,7 @@ static void sp_nodepath_set_line_type(Inkscape::NodePath::Node *end, NRPathcode
start->type = Inkscape::NodePath::NODE_SMOOTH;
if (end->type == Inkscape::NodePath::NODE_AUTO)
end->type = Inkscape::NodePath::NODE_SMOOTH;
-
+
start->n.pos = start->pos;
end->p.pos = end->pos;
@@ -1152,10 +1152,10 @@ sp_node_side_is_line (Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeSi
other_to_me = &othernode->n;
} else if (&node->n == side) {
other_to_me = &othernode->p;
- }
+ }
if (!other_to_me)
return false;
- bool is_line =
+ bool is_line =
(Geom::L2(othernode->pos - other_to_me->pos) < 1e-6 &&
Geom::L2(node->pos - side->pos) < 1e-6);
return is_line;
@@ -1164,7 +1164,7 @@ sp_node_side_is_line (Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeSi
/**
* Same as sp_nodepath_set_node_type(), but also converts, if necessary, adjacent segments from
* lines to curves. If adjacent to one line segment, pulls out or rotates opposite handle to align
- * with that segment, procucing half-smooth node. If already half-smooth, pull out the second handle too.
+ * with that segment, procucing half-smooth node. If already half-smooth, pull out the second handle too.
* If already cusp and set to cusp, retracts handles.
*/
void sp_nodepath_convert_node_type(Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeType type)
@@ -1178,9 +1178,9 @@ void sp_nodepath_convert_node_type(Inkscape::NodePath::Node *node, Inkscape::Nod
if (type == Inkscape::NodePath::NODE_SYMM || type == Inkscape::NodePath::NODE_SMOOTH) {
-/*
+/*
Here's the algorithm of converting node to smooth (Shift+S or toolbar button), in pseudocode:
-
+
if (two_handles) {
// do nothing, adjust_handles called via set_node_type will line them up
} else if (one_handle) {
* Call sp_node_moveto() for node selection and handle possible snapping.
*/
static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath, Geom::Coord dx, Geom::Coord dy,
- bool const snap, bool constrained = false,
+ bool const snap, bool constrained = false,
Inkscape::Snapper::ConstraintLine const &constraint = Geom::Point())
{
Geom::Point delta(dx, dy);
Geom::Point best_pt = delta;
Inkscape::SnappedPoint best;
-
- if (snap) {
+
+ if (snap) {
/* When dragging a (selected) node, it should only snap to other nodes (i.e. unselected nodes), and
- * not to itself. The snapper however can not tell which nodes are selected and which are not, so we
+ * not to itself. The snapper however can not tell which nodes are selected and which are not, so we
* must provide that information. */
-
- // Build a list of the unselected nodes to which the snapper should snap
+
+ // Build a list of the unselected nodes to which the snapper should snap
std::vector<Geom::Point> unselected_nodes;
for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
@@ -1357,20 +1357,20 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data;
if (!node->selected) {
unselected_nodes.push_back(to_2geom(node->pos));
- }
+ }
}
- }
-
+ }
+
SnapManager &m = nodepath->desktop->namedview->snap_manager;
-
- // When only the node closest to the mouse pointer is to be snapped
+
+ // When only the node closest to the mouse pointer is to be snapped
// then we will not even try to snap to other points and discard those immediately
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- bool closest_only = prefs->getBool("/options/snapclosestonly/value", false);
-
+ bool closest_only = prefs->getBool("/options/snapclosestonly/value", false);
+
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;
@@ -1379,25 +1379,25 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
closest_node = n;
closest_dist = dist;
}
- }
+ }
}
-
+
// Iterate through all selected nodes
m.setup(nodepath->desktop, false, SP_PATH(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::SnappedPoint s;
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), dedicated_constraint);
} else {
s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta));
- }
-
+ }
+
if (s.getSnapped()) {
- s.setPointerDistance(Geom::L2(nodepath->drag_origin_mouse - n->origin));
+ 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;
@@ -1405,11 +1405,11 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
}
}
}
-
+
if (best.getSnapped()) {
nodepath->desktop->snapindicator->set_new_snaptarget(best);
} else {
- nodepath->desktop->snapindicator->remove_snaptarget();
+ nodepath->desktop->snapindicator->remove_snaptarget();
}
}
@@ -2296,13 +2296,13 @@ static void do_node_selected_join(Inkscape::NodePath::Path *nodepath, Inkscape::
}
if (b == sb->first) {
- // copy all nodes from b to a, forward
+ // copy all nodes from b to a, forward
sp_nodepath_node_new(sa, NULL,Inkscape::NodePath::NODE_CUSP, code, &p, &c, &sb->first->n.pos);
for (n = sb->first->n.other; n != NULL; n = n->n.other) {
sp_nodepath_node_new(sa, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->code, &n->p.pos, &n->pos, &n->n.pos);
}
} else if (b == sb->last) {
- // copy all nodes from b to a, backward
+ // copy all nodes from b to a, backward
sp_nodepath_node_new(sa, NULL,Inkscape::NodePath::NODE_CUSP, code, &p, &c, &sb->last->p.pos);
for (n = sb->last->p.other; n != NULL; n = n->p.other) {
sp_nodepath_node_new(sa, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos);
@@ -3333,7 +3333,7 @@ static void sp_node_adjust_handle(Inkscape::NodePath::Node *node, gint which_adj
}
if (node->type == Inkscape::NodePath::NODE_SYMM) {
- // symmetrize
+ // symmetrize
me->pos = 2 * node->pos - other->pos;
return;
} else {
Geom::Point leg_prev = to_2geom(node->p.other->pos - node->pos);
Geom::Point leg_next = to_2geom(node->n.other->pos - node->pos);
-
+
double norm_leg_prev = Geom::L2(leg_prev);
double norm_leg_next = Geom::L2(leg_next);
-
+
Geom::Point delta;
if (norm_leg_next > 0.0) {
delta = (norm_leg_prev / norm_leg_next) * leg_next - leg_prev;
delta.normalize();
}
-
+
node->p.pos = node->pos - norm_leg_prev / 3 * delta;
node->n.pos = node->pos + norm_leg_next / 3 * delta;
}
}
n->is_dragging = true;
+ sp_canvas_set_snap_delay_active(n->subpath->nodepath->desktop->canvas, true);
// Reconstruct and store the location of the mouse pointer at the time when we started dragging (needed for snapping)
- n->subpath->nodepath->drag_origin_mouse = knot->grabbed_rel_pos + knot->drag_origin;
-
+ n->subpath->nodepath->drag_origin_mouse = knot->grabbed_rel_pos + knot->drag_origin;
+
sp_canvas_force_full_redraw_after_interruptions(n->subpath->nodepath->desktop->canvas, 5);
sp_nodepath_remember_origins (n->subpath->nodepath);
n->dragging_out = NULL;
n->is_dragging = false;
+ sp_canvas_set_snap_delay_active(n->subpath->nodepath->desktop->canvas, false);
n->subpath->nodepath->drag_origin_mouse = Geom::Point(NR_HUGE, NR_HUGE);
sp_canvas_end_forced_full_redraws(n->subpath->nodepath->desktop->canvas);
@@ -3798,16 +3800,16 @@ node_request(SPKnot */*knot*/, Geom::Point const &p, guint state, gpointer data)
// move the node to the closest point
sp_nodepath_selected_nodes_move(n->subpath->nodepath,
n->origin[Geom::X] + c[Geom::X] - n->pos[Geom::X],
- n->origin[Geom::Y] + c[Geom::Y] - n->pos[Geom::Y],
+ n->origin[Geom::Y] + c[Geom::Y] - n->pos[Geom::Y],
true);
} else { // constraining to hor/vert
if (fabs(p[Geom::X] - n->origin[Geom::X]) > fabs(p[Geom::Y] - n->origin[Geom::Y])) { // snap to hor
sp_nodepath_selected_nodes_move(n->subpath->nodepath,
- p[Geom::X] - n->pos[Geom::X],
+ p[Geom::X] - n->pos[Geom::X],
n->origin[Geom::Y] - n->pos[Geom::Y],
- true,
+ true,
true, Inkscape::Snapper::ConstraintLine(component_vectors[Geom::X]));
} else { // snap to vert
sp_nodepath_selected_nodes_move(n->subpath->nodepath,
@@ -3935,10 +3937,10 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, n->subpath->nodepath->item);
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
+ // so remove the old snap indicator and don't wait for it to time-out
desktop->snapindicator->remove_snaptarget();
}
@@ -3968,7 +3970,7 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
}
}
-
+
s.getPoint(p);
sp_node_adjust_handle(n, -which);
@@ -4613,7 +4615,7 @@ sp_nodepath_node_new(Inkscape::NodePath::SubPath *sp, Inkscape::NodePath::Node *
n->pos = *pos;
n->p.pos = *ppos;
n->n.pos = *npos;
-
+
n->dragging_out = NULL;
Inkscape::NodePath::Node *prev;
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 1762d668c00d3ba7ccffaffe10b47b25b3eacaf8..804c736bee91c1af5b30dbf913674810eefa6d43 100644 (file)
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
pc->c1 = NULL;
pc->cl0 = NULL;
pc->cl1 = NULL;
-
+
pc->events_disabled = 0;
pc->num_clicks = 0;
pc = SP_PEN_CONTEXT(ec);
+ sp_canvas_set_snap_delay_active(pc->desktop->canvas, true);
+
if (((SPEventContextClass *) pen_parent_class)->setup) {
((SPEventContextClass *) pen_parent_class)->setup(ec);
}
}
static void
-pen_cancel (SPPenContext *const pc)
+pen_cancel (SPPenContext *const pc)
{
pc->num_clicks = 0;
pc->state = SP_PEN_CONTEXT_STOP;
{
SPPenContext *pc = SP_PEN_CONTEXT(ec);
+ sp_canvas_set_snap_delay_active(pc->desktop->canvas, false);
+
if (pc->npoints != 0) {
pen_cancel (pc);
}
@@ -332,7 +336,7 @@ spdc_endpoint_snap_handle(SPPenContext const *const pc, Geom::Point &p, guint co
}
}
-static gint
+static gint
sp_pen_context_item_handler(SPEventContext *ec, SPItem *item, GdkEvent *event)
{
SPPenContext *const pc = SP_PEN_CONTEXT(ec);
@@ -417,7 +421,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
SPDrawContext * const dc = SP_DRAW_CONTEXT(pc);
SPDesktop * const desktop = SP_EVENT_CONTEXT_DESKTOP(dc);
Geom::Point const event_w(bevent.x, bevent.y);
- Geom::Point const event_dt(desktop->w2d(event_w));
+ Geom::Point event_dt(desktop->w2d(event_w));
SPEventContext *event_context = SP_EVENT_CONTEXT(pc);
gint ret = FALSE;
@@ -453,7 +457,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
case SP_PEN_CONTEXT_CLOSE:
break;
case SP_PEN_CONTEXT_STOP:
- /* This is allowed, if we just cancelled curve */
+ /* This is allowed, if we just canceled curve */
pc->state = SP_PEN_CONTEXT_POINT;
break;
default:
@@ -463,13 +467,20 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
case SP_PEN_CONTEXT_MODE_DRAG:
switch (pc->state) {
case SP_PEN_CONTEXT_STOP:
- /* This is allowed, if we just cancelled curve */
+ /* This is allowed, if we just canceled curve */
case SP_PEN_CONTEXT_POINT:
if (pc->npoints == 0) {
+ Geom::Point p;
if (bevent.state & GDK_CONTROL_MASK) {
- spdc_create_single_dot(event_context, event_dt, "/tools/freehand/pen", bevent.state);
- ret = TRUE;
+ p = event_dt;
+ if (!(bevent.state & GDK_SHIFT_MASK)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ }
+ spdc_create_single_dot(event_context, p, "/tools/freehand/pen", bevent.state);
+ ret = TRUE;
break;
}
@@ -478,7 +489,6 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
/* Set start anchor */
pc->sa = anchor;
- Geom::Point p;
if (anchor && !sp_pen_context_has_waiting_LPE(pc)) {
/* Adjust point to anchor if needed; if we have a waiting LPE, we need
a fresh path to be created so don't continue an existing one */
// allow scrolling
return FALSE;
}
-
+
if (pc->events_disabled) {
// skip motion events if pen events are disabled
return FALSE;
ret = TRUE;
break;
case SP_PEN_CONTEXT_STOP:
- /* This is allowed, if we just cancelled curve */
+ /* This is allowed, if we just canceled curve */
pc->state = SP_PEN_CONTEXT_POINT;
ret = TRUE;
break;
static gint
pen_handle_key_press(SPPenContext *const pc, GdkEvent *event)
{
- gint ret = FALSE;
+
+ gint ret = FALSE;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gdouble const nudge = prefs->getDoubleLimited("/options/nudgedistance/value", 2, 0, 1000); // in px
* Show the status message for the current line/curve segment.
* This type of message always shows angle/distance as the last
* two parameters ("angle %3.2f°, distance %s").
- */
+ */
static void
spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, Geom::Point const p, int pc_point_to_compare, gchar const *message)
{
pc->num_clicks = 0;
pen_disable_events(pc);
-
+
SPDesktop *const desktop = pc->desktop;
pc->_message_context->clear();
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished"));
static void
pen_enable_events(SPPenContext *const pc) {
g_return_if_fail(pc->events_disabled != 0);
-
+
pc->events_disabled--;
}
diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp
index d089146b808171f016d4ba2ca59adba64fa7de8f..a8c3112acd0617ce65e091d5c2d5bdf29f5bb088 100644 (file)
--- a/src/pencil-context.cpp
+++ b/src/pencil-context.cpp
@@ -252,9 +252,17 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
break;
default:
/* Set first point of sequence */
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
+
if (bevent.state & GDK_CONTROL_MASK) {
- spdc_create_single_dot(event_context, p, "/tools/freehand/pencil", bevent.state);
- ret = true;
+ if (!(bevent.state & GDK_SHIFT_MASK)) {
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ }
+ spdc_create_single_dot(event_context, p, "/tools/freehand/pencil", bevent.state);
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
+ ret = true;
break;
}
if (anchor) {
@@ -263,23 +271,15 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
} else {
if (!(bevent.state & GDK_SHIFT_MASK)) {
-
- // This is the first click of a new curve; deselect item so that
+ // This is the first click of a new curve; deselect item so that
// this curve is not combined with it (unless it is drawn from its
// anchor, which is handled by the sibling branch above)
selection->clear();
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new path"));
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
- if (s.getSnapped()) {
- s.getPoint(p);
- pc->prev_snap_was_succesful = true;
- } else {
- pc->prev_snap_was_succesful = false;
- }
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
} else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) {
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path"));
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
}
}
pc->sa = anchor;
@@ -296,14 +296,15 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
static gint
pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mevent)
{
- if ((mevent.state & GDK_CONTROL_MASK) && (mevent.state & GDK_BUTTON1_MASK)) {
+ SPDesktop *const dt = pc->desktop;
+
+ if ((mevent.state & GDK_CONTROL_MASK) && (mevent.state & GDK_BUTTON1_MASK)) {
// mouse was accidentally moved during Ctrl+click;
// ignore the motion and create a single point
pc->is_drawing = false;
return TRUE;
}
gint ret = FALSE;
- SPDesktop *const dt = pc->desktop;
SPEventContext *event_context = SP_EVENT_CONTEXT(pc);
if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
@@ -355,7 +356,11 @@ pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mev
default:
/* We may be idle or already freehand */
if ( mevent.state & GDK_BUTTON1_MASK && pc->is_drawing ) {
- pc->state = SP_PENCIL_CONTEXT_FREEHAND;
+ if (pc->state == SP_PENCIL_CONTEXT_IDLE) {
+ sp_canvas_set_snap_delay_active(dt->canvas, false);
+ }
+ pc->state = SP_PENCIL_CONTEXT_FREEHAND;
+
if ( !pc->sa && !pc->green_anchor ) {
/* Create green anchor */
pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, pc->p[0]);
@@ -364,27 +369,13 @@ pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mev
* fixme: I am not sure whether we want to snap to anchors
* in middle of freehand (Lauris)
*/
- SnapManager &m = dt->namedview->snap_manager;
-
if (anchor) {
p = anchor->dp;
- } else if ((mevent.state & GDK_SHIFT_MASK) == 0) {
- m.setup(dt);
- Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
- if (s.getSnapped()) {
- s.getPoint(p);
- pc->prev_snap_was_succesful = true;
- } else {
- pc->prev_snap_was_succesful = false;
- }
}
+
if ( pc->npoints != 0) { // buttonpress may have happened before we entered draw context!
- if (!(pc->prev_snap_was_succesful && m.snapprefs.getSnapPostponedGlobally())) {
- // When snapping is enabled but temporarily on hold because the mouse is moving
- // fast, then we don't want to add nodes off-grid
- spdc_add_freehand_point(pc, p, mevent.state);
- ret = TRUE;
- }
+ spdc_add_freehand_point(pc, p, mevent.state);
+ ret = TRUE;
}
if (anchor && !pc->anchor_statusbar) {
@@ -436,6 +427,7 @@ pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &re
if (!(revent.state & GDK_CONTROL_MASK)) {
// Ctrl+click creates a single point so only set context in ADDLINE mode when Ctrl isn't pressed
pc->state = SP_PENCIL_CONTEXT_ADDLINE;
+ //sp_canvas_set_snap_delay_active(dt->canvas, true);
}
ret = TRUE;
break;
@@ -450,6 +442,7 @@ pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &re
spdc_set_endpoint(pc, p);
spdc_finish_endpoint(pc);
pc->state = SP_PENCIL_CONTEXT_IDLE;
+ sp_canvas_set_snap_delay_active(dt->canvas, false);
ret = TRUE;
break;
case SP_PENCIL_CONTEXT_FREEHAND:
@@ -463,6 +456,7 @@ pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &re
}
pc->state = SP_PENCIL_CONTEXT_SKETCH;
+ //sp_canvas_set_snap_delay_active(dt->canvas, true);
} else {
/* Finish segment now */
/// \todo fixme: Clean up what follows (Lauris)
@@ -482,6 +476,7 @@ pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &re
pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
}
pc->state = SP_PENCIL_CONTEXT_IDLE;
+ // sp_canvas_set_snap_delay_active(dt->canvas, false);
// reset sketch mode too
pc->sketch_n = 0;
}
@@ -504,7 +499,7 @@ pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &re
}
static void
-pencil_cancel (SPPencilContext *const pc)
+pencil_cancel (SPPencilContext *const pc)
{
if (pc->grab) {
/* Release grab now */
}
pc->is_drawing = false;
-
pc->state = SP_PENCIL_CONTEXT_IDLE;
+ sp_canvas_set_snap_delay_active(pc->desktop->canvas, false);
pc->red_curve->reset();
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
@@ -605,6 +600,7 @@ pencil_handle_key_release(SPPencilContext *const pc, guint const keyval, guint c
pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
}
pc->state = SP_PENCIL_CONTEXT_IDLE;
+ sp_canvas_set_snap_delay_active(pc->desktop->canvas, false);
pc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand sketch"));
ret = TRUE;
}
interpolate(SPPencilContext *pc)
{
- g_assert( pc->ps.size() > 1 );
+ if ( pc->ps.size() <= 1 ) {
+ return;
+ }
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
- double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() *
+ double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() *
tol) * exp(0.2*tol - 2);
g_assert(is_zero(pc->req_tangent)
Geom::Point * b = g_new(Geom::Point, 4*n_points);
Geom::Point * points = g_new(Geom::Point, 4*n_points);
- for (unsigned int i = 0; i < pc->ps.size(); i++) {
+ for (unsigned int i = 0; i < pc->ps.size(); i++) {
points[i] = pc->ps[i];
}
{
/* Fit and draw and reset state */
pc->green_curve->moveto(b[0]);
- for (int c = 0; c < n_segs; c++) {
+ for (int c = 0; c < n_segs; c++) {
pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]);
}
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
- double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() *
+ double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() *
tol) * exp(0.2*tol - 2);
bool average_all_sketches = prefs->getBool("/tools/freehand/pencil/average_all_sketches", true);
Geom::Point * b = g_new(Geom::Point, 4*n_points);
Geom::Point * points = g_new(Geom::Point, 4*n_points);
- for (unsigned i = 0; i < pc->ps.size(); i++) {
+ for (unsigned i = 0; i < pc->ps.size(); i++) {
points[i] = pc->ps[i];
}
if ( n_segs > 0)
{
Geom::Path fit(b[0]);
- for (int c = 0; c < n_segs; c++) {
+ for (int c = 0; c < n_segs; c++) {
fit.appendNew<Geom::CubicBezier>(b[4*c+1], b[4*c+2], b[4*c+3]);
}
Geom::Piecewise<Geom::D2<Geom::SBasis> > fit_pwd2 = fit.toPwSb();
|| is_unit_vector(pc->req_tangent));
Geom::Point const tHatEnd(0, 0);
int const n_segs = Geom::bezier_fit_cubic_full(b, NULL, pc->p, pc->npoints,
- pc->req_tangent, tHatEnd,
+ pc->req_tangent, tHatEnd,
tolerance_sq, 1);
if ( n_segs > 0
&& unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) )
diff --git a/src/pencil-context.h b/src/pencil-context.h
index c3b34b6473e995ee86920dad43cb2494c4f66c19..cbcf2b98e4e16afed55642605934a22c77255251 100644 (file)
--- a/src/pencil-context.h
+++ b/src/pencil-context.h
Geom::Point req_tangent;
bool is_drawing;
- bool prev_snap_was_succesful;
std::vector<Geom::Point> ps;
diff --git a/src/rect-context.cpp b/src/rect-context.cpp
index 65292851be4c59c79e1a67957a456af8248ea2a5..c63e1dc2ab5505db9f10a90b3a58ff35f2461545 100644 (file)
--- a/src/rect-context.cpp
+++ b/src/rect-context.cpp
SPEventContext *ec = SP_EVENT_CONTEXT(rc);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
- SPItem *item = selection->singleItem();
+ SPItem *item = selection->singleItem();
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}
@@ -257,17 +257,18 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE);
dragging = true;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
/* Position center */
Geom::Point button_dt(desktop->w2d(button_w));
rc->center = from_2geom(button_dt);
-
+
/* Snap center */
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
rc->center = from_2geom(button_dt);
-
+
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
( GDK_KEY_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
@@ -275,7 +276,7 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON_PRESS_MASK ),
NULL, event->button.time);
-
+
ret = TRUE;
}
break;
@@ -295,7 +296,7 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
Geom::Point const motion_w(event->motion.x, event->motion.y);
Geom::Point motion_dt(desktop->w2d(motion_w));
-
+
sp_rect_drag(*rc, motion_dt, event->motion.state); // this will also handle the snapping
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
@@ -305,6 +306,7 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
event_context->xp = event_context->yp = 0;
if (event->button.button == 1 && !event_context->space_panning) {
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the rect
@@ -379,6 +381,7 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the rect
sp_rect_finish(rc);
diff --git a/src/select-context.cpp b/src/select-context.cpp
index 1daf6b0e56967be6363dfba5b2c67f47feb2b4df..c7b305dd201aee4fd63487469a607cfefa216d8c 100644 (file)
--- a/src/select-context.cpp
+++ b/src/select-context.cpp
@@ -326,7 +326,7 @@ sp_select_context_item_handler(SPEventContext *event_context, SPItem *item, GdkE
sc->moved = FALSE;
sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5);
-
+
// remember the clicked item in sc->item:
if (sc->item) {
sp_object_unref(sc->item, NULL);
@@ -511,10 +511,10 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
item_in_group = desktop->item_at_point(Geom::Point(event->button.x, event->button.y), TRUE);
group_at_point = desktop->group_at_point(Geom::Point(event->button.x, event->button.y));
- // group-at-point is meant to be topmost item if it's a group,
+ // group-at-point is meant to be topmost item if it's a group,
// not topmost group of all items at point
- if (group_at_point != item_in_group &&
- !(group_at_point && item_at_point &&
+ if (group_at_point != item_in_group &&
+ !(group_at_point && item_at_point &&
group_at_point->isAncestorOf(item_at_point)))
group_at_point = NULL;
sp_canvas_item_ungrab(sc->grabbed, event->button.time);
sc->grabbed = NULL;
}
-
+
desktop->updateNow();
}
if (event->button.button == 1) {
}
ret = TRUE;
}
- break;
+ break;
case GDK_g:
case GDK_G:
if (MOD__SHIFT_ONLY) {
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index 0fd15593c78ae910c35670e33bc357a6e8354ea5..b1917edfd523393abfe150eea325634e1a0ca162 100644 (file)
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -366,6 +366,8 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
}
}
+ sp_canvas_set_snap_delay_active(_desktop->canvas, true);
+
// The lines below are useful for debugging any snapping issues, as they'll spit out all points that are considered for snapping
/*std::cout << "Number of snap points: " << _snap_points.size() << std::endl;
_grabbed = false;
_show_handles = true;
+ sp_canvas_set_snap_delay_active(_desktop->canvas, false);
+
Inkscape::Selection *selection = sp_desktop_selection(_desktop);
_updateVolatileState();
diff --git a/src/snap.cpp b/src/snap.cpp
index 24cfefe0ba53024633648f31a275a5e41d597560..11ba077e449976e42031fd4112a347c9b5f8b621 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
*
* Copyright (C) 2006-2007 Johan Engelen <johan@shouraizou.nl>
* Copyrigth (C) 2004 Nathan Hurst
- * Copyright (C) 1999-2008 Authors
+ * Copyright (C) 1999-2009 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -162,7 +162,12 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
- if (!someSnapperMightSnap()) {
+ if (_desktop->canvas->context_snap_delay_active == false) {
+ g_warning("context_snap_delay_active has not been set to true by the current context. Please report this!");
+ // When the context goes into dragging-mode, then Inkscape should call this: sp_canvas_set_snap_delay_active(desktop->canvas, true);
+ }
+
+ if (!someSnapperMightSnap()) {
return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
}
@@ -286,7 +291,12 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
- if (!someSnapperMightSnap()) {
+ if (_desktop->canvas->context_snap_delay_active == false) {
+ g_warning("context_snap_delay_active has not been set to true by the current context. Please report this!");
+ // When the context goes into dragging-mode, then Inkscape should call this: sp_canvas_set_snap_delay_active(desktop->canvas, true);
+ }
+
+ if (!someSnapperMightSnap()) {
return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
}
@@ -317,6 +327,11 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
{
// This method is used to snap a guide to nodes, while dragging the guide around
+ if (_desktop->canvas->context_snap_delay_active == false) {
+ g_warning("context_snap_delay_active has not been set to true by the current context. Please report this!");
+ // When the context goes into dragging-mode, then Inkscape should call this: sp_canvas_set_snap_delay_active(desktop->canvas, true);
+ }
+
if ( !(object.GuidesMightSnap() && snapprefs.getSnapEnabledGlobally()) || snapprefs.getSnapPostponedGlobally() ) {
return;
}
diff --git a/src/spiral-context.cpp b/src/spiral-context.cpp
index ce9ea1e03fabbbafb96c4c71eac50a72d188fc89..35d5144a7881d58f8b67f87321bd848fc10b6fa6 100644 (file)
--- a/src/spiral-context.cpp
+++ b/src/spiral-context.cpp
@@ -149,7 +149,7 @@ sp_spiral_context_selection_changed(Inkscape::Selection *selection, gpointer dat
SPEventContext *ec = SP_EVENT_CONTEXT(sc);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
- SPItem *item = selection->singleItem();
+ SPItem *item = selection->singleItem();
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}
if (event->button.button == 1 && !event_context->space_panning) {
dragging = TRUE;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
sc->center = Inkscape::setup_for_drag_start(desktop, event_context, event);
SnapManager &m = desktop->namedview->snap_manager;
Geom::Point const motion_w(event->motion.x, event->motion.y);
Geom::Point motion_dt(event_context->desktop->w2d(motion_w));
-
+
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, sc->item);
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt);
event_context->xp = event_context->yp = 0;
if (event->button.button == 1 && !event_context->space_panning) {
dragging = FALSE;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the spiral
sp_spiral_finish(sc);
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the rect
sp_spiral_finish(sc);
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
- Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));
-
+ Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));
+
SPSpiral *spiral = SP_SPIRAL(sc->item);
Geom::Point const delta = p1 - p0;
sp_canvas_end_forced_full_redraws(desktop->canvas);
sp_desktop_selection(desktop)->set(sc->item);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL,
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL,
_("Create spiral"));
sc->item = NULL;
diff --git a/src/star-context.cpp b/src/star-context.cpp
index 9dc2db296dcb978d09c40f14b2d9edf518051107..da79d4719a9852ce62e294b91516ac7e919f9750 100644 (file)
--- a/src/star-context.cpp
+++ b/src/star-context.cpp
@@ -156,7 +156,7 @@ sp_star_context_selection_changed (Inkscape::Selection * selection, gpointer dat
SPEventContext *ec = SP_EVENT_CONTEXT (sc);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
- SPItem *item = selection->singleItem();
+ SPItem *item = selection->singleItem();
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}
{
SPStarContext *sc = SP_STAR_CONTEXT (ec);
Glib::ustring path = val->getEntryName();
-
+
if (path == "magnitude") {
sc->magnitude = CLAMP (val->getInt(5), 3, 1024);
} else if (path == "proportion") {
@@ -235,9 +235,10 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
if (event->button.button == 1 && !event_context->space_panning) {
dragging = TRUE;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
sc->center = Inkscape::setup_for_drag_start(desktop, event_context, event);
-
+
/* Snap center */
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true);
@@ -269,7 +270,7 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
Geom::Point const motion_w(event->motion.x, event->motion.y);
Geom::Point motion_dt(desktop->w2d(motion_w));
-
+
sp_star_drag (sc, motion_dt, event->motion.state);
gobble_motion_events(GDK_BUTTON1_MASK);
@@ -281,6 +282,7 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
event_context->xp = event_context->yp = 0;
if (event->button.button == 1 && !event_context->space_panning) {
dragging = FALSE;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the star
sp_star_finish (sc);
@@ -340,6 +342,7 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
event->button.time);
dragging = false;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
if (!event_context->within_tolerance) {
// we've been dragging, finish the rect
sp_star_finish(sc);
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, sc->item);
Geom::Point pt2g = to_2geom(p);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
-
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+
Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));
-
+
SPStar *star = SP_STAR(sc->item);
double const sides = (gdouble) sc->magnitude;
sp_canvas_end_forced_full_redraws(desktop->canvas);
sp_desktop_selection(desktop)->set(sc->item);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
+ sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR,
_("Create star"));
sc->item = NULL;
diff --git a/src/text-context.cpp b/src/text-context.cpp
index ad9211cbac0e363ef79d759c38fd2416288f3317..6e4b637b85d26b5163ec5821284f6d42850d99f7 100644 (file)
--- a/src/text-context.cpp
+++ b/src/text-context.cpp
@@ -353,6 +353,7 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
sp_text_context_update_cursor(tc);
sp_text_context_update_text_selection(tc);
tc->dragging = 1;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
}
ret = TRUE;
}
@@ -369,6 +370,7 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
sp_text_context_update_cursor(tc);
sp_text_context_update_text_selection(tc);
tc->dragging = 2;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
ret = TRUE;
}
}
@@ -380,12 +382,14 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
sp_text_context_update_cursor(tc);
sp_text_context_update_text_selection(tc);
tc->dragging = 3;
+ sp_canvas_set_snap_delay_active(desktop->canvas, true);
ret = TRUE;
}
break;
case GDK_BUTTON_RELEASE:
if (event->button.button == 1 && tc->dragging && !event_context->space_panning) {
tc->dragging = 0;
+ sp_canvas_set_snap_delay_active(desktop->canvas, false);
ret = TRUE;
}
break;
@@ -1011,7 +1015,7 @@ sp_text_context_root_handler(SPEventContext *const event_context, GdkEvent *cons
sp_document_maybe_done(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT,
_("Kern to the left"));
} else {
- if (MOD__CTRL)
+ if (MOD__CTRL)
tc->text_sel_end.cursorLeftWithControl();
else
tc->text_sel_end.cursorLeft();
Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
Glib::ustring const clip_text = refClipboard->wait_for_text();
-
+
if (!clip_text.empty()) {
// Fix for 244940
// The XML standard defines the following as valid characters
itr = text.erase(itr);
}
}
-
+
if (!tc->text) { // create text if none (i.e. if nascent_object)
sp_text_context_setup_text(tc);
tc->nascent_object = 0; // we don't need it anymore, having created a real <text>
@@ -1430,7 +1434,7 @@ sp_text_context_selection_changed(Inkscape::Selection *selection, SPTextContext
SPEventContext *ec = SP_EVENT_CONTEXT(tc);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
- SPItem *item = selection->singleItem();
+ SPItem *item = selection->singleItem();
if (item && SP_IS_FLOWTEXT (item) && SP_FLOWTEXT(item)->has_internal_frame()) {
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}