X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fpen-context.cpp;h=3267912752bb8378c1b0895e6f8d40173d8103a9;hb=f0e5ef1c60ad148623253dc3cc5d53014724094a;hp=c1d7af150f53aed7d56b9e3a19a48134a148aae7;hpb=124aed58b23bd24292c6e2175522db06a196e39e;p=inkscape.git diff --git a/src/pen-context.cpp b/src/pen-context.cpp index c1d7af150..326791275 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -30,7 +30,6 @@ #include "sp-path.h" #include "pixmaps/cursor-pen.xpm" -#include "pixmaps/cursor-pen.pixbuf" #include "display/canvas-bpath.h" #include "display/sp-ctrlline.h" #include "display/sodipodi-ctrl.h" @@ -49,6 +48,7 @@ static void sp_pen_context_setup(SPEventContext *ec); static void sp_pen_context_finish(SPEventContext *ec); static void sp_pen_context_set(SPEventContext *ec, gchar const *key, gchar const *val); static gint sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event); +static gint sp_pen_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); static void spdc_pen_set_initial_point(SPPenContext *pc, NR::Point const p); static void spdc_pen_set_subsequent_point(SPPenContext *pc, NR::Point const p, bool statusbar); @@ -60,10 +60,12 @@ static void spdc_pen_finish(SPPenContext *pc, gboolean closed); static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const &bevent); static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion const &mevent); static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton const &revent); -static gint pen_handle_2button_press(SPPenContext *const pc); +static gint pen_handle_2button_press(SPPenContext *const pc, GdkEventButton const &bevent); static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event); static void spdc_reset_colors(SPPenContext *pc); +static void pen_disable_events(SPPenContext *const pc); +static void pen_enable_events(SPPenContext *const pc); static NR::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; @@ -113,6 +115,7 @@ sp_pen_context_class_init(SPPenContextClass *klass) event_context_class->finish = sp_pen_context_finish; event_context_class->set = sp_pen_context_set; event_context_class->root_handler = sp_pen_context_root_handler; + event_context_class->item_handler = sp_pen_context_item_handler; } /** @@ -125,11 +128,6 @@ sp_pen_context_init(SPPenContext *pc) SPEventContext *event_context = SP_EVENT_CONTEXT(pc); event_context->cursor_shape = cursor_pen_xpm; - event_context->cursor_pixbuf = gdk_pixbuf_new_from_inline( - -1, - cursor_pen_pixbuf, - FALSE, - NULL); event_context->hot_x = 4; event_context->hot_y = 4; @@ -141,6 +139,8 @@ sp_pen_context_init(SPPenContext *pc) pc->c1 = NULL; pc->cl0 = NULL; pc->cl1 = NULL; + + pc->events_disabled = 0; } /** @@ -222,6 +222,8 @@ pen_cancel (SPPenContext *const pc) sp_canvas_item_hide(pc->cl1); pc->_message_context->clear(); pc->_message_context->flash(Inkscape::NORMAL_MESSAGE, _("Drawing cancelled")); + + sp_canvas_end_forced_full_redraws(pc->desktop->canvas); } /** @@ -284,6 +286,29 @@ spdc_endpoint_snap_handle(SPPenContext const *const pc, NR::Point &p, guint cons spdc_endpoint_snap_free(pc, p, state); } +static gint +sp_pen_context_item_handler(SPEventContext *ec, SPItem *item, GdkEvent *event) +{ + SPPenContext *const pc = SP_PEN_CONTEXT(ec); + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + ret = pen_handle_button_press(pc, event->button); + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) pen_parent_class)->item_handler) + ret = ((SPEventContextClass *) pen_parent_class)->item_handler(ec, item, event); + } + + return ret; +} + /** * Callback to handle all pen events. */ @@ -308,7 +333,7 @@ sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event) break; case GDK_2BUTTON_PRESS: - ret = pen_handle_2button_press(pc); + ret = pen_handle_2button_press(pc, event->button); break; case GDK_KEY_PRESS: @@ -335,24 +360,30 @@ sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event) */ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const &bevent) { - gint ret = FALSE; - if (bevent.button == 1) { + if (pc->events_disabled) { + // skip event processing if events are disabled + return FALSE; + } + + SPDrawContext * const dc = SP_DRAW_CONTEXT(pc); + SPDesktop * const desktop = SP_EVENT_CONTEXT_DESKTOP(dc); + NR::Point const event_w(bevent.x, bevent.y); + NR::Point const event_dt(desktop->w2d(event_w)); + SPEventContext *event_context = SP_EVENT_CONTEXT(pc); - SPDrawContext * const dc = SP_DRAW_CONTEXT(pc); - SPDesktop * const desktop = SP_EVENT_CONTEXT_DESKTOP(dc); + gint ret = FALSE; + if (bevent.button == 1 && !event_context->space_panning) { if (Inkscape::have_viable_layer(desktop, dc->_message_context) == false) { return TRUE; } - NR::Point const event_w(bevent.x, bevent.y); pen_drag_origin_w = event_w; pen_within_tolerance = true; /* Test whether we hit any anchor. */ SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); - NR::Point const event_dt(desktop->w2d(event_w)); switch (pc->mode) { case SP_PEN_CONTEXT_MODE_CLICK: /* In click mode we add point on release */ @@ -453,7 +484,16 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const } } else if (bevent.button == 3) { if (pc->npoints != 0) { - spdc_pen_finish(pc, FALSE); + + spdc_pen_finish_segment(pc, event_dt, bevent.state); + if (pc->green_closed) { + // finishing at the start anchor, close curve + spdc_pen_finish(pc, TRUE); + } else { + // finishing at some other anchor, finish curve but not close + spdc_pen_finish(pc, FALSE); + } + ret = TRUE; } } @@ -469,8 +509,15 @@ pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion const &mevent) { gint ret = FALSE; - if (mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) { - // allow middle-button scrolling + SPEventContext *event_context = SP_EVENT_CONTEXT(pc); + + if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) { + // allow scrolling + return FALSE; + } + + if (pc->events_disabled) { + // skip motion events if pen events are disabled return FALSE; } @@ -568,6 +615,7 @@ pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion const &mevent) spdc_endpoint_snap_handle(pc, p, mevent.state); spdc_pen_set_ctrl(pc, p, mevent.state); + gobble_motion_events(GDK_BUTTON1_MASK); ret = TRUE; break; case SP_PEN_CONTEXT_STOP: @@ -589,8 +637,14 @@ pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion const &mevent) static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton const &revent) { + if (pc->events_disabled) { + // skip event processing if events are disabled + return FALSE; + } + gint ret = FALSE; - if ( revent.button == 1 ) { + SPEventContext *event_context = SP_EVENT_CONTEXT(pc); + if ( revent.button == 1 && !event_context->space_panning) { SPDrawContext *dc = SP_DRAW_CONTEXT (pc); @@ -695,10 +749,10 @@ pen_handle_button_release(SPPenContext *const pc, GdkEventButton const &revent) } static gint -pen_handle_2button_press(SPPenContext *const pc) +pen_handle_2button_press(SPPenContext *const pc, GdkEventButton const &bevent) { gint ret = FALSE; - if (pc->npoints != 0) { + if (pc->npoints != 0 && bevent.button != 2) { spdc_pen_finish(pc, FALSE); ret = TRUE; } @@ -1007,6 +1061,8 @@ spdc_pen_set_initial_point(SPPenContext *const pc, NR::Point const p) pc->p[1] = p; pc->npoints = 2; sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); + + sp_canvas_force_full_redraw_after_interruptions(pc->desktop->canvas, 5); } static void @@ -1031,6 +1087,7 @@ spdc_pen_set_subsequent_point(SPPenContext *const pc, NR::Point const p, bool st sp_curve_lineto(pc->red_curve, p); is_curve = false; } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); if (statusbar) { @@ -1041,7 +1098,7 @@ spdc_pen_set_subsequent_point(SPPenContext *const pc, NR::Point const p, bool st double angle = atan2(rel[NR::Y], rel[NR::X]) * 180 / M_PI; if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) angle = angle_to_compass (angle); - pc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"), is_curve? "Curve segment" : "Line segment", angle, dist->str); + pc->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("%s: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"), is_curve? "Curve segment" : "Line segment", angle, dist->str); g_string_free(dist, FALSE); } } @@ -1066,7 +1123,7 @@ spdc_pen_set_ctrl(SPPenContext *const pc, NR::Point const p, guint const state) double angle = atan2(rel[NR::Y], rel[NR::X]) * 180 / M_PI; if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) angle = angle_to_compass (angle); - pc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Curve handle: angle %3.2f°, length %s; with Ctrl to snap angle"), angle, dist->str); + pc->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Curve handle: angle %3.2f°, length %s; with Ctrl to snap angle"), angle, dist->str); g_string_free(dist, FALSE); } else if ( pc->npoints == 5 ) { @@ -1096,7 +1153,7 @@ spdc_pen_set_ctrl(SPPenContext *const pc, NR::Point const p, guint const state) double angle = atan2(rel[NR::Y], rel[NR::X]) * 180 / M_PI; if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) angle = angle_to_compass (angle); - pc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s: angle %3.2f°, length %s; with Ctrl to snap angle, with Shift to move this handle only"), is_symm? "Curve handle, symmetric" : "Curve handle", angle, dist->str); + pc->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("%s: angle %3.2f°, length %s; with Ctrl to snap angle, with Shift to move this handle only"), is_symm? "Curve handle, symmetric" : "Curve handle", angle, dist->str); g_string_free(dist, FALSE); } else { @@ -1105,7 +1162,7 @@ spdc_pen_set_ctrl(SPPenContext *const pc, NR::Point const p, guint const state) } static void -spdc_pen_finish_segment(SPPenContext *const pc, NR::Point const p, guint const state) +spdc_pen_finish_segment(SPPenContext *const pc, NR::Point const /*p*/, guint const /*state*/) { if (!sp_curve_empty(pc->red_curve)) { sp_curve_append_continuous(pc->green_curve, pc->red_curve, 0.0625); @@ -1128,6 +1185,8 @@ spdc_pen_finish_segment(SPPenContext *const pc, NR::Point const p, guint const s static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) { + pen_disable_events(pc); + SPDesktop *const desktop = pc->desktop; pc->_message_context->clear(); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); @@ -1148,8 +1207,24 @@ spdc_pen_finish(SPPenContext *const pc, gboolean const closed) if (pc->green_anchor) { pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); } + + + sp_canvas_end_forced_full_redraws(pc->desktop->canvas); + + pen_enable_events(pc); +} + +static void +pen_disable_events(SPPenContext *const pc) { + pc->events_disabled++; } +static void +pen_enable_events(SPPenContext *const pc) { + g_return_if_fail(pc->events_disabled != 0); + + pc->events_disabled--; +} /* Local Variables: