Code

r11516@tres: ted | 2006-04-26 21:30:18 -0700
[inkscape.git] / src / node-context.cpp
index 747fa65b3eb86155a32f7eeaf245e380ff3db604..67511ea30e83c3e0a4f4445e3c9da1fdc5084608 100644 (file)
@@ -57,10 +57,6 @@ static Inkscape::XML::NodeEventVector nodepath_repr_events = {
 
 static SPEventContextClass *parent_class;
 
-static gchar *undo_label_1 = "dragcurve:1";
-static gchar *undo_label_2 = "dragcurve:2";
-static gchar *undo_label = undo_label_1;
-
 GType
 sp_node_context_get_type()
 {
@@ -163,9 +159,9 @@ sp_node_context_setup(SPEventContext *ec)
         ((SPEventContextClass *) parent_class)->setup(ec);
 
     nc->sel_changed_connection.disconnect();
-    nc->sel_changed_connection = SP_DT_SELECTION(ec->desktop)->connectChanged(sigc::bind(sigc::ptr_fun(&sp_node_context_selection_changed), (gpointer)nc));
+    nc->sel_changed_connection = sp_desktop_selection(ec->desktop)->connectChanged(sigc::bind(sigc::ptr_fun(&sp_node_context_selection_changed), (gpointer)nc));
 
-    Inkscape::Selection *selection = SP_DT_SELECTION(ec->desktop);
+    Inkscape::Selection *selection = sp_desktop_selection(ec->desktop);
     SPItem *item = selection->singleItem();
 
     nc->nodepath = NULL;
@@ -191,11 +187,10 @@ sp_node_context_setup(SPEventContext *ec)
             if (ec->shape_knot_holder)
                 repr = ec->shape_knot_holder->repr;
             else
-                repr = SP_OBJECT_REPR(item); 
+                repr = SP_OBJECT_REPR(item);
             if (repr) {
                 Inkscape::GC::anchor(repr);
                 sp_repr_add_listener(repr, &nodepath_repr_events, ec);
-                sp_repr_synthesize_events(repr, &nodepath_repr_events, ec);
             }
         }
     }
@@ -227,7 +222,9 @@ sp_node_context_selection_changed(Inkscape::Selection *selection, gpointer data)
     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);
@@ -256,11 +253,10 @@ sp_node_context_selection_changed(Inkscape::Selection *selection, gpointer data)
             if (ec->shape_knot_holder)
                 repr = ec->shape_knot_holder->repr;
             else
-                repr = SP_OBJECT_REPR(item); 
+                repr = SP_OBJECT_REPR(item);
             if (repr) {
                 Inkscape::GC::anchor(repr);
                 sp_repr_add_listener(repr, &nodepath_repr_events, ec);
-                sp_repr_synthesize_events(repr, &nodepath_repr_events, ec);
             }
         }
     }
@@ -284,17 +280,17 @@ sp_nodepath_update_from_item(SPNodeContext *nc, SPItem *item)
 
     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_DT_SELECTION(desktop);
+    Inkscape::Selection *selection = sp_desktop_selection(desktop);
     item = selection->singleItem();
 
-    nc->nodepath = NULL;
-    ec->shape_knot_holder = NULL;
     if (item) {
         nc->nodepath = sp_nodepath_new(desktop, item);
         if (nc->nodepath) {
@@ -314,7 +310,6 @@ nodepath_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
                             bool is_interactive, gpointer data)
 {
     SPItem *item = NULL;
-    char const *newd = NULL, *newtypestr = NULL;
     gboolean changed = FALSE;
 
     g_assert(data);
@@ -326,21 +321,18 @@ nodepath_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
 
     if (np) {
         item = SP_ITEM(np->path);
-        if (!strcmp(name, "d")) {
-            newd = new_value;
-            changed = nodepath_repr_d_changed(np, new_value);
-        } else if (!strcmp(name, "sodipodi:nodetypes")) {
-            newtypestr = new_value;
-            changed = nodepath_repr_typestr_changed(np, new_value);
-        } else {
-            return;
-            // With paths, we only need to act if one of the path-affecting attributes has changed.
+        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;
@@ -369,8 +361,8 @@ sp_node_context_show_modifier_tip(SPEventContext *event_context, GdkEvent *event
          _("<b>Alt</b>: lock handle length; <b>Ctrl+Alt</b>: move along handles"));
 }
 
-bool 
-sp_node_context_is_over_stroke (SPNodeContext *nc, SPItem *item, NR::Point event_p, bool remember) 
+bool
+sp_node_context_is_over_stroke (SPNodeContext *nc, SPItem *item, NR::Point event_p, bool remember)
 {
     SPDesktop *desktop = SP_EVENT_CONTEXT (nc)->desktop;
 
@@ -379,17 +371,17 @@ sp_node_context_is_over_stroke (SPNodeContext *nc, SPItem *item, NR::Point event
     nc->curvepoint_doc *= sp_item_dt2i_affine(item);
     nc->curvepoint_doc *= sp_item_i2doc_affine(item);
 
-    NR::Maybe<Path::cut_position> position = get_nearest_position_on_Path(item, nc->curvepoint_doc);
-    NR::Point nearest = get_point_on_Path(item, position.assume().piece, position.assume().t);
+    NR::Maybe<Path::cut_position> 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 
+    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;
 
@@ -413,7 +405,7 @@ sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
     gint ret = FALSE;
 
     SPDesktop *desktop = event_context->desktop;
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
 
     SPNodeContext *nc = SP_NODE_CONTEXT(event_context);
 
@@ -424,12 +416,13 @@ sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
                 if (!nc->drag) {
 
                     // find out clicked item, disregarding groups, honoring Alt
-                    SPItem *item_clicked = sp_event_context_find_item (desktop, 
+                    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(), 
+                    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);
@@ -440,7 +433,7 @@ sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
                             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(item_over, nc->curvepoint_doc);
+                                    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;
@@ -448,20 +441,20 @@ sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
                                     }
                                     //select the segment
                                     if (event->button.state & GDK_SHIFT_MASK) {
-                                        sp_nodepath_select_segment_near_point(item_over, nc->curvepoint_doc, true);
+                                        sp_nodepath_select_segment_near_point(nc->nodepath, nc->curvepoint_doc, true);
                                     } else {
-                                        sp_nodepath_select_segment_near_point(item_over, nc->curvepoint_doc, false);
+                                        sp_nodepath_select_segment_near_point(nc->nodepath, nc->curvepoint_doc, false);
                                     }
                                 }
-                                break; 
+                                break;
                             case GDK_2BUTTON_PRESS:
                                 //add a node
-                                sp_nodepath_add_node_near_point(item_over, nc->curvepoint_doc);
+                                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);
                     } else {
@@ -483,7 +476,7 @@ sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
 
                 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(), 
+                    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) {
@@ -492,7 +485,7 @@ sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
                             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(item_over, nc->curvepoint_doc, false);
+                                sp_nodepath_select_segment_near_point(nc->nodepath, nc->curvepoint_doc, false);
                                 ret = TRUE;
                             } else {
                                 break;
@@ -522,7 +515,7 @@ static gint
 sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
 {
     SPDesktop *desktop = event_context->desktop;
-    Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
 
     SPNodeContext *nc = SP_NODE_CONTEXT(event_context);
     double const nudge = prefs_get_double_attribute_limited("options.nudgedistance", "value", 2, 0, 1000); // in px
@@ -565,8 +558,8 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                     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, undo_label);
-                    nc->curvepoint_event[NR::X] = (gint) event->motion.x;   
+                    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 {
@@ -582,7 +575,7 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                     break;
                 }
 
-                SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), 
+                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) {
@@ -609,12 +602,9 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
             if (event->button.button == 1) {
 
                 NR::Maybe<NR::Rect> b = Inkscape::Rubberband::get()->getRectangle();
-                    
+
                 if (nc->hit && !event_context->within_tolerance) { //drag curve
-                    if (undo_label == undo_label_1)
-                        undo_label = undo_label_2;
-                    else 
-                        undo_label = undo_label_1;
+                    sp_nodepath_update_repr (nc->nodepath);
                 } 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);
@@ -624,7 +614,7 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                         if (nc->nodepath && nc->nodepath->selected)
                             sp_nodepath_deselect(nc->nodepath);
                         else
-                            SP_DT_SELECTION(desktop)->clear();
+                            sp_desktop_selection(desktop)->clear();
                     }
                 }
                 ret = TRUE;
@@ -646,8 +636,13 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                 case GDK_Delete:
                 case GDK_KP_Delete:
                 case GDK_BackSpace:
-                    // with any modifiers
-                    sp_node_selected_delete();
+                    if (MOD__CTRL_ONLY) {
+                        sp_node_selected_delete();
+                    } else {
+                        if (nc->nodepath && nc->nodepath->selected) {
+                            sp_node_delete_preserve(g_list_copy(nc->nodepath->selected));
+                        }
+                    }
                     ret = TRUE;
                     break;
                 case GDK_C:
@@ -796,7 +791,7 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                         if (nc->nodepath && nc->nodepath->selected) {
                             sp_nodepath_deselect(nc->nodepath);
                         } else {
-                            SP_DT_SELECTION(desktop)->clear();
+                            sp_desktop_selection(desktop)->clear();
                         }
                     }
                     ret = TRUE;