static void spdc_pen_finish_segment (SPPenContext *pc, NRPointF *p, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); if (!sp_curve_empty (dc->red_curve)) { SPCurve *curve; SPCanvasItem *cshape; sp_curve_append_continuous (dc->green_curve, dc->red_curve, 0.0625); curve = sp_curve_copy (dc->red_curve); /* fixme: */ cshape = sp_canvas_bpath_new (SP_DT_SKETCH (SP_EVENT_CONTEXT (dc)->desktop), curve); sp_curve_unref (curve); sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (cshape), dc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); dc->green_bpaths = g_slist_prepend (dc->green_bpaths, cshape); dc->p[0] = dc->p[3]; dc->p[1] = dc->p[4]; dc->npoints = 2; sp_curve_reset (dc->red_curve); } }
static void sp_draw_context_set (SPEventContext *ec, const gchar *key, const gchar *value) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (ec); }
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); } }
static void spdc_pen_set_point (SPPenContext *pc, NRPointF *p, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); if (dc->npoints == 0) { /* Just set initial point */ dc->p[0] = *p; dc->p[1] = *p; dc->npoints = 2; sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL); } else { dc->p[2] = *p; dc->p[3] = *p; dc->p[4] = *p; dc->npoints = 5; sp_curve_reset (dc->red_curve); sp_curve_moveto (dc->red_curve, dc->p[0].x, dc->p[0].y); if ((pc->onlycurves) || (dc->p[1].x != dc->p[0].x) || (dc->p[1].y != dc->p[0].y)) { sp_curve_curveto (dc->red_curve, dc->p[1].x, dc->p[1].y, dc->p[2].x, dc->p[2].y, dc->p[3].x, dc->p[3].y); } else { sp_curve_lineto (dc->red_curve, dc->p[3].x, dc->p[3].y); } sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve); } }
static void spdc_set_startpoint (SPPencilContext *pc, NRPointF *p, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); sp_desktop_free_snap (SP_EVENT_CONTEXT_DESKTOP (dc), p); dc->npoints = 0; dc->p[dc->npoints++] = *p; }
static void spdc_add_freehand_point (SPPencilContext *pc, NRPointF *p, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); /* fixme: Cleanup following (Lauris) */ g_assert (dc->npoints > 0); if ((p->x != dc->p[dc->npoints - 1].x) || (p->y != dc->p[dc->npoints - 1].y)) { dc->p[dc->npoints++] = *p; fit_and_split (dc); } }
static void sp_draw_context_finish (SPEventContext *ec) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (ec); if (dc->grab) { sp_canvas_item_ungrab (dc->grab, GDK_CURRENT_TIME); } if (dc->selection) { sp_signal_disconnect_by_data (dc->selection, dc); dc->selection = NULL; } spdc_free_colors (dc); }
static void spdc_set_endpoint (SPPencilContext *pc, NRPointF *p, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); g_assert (dc->npoints > 0); spdc_endpoint_snap (dc, p, state); dc->p[1] = *p; dc->npoints = 2; sp_curve_reset (dc->red_curve); sp_curve_moveto (dc->red_curve, dc->p[0].x, dc->p[0].y); sp_curve_lineto (dc->red_curve, dc->p[1].x, dc->p[1].y); sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve); }
static void sp_draw_context_dispose (GObject *object) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (object); if (dc->grab) { sp_canvas_item_ungrab (dc->grab, GDK_CURRENT_TIME); dc->grab = NULL; } if (dc->selection) { sp_signal_disconnect_by_data (dc->selection, dc); dc->selection = NULL; } spdc_free_colors (dc); G_OBJECT_CLASS (draw_parent_class)->dispose (object); }
static void spdc_pen_set_ctrl (SPPenContext *pc, NRPointF *p, guint state) { SPDrawContext *dc; dc = SP_DRAW_CONTEXT (pc); sp_canvas_item_show (pc->c1); sp_canvas_item_show (pc->cl1); if (dc->npoints == 2) { dc->p[1] = *p; sp_canvas_item_hide (pc->c0); sp_canvas_item_hide (pc->cl0); sp_ctrl_moveto (SP_CTRL (pc->c1), dc->p[1].x, dc->p[1].y); sp_ctrlline_set_coords (SP_CTRLLINE (pc->cl1), dc->p[0].x, dc->p[0].y, dc->p[1].x, dc->p[1].y); } else if (dc->npoints == 5) { dc->p[4] = *p; sp_canvas_item_show (pc->c0); sp_canvas_item_show (pc->cl0); if (((pc->mode == SP_PEN_CONTEXT_MODE_CLICK) && (state & GDK_CONTROL_MASK)) || ((pc->mode == SP_PEN_CONTEXT_MODE_DRAG) && !(state & GDK_MOD1_MASK))) { gdouble dx, dy; dx = p->x - dc->p[3].x; dy = p->y - dc->p[3].y; dc->p[2].x = dc->p[3].x - dx; dc->p[2].y = dc->p[3].y - dy; sp_curve_reset (dc->red_curve); sp_curve_moveto (dc->red_curve, dc->p[0].x, dc->p[0].y); sp_curve_curveto (dc->red_curve, dc->p[1].x, dc->p[1].y, dc->p[2].x, dc->p[2].y, dc->p[3].x, dc->p[3].y); sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve); } sp_ctrl_moveto (SP_CTRL (pc->c0), dc->p[2].x, dc->p[2].y); sp_ctrlline_set_coords (SP_CTRLLINE (pc->cl0), dc->p[3].x, dc->p[3].y, dc->p[2].x, dc->p[2].y); sp_ctrl_moveto (SP_CTRL (pc->c1), dc->p[4].x, dc->p[4].y); sp_ctrlline_set_coords (SP_CTRLLINE (pc->cl1), dc->p[3].x, dc->p[3].y, dc->p[4].x, dc->p[4].y); } else { g_warning ("Something bad happened - npoints is %d", dc->npoints); } }
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; } } }
gint sp_draw_context_root_handler (SPEventContext *ec, GdkEvent *event) { SPDrawContext *dc; gint ret; dc = SP_DRAW_CONTEXT (ec); ret = FALSE; switch (event->type) { case GDK_KEY_PRESS: /* fixme: */ switch (event->key.keyval) { case GDK_A: case GDK_a: if (dc->attach) { spdc_set_attach (dc, FALSE); } else { spdc_set_attach (dc, TRUE); } ret = TRUE; break; default: break; } break; default: break; } if (!ret) { if (((SPEventContextClass *) draw_parent_class)->root_handler) ret = ((SPEventContextClass *) draw_parent_class)->root_handler (ec, event); } return ret; }
static void sp_draw_context_setup (SPEventContext *ec) { SPDrawContext *dc; SPDesktop *dt; dc = SP_DRAW_CONTEXT (ec); dt = ec->desktop; if (((SPEventContextClass *) draw_parent_class)->setup) ((SPEventContextClass *) draw_parent_class)->setup (ec); dc->selection = SP_DT_SELECTION (dt); /* Connect signals to track selection changes */ g_signal_connect (G_OBJECT (dc->selection), "changed", G_CALLBACK (spdc_selection_changed), dc); g_signal_connect (G_OBJECT (dc->selection), "modified", G_CALLBACK (spdc_selection_modified), dc); /* Create red bpath */ dc->red_bpath = sp_canvas_bpath_new (SP_DT_SKETCH (ec->desktop), NULL); sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (dc->red_bpath), dc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); /* Create red curve */ dc->red_curve = sp_curve_new_sized (4); /* Create blue bpath */ dc->blue_bpath = sp_canvas_bpath_new (SP_DT_SKETCH (ec->desktop), NULL); sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (dc->blue_bpath), dc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); /* Create blue curve */ dc->blue_curve = sp_curve_new_sized (8); /* Create green curve */ dc->green_curve = sp_curve_new_sized (64); /* No green anchor by default */ dc->green_anchor = NULL; spdc_set_attach (dc, FALSE); }
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; }
gint sp_pen_context_root_handler (SPEventContext *ec, GdkEvent *event) { SPDrawContext *dc; SPPenContext *pc; SPDesktop *dt; NRPointF p; gint ret; SPDrawAnchor *anchor; NRPointF fp; dc = SP_DRAW_CONTEXT (ec); pc = SP_PEN_CONTEXT (ec); dt = ec->desktop; ret = FALSE; switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1) { #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->mode) { case SP_PEN_CONTEXT_MODE_CLICK: /* In click mode we add point on release */ switch (pc->state) { case SP_PEN_CONTEXT_POINT: case SP_PEN_CONTEXT_CONTROL: case SP_PEN_CONTEXT_CLOSE: break; case SP_PEN_CONTEXT_STOP: /* This is allowed, if we just cancelled curve */ pc->state = SP_PEN_CONTEXT_POINT; break; default: break; } break; case SP_PEN_CONTEXT_MODE_DRAG: switch (pc->state) { case SP_PEN_CONTEXT_STOP: /* This is allowed, if we just cancelled curve */ case SP_PEN_CONTEXT_POINT: if (dc->npoints == 0) { /* Set start anchor */ dc->sa = anchor; if (anchor) { /* Adjust point to anchor if needed */ p = anchor->dp; } else { /* Create green anchor */ dc->green_anchor = sp_draw_anchor_new (dc, dc->green_curve, TRUE, p.x, p.y); } spdc_pen_set_point (pc, &p, event->motion.state); } else { /* Set end anchor */ dc->ea = anchor; spdc_pen_set_point (pc, &p, event->motion.state); if (dc->green_anchor && dc->green_anchor->active) { pc->state = SP_PEN_CONTEXT_CLOSE; ret = TRUE; break; } } pc->state = SP_PEN_CONTEXT_CONTROL; ret = TRUE; break; case SP_PEN_CONTEXT_CONTROL: g_warning ("Button down in CONTROL state"); break; case SP_PEN_CONTEXT_CLOSE: g_warning ("Button down in CLOSE state"); break; default: break; } break; default: 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); if (!anchor) { /* Snap only if not hitting anchor */ spdc_endpoint_snap (dc, &p, event->motion.state); } switch (pc->mode) { case SP_PEN_CONTEXT_MODE_CLICK: switch (pc->state) { case SP_PEN_CONTEXT_POINT: if (dc->npoints != 0) { /* Only set point, if we are already appending */ /* fixme: Snapping */ spdc_pen_set_point (pc, &p, event->motion.state); ret = TRUE; } break; case SP_PEN_CONTEXT_CONTROL: case SP_PEN_CONTEXT_CLOSE: /* Placing controls is last operation in CLOSE state */ /* fixme: Snapping */ spdc_pen_set_ctrl (pc, &p, event->motion.state); ret = TRUE; break; case SP_PEN_CONTEXT_STOP: /* This is perfectly valid */ break; default: break; } break; case SP_PEN_CONTEXT_MODE_DRAG: switch (pc->state) { case SP_PEN_CONTEXT_POINT: if (dc->npoints > 0) { /* Only set point, if we are already appending */ /* fixme: Snapping */ spdc_pen_set_point (pc, &p, event->motion.state); ret = TRUE; } break; case SP_PEN_CONTEXT_CONTROL: case SP_PEN_CONTEXT_CLOSE: /* Placing controls is last operation in CLOSE state */ /* fixme: Snapping */ spdc_pen_set_ctrl (pc, &p, event->motion.state); ret = TRUE; break; case SP_PEN_CONTEXT_STOP: /* This is perfectly valid */ break; default: break; } break; default: break; } break; case GDK_BUTTON_RELEASE: if (event->button.button == 1) { /* 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->mode) { case SP_PEN_CONTEXT_MODE_CLICK: switch (pc->state) { case SP_PEN_CONTEXT_POINT: if (dc->npoints == 0) { /* Start new thread only with button release */ if (anchor) { p = anchor->dp; } dc->sa = anchor; spdc_pen_set_point (pc, &p, event->motion.state); } else { /* Set end anchor here */ dc->ea = anchor; } pc->state = SP_PEN_CONTEXT_CONTROL; ret = TRUE; break; case SP_PEN_CONTEXT_CONTROL: /* End current segment */ spdc_pen_finish_segment (pc, &p, event->button.state); pc->state = SP_PEN_CONTEXT_POINT; ret = TRUE; break; case SP_PEN_CONTEXT_CLOSE: /* End current segment */ spdc_pen_finish_segment (pc, &p, event->button.state); spdc_pen_finish (pc, TRUE); pc->state = SP_PEN_CONTEXT_POINT; ret = TRUE; break; case SP_PEN_CONTEXT_STOP: /* This is allowed, if we just cancelled curve */ pc->state = SP_PEN_CONTEXT_POINT; ret = TRUE; break; default: break; } break; case SP_PEN_CONTEXT_MODE_DRAG: switch (pc->state) { case SP_PEN_CONTEXT_POINT: case SP_PEN_CONTEXT_CONTROL: spdc_pen_finish_segment (pc, &p, event->button.state); break; case SP_PEN_CONTEXT_CLOSE: spdc_pen_finish_segment (pc, &p, event->button.state); spdc_pen_finish (pc, TRUE); break; case SP_PEN_CONTEXT_STOP: /* This is allowed, if we just cancelled curve */ break; default: break; } pc->state = SP_PEN_CONTEXT_POINT; 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 ret = TRUE; } break; case GDK_2BUTTON_PRESS: spdc_pen_finish (pc, FALSE); ret = TRUE; break; case GDK_KEY_PRESS: /* fixme: */ switch (event->key.keyval) { case GDK_Return: spdc_pen_finish (pc, FALSE); ret = TRUE; break; case GDK_Escape: pc->state = SP_PEN_CONTEXT_STOP; spdc_reset_colors (dc); sp_canvas_item_hide (pc->c0); sp_canvas_item_hide (pc->c1); sp_canvas_item_hide (pc->cl0); sp_canvas_item_hide (pc->cl1); ret = TRUE; break; case GDK_BackSpace: if (sp_curve_is_empty (dc->green_curve)) { /* Same as cancel */ pc->state = SP_PEN_CONTEXT_STOP; spdc_reset_colors (dc); sp_canvas_item_hide (pc->c0); sp_canvas_item_hide (pc->c1); sp_canvas_item_hide (pc->cl0); sp_canvas_item_hide (pc->cl1); ret = TRUE; break; } else { NRPointF pt; ArtBpath *p; gint e; /* Reset red curve */ sp_curve_reset (dc->red_curve); /* Destroy topmost green bpath */ gtk_object_destroy (GTK_OBJECT (dc->green_bpaths->data)); dc->green_bpaths = g_slist_remove (dc->green_bpaths, dc->green_bpaths->data); /* Get last segment */ p = SP_CURVE_BPATH (dc->green_curve); e = SP_CURVE_LENGTH (dc->green_curve); if (e < 2) { g_warning ("Green curve length is %d", e); break; } dc->p[0].x = p[e - 2].x3; dc->p[0].y = p[e - 2].y3; dc->p[1].x = p[e - 1].x1; dc->p[1].y = p[e - 1].y1; if (dc->npoints < 4) { pt.x = p[e - 1].x3; pt.y = p[e - 1].y3; } else { pt.x = dc->p[3].x; pt.y = dc->p[3].y; } dc->npoints = 2; sp_curve_backspace (dc->green_curve); sp_canvas_item_hide (pc->c0); sp_canvas_item_hide (pc->c1); sp_canvas_item_hide (pc->cl0); sp_canvas_item_hide (pc->cl1); pc->state = SP_PEN_CONTEXT_POINT; spdc_pen_set_point (pc, &pt, event->motion.state); ret = TRUE; } break; default: break; } break; default: break; } if (!ret) { if (((SPEventContextClass *) pen_parent_class)->root_handler) return ((SPEventContextClass *) pen_parent_class)->root_handler (ec, event); } return ret; }