X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fnode-context.cpp;h=3d11aefe4a39c303ba783e9e41aa1a11199ee04f;hb=1cb64c3a763a8a064cfff29309c9ad16f96a0aa5;hp=8f8a48bf7718f9ddf06a90ed3af9590be447af76;hpb=e77ce9f12f531d4701b0b99809e0a6d8f92c0085;p=inkscape.git diff --git a/src/node-context.cpp b/src/node-context.cpp index 8f8a48bf7..3d11aefe4 100644 --- a/src/node-context.cpp +++ b/src/node-context.cpp @@ -7,8 +7,7 @@ * Lauris Kaplinski * bulia byak * - * This code is in public domain, except stamping code, - * which is Copyright (C) Masatake Yamato 2002 + * This code is in public domain */ #ifdef HAVE_CONFIG_H @@ -26,15 +25,14 @@ #include "desktop-handles.h" #include "selection.h" #include "pixmaps/cursor-node.xpm" -#include "pixmaps/cursor-node.pixbuf" #include "message-context.h" #include "node-context.h" #include "pixmaps/cursor-node-d.xpm" -#include "pixmaps/cursor-node-d.pixbuf" #include "prefs-utils.h" #include "xml/node-event-vector.h" #include "style.h" #include "splivarot.h" +#include "shape-editor.h" static void sp_node_context_class_init(SPNodeContextClass *klass); static void sp_node_context_init(SPNodeContext *node_context); @@ -45,18 +43,6 @@ static gint sp_node_context_root_handler(SPEventContext *event_context, GdkEvent static gint sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); -static void nodepath_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, - gchar const *old_value, gchar const *new_value, - bool is_interactive, gpointer data); - -static Inkscape::XML::NodeEventVector nodepath_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - nodepath_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - static SPEventContextClass *parent_class; GType @@ -100,11 +86,6 @@ sp_node_context_init(SPNodeContext *node_context) SPEventContext *event_context = SP_EVENT_CONTEXT(node_context); event_context->cursor_shape = cursor_node_xpm; - event_context->cursor_pixbuf = gdk_pixbuf_new_from_inline( - -1, - cursor_node_pixbuf, - FALSE, - NULL); event_context->hot_x = 1; event_context->hot_y = 1; @@ -112,7 +93,7 @@ sp_node_context_init(SPNodeContext *node_context) node_context->rightalt = FALSE; node_context->leftctrl = FALSE; node_context->rightctrl = FALSE; - + new (&node_context->sel_changed_connection) sigc::connection(); } @@ -127,28 +108,7 @@ sp_node_context_dispose(GObject *object) nc->sel_changed_connection.disconnect(); nc->sel_changed_connection.~connection(); - Inkscape::XML::Node *repr = NULL; - if (nc->nodepath) { - repr = nc->nodepath->repr; - } - if (!repr && ec->shape_knot_holder) { - repr = ec->shape_knot_holder->repr; - } - - if (repr) { - sp_repr_remove_listener_by_data(repr, ec); - Inkscape::GC::release(repr); - } - - if (nc->nodepath) { - sp_nodepath_destroy(nc->nodepath); - nc->nodepath = NULL; - } - - if (ec->shape_knot_holder) { - sp_knot_holder_destroy(ec->shape_knot_holder); - ec->shape_knot_holder = NULL; - } + delete nc->shape_editor; if (nc->_node_message_context) { delete nc->_node_message_context; @@ -171,8 +131,7 @@ sp_node_context_setup(SPEventContext *ec) Inkscape::Selection *selection = sp_desktop_selection(ec->desktop); SPItem *item = selection->singleItem(); - nc->nodepath = NULL; - ec->shape_knot_holder = NULL; + nc->shape_editor = new ShapeEditor(ec->desktop); nc->rb_escaped = false; @@ -180,26 +139,10 @@ sp_node_context_setup(SPEventContext *ec) nc->added_node = false; + nc->current_state = SP_NODE_CONTEXT_INACTIVE; + if (item) { - nc->nodepath = sp_nodepath_new(ec->desktop, item, (prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0)); - if ( nc->nodepath) { - //point pack to parent in case nodepath is deleted - nc->nodepath->nodeContext = nc; - } - ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop); - - if (nc->nodepath || ec->shape_knot_holder) { - // setting listener - Inkscape::XML::Node *repr; - if (ec->shape_knot_holder) - repr = ec->shape_knot_holder->repr; - else - repr = SP_OBJECT_REPR(item); - if (repr) { - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &nodepath_repr_events, ec); - } - } + nc->shape_editor->set_item(item); } if (prefs_get_int_attribute("tools.nodes", "selcue", 0) != 0) { @@ -210,8 +153,11 @@ sp_node_context_setup(SPEventContext *ec) ec->enableGrDrag(); } + ec->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive + nc->_node_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); - sp_nodepath_update_statusbar(nc->nodepath); + + nc->shape_editor->update_statusbar(); } /** @@ -222,140 +168,13 @@ void sp_node_context_selection_changed(Inkscape::Selection *selection, gpointer data) { SPNodeContext *nc = SP_NODE_CONTEXT(data); - SPEventContext *ec = SP_EVENT_CONTEXT(nc); - - Inkscape::XML::Node *old_repr = NULL; - - if (nc->nodepath) { - old_repr = nc->nodepath->repr; - sp_nodepath_destroy(nc->nodepath); - nc->nodepath = NULL; - } - if (ec->shape_knot_holder) { - old_repr = ec->shape_knot_holder->repr; - sp_knot_holder_destroy(ec->shape_knot_holder); - } - - if (old_repr) { // remove old listener - sp_repr_remove_listener_by_data(old_repr, ec); - Inkscape::GC::release(old_repr); - } - - SPItem *item = selection->singleItem(); - - SPDesktop *desktop = selection->desktop(); - nc->nodepath = NULL; - ec->shape_knot_holder = NULL; - if (item) { - nc->nodepath = sp_nodepath_new(desktop, item, (prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0)); - if (nc->nodepath) { - nc->nodepath->nodeContext = nc; - } - ec->shape_knot_holder = sp_item_knot_holder(item, desktop); - - if (nc->nodepath || ec->shape_knot_holder) { - // setting new listener - Inkscape::XML::Node *repr; - if (ec->shape_knot_holder) - repr = ec->shape_knot_holder->repr; - else - repr = SP_OBJECT_REPR(item); - if (repr) { - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &nodepath_repr_events, ec); - } - } - } - sp_nodepath_update_statusbar(nc->nodepath); -} - -/** -\brief Regenerates nodepath when the item's repr was change outside of node edit -(e.g. by undo, or xml editor, or edited in another view). The item is assumed to be the same -(otherwise sp_node_context_selection_changed() would have been called), so repr and listeners -are not changed. -*/ -void -sp_nodepath_update_from_item(SPNodeContext *nc, SPItem *item) -{ - g_assert(nc); - SPEventContext *ec = ((SPEventContext *) nc); - - SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(SP_EVENT_CONTEXT(nc)); - g_assert(desktop); - - if (nc->nodepath) { - sp_nodepath_destroy(nc->nodepath); - nc->nodepath = NULL; - } - - if (ec->shape_knot_holder) { - sp_knot_holder_destroy(ec->shape_knot_holder); - ec->shape_knot_holder = NULL; - } - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - item = selection->singleItem(); - - if (item) { - nc->nodepath = sp_nodepath_new(desktop, item, (prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0)); - if (nc->nodepath) { - nc->nodepath->nodeContext = nc; - } - ec->shape_knot_holder = sp_item_knot_holder(item, desktop); - } - sp_nodepath_update_statusbar(nc->nodepath); -} - -/** -\brief Callback that is fired whenever an attribute of the selected item (which we have in the nodepath) changes -*/ -static void -nodepath_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, - gchar const *old_value, gchar const *new_value, - bool is_interactive, gpointer data) -{ - SPItem *item = NULL; - gboolean changed = FALSE; - - g_assert(data); - SPNodeContext *nc = ((SPNodeContext *) data); - SPEventContext *ec = ((SPEventContext *) data); - g_assert(nc); - Inkscape::NodePath::Path *np = nc->nodepath; - SPKnotHolder *kh = ec->shape_knot_holder; - - if (np) { - item = SP_ITEM(np->path); - if (!strcmp(name, "d") || !strcmp(name, "sodipodi:nodetypes")) { // With paths, we only need to act if one of the path-affecting attributes has changed. - changed = (np->local_change == 0); - if (np->local_change > 0) - np->local_change--; - } - - } else if (kh) { - item = SP_ITEM(kh->item); - changed = !(kh->local_change); - kh->local_change = FALSE; - } - - if (np && changed) { - GList *saved = NULL; - SPDesktop *desktop = np->desktop; - g_assert(desktop); - Inkscape::Selection *selection = desktop->selection; - g_assert(selection); - - saved = save_nodepath_selection(nc->nodepath); - sp_nodepath_update_from_item(nc, item); - if (nc->nodepath && saved) restore_nodepath_selection(nc->nodepath, saved); - - } else if (kh && changed) { - sp_nodepath_update_from_item(nc, item); - } + // TODO: update ShapeEditorsCollective instead + nc->shape_editor->unset_item(); + SPItem *item = selection->singleItem(); + nc->shape_editor->set_item(item); - sp_nodepath_update_statusbar(nc->nodepath); + nc->shape_editor->update_statusbar(); } void @@ -368,155 +187,14 @@ sp_node_context_show_modifier_tip(SPEventContext *event_context, GdkEvent *event _("Alt: lock handle length; Ctrl+Alt: move along handles")); } -bool -sp_node_context_is_over_stroke (SPNodeContext *nc, SPItem *item, NR::Point event_p, bool remember) -{ - SPDesktop *desktop = SP_EVENT_CONTEXT (nc)->desktop; - - //Translate click point into proper coord system - nc->curvepoint_doc = desktop->w2d(event_p); - nc->curvepoint_doc *= sp_item_dt2i_affine(item); - nc->curvepoint_doc *= sp_item_i2doc_affine(item); - - NR::Maybe position = get_nearest_position_on_Path(nc->nodepath->livarot_path, nc->curvepoint_doc); - NR::Point nearest = get_point_on_Path(nc->nodepath->livarot_path, position.assume().piece, position.assume().t); - NR::Point delta = nearest - nc->curvepoint_doc; - - delta = desktop->d2w(delta); - - double stroke_tolerance = - (SP_OBJECT_STYLE (item)->stroke.type != SP_PAINT_TYPE_NONE? - desktop->current_zoom() * - SP_OBJECT_STYLE (item)->stroke_width.computed * - sp_item_i2d_affine (item).expansion() * 0.5 - : 0.0) - + (double) SP_EVENT_CONTEXT(nc)->tolerance; - - bool close = (NR::L2 (delta) < stroke_tolerance); - - if (remember && close) { - nc->curvepoint_event[NR::X] = (gint) event_p [NR::X]; - nc->curvepoint_event[NR::Y] = (gint) event_p [NR::Y]; - nc->hit = true; - nc->grab_t = position.assume().t; - nc->grab_node = sp_nodepath_get_node_by_index(position.assume().piece); - } - - return close; -} - static gint sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event) { gint ret = FALSE; - SPDesktop *desktop = event_context->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); - - SPNodeContext *nc = SP_NODE_CONTEXT(event_context); - - switch (event->type) { - case GDK_2BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - if (event->button.button == 1) { - if (!nc->drag) { - - // find out clicked item, disregarding groups, honoring Alt - SPItem *item_clicked = sp_event_context_find_item (desktop, - NR::Point(event->button.x, event->button.y), - (event->button.state & GDK_MOD1_MASK) && !(event->button.state & GDK_CONTROL_MASK), TRUE); - // find out if we're over the selected item, disregarding groups - SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), - NR::Point(event->button.x, event->button.y)); - - bool over_stroke = false; - if (item_over && nc->nodepath) { - over_stroke = sp_node_context_is_over_stroke (nc, item_over, NR::Point(event->button.x, event->button.y), false); - } - - if (over_stroke || nc->added_node) { - switch (event->type) { - case GDK_BUTTON_RELEASE: - if (event->button.state & GDK_CONTROL_MASK && event->button.state & GDK_MOD1_MASK) { - //add a node - sp_nodepath_add_node_near_point(nc->nodepath, nc->curvepoint_doc); - } else { - if (nc->added_node) { // we just received double click, ignore release - nc->added_node = false; - break; - } - //select the segment - if (event->button.state & GDK_SHIFT_MASK) { - sp_nodepath_select_segment_near_point(nc->nodepath, nc->curvepoint_doc, true); - } else { - sp_nodepath_select_segment_near_point(nc->nodepath, nc->curvepoint_doc, false); - } - desktop->updateNow(); - } - break; - case GDK_2BUTTON_PRESS: - //add a node - sp_nodepath_add_node_near_point(nc->nodepath, nc->curvepoint_doc); - nc->added_node = true; - break; - default: - break; - } - } else if (event->button.state & GDK_SHIFT_MASK) { - selection->toggle(item_clicked); - desktop->updateNow(); - } else { - selection->set(item_clicked); - desktop->updateNow(); - } - - ret = TRUE; - } - break; - } - break; - case GDK_BUTTON_PRESS: - if (event->button.button == 1 && !(event->button.state & GDK_SHIFT_MASK)) { - // save drag origin - event_context->xp = (gint) event->button.x; - event_context->yp = (gint) event->button.y; - event_context->within_tolerance = true; - nc->hit = false; - - if (!nc->drag) { - // find out if we're over the selected item, disregarding groups - SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), - NR::Point(event->button.x, event->button.y)); - - if (nc->nodepath && selection->single() && item_over) { - - // save drag origin - bool over_stroke = sp_node_context_is_over_stroke (nc, item_over, NR::Point(event->button.x, event->button.y), true); - //only dragging curves - if (over_stroke) { - sp_nodepath_select_segment_near_point(nc->nodepath, nc->curvepoint_doc, false); - ret = TRUE; - } else { - break; - } - } else { - break; - } - - ret = TRUE; - } - break; - } - break; - default: - break; - } - - if (!ret) { - if (((SPEventContextClass *) parent_class)->item_handler) - ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); - } + if (((SPEventContextClass *) parent_class)->item_handler) + ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); return ret; } @@ -534,82 +212,105 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) double const offset = prefs_get_double_attribute_limited("options.defaultscale", "value", 2, 0, 1000); gint ret = FALSE; - switch (event->type) { case GDK_BUTTON_PRESS: - if (event->button.button == 1) { + if (event->button.button == 1 && !event_context->space_panning) { // save drag origin event_context->xp = (gint) event->button.x; event_context->yp = (gint) event->button.y; event_context->within_tolerance = true; - nc->hit = false; + nc->shape_editor->cancel_hit(); + if (!(event->button.state & GDK_SHIFT_MASK)) { + if (!nc->drag) { + if (nc->shape_editor->has_nodepath() && selection->single() /* && item_over */) { + // save drag origin + bool over_stroke = nc->shape_editor->is_over_stroke(NR::Point(event->button.x, event->button.y), true); + //only dragging curves + if (over_stroke) { + ret = TRUE; + break; + } + } + } + } NR::Point const button_w(event->button.x, event->button.y); NR::Point const button_dt(desktop->w2d(button_w)); Inkscape::Rubberband::get()->start(desktop, button_dt); + nc->current_state = SP_NODE_CONTEXT_INACTIVE; + desktop->updateNow(); ret = TRUE; } break; case GDK_MOTION_NOTIFY: - if (event->motion.state & GDK_BUTTON1_MASK) { + if (event->motion.state & GDK_BUTTON1_MASK && !event_context->space_panning) { if ( event_context->within_tolerance && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance ) && ( abs( (gint) event->motion.y - event_context->yp ) < event_context->tolerance ) ) { break; // do not drag if we're within tolerance from origin } + + // The path went away while dragging; throw away any further motion + // events until the mouse pointer is released. + + if (nc->shape_editor->hits_curve() && !nc->shape_editor->has_nodepath()) { + break; + } + // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) event_context->within_tolerance = false; - if (nc->nodepath && nc->hit) { - NR::Point const delta_w(event->motion.x - nc->curvepoint_event[NR::X], - event->motion.y - nc->curvepoint_event[NR::Y]); - NR::Point const delta_dt(desktop->w2d(delta_w)); - sp_nodepath_curve_drag (nc->grab_node, nc->grab_t, delta_dt); - nc->curvepoint_event[NR::X] = (gint) event->motion.x; - nc->curvepoint_event[NR::Y] = (gint) event->motion.y; - gobble_motion_events(GDK_BUTTON1_MASK); - } else { - NR::Point const motion_w(event->motion.x, - event->motion.y); - NR::Point const motion_dt(desktop->w2d(motion_w)); - Inkscape::Rubberband::get()->move(motion_dt); + // Once we determine what the user is doing (dragging either a node or the + // selection rubberband), make sure we continue to perform that operation + // until the mouse pointer is lifted. + if (nc->current_state == SP_NODE_CONTEXT_INACTIVE) { + if (nc->shape_editor->hits_curve() && nc->shape_editor->has_nodepath()) { + nc->current_state = SP_NODE_CONTEXT_NODE_DRAGGING; + } else { + nc->current_state = SP_NODE_CONTEXT_RUBBERBAND_DRAGGING; + } } + + switch (nc->current_state) { + case SP_NODE_CONTEXT_NODE_DRAGGING: + { + nc->shape_editor->curve_drag (event->motion.x, event->motion.y); + + gobble_motion_events(GDK_BUTTON1_MASK); + break; + } + case SP_NODE_CONTEXT_RUBBERBAND_DRAGGING: + if (Inkscape::Rubberband::get()->is_started()) { + NR::Point const motion_w(event->motion.x, + event->motion.y); + NR::Point const motion_dt(desktop->w2d(motion_w)); + Inkscape::Rubberband::get()->move(motion_dt); + } + break; + } + nc->drag = TRUE; ret = TRUE; } else { - if (!nc->nodepath || selection->singleItem() == NULL) { + if (!nc->shape_editor->has_nodepath() || selection->singleItem() == NULL) { break; } - SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), - NR::Point(event->motion.x, event->motion.y)); bool over_stroke = false; - if (item_over && nc->nodepath) { - over_stroke = sp_node_context_is_over_stroke (nc, item_over, NR::Point(event->motion.x, event->motion.y), false); - } + over_stroke = nc->shape_editor->is_over_stroke(NR::Point(event->motion.x, event->motion.y), false); if (nc->cursor_drag && !over_stroke) { event_context->cursor_shape = cursor_node_xpm; - event_context->cursor_pixbuf = gdk_pixbuf_new_from_inline( - -1, - cursor_node_pixbuf, - FALSE, - NULL); event_context->hot_x = 1; event_context->hot_y = 1; sp_event_context_update_cursor(event_context); nc->cursor_drag = false; } else if (!nc->cursor_drag && over_stroke) { event_context->cursor_shape = cursor_node_d_xpm; - event_context->cursor_pixbuf = gdk_pixbuf_new_from_inline( - -1, - cursor_node_d_pixbuf, - FALSE, - NULL); event_context->hot_x = 1; event_context->hot_y = 1; sp_event_context_update_cursor(event_context); @@ -617,33 +318,88 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) } } break; + + case GDK_2BUTTON_PRESS: case GDK_BUTTON_RELEASE: - event_context->xp = event_context->yp = 0; - if (event->button.button == 1) { + if ( (event->button.button == 1) && (!nc->drag) && !event_context->space_panning) { + // find out clicked item, disregarding groups, honoring Alt + SPItem *item_clicked = sp_event_context_find_item (desktop, + NR::Point(event->button.x, event->button.y), + (event->button.state & GDK_MOD1_MASK) && !(event->button.state & GDK_CONTROL_MASK), TRUE); - NR::Maybe b = Inkscape::Rubberband::get()->getRectangle(); + event_context->xp = event_context->yp = 0; - if (nc->hit && !event_context->within_tolerance) { //drag curve - sp_nodepath_update_repr (nc->nodepath, _("Drag curve")); - } else if (b != NR::Nothing() && !event_context->within_tolerance) { // drag to select - if (nc->nodepath) { - sp_nodepath_select_rect(nc->nodepath, b.assume(), event->button.state & GDK_SHIFT_MASK); + bool over_stroke = false; + if (nc->shape_editor->has_nodepath()) { + over_stroke = nc->shape_editor->is_over_stroke(NR::Point(event->button.x, event->button.y), false); + } + + if (item_clicked || over_stroke) { + if (over_stroke || nc->added_node) { + switch (event->type) { + case GDK_BUTTON_RELEASE: + if (event->button.state & GDK_CONTROL_MASK && event->button.state & GDK_MOD1_MASK) { + //add a node + nc->shape_editor->add_node_near_point(); + } else { + if (nc->added_node) { // we just received double click, ignore release + nc->added_node = false; + break; + } + //select the segment + if (event->button.state & GDK_SHIFT_MASK) { + nc->shape_editor->select_segment_near_point(true); + } else { + nc->shape_editor->select_segment_near_point(false); + } + desktop->updateNow(); + } + break; + case GDK_2BUTTON_PRESS: + //add a node + nc->shape_editor->add_node_near_point(); + nc->added_node = true; + break; + default: + break; + } + } else if (event->button.state & GDK_SHIFT_MASK) { + selection->toggle(item_clicked); + desktop->updateNow(); + } else { + selection->set(item_clicked); + desktop->updateNow(); } - } else { - if (!(nc->rb_escaped)) { // unless something was cancelled - if (nc->nodepath && nc->nodepath->selected) - sp_nodepath_deselect(nc->nodepath); - else - sp_desktop_selection(desktop)->clear(); + Inkscape::Rubberband::get()->stop(); + ret = TRUE; + break; + } + } + if (event->type == GDK_BUTTON_RELEASE) { + event_context->xp = event_context->yp = 0; + if (event->button.button == 1) { + NR::Maybe b = Inkscape::Rubberband::get()->getRectangle(); + + if (nc->shape_editor->hits_curve() && !event_context->within_tolerance) { //drag curve + nc->shape_editor->finish_drag(); + } else if (b && !event_context->within_tolerance) { // drag to select + nc->shape_editor->select_rect(*b, event->button.state & GDK_SHIFT_MASK); + } else { + if (!(nc->rb_escaped)) { // unless something was cancelled + if (nc->shape_editor->has_selection()) + nc->shape_editor->deselect(); + else + sp_desktop_selection(desktop)->clear(); + } } + ret = TRUE; + Inkscape::Rubberband::get()->stop(); + desktop->updateNow(); + nc->rb_escaped = false; + nc->drag = FALSE; + nc->shape_editor->cancel_hit(); + nc->current_state = SP_NODE_CONTEXT_INACTIVE; } - ret = TRUE; - Inkscape::Rubberband::get()->stop(); - desktop->updateNow(); - nc->rb_escaped = false; - nc->drag = FALSE; - nc->hit = false; - break; } break; case GDK_KEY_PRESS: @@ -651,74 +407,72 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_Insert: case GDK_KP_Insert: // with any modifiers - sp_node_selected_add_node(); + nc->shape_editor->add_node(); ret = TRUE; break; case GDK_Delete: case GDK_KP_Delete: case GDK_BackSpace: if (MOD__CTRL_ONLY) { - sp_node_selected_delete(); + nc->shape_editor->delete_nodes(); } else { - if (nc->nodepath && nc->nodepath->selected) { - sp_node_delete_preserve(g_list_copy(nc->nodepath->selected)); - } + nc->shape_editor->delete_nodes_preserving_shape(); } ret = TRUE; break; case GDK_C: case GDK_c: if (MOD__SHIFT_ONLY) { - sp_node_selected_set_type(Inkscape::NodePath::NODE_CUSP); + nc->shape_editor->set_node_type(Inkscape::NodePath::NODE_CUSP); ret = TRUE; } break; case GDK_S: case GDK_s: if (MOD__SHIFT_ONLY) { - sp_node_selected_set_type(Inkscape::NodePath::NODE_SMOOTH); + nc->shape_editor->set_node_type(Inkscape::NodePath::NODE_SMOOTH); ret = TRUE; } break; case GDK_Y: case GDK_y: if (MOD__SHIFT_ONLY) { - sp_node_selected_set_type(Inkscape::NodePath::NODE_SYMM); + nc->shape_editor->set_node_type(Inkscape::NodePath::NODE_SYMM); ret = TRUE; } break; case GDK_B: case GDK_b: if (MOD__SHIFT_ONLY) { - sp_node_selected_break(); + nc->shape_editor->break_at_nodes(); ret = TRUE; } break; case GDK_J: case GDK_j: if (MOD__SHIFT_ONLY) { - sp_node_selected_join(); + nc->shape_editor->join_nodes(); ret = TRUE; } break; case GDK_D: case GDK_d: if (MOD__SHIFT_ONLY) { - sp_node_selected_duplicate(); + nc->shape_editor->duplicate_nodes(); ret = TRUE; } break; case GDK_L: case GDK_l: if (MOD__SHIFT_ONLY) { - sp_node_selected_set_line_type(NR_LINETO); + nc->shape_editor->set_type_of_segments(NR_LINETO); ret = TRUE; } break; case GDK_U: case GDK_u: if (MOD__SHIFT_ONLY) { - sp_node_selected_set_line_type(NR_CURVETO); + nc->shape_editor->set_type_of_segments(NR_CURVETO); ret = TRUE; } break; @@ -730,17 +484,26 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) ret = TRUE; } break; + case GDK_x: + case GDK_X: + if (MOD__ALT_ONLY) { + desktop->setToolboxFocusTo ("altx-nodes"); + ret = TRUE; + } + break; case GDK_Left: // move selection left case GDK_KP_Left: case GDK_KP_4: if (!MOD__CTRL) { // not ctrl + gint mul = 1 + gobble_key_events( + get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT) { // alt - if (MOD__SHIFT) sp_node_selected_move_screen(-10, 0); // shift - else sp_node_selected_move_screen(-1, 0); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes_screen(mul*-10, 0); // shift + else nc->shape_editor->move_nodes_screen(mul*-1, 0); // no shift } else { // no alt - if (MOD__SHIFT) sp_node_selected_move(-10*nudge, 0); // shift - else sp_node_selected_move(-nudge, 0); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes(mul*-10*nudge, 0); // shift + else nc->shape_editor->move_nodes(mul*-nudge, 0); // no shift } ret = TRUE; } @@ -749,13 +512,15 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_KP_Up: case GDK_KP_8: if (!MOD__CTRL) { // not ctrl + gint mul = 1 + gobble_key_events( + get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT) { // alt - if (MOD__SHIFT) sp_node_selected_move_screen(0, 10); // shift - else sp_node_selected_move_screen(0, 1); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes_screen(0, mul*10); // shift + else nc->shape_editor->move_nodes_screen(0, mul*1); // no shift } else { // no alt - if (MOD__SHIFT) sp_node_selected_move(0, 10*nudge); // shift - else sp_node_selected_move(0, nudge); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes(0, mul*10*nudge); // shift + else nc->shape_editor->move_nodes(0, mul*nudge); // no shift } ret = TRUE; } @@ -764,13 +529,15 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_KP_Right: case GDK_KP_6: if (!MOD__CTRL) { // not ctrl + gint mul = 1 + gobble_key_events( + get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT) { // alt - if (MOD__SHIFT) sp_node_selected_move_screen(10, 0); // shift - else sp_node_selected_move_screen(1, 0); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes_screen(mul*10, 0); // shift + else nc->shape_editor->move_nodes_screen(mul*1, 0); // no shift } else { // no alt - if (MOD__SHIFT) sp_node_selected_move(10*nudge, 0); // shift - else sp_node_selected_move(nudge, 0); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes(mul*10*nudge, 0); // shift + else nc->shape_editor->move_nodes(mul*nudge, 0); // no shift } ret = TRUE; } @@ -779,38 +546,29 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_KP_Down: case GDK_KP_2: if (!MOD__CTRL) { // not ctrl + gint mul = 1 + gobble_key_events( + get_group0_keyval(&event->key), 0); // with any mask if (MOD__ALT) { // alt - if (MOD__SHIFT) sp_node_selected_move_screen(0, -10); // shift - else sp_node_selected_move_screen(0, -1); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes_screen(0, mul*-10); // shift + else nc->shape_editor->move_nodes_screen(0, mul*-1); // no shift } else { // no alt - if (MOD__SHIFT) sp_node_selected_move(0, -10*nudge); // shift - else sp_node_selected_move(0, -nudge); // no shift + if (MOD__SHIFT) nc->shape_editor->move_nodes(0, mul*-10*nudge); // shift + else nc->shape_editor->move_nodes(0, mul*-nudge); // no shift } ret = TRUE; } break; - case GDK_Tab: // Tab - cycle selection forward - if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { - sp_nodepath_select_next(nc->nodepath); - ret = TRUE; - } - break; - case GDK_ISO_Left_Tab: // Shift Tab - cycle selection backward - if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { - sp_nodepath_select_prev(nc->nodepath); - ret = TRUE; - } - break; case GDK_Escape: { NR::Maybe const b = Inkscape::Rubberband::get()->getRectangle(); - if (b != NR::Nothing()) { + if (b) { Inkscape::Rubberband::get()->stop(); + nc->current_state = SP_NODE_CONTEXT_INACTIVE; nc->rb_escaped = true; } else { - if (nc->nodepath && nc->nodepath->selected) { - sp_nodepath_deselect(nc->nodepath); + if (nc->shape_editor->has_selection()) { + nc->shape_editor->deselect(); } else { sp_desktop_selection(desktop)->clear(); } @@ -822,40 +580,40 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_bracketleft: if ( MOD__CTRL && !MOD__ALT && ( snaps != 0 ) ) { if (nc->leftctrl) - sp_nodepath_selected_nodes_rotate (nc->nodepath, M_PI/snaps, -1, false); + nc->shape_editor->rotate_nodes (M_PI/snaps, -1, false); if (nc->rightctrl) - sp_nodepath_selected_nodes_rotate (nc->nodepath, M_PI/snaps, 1, false); + nc->shape_editor->rotate_nodes (M_PI/snaps, 1, false); } else if ( MOD__ALT && !MOD__CTRL ) { if (nc->leftalt && nc->rightalt) - sp_nodepath_selected_nodes_rotate (nc->nodepath, 1, 0, true); + nc->shape_editor->rotate_nodes (1, 0, true); else { if (nc->leftalt) - sp_nodepath_selected_nodes_rotate (nc->nodepath, 1, -1, true); + nc->shape_editor->rotate_nodes (1, -1, true); if (nc->rightalt) - sp_nodepath_selected_nodes_rotate (nc->nodepath, 1, 1, true); + nc->shape_editor->rotate_nodes (1, 1, true); } } else if ( snaps != 0 ) { - sp_nodepath_selected_nodes_rotate (nc->nodepath, M_PI/snaps, 0, false); + nc->shape_editor->rotate_nodes (M_PI/snaps, 0, false); } ret = TRUE; break; case GDK_bracketright: if ( MOD__CTRL && !MOD__ALT && ( snaps != 0 ) ) { if (nc->leftctrl) - sp_nodepath_selected_nodes_rotate (nc->nodepath, -M_PI/snaps, -1, false); + nc->shape_editor->rotate_nodes (-M_PI/snaps, -1, false); if (nc->rightctrl) - sp_nodepath_selected_nodes_rotate (nc->nodepath, -M_PI/snaps, 1, false); + nc->shape_editor->rotate_nodes (-M_PI/snaps, 1, false); } else if ( MOD__ALT && !MOD__CTRL ) { if (nc->leftalt && nc->rightalt) - sp_nodepath_selected_nodes_rotate (nc->nodepath, -1, 0, true); + nc->shape_editor->rotate_nodes (-1, 0, true); else { if (nc->leftalt) - sp_nodepath_selected_nodes_rotate (nc->nodepath, -1, -1, true); + nc->shape_editor->rotate_nodes (-1, -1, true); if (nc->rightalt) - sp_nodepath_selected_nodes_rotate (nc->nodepath, -1, 1, true); + nc->shape_editor->rotate_nodes (-1, 1, true); } } else if ( snaps != 0 ) { - sp_nodepath_selected_nodes_rotate (nc->nodepath, -M_PI/snaps, 0, false); + nc->shape_editor->rotate_nodes (-M_PI/snaps, 0, false); } ret = TRUE; break; @@ -863,20 +621,20 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_comma: if (MOD__CTRL) { if (nc->leftctrl) - sp_nodepath_selected_nodes_scale(nc->nodepath, -offset, -1); + nc->shape_editor->scale_nodes(-offset, -1); if (nc->rightctrl) - sp_nodepath_selected_nodes_scale(nc->nodepath, -offset, 1); + nc->shape_editor->scale_nodes(-offset, 1); } else if (MOD__ALT) { if (nc->leftalt && nc->rightalt) - sp_nodepath_selected_nodes_scale_screen(nc->nodepath, -1, 0); + nc->shape_editor->scale_nodes_screen (-1, 0); else { if (nc->leftalt) - sp_nodepath_selected_nodes_scale_screen(nc->nodepath, -1, -1); + nc->shape_editor->scale_nodes_screen (-1, -1); if (nc->rightalt) - sp_nodepath_selected_nodes_scale_screen(nc->nodepath, -1, 1); + nc->shape_editor->scale_nodes_screen (-1, 1); } } else { - sp_nodepath_selected_nodes_scale(nc->nodepath, -offset, 0); + nc->shape_editor->scale_nodes (-offset, 0); } ret = TRUE; break; @@ -884,20 +642,20 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) case GDK_period: if (MOD__CTRL) { if (nc->leftctrl) - sp_nodepath_selected_nodes_scale(nc->nodepath, offset, -1); + nc->shape_editor->scale_nodes (offset, -1); if (nc->rightctrl) - sp_nodepath_selected_nodes_scale(nc->nodepath, offset, 1); + nc->shape_editor->scale_nodes (offset, 1); } else if (MOD__ALT) { if (nc->leftalt && nc->rightalt) - sp_nodepath_selected_nodes_scale_screen(nc->nodepath, 1, 0); + nc->shape_editor->scale_nodes_screen (1, 0); else { if (nc->leftalt) - sp_nodepath_selected_nodes_scale_screen(nc->nodepath, 1, -1); + nc->shape_editor->scale_nodes_screen (1, -1); if (nc->rightalt) - sp_nodepath_selected_nodes_scale_screen(nc->nodepath, 1, 1); + nc->shape_editor->scale_nodes_screen (1, 1); } } else { - sp_nodepath_selected_nodes_scale(nc->nodepath, offset, 0); + nc->shape_editor->scale_nodes (offset, 0); } ret = TRUE; break;