X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fknot.cpp;h=28c991fdec590cb479cc3df875db2493452acfa2;hb=22899f52f2742b4e3496f87d259c1273e492b43f;hp=95cadfdb7aee1a44c030dfb31d6c96ea2f08a4e8;hpb=3631c7532dab289cde84b6c9d2e05eee0addddad;p=inkscape.git diff --git a/src/knot.cpp b/src/knot.cpp index 95cadfdb7..28c991fde 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -1,11 +1,10 @@ -#define __SP_KNOT_C__ - /** \file * SPKnot implementation * * Authors: * Lauris Kaplinski * bulia byak + * Abhishek Sharma * * Copyright (C) 1999-2005 authors * Copyright (C) 2001-2002 Ximian, Inc. @@ -24,14 +23,16 @@ #include "desktop-handles.h" #include "knot.h" #include "document.h" -#include "prefs-utils.h" +#include "preferences.h" #include "message-stack.h" #include "message-context.h" #include "event-context.h" +using Inkscape::DocumentUndo; #define KNOT_EVENT_MASK (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | \ - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | \ + GDK_POINTER_MOTION_MASK | \ + GDK_POINTER_MOTION_HINT_MASK | \ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK) static bool nograb = false; @@ -62,7 +63,6 @@ static void sp_knot_init(SPKnot *knot); static void sp_knot_dispose(GObject *object); static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot); -static void sp_knot_set_flag(SPKnot *knot, guint flag, bool set); static void sp_knot_set_ctrl_state(SPKnot *knot); static GObjectClass *parent_class; @@ -97,7 +97,7 @@ GType sp_knot_get_type() */ static void sp_knot_class_init(SPKnotClass *klass) { - GObjectClass *object_class = (GObjectClass *) klass; + GObjectClass *object_class = (GObjectClass*)klass; parent_class = (GObjectClass*) g_type_class_peek_parent(klass); @@ -117,7 +117,7 @@ static void sp_knot_class_init(SPKnotClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(SPKnotClass, clicked), NULL, NULL, - sp_marshal_NONE__UINT, + g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -126,7 +126,7 @@ static void sp_knot_class_init(SPKnotClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(SPKnotClass, doubleclicked), NULL, NULL, - sp_marshal_NONE__UINT, + g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -135,7 +135,7 @@ static void sp_knot_class_init(SPKnotClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(SPKnotClass, grabbed), NULL, NULL, - sp_marshal_NONE__UINT, + g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -144,7 +144,7 @@ static void sp_knot_class_init(SPKnotClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(SPKnotClass, ungrabbed), NULL, NULL, - sp_marshal_NONE__UINT, + g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -189,13 +189,14 @@ static void sp_knot_init(SPKnot *knot) knot->flags = 0; knot->size = 8; - knot->pos = NR::Point(0, 0); - knot->grabbed_rel_pos = NR::Point(0, 0); + knot->pos = Geom::Point(0, 0); + knot->grabbed_rel_pos = Geom::Point(0, 0); knot->anchor = GTK_ANCHOR_CENTER; knot->shape = SP_KNOT_SHAPE_SQUARE; knot->mode = SP_KNOT_MODE_XOR; knot->tip = NULL; knot->_event_handler_id = 0; + knot->pressure = 0; knot->fill[SP_KNOT_STATE_NORMAL] = 0xffffff00; knot->fill[SP_KNOT_STATE_MOUSEOVER] = 0xff0000ff; @@ -231,7 +232,7 @@ static void sp_knot_dispose(GObject *object) if (knot->_event_handler_id > 0) { - g_signal_handler_disconnect(GTK_OBJECT (knot->item), knot->_event_handler_id); + g_signal_handler_disconnect(G_OBJECT (knot->item), knot->_event_handler_id); knot->_event_handler_id = 0; } @@ -252,15 +253,15 @@ static void sp_knot_dispose(GObject *object) knot->tip = NULL; } - if (((GObjectClass *) (parent_class))->dispose) { - (* ((GObjectClass *) (parent_class))->dispose) (object); + if (parent_class->dispose) { + (*parent_class->dispose) (object); } } /** * Update knot for dragging and tell canvas an item was grabbed. */ -void sp_knot_start_dragging(SPKnot *knot, NR::Point p, gint x, gint y, guint32 etime) +void sp_knot_start_dragging(SPKnot *knot, Geom::Point const &p, gint x, gint y, guint32 etime) { // save drag origin xp = x; @@ -282,43 +283,52 @@ void sp_knot_start_dragging(SPKnot *knot, NR::Point p, gint x, gint y, guint32 e /** * Called to handle events on knots. */ -static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) +static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot) { g_assert(knot != NULL); g_assert(SP_IS_KNOT(knot)); - g_object_ref(G_OBJECT(knot)); - tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + /* Run client universal event handler, if present */ gboolean consumed = FALSE; - /* Run client universal event handler, if present */ - - g_signal_emit(G_OBJECT(knot), knot_signals[EVENT], 0, event, &consumed); + 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: + case GDK_2BUTTON_PRESS: if (event->button.button == 1) { - g_signal_emit(G_OBJECT(knot), knot_signals[DOUBLECLICKED], 0, event->button.state); + 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) { - NR::Point const p = knot->desktop->w2d(NR::Point(event->button.x, event->button.y)); + 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) { + case GDK_BUTTON_RELEASE: + if (event->button.button == 1 && !knot->desktop->event_context->space_panning) { + // If we have any pending snap event, then invoke it now + if (knot->desktop->event_context->_delayed_snap_event) { + sp_event_context_snap_watchdog_callback(knot->desktop->event_context->_delayed_snap_event); + } + + sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); + + knot->pressure = 0; if (transform_escaped) { transform_escaped = false; consumed = TRUE; @@ -331,13 +341,15 @@ static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) sp_knot_set_flag(knot, SP_KNOT_DRAGGING, FALSE); - g_signal_emit(G_OBJECT (knot), + g_signal_emit(knot, knot_signals[UNGRABBED], 0, event->button.state); + knot->_ungrabbed_signal.emit(knot); } else { - g_signal_emit(G_OBJECT (knot), + g_signal_emit(knot, knot_signals[CLICKED], 0, event->button.state); + knot->_click_signal.emit(knot, event->button.state); } grabbed = FALSE; moved = FALSE; @@ -345,8 +357,8 @@ static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) } } break; - case GDK_MOTION_NOTIFY: - if (grabbed) { + case GDK_MOTION_NOTIFY: + if (grabbed && !knot->desktop->event_context->space_panning) { consumed = TRUE; if ( within_tolerance @@ -360,23 +372,25 @@ static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) // 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(G_OBJECT (knot), + g_signal_emit(knot, knot_signals[GRABBED], 0, event->motion.state); sp_knot_set_flag(knot, SP_KNOT_DRAGGING, TRUE); } - NR::Point const motion_w(event->motion.x, event->motion.y); - NR::Point const motion_dt = knot->desktop->w2d(motion_w); - NR::Point p = motion_dt - knot->grabbed_rel_pos; - sp_knot_request_position (knot, &p, event->motion.state); - knot->desktop->scroll_to_point (&motion_dt); + sp_event_context_snap_delay_handler(knot->desktop->event_context, NULL, (gpointer) knot, (GdkEventMotion *)event, DelayedSnapEvent::KNOT_HANDLER); + sp_knot_handler_request_position(event, knot); moved = TRUE; } break; - case GDK_ENTER_NOTIFY: + case GDK_ENTER_NOTIFY: sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE); sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); @@ -388,7 +402,7 @@ static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) moved = FALSE; consumed = TRUE; break; - case GDK_LEAVE_NOTIFY: + case GDK_LEAVE_NOTIFY: sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE); sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); @@ -398,43 +412,55 @@ static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) grabbed = FALSE; moved = FALSE; - consumed = TRUE; break; - case GDK_KEY_PRESS: // keybindings for knot + 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); + 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); + DocumentUndo::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; + sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); + break; + default: + consumed = FALSE; + break; } - if (moved) { - sp_knot_set_flag(knot, - SP_KNOT_DRAGGING, - FALSE); - g_signal_emit(G_OBJECT(knot), - knot_signals[UNGRABBED], 0, - event->button.state); - sp_document_undo(SP_DT_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: + default: break; } - g_object_unref(G_OBJECT(knot)); + g_object_unref(knot); - return consumed; + return consumed || grabbed; +} + +void sp_knot_handler_request_position(GdkEvent *event, SPKnot *knot) +{ + 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); } /** @@ -452,7 +478,7 @@ SPKnot *sp_knot_new(SPDesktop *desktop, const gchar *tip) knot->tip = g_strdup (tip); } - knot->item = sp_canvas_item_new(SP_DT_CONTROLS (desktop), + knot->item = sp_canvas_item_new(sp_desktop_controls (desktop), SP_TYPE_CTRL, "anchor", GTK_ANCHOR_CENTER, "size", 8.0, @@ -494,16 +520,16 @@ void sp_knot_hide(SPKnot *knot) /** * Request or set new position for knot. */ -void sp_knot_request_position(SPKnot *knot, NR::Point *p, guint state) +void sp_knot_request_position(SPKnot *knot, Geom::Point const &p, guint state) { g_return_if_fail(knot != NULL); g_return_if_fail(SP_IS_KNOT(knot)); gboolean done = FALSE; - g_signal_emit(G_OBJECT (knot), + g_signal_emit(knot, knot_signals[REQUEST], 0, - p, + &p, state, &done); @@ -517,16 +543,16 @@ void sp_knot_request_position(SPKnot *knot, NR::Point *p, guint state) /** * Return distance of point to knot's position; unused. */ -gdouble sp_knot_distance(SPKnot * knot, NR::Point *p, guint state) +gdouble sp_knot_distance(SPKnot * knot, Geom::Point const &p, guint state) { g_return_val_if_fail(knot != NULL, 1e18); g_return_val_if_fail(SP_IS_KNOT(knot), 1e18); - gdouble distance = NR::L2(*p - knot->pos); + gdouble distance = Geom::L2(p - knot->pos); - g_signal_emit(G_OBJECT(knot), + g_signal_emit(knot, knot_signals[DISTANCE], 0, - p, + &p, state, &distance); @@ -536,42 +562,43 @@ gdouble sp_knot_distance(SPKnot * knot, NR::Point *p, guint state) /** * Move knot to new position. */ -void sp_knot_set_position(SPKnot *knot, NR::Point *p, guint state) +void sp_knot_set_position(SPKnot *knot, Geom::Point const &p, guint state) { g_return_if_fail(knot != NULL); g_return_if_fail(SP_IS_KNOT (knot)); - knot->pos = *p; + knot->pos = p; if (knot->item) { - SP_CTRL(knot->item)->moveto (*p); + SP_CTRL(knot->item)->moveto (p); } - g_signal_emit(G_OBJECT (knot), + g_signal_emit(knot, knot_signals[MOVED], 0, - p, + &p, state); + knot->_moved_signal.emit(knot, p, state); } /** - * Move knot to new position, without emitting a MOVED signal. + * Move knot to new position, without emitting a MOVED signal. */ -void sp_knot_moveto(SPKnot *knot, NR::Point *p) +void sp_knot_moveto(SPKnot *knot, Geom::Point const &p) { g_return_if_fail(knot != NULL); g_return_if_fail(SP_IS_KNOT(knot)); - knot->pos = *p; + knot->pos = p; if (knot->item) { - SP_CTRL(knot->item)->moveto (*p); + SP_CTRL(knot->item)->moveto (p); } } /** * Returns position of knot. */ -NR::Point sp_knot_position(SPKnot const *knot) +Geom::Point sp_knot_position(SPKnot const *knot) { g_assert(knot != NULL); g_assert(SP_IS_KNOT (knot)); @@ -582,7 +609,7 @@ NR::Point sp_knot_position(SPKnot const *knot) /** * Set flag in knot, with side effects. */ -static void sp_knot_set_flag(SPKnot *knot, guint flag, bool set) +void sp_knot_set_flag(SPKnot *knot, guint flag, bool set) { g_assert(knot != NULL); g_assert(SP_IS_KNOT(knot)); @@ -594,20 +621,20 @@ static void sp_knot_set_flag(SPKnot *knot, guint flag, bool set) } switch (flag) { - case SP_KNOT_VISIBLE: + case SP_KNOT_VISIBLE: if (set) { sp_canvas_item_show(knot->item); } else { sp_canvas_item_hide(knot->item); } break; - case SP_KNOT_MOUSEOVER: - case SP_KNOT_DRAGGING: + case SP_KNOT_MOUSEOVER: + case SP_KNOT_DRAGGING: sp_knot_set_ctrl_state(knot); break; - case SP_KNOT_GRABBED: + case SP_KNOT_GRABBED: break; - default: + default: g_assert_not_reached(); break; }