static gint pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &bevent) { gint ret = FALSE; SPEventContext *event_context = SP_EVENT_CONTEXT(pc); if ( bevent.button == 1 && !event_context->space_panning) { SPDrawContext *dc = SP_DRAW_CONTEXT (pc); SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(dc); Inkscape::Selection *selection = sp_desktop_selection(desktop); if (Inkscape::have_viable_layer(desktop, dc->_message_context) == false) { return TRUE; } Geom::Point const button_w(bevent.x, bevent.y); /* Find desktop coordinates */ Geom::Point p = pc->desktop->w2d(button_w); /* Test whether we hit any anchor. */ SPDrawAnchor *anchor = spdc_test_inside(pc, button_w); pencil_drag_origin_w = Geom::Point(bevent.x,bevent.y); pencil_within_tolerance = true; 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 (bevent.state & GDK_CONTROL_MASK) { spdc_create_single_dot(event_context, p, "/tools/freehand/pencil", bevent.state); ret = true; break; } if (anchor) { p = anchor->dp; desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); } else { if (!(bevent.state & GDK_SHIFT_MASK)) { // This is the first click of a new curve; deselect item so that // this curve is not combined with it (unless it is drawn from its // anchor, which is handled by the sibling branch above) selection->clear(); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new path")); SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p); if (s.getSnapped()) { s.getPoint(p); pc->prev_snap_was_succesful = true; } else { pc->prev_snap_was_succesful = false; } } else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path")); } } pc->sa = anchor; spdc_set_startpoint(pc, p); ret = TRUE; break; } pc->is_drawing = 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; }