static gint pencil_handle_key_release(SPPencilContext *const pc, guint const keyval, guint const /*state*/) { gint ret = FALSE; switch (keyval) { case GDK_Alt_L: case GDK_Alt_R: case GDK_Meta_L: case GDK_Meta_R: if (pc->state == SP_PENCIL_CONTEXT_SKETCH) { spdc_concat_colors_and_flush(pc, FALSE); pc->sketch_n = 0; pc->sa = NULL; pc->ea = NULL; if (pc->green_anchor) { pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); } pc->state = SP_PENCIL_CONTEXT_IDLE; pc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand sketch")); ret = TRUE; } break; default: break; } return ret; }
static void spdc_pen_finish (SPPenContext *pc, gboolean closed) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); g_print ("Finishing pen\n"); sp_curve_reset (dc->red_curve); spdc_concat_colors_and_flush (dc, closed); dc->sa = NULL; dc->ea = NULL; dc->npoints = 0; pc->state = SP_PEN_CONTEXT_POINT; sp_canvas_item_hide (pc->c0); sp_canvas_item_hide (pc->c1); sp_canvas_item_hide (pc->cl0); sp_canvas_item_hide (pc->cl1); if (dc->green_anchor) { dc->green_anchor = sp_draw_anchor_destroy (dc->green_anchor); } }
/** * Finalize addline. * * \todo * fixme: I'd like remove red reset from concat colors (lauris). * Still not sure, how it will make most sense. */ static void spdc_finish_endpoint(SPPencilContext *const pc) { if ( ( pc->red_curve->is_empty() ) || ( *(pc->red_curve->first_point()) == *(pc->red_curve->second_point()) ) ) { pc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); } else { /* Write curves to object. */ spdc_concat_colors_and_flush(pc, FALSE); pc->sa = NULL; pc->ea = NULL; } }
static void spdc_finish_endpoint (SPPencilContext *pc, NRPointF *p, gboolean snap, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); if (SP_CURVE_LENGTH (dc->red_curve) < 2) { /* Just a click, reset red curve and continue */ g_print ("Finishing empty red curve\n"); sp_curve_reset (dc->red_curve); sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL); } else if (SP_CURVE_LENGTH (dc->red_curve) > 2) { g_warning ("Red curve length is %d", SP_CURVE_LENGTH (dc->red_curve)); sp_curve_reset (dc->red_curve); sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL); } else { ArtBpath *s, *e; /* We have actual line */ if (snap) { /* Do (bogus?) snap */ spdc_endpoint_snap (dc, p, state); } /* fixme: We really should test start and end anchors instead */ s = SP_CURVE_SEGMENT (dc->red_curve, 0); e = SP_CURVE_SEGMENT (dc->red_curve, 1); if ((e->x3 == s->x3) && (e->y3 == s->y3)) { /* Empty line, reset red curve and continue */ g_print ("Finishing zero length red curve\n"); sp_curve_reset (dc->red_curve); sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL); } else { /* Write curves to object */ g_print ("Finishing real red curve\n"); spdc_concat_colors_and_flush (dc, FALSE); dc->sa = NULL; dc->ea = NULL; } } }
static gint pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &revent) { gint ret = FALSE; SPEventContext *event_context = SP_EVENT_CONTEXT(pc); if ( revent.button == 1 && pc->is_drawing && !event_context->space_panning) { SPDesktop *const dt = pc->desktop; pc->is_drawing = false; /* Find desktop coordinates */ Geom::Point p = dt->w2d(Geom::Point(revent.x, revent.y)); /* Test whether we hit any anchor. */ SPDrawAnchor *anchor = spdc_test_inside(pc, Geom::Point(revent.x, revent.y)); switch (pc->state) { case SP_PENCIL_CONTEXT_IDLE: /* Releasing button in idle mode means single click */ /* We have already set up start point/anchor in button_press */ 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; } ret = TRUE; break; case SP_PENCIL_CONTEXT_ADDLINE: /* Finish segment now */ if (anchor) { p = anchor->dp; } else { spdc_endpoint_snap(pc, p, revent.state); } pc->ea = anchor; spdc_set_endpoint(pc, p); spdc_finish_endpoint(pc); pc->state = SP_PENCIL_CONTEXT_IDLE; ret = TRUE; break; case SP_PENCIL_CONTEXT_FREEHAND: if (revent.state & GDK_MOD1_MASK) { /* sketch mode: interpolate the sketched path and improve the current output path with the new interpolation. don't finish sketch */ sketch_interpolate(pc); if (pc->green_anchor) { pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); } pc->state = SP_PENCIL_CONTEXT_SKETCH; } else { /* Finish segment now */ /// \todo fixme: Clean up what follows (Lauris) if (anchor) { p = anchor->dp; } pc->ea = anchor; /* Write curves to object */ dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand")); interpolate(pc); spdc_concat_colors_and_flush(pc, FALSE); pc->sa = NULL; pc->ea = NULL; if (pc->green_anchor) { pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); } pc->state = SP_PENCIL_CONTEXT_IDLE; // reset sketch mode too pc->sketch_n = 0; } ret = TRUE; break; case SP_PENCIL_CONTEXT_SKETCH: default: break; } if (pc->grab) { /* Release grab now */ sp_canvas_item_ungrab(pc->grab, revent.time); pc->grab = NULL; } ret = TRUE; } return ret; }
gint sp_pencil_context_root_handler (SPEventContext *ec, GdkEvent *event) { SPDrawContext *dc; SPPencilContext *pc; SPDesktop *dt; NRPointF p; gint ret; SPDrawAnchor *anchor; NRPointF fp; dc = SP_DRAW_CONTEXT (ec); pc = SP_PENCIL_CONTEXT (ec); dt = ec->desktop; ret = FALSE; switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1) { NRPointF fp; #if 0 /* Grab mouse, so release will not pass unnoticed */ dc->grab = SP_CANVAS_ITEM (dt->acetate); sp_canvas_item_grab (dc->grab, SPDC_EVENT_MASK, NULL, event->button.time); #endif /* Find desktop coordinates */ sp_desktop_w2d_xy_point (dt, &fp, event->button.x, event->button.y); p.x = fp.x; p.y = fp.y; /* Test, whether we hit any anchor */ anchor = test_inside (dc, event->button.x, event->button.y); switch (pc->state) { case SP_PENCIL_CONTEXT_ADDLINE: /* Current segment will be finished with release */ ret = TRUE; break; default: /* Set first point of sequence */ if (anchor) { p = anchor->dp; } dc->sa = anchor; spdc_set_startpoint (pc, &p, event->button.state); ret = TRUE; break; } } break; case GDK_MOTION_NOTIFY: #if 1 if ((event->motion.state & GDK_BUTTON1_MASK) && !dc->grab) { /* Grab mouse, so release will not pass unnoticed */ dc->grab = SP_CANVAS_ITEM (dt->acetate); sp_canvas_item_grab (dc->grab, SPDC_EVENT_MASK, NULL, event->button.time); } #endif /* Find desktop coordinates */ sp_desktop_w2d_xy_point (dt, &fp, event->motion.x, event->motion.y); p.x = fp.x; p.y = fp.y; /* Test, whether we hit any anchor */ anchor = test_inside (dc, event->button.x, event->button.y); switch (pc->state) { case SP_PENCIL_CONTEXT_ADDLINE: /* Set red endpoint */ if (anchor) { p = anchor->dp; } spdc_set_endpoint (pc, &p, event->motion.state); ret = TRUE; break; default: /* We may be idle or already freehand */ if (event->motion.state & GDK_BUTTON1_MASK) { pc->state = SP_PENCIL_CONTEXT_FREEHAND; if (!dc->sa && !dc->green_anchor) { /* Create green anchor */ dc->green_anchor = sp_draw_anchor_new (dc, dc->green_curve, TRUE, dc->p[0].x, dc->p[0].y); } /* fixme: I am not sure, whether we want to snap to anchors in middle of freehand (Lauris) */ if (anchor) { p = anchor->dp; } else { sp_desktop_free_snap (dt, &p); } spdc_add_freehand_point (pc, &p, event->motion.state); ret = TRUE; } break; } break; case GDK_BUTTON_RELEASE: if (event->button.button == 1) { NRPointF fp; /* Find desktop coordinates */ sp_desktop_w2d_xy_point (dt, &fp, event->motion.x, event->motion.y); p.x = fp.x; p.y = fp.y; /* Test, whether we hit any anchor */ anchor = test_inside (dc, event->button.x, event->button.y); switch (pc->state) { case SP_PENCIL_CONTEXT_IDLE: /* Releasing button in idle mode means single click */ /* We have already set up start point/anchor in button_press */ pc->state = SP_PENCIL_CONTEXT_ADDLINE; ret = TRUE; break; case SP_PENCIL_CONTEXT_ADDLINE: /* Finish segment now */ if (anchor) { p = anchor->dp; } dc->ea = anchor; spdc_finish_endpoint (pc, &p, !anchor, event->button.state); pc->state = SP_PENCIL_CONTEXT_IDLE; ret = TRUE; break; case SP_PENCIL_CONTEXT_FREEHAND: /* Finish segment now */ /* fixme: Clean up what follows (Lauris) */ if (anchor) { p = anchor->dp; } dc->ea = anchor; /* Write curves to object */ g_print ("Finishing freehand\n"); spdc_concat_colors_and_flush (dc, FALSE); dc->sa = NULL; dc->ea = NULL; if (dc->green_anchor) { dc->green_anchor = sp_draw_anchor_destroy (dc->green_anchor); } pc->state = SP_PENCIL_CONTEXT_IDLE; ret = TRUE; break; default: break; } #if 1 if (dc->grab) { /* Release grab now */ sp_canvas_item_ungrab (dc->grab, event->button.time); dc->grab = NULL; } #endif dc->grab = NULL; ret = TRUE; } break; default: break; } if (!ret) { if (((SPEventContextClass *) pencil_parent_class)->root_handler) ret = ((SPEventContextClass *) pencil_parent_class)->root_handler (ec, event); } return ret; }