diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index b224c970c7e347a47e6f8952d9abdf4ced55a060..0ad4c66a030c190776b9c53cc158dd6c1ea7ae5e 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
static void sp_node_set_selected(Inkscape::NodePath::Node *node, gboolean selected);
+static Inkscape::NodePath::Node *sp_nodepath_set_node_type(Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeType type);
+
/* Adjust handle placement, if the node or the other handle is moved */
static void sp_node_adjust_handle(Inkscape::NodePath::Node *node, gint which_adjust);
static void sp_node_adjust_handles(Inkscape::NodePath::Node *node);
@@ -134,7 +136,7 @@ static Inkscape::NodePath::NodeSide *sp_node_opposite_side(Inkscape::NodePath::N
static NRPathcode sp_node_path_code_from_side(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeSide *me);
// active_node indicates mouseover node
-static Inkscape::NodePath::Node *active_node = NULL;
+Inkscape::NodePath::Node * Inkscape::NodePath::Path::active_node = NULL;
/**
* \brief Creates new nodepath from item
@@ -743,8 +745,10 @@ static Inkscape::NodePath::Node *sp_nodepath_line_add_node(Inkscape::NodePath::N
&start->pos, &start->pos, &start->n.pos);
sp_nodepath_line_midpoint(newnode, end, t);
+ sp_node_adjust_handles(start);
sp_node_update_handles(start);
sp_node_update_handles(newnode);
+ sp_node_adjust_handles(end);
sp_node_update_handles(end);
return newnode;
@@ -840,12 +844,14 @@ static void sp_nodepath_set_line_type(Inkscape::NodePath::Node *end, NRPathcode
end->code = code;
if (code == NR_LINETO) {
- if (start->code == NR_LINETO) start->type =Inkscape::NodePath::NODE_CUSP;
+ if (start->code == NR_LINETO) {
+ sp_nodepath_set_node_type (start, Inkscape::NodePath::NODE_CUSP);
+ }
if (end->n.other) {
- if (end->n.other->code == NR_LINETO) end->type =Inkscape::NodePath::NODE_CUSP;
+ if (end->n.other->code == NR_LINETO) {
+ sp_nodepath_set_node_type (end, Inkscape::NodePath::NODE_CUSP);
+ }
}
- sp_node_adjust_handle(start, -1);
- sp_node_adjust_handle(end, 1);
} else {
NR::Point delta = end->pos - start->pos;
start->n.pos = start->pos + delta / 3;
for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
- Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAP_POINT, n->pos + delta, NULL);
+ Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAP_POINT, n->pos + delta, n->subpath->nodepath->path);
if (s.getDistance() < best) {
best = s.getDistance();
best_pt = s.getPoint() - n->pos;
@@ -2891,10 +2897,10 @@ static gboolean node_event(SPKnot *knot, GdkEvent *event, Inkscape::NodePath::No
gboolean ret = FALSE;
switch (event->type) {
case GDK_ENTER_NOTIFY:
- active_node = n;
+ Inkscape::NodePath::Path::active_node = n;
break;
case GDK_LEAVE_NOTIFY:
- active_node = NULL;
+ Inkscape::NodePath::Path::active_node = NULL;
break;
case GDK_SCROLL:
if ((event->scroll.state & GDK_CONTROL_MASK) && !(event->scroll.state & GDK_SHIFT_MASK)) { // linearly
Inkscape::NodePath::Path *np;
// there is no way to verify nodes so set active_node to nil when deleting!!
- if (active_node == NULL) return FALSE;
+ if (Inkscape::NodePath::Path::active_node == NULL) return FALSE;
if ((event->type == GDK_KEY_PRESS) && !(event->key.state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))) {
gint ret = FALSE;
switch (get_group0_keyval (&event->key)) {
/// \todo FIXME: this does not seem to work, the keys are stolen by tool contexts!
case GDK_BackSpace:
- np = active_node->subpath->nodepath;
- sp_nodepath_node_destroy(active_node);
+ np = Inkscape::NodePath::Path::active_node->subpath->nodepath;
+ sp_nodepath_node_destroy(Inkscape::NodePath::Path::active_node);
sp_nodepath_update_repr(np, _("Delete node"));
- active_node = NULL;
+ Inkscape::NodePath::Path::active_node = NULL;
ret = TRUE;
break;
case GDK_c:
- sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_CUSP);
+ sp_nodepath_set_node_type(Inkscape::NodePath::Path::active_node,Inkscape::NodePath::NODE_CUSP);
ret = TRUE;
break;
case GDK_s:
- sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_SMOOTH);
+ sp_nodepath_set_node_type(Inkscape::NodePath::Path::active_node,Inkscape::NodePath::NODE_SMOOTH);
ret = TRUE;
break;
case GDK_y:
- sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_SYMM);
+ sp_nodepath_set_node_type(Inkscape::NodePath::Path::active_node,Inkscape::NodePath::NODE_SYMM);
ret = TRUE;
break;
case GDK_b:
- sp_nodepath_node_break(active_node);
+ sp_nodepath_node_break(Inkscape::NodePath::Path::active_node);
ret = TRUE;
break;
}
@@ -3446,12 +3452,14 @@ static void node_handle_moved(SPKnot *knot, NR::Point *p, guint state, gpointer
}
if (( n->type !=Inkscape::NodePath::NODE_CUSP || (state & GDK_SHIFT_MASK))
- && rme.a != HUGE_VAL && rnew.a != HUGE_VAL && fabs(rme.a - rnew.a) > 0.001) {
+ && rme.a != HUGE_VAL && rnew.a != HUGE_VAL && (fabs(rme.a - rnew.a) > 0.001 || n->type ==Inkscape::NodePath::NODE_SYMM)) {
// rotate the other handle correspondingly, if both old and new angles exist and are not the same
rother.a += rnew.a - rme.a;
other->pos = NR::Point(rother) + n->pos;
- sp_ctrlline_set_coords(SP_CTRLLINE(other->line), n->pos, other->pos);
- sp_knot_set_position(other->knot, &other->pos, 0);
+ if (other->knot) {
+ sp_ctrlline_set_coords(SP_CTRLLINE(other->line), n->pos, other->pos);
+ sp_knot_moveto(other->knot, &other->pos);
+ }
}
me->pos = NR::Point(rnew) + n->pos;
@@ -3505,6 +3513,16 @@ static gboolean node_handle_event(SPKnot *knot, GdkEvent *event,Inkscape::NodePa
break;
}
break;
+ case GDK_ENTER_NOTIFY:
+ // we use an experimentally determined threshold that seems to work fine
+ if (NR::L2(n->pos - knot->pos) < 0.75)
+ Inkscape::NodePath::Path::active_node = n;
+ break;
+ case GDK_LEAVE_NOTIFY:
+ // we use an experimentally determined threshold that seems to work fine
+ if (NR::L2(n->pos - knot->pos) < 0.75)
+ Inkscape::NodePath::Path::active_node = NULL;
+ break;
default:
break;
}
@@ -3795,11 +3813,11 @@ void sp_nodepath_selected_nodes_scale_screen(Inkscape::NodePath::Path *nodepath,
/**
* Flip selected nodes horizontally/vertically.
*/
-void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis)
+void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis, NR::Maybe<NR::Point> center)
{
if (!nodepath || !nodepath->selected) return;
- if (g_list_length(nodepath->selected) == 1) {
+ if (g_list_length(nodepath->selected) == 1 && !center) {
// flip handles of the single selected node
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) nodepath->selected->data;
double temp = n->p.pos[axis];
box.expandTo (n->pos); // contain all selected nodes
}
+ if (!center) {
+ center = box.midpoint();
+ }
NR::Matrix t =
- NR::Matrix (NR::translate(-box.midpoint())) *
+ NR::Matrix (NR::translate(- *center)) *
NR::Matrix ((axis == NR::X)? NR::scale(-1, 1) : NR::scale(1, -1)) *
- NR::Matrix (NR::translate(box.midpoint()));
+ NR::Matrix (NR::translate(*center));
for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;