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: