static bool sp_select_context_abort(SPEventContext *event_context) { SPDesktop *desktop = event_context->desktop; SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); Inkscape::SelTrans *seltrans = sc->_seltrans; if (sc->dragging) { if (sc->moved) { // cancel dragging an object seltrans->ungrab(); sc->moved = FALSE; sc->dragging = FALSE; sp_event_context_discard_delayed_snap_event(event_context); drag_escaped = 1; if (sc->item) { // only undo if the item is still valid if (SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))) { sp_document_undo(sp_desktop_document(desktop)); } sp_object_unref( SP_OBJECT(sc->item), NULL); } else if (sc->button_press_ctrl) { // NOTE: This is a workaround to a bug. // When the ctrl key is held, sc->item is not defined // so in this case (only), we skip the object doc check sp_document_undo(sp_desktop_document(desktop)); } sc->item = NULL; SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Move canceled.")); return true; } } else { if (Inkscape::Rubberband::get(desktop)->is_started()) { Inkscape::Rubberband::get(desktop)->stop(); rb_escaped = 1; SP_EVENT_CONTEXT(sc)->defaultMessageContext()->clear(); SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selection canceled.")); return true; } } return false; }
/** * Called to handle events on knots. */ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot) { g_assert(knot != NULL); g_assert(SP_IS_KNOT(knot)); /* Run client universal event handler, if present */ gboolean consumed = FALSE; g_signal_emit(knot, knot_signals[EVENT], 0, event, &consumed); if (consumed) { return TRUE; } g_object_ref(knot); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); switch (event->type) { case GDK_2BUTTON_PRESS: if (event->button.button == 1) { g_signal_emit(knot, knot_signals[DOUBLECLICKED], 0, event->button.state); grabbed = FALSE; moved = FALSE; consumed = TRUE; } break; case GDK_BUTTON_PRESS: if (event->button.button == 1 && !knot->desktop->event_context->space_panning) { Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y)); sp_knot_start_dragging(knot, p, (gint) event->button.x, (gint) event->button.y, event->button.time); consumed = TRUE; } break; case GDK_BUTTON_RELEASE: if (event->button.button == 1 && !knot->desktop->event_context->space_panning) { knot->pressure = 0; if (transform_escaped) { transform_escaped = false; consumed = TRUE; } else { sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); if (!nograb) { sp_canvas_item_ungrab(knot->item, event->button.time); } if (moved) { sp_knot_set_flag(knot, SP_KNOT_DRAGGING, FALSE); g_signal_emit(knot, knot_signals[UNGRABBED], 0, event->button.state); knot->_ungrabbed_signal.emit(knot); } else { g_signal_emit(knot, knot_signals[CLICKED], 0, event->button.state); knot->_click_signal.emit(knot, event->button.state); } grabbed = FALSE; moved = FALSE; consumed = TRUE; } } break; case GDK_MOTION_NOTIFY: if (grabbed && !knot->desktop->event_context->space_panning) { consumed = TRUE; if ( within_tolerance && ( abs( (gint) event->motion.x - xp ) < tolerance ) && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { break; // do not drag if we're within tolerance from origin } // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) within_tolerance = false; if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &knot->pressure)) knot->pressure = CLAMP (knot->pressure, 0, 1); else knot->pressure = 0.5; if (!moved) { g_signal_emit(knot, knot_signals[GRABBED], 0, event->motion.state); sp_knot_set_flag(knot, SP_KNOT_DRAGGING, TRUE); } Geom::Point const motion_w(event->motion.x, event->motion.y); Geom::Point const motion_dt = knot->desktop->w2d(motion_w); Geom::Point p = motion_dt - knot->grabbed_rel_pos; sp_knot_request_position (knot, p, event->motion.state); knot->desktop->scroll_to_point (motion_dt); knot->desktop->set_coordinate_status(knot->pos); // display the coordinate of knot, not cursor - they may be different! if (event->motion.state & GDK_BUTTON1_MASK) gobble_motion_events(GDK_BUTTON1_MASK); moved = TRUE; } break; case GDK_ENTER_NOTIFY: sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE); sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); if (knot->tip) { knot->desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, knot->tip); } grabbed = FALSE; moved = FALSE; consumed = TRUE; break; case GDK_LEAVE_NOTIFY: sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE); sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); if (knot->tip) { knot->desktop->event_context->defaultMessageContext()->clear(); } grabbed = FALSE; moved = FALSE; consumed = TRUE; break; case GDK_KEY_PRESS: // keybindings for knot switch (get_group0_keyval(&event->key)) { case GDK_Escape: sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); if (!nograb) { sp_canvas_item_ungrab(knot->item, event->button.time); } if (moved) { sp_knot_set_flag(knot, SP_KNOT_DRAGGING, FALSE); g_signal_emit(knot, knot_signals[UNGRABBED], 0, event->button.state); sp_document_undo(sp_desktop_document(knot->desktop)); knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); transform_escaped = true; consumed = TRUE; } grabbed = FALSE; moved = FALSE; break; default: consumed = FALSE; break; } break; default: break; } g_object_unref(knot); return consumed; }