diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index c28ca7b80361f65cbb121f317cf2b594b5ecd6f8..26078ea92d30bb6accf1d635ffc9c42c658d8ae8 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
/// evil evil evil. FIXME: conflict of two different Path classes!
/// There is a conflict in the namespace between two classes named Path.
/// #include "sp-flowtext.h"
-/// #include "sp-flowregion.h"
+/// #include "sp-flowregion.h"
#define SP_TYPE_FLOWREGION (sp_flowregion_get_type ())
#define SP_IS_FLOWREGION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWREGION))
static void node_ctrl_ungrabbed(SPKnot *knot, guint state, gpointer data);
static gboolean node_ctrl_request(SPKnot *knot, NR::Point *p, guint state, gpointer data);
static void node_ctrl_moved(SPKnot *knot, NR::Point *p, guint state, gpointer data);
+static gboolean node_ctrl_event(SPKnot *knot, GdkEvent *event, Inkscape::NodePath::Node *n);
/* Constructors and destructors */
@@ -131,7 +132,7 @@ static NRPathcode sp_node_path_code_from_side(Inkscape::NodePath::Node *node,Ink
static Inkscape::NodePath::Node *active_node = NULL;
/**
- * \brief Creates new nodepath from item
+ * \brief Creates new nodepath from item
*/
Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPItem *item)
{
np->nodeContext = NULL; //Let the context that makes this set it
// we need to update item's transform from the repr here,
- // because they may be out of sync when we respond
+ // because they may be out of sync when we respond
// to a change in repr by regenerating nodepath --bb
sp_object_read_attr(SP_OBJECT(item), "transform");
/**
* Clean up a nodepath after editing.
- *
+ *
* Currently we are deleting trivial subpaths.
*/
static void sp_nodepath_cleanup(Inkscape::NodePath::Path *nodepath)
/**
- * \brief Returns true if the argument nodepath and the d attribute in
- * its repr do not match.
+ * \brief Returns true if the argument nodepath and the d attribute in
+ * its repr do not match.
+ *
+ * This may happen if repr was changed in, e.g., XML editor or by undo.
*
- * This may happen if repr was changed in, e.g., XML editor or by undo.
- *
* \todo
* UGLY HACK, think how we can eliminate it.
*/
@@ -307,7 +308,7 @@ gboolean nodepath_repr_d_changed(Inkscape::NodePath::Path *np, char const *newd)
gboolean ret;
if (attr_d && svgpath)
ret = strcmp(attr_d, svgpath);
- else
+ else
ret = TRUE;
g_free(svgpath);
@@ -317,8 +318,8 @@ gboolean nodepath_repr_d_changed(Inkscape::NodePath::Path *np, char const *newd)
}
/**
- * \brief Returns true if the argument nodepath and the sodipodi:nodetypes
- * attribute in its repr do not match.
+ * \brief Returns true if the argument nodepath and the sodipodi:nodetypes
+ * attribute in its repr do not match.
*
* This may happen if repr was changed in, e.g., the XML editor or by undo.
*/
@@ -681,7 +682,7 @@ static void sp_nodepath_line_midpoint(Inkscape::NodePath::Node *new_path,Inkscap
}
/**
- * Adds new node on direct line between two nodes, activates handles of all
+ * Adds new node on direct line between two nodes, activates handles of all
* three nodes.
*/
static Inkscape::NodePath::Node *sp_nodepath_line_add_node(Inkscape::NodePath::Node *end, gdouble t)
@@ -834,9 +835,13 @@ static Inkscape::NodePath::Node *sp_nodepath_set_node_type(Inkscape::NodePath::N
node->type = type;
if (node->type == Inkscape::NodePath::NODE_CUSP) {
- g_object_set(G_OBJECT(node->knot), "shape", SP_KNOT_SHAPE_DIAMOND, "size", 9, NULL);
+ node->knot->setShape (SP_KNOT_SHAPE_DIAMOND);
+ node->knot->setSize (node->selected? 11 : 9);
+ sp_knot_update_ctrl(node->knot);
} else {
- g_object_set(G_OBJECT(node->knot), "shape", SP_KNOT_SHAPE_SQUARE, "size", 7, NULL);
+ node->knot->setShape (SP_KNOT_SHAPE_SQUARE);
+ node->knot->setSize (node->selected? 9 : 7);
+ sp_knot_update_ctrl(node->knot);
}
sp_node_adjust_knots(node);
@@ -847,7 +852,7 @@ static Inkscape::NodePath::Node *sp_nodepath_set_node_type(Inkscape::NodePath::N
}
/**
- * Same as sp_nodepath_set_node_type(), but also converts, if necessary,
+ * Same as sp_nodepath_set_node_type(), but also converts, if necessary,
* adjacent segments from lines to curves.
*/
void sp_nodepath_convert_node_type(Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeType type)
@@ -859,7 +864,7 @@ void sp_nodepath_convert_node_type(Inkscape::NodePath::Node *node, Inkscape::Nod
NR::Point delta;
if (node->n.other != NULL)
delta = node->n.other->pos - node->p.other->pos;
- else
+ else
delta = node->pos - node->p.other->pos;
node->p.pos = node->pos - delta / 4;
sp_node_ensure_ctrls(node);
@@ -871,7 +876,7 @@ void sp_nodepath_convert_node_type(Inkscape::NodePath::Node *node, Inkscape::Nod
NR::Point delta;
if (node->p.other != NULL)
delta = node->p.other->pos - node->n.other->pos;
- else
+ else
delta = node->pos - node->n.other->pos;
node->n.pos = node->pos - delta / 4;
sp_node_ensure_ctrls(node);
}
}
+/** If they don't yet exist, creates knot and line for the given side of the node */
+static void sp_node_ensure_knot_exists (SPDesktop *desktop, Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeSide *side)
+{
+ if (!side->knot) {
+ side->knot = sp_knot_new(desktop, _("<b>Node handle</b>: drag to shape the curve; with <b>Ctrl</b> to snap angle; with <b>Alt</b> to lock length; with <b>Shift</b> to rotate both handles"));
+
+ side->knot->setShape (SP_KNOT_SHAPE_CIRCLE);
+ side->knot->setSize (7);
+ side->knot->setAnchor (GTK_ANCHOR_CENTER);
+ side->knot->setFill(KNOT_FILL, KNOT_FILL_HI, KNOT_FILL_HI);
+ side->knot->setStroke(KNOT_STROKE, KNOT_STROKE_HI, KNOT_STROKE_HI);
+ sp_knot_update_ctrl(side->knot);
+
+ g_signal_connect(G_OBJECT(side->knot), "clicked", G_CALLBACK(node_ctrl_clicked), node);
+ g_signal_connect(G_OBJECT(side->knot), "grabbed", G_CALLBACK(node_ctrl_grabbed), node);
+ g_signal_connect(G_OBJECT(side->knot), "ungrabbed", G_CALLBACK(node_ctrl_ungrabbed), node);
+ g_signal_connect(G_OBJECT(side->knot), "request", G_CALLBACK(node_ctrl_request), node);
+ g_signal_connect(G_OBJECT(side->knot), "moved", G_CALLBACK(node_ctrl_moved), node);
+ g_signal_connect(G_OBJECT(side->knot), "event", G_CALLBACK(node_ctrl_event), node);
+ }
+
+ if (!side->line) {
+ side->line = sp_canvas_item_new(SP_DT_CONTROLS(desktop),
+ SP_TYPE_CTRLLINE, NULL);
+ }
+}
+
/**
* Ensure knot on side of node is visible/invisible.
*/
@@ -1004,18 +1036,31 @@ static void sp_node_ensure_knot(Inkscape::NodePath::Node *node, gint which, gboo
show_knot = show_knot && (code == NR_CURVETO) && (NR::L2(side->pos - node->pos) > 1e-6);
if (show_knot) {
- if (!SP_KNOT_IS_VISIBLE(side->knot)) {
+ if (!side->knot) {
+ sp_node_ensure_knot_exists(node->subpath->nodepath->desktop, node, side);
+ // Just created, so we shouldn't fire the node_moved callback - instead set the knot position directly
+ side->knot->pos = side->pos;
+ if (side->knot->item) SP_CTRL(side->knot->item)->moveto(side->pos);
+ sp_ctrlline_set_coords(SP_CTRLLINE(side->line), node->pos, side->pos);
sp_knot_show(side->knot);
+ } else {
+ if (side->knot->pos != side->pos) { // only if it's really moved
+ sp_knot_set_position(side->knot, &side->pos, 0); // this will set coords of the line as well
+ }
+ if (!SP_KNOT_IS_VISIBLE(side->knot)) {
+ sp_knot_show(side->knot);
+ }
}
-
- sp_knot_set_position(side->knot, &side->pos, 0);
sp_canvas_item_show(side->line);
-
} else {
- if (SP_KNOT_IS_VISIBLE(side->knot)) {
- sp_knot_hide(side->knot);
+ if (side->knot) {
+ if (SP_KNOT_IS_VISIBLE(side->knot)) {
+ sp_knot_hide(side->knot);
+ }
+ }
+ if (side->line) {
+ sp_canvas_item_hide(side->line);
}
- sp_canvas_item_hide(side->line);
}
}
@@ -1225,11 +1270,12 @@ sp_nodepath_select_segment_near_point(SPItem * item, NR::Point p, bool toggle)
Inkscape::NodePath::Node *e = sp_nodepath_get_node_by_index(position.piece);
gboolean force = FALSE;
- if (!(e->selected && e->p.other->selected)) {
+ if (!(e->selected && (!e->p.other || e->p.other->selected))) {
force = TRUE;
- }
+ }
sp_nodepath_node_select(e, (gboolean) toggle, force);
- sp_nodepath_node_select(e->p.other, TRUE, force);
+ if (e->p.other)
+ sp_nodepath_node_select(e->p.other, TRUE, force);
sp_nodepath_ensure_ctrls(nodepath);
//find segment to split
Inkscape::NodePath::Node *e = sp_nodepath_get_node_by_index(position.piece);
-
+
//don't know why but t seems to flip for lines
if (sp_node_path_code_from_side(e, sp_node_get_side(e, -1)) == NR_LINETO) {
position.t = 1.0 - position.t;
* cf. app/vectors/gimpbezierstroke.c, gimp_bezier_stroke_point_move_relative()
*/
void
-sp_nodepath_curve_drag(Inkscape::NodePath::Node * e, double t, NR::Point delta, char * key)
+sp_nodepath_curve_drag(Inkscape::NodePath::Node * e, double t, NR::Point delta, char * key)
{
/* feel good is an arbitrary parameter that distributes the delta between handles
* if t of the drag point is less than 1/6 distance form the endpoint only
@@ -1290,7 +1336,7 @@ sp_nodepath_curve_drag(Inkscape::NodePath::Node * e, double t, NR::Point delta,
feel_good = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
else
feel_good = 1;
-
+
//if we're dragging a line convert it to a curve
if (sp_node_path_code_from_side(e, sp_node_get_side(e, -1))==NR_LINETO) {
sp_nodepath_set_line_type(e, NR_CURVETO);
@@ -1810,21 +1856,15 @@ static void sp_node_set_selected(Inkscape::NodePath::Node *node, gboolean select
node->selected = selected;
if (selected) {
- g_object_set(G_OBJECT(node->knot),
- "fill", NODE_FILL_SEL,
- "fill_mouseover", NODE_FILL_SEL_HI,
- "stroke", NODE_STROKE_SEL,
- "stroke_mouseover", NODE_STROKE_SEL_HI,
- "size", (node->type == Inkscape::NodePath::NODE_CUSP) ? 11 : 9,
- NULL);
+ node->knot->setSize ((node->type == Inkscape::NodePath::NODE_CUSP) ? 11 : 9);
+ node->knot->setFill(NODE_FILL_SEL, NODE_FILL_SEL_HI, NODE_FILL_SEL_HI);
+ node->knot->setStroke(NODE_STROKE_SEL, NODE_STROKE_SEL_HI, NODE_STROKE_SEL_HI);
+ sp_knot_update_ctrl(node->knot);
} else {
- g_object_set(G_OBJECT(node->knot),
- "fill", NODE_FILL,
- "fill_mouseover", NODE_FILL_HI,
- "stroke", NODE_STROKE,
- "stroke_mouseover", NODE_STROKE_HI,
- "size", (node->type == Inkscape::NodePath::NODE_CUSP) ? 9 : 7,
- NULL);
+ node->knot->setSize ((node->type == Inkscape::NodePath::NODE_CUSP) ? 9 : 7);
+ node->knot->setFill(NODE_FILL, NODE_FILL_HI, NODE_FILL_HI);
+ node->knot->setStroke(NODE_STROKE, NODE_STROKE_HI, NODE_STROKE_HI);
+ sp_knot_update_ctrl(node->knot);
}
sp_node_ensure_ctrls(node);
@@ -1845,7 +1885,7 @@ static void sp_nodepath_node_select(Inkscape::NodePath::Node *node, gboolean inc
if (incremental) {
if (override) {
if (!g_list_find(nodepath->selected, node)) {
- nodepath->selected = g_list_append(nodepath->selected, node);
+ nodepath->selected = g_list_prepend(nodepath->selected, node);
}
sp_node_set_selected(node, TRUE);
} else { // toggle
@@ -1854,13 +1894,13 @@ static void sp_nodepath_node_select(Inkscape::NodePath::Node *node, gboolean inc
nodepath->selected = g_list_remove(nodepath->selected, node);
} else {
g_assert(!g_list_find(nodepath->selected, node));
- nodepath->selected = g_list_append(nodepath->selected, node);
+ nodepath->selected = g_list_prepend(nodepath->selected, node);
}
sp_node_set_selected(node, !node->selected);
}
} else {
sp_nodepath_deselect(nodepath);
- nodepath->selected = g_list_append(nodepath->selected, node);
+ nodepath->selected = g_list_prepend(nodepath->selected, node);
sp_node_set_selected(node, TRUE);
}
}
}
-/**
- * If nothing selected, does the same as sp_nodepath_select_all();
- * otherwise selects/inverts all nodes in all subpaths that have selected nodes
- * (i.e., similar to "select all in layer", with the "selected" subpaths
+/**
+ * If nothing selected, does the same as sp_nodepath_select_all();
+ * otherwise selects/inverts all nodes in all subpaths that have selected nodes
+ * (i.e., similar to "select all in layer", with the "selected" subpaths
* being treated as "layers" in the path).
*/
void
@@ -1939,7 +1979,7 @@ sp_nodepath_select_all_from_subpath(Inkscape::NodePath::Path *nodepath, bool inv
}
/**
- * \brief Select the node after the last selected; if none is selected,
+ * \brief Select the node after the last selected; if none is selected,
* select the first within path.
*/
void sp_nodepath_select_next(Inkscape::NodePath::Path *nodepath)
}
/**
- * \brief Select the node before the first selected; if none is selected,
+ * \brief Select the node before the first selected; if none is selected,
* select the last within path
*/
void sp_nodepath_select_prev(Inkscape::NodePath::Path *nodepath)
@@ -2165,7 +2205,6 @@ static void sp_node_adjust_knot(Inkscape::NodePath::Node *node, gint which_adjus
if (linelen < 1e-18) return;
me->pos = node->pos + (len / linelen)*delta;
- sp_knot_set_position(me->knot, &me->pos, 0);
sp_node_ensure_ctrls(node);
return;
@@ -2174,7 +2213,6 @@ static void sp_node_adjust_knot(Inkscape::NodePath::Node *node, gint which_adjus
if (node->type == Inkscape::NodePath::NODE_SYMM) {
me->pos = 2 * node->pos - other->pos;
- sp_knot_set_position(me->knot, &me->pos, 0);
sp_node_ensure_ctrls(node);
return;
@@ -2188,7 +2226,6 @@ static void sp_node_adjust_knot(Inkscape::NodePath::Node *node, gint which_adjus
if (otherlen < 1e-18) return;
me->pos = node->pos - (len / otherlen) * delta;
- sp_knot_set_position(me->knot, &me->pos, 0);
sp_node_ensure_ctrls(node);
}
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data;
// If either (Shift and some handle retracted), or (we're already dragging out a handle)
- if (((state & GDK_SHIFT_MASK) && ((n->n.other && n->n.pos == n->pos) || (n->p.other && n->p.pos == n->pos))) || n->dragging_out) {
+ if (((state & GDK_SHIFT_MASK) && ((n->n.other && n->n.pos == n->pos) || (n->p.other && n->p.pos == n->pos))) || n->dragging_out) {
NR::Point mouse = (*p);
if (opposite->pos != n->pos) {
mouse = n->pos - NR::L2(mouse - n->pos) * NR::unit_vector(opposite->pos - n->pos);
}
+
+ // knots might not be created yet!
+ sp_node_ensure_knot_exists (n->subpath->nodepath->desktop, n, n->dragging_out);
+ sp_node_ensure_knot_exists (n->subpath->nodepath->desktop, n, opposite);
}
// pass this on to the handle-moved callback
@@ -2949,7 +2990,7 @@ void sp_nodepath_selected_nodes_rotate(Inkscape::NodePath::Path *nodepath, gdoub
Inkscape::NodePath::Node *n0 = (Inkscape::NodePath::Node *) nodepath->selected->data;
NR::Rect box (n0->pos, n0->pos); // originally includes the first selected node
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
box.expandTo (n->pos); // contain all selected nodes
}
@@ -2964,12 +3005,12 @@ void sp_nodepath_selected_nodes_rotate(Inkscape::NodePath::Path *nodepath, gdoub
rot = angle;
}
- NR::Matrix t =
- NR::Matrix (NR::translate(-box.midpoint())) *
- NR::Matrix (NR::rotate(rot)) *
+ NR::Matrix t =
+ NR::Matrix (NR::translate(-box.midpoint())) *
+ NR::Matrix (NR::rotate(rot)) *
NR::Matrix (NR::translate(box.midpoint()));
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
n->pos *= t;
n->n.pos *= t;
@@ -3001,14 +3042,14 @@ static void node_scale_one (Inkscape::NodePath::Node *n, gdouble grow, int which
} else if (!n->p.other) {
me = &(n->n);
other = &(n->p);
- if (n->n.other)
+ if (n->n.other)
n->n.other->code = NR_CURVETO;
} else {
if (which > 0) { // right handle
if (xn > xp) {
me = &(n->n);
other = &(n->p);
- if (n->n.other)
+ if (n->n.other)
n->n.other->code = NR_CURVETO;
} else {
me = &(n->p);
@@ -3019,7 +3060,7 @@ static void node_scale_one (Inkscape::NodePath::Node *n, gdouble grow, int which
if (xn <= xp) {
me = &(n->n);
other = &(n->p);
- if (n->n.other)
+ if (n->n.other)
n->n.other->code = NR_CURVETO;
} else {
me = &(n->p);
@@ -3031,7 +3072,7 @@ static void node_scale_one (Inkscape::NodePath::Node *n, gdouble grow, int which
other = &(n->p);
both = true;
n->code = NR_CURVETO;
- if (n->n.other)
+ if (n->n.other)
n->n.other->code = NR_CURVETO;
}
}
@@ -3082,19 +3123,19 @@ void sp_nodepath_selected_nodes_scale(Inkscape::NodePath::Path *nodepath, gdoubl
Inkscape::NodePath::Node *n0 = (Inkscape::NodePath::Node *) nodepath->selected->data;
NR::Rect box (n0->pos, n0->pos); // originally includes the first selected node
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
box.expandTo (n->pos); // contain all selected nodes
}
double scale = (box.maxExtent() + grow)/box.maxExtent();
- NR::Matrix t =
- NR::Matrix (NR::translate(-box.midpoint())) *
- NR::Matrix (NR::scale(scale, scale)) *
+ NR::Matrix t =
+ NR::Matrix (NR::translate(-box.midpoint())) *
+ NR::Matrix (NR::scale(scale, scale)) *
NR::Matrix (NR::translate(box.midpoint()));
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
n->pos *= t;
n->n.pos *= t;
Inkscape::NodePath::Node *n0 = (Inkscape::NodePath::Node *) nodepath->selected->data;
NR::Rect box (n0->pos, n0->pos); // originally includes the first selected node
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
box.expandTo (n->pos); // contain all selected nodes
}
- NR::Matrix t =
- NR::Matrix (NR::translate(-box.midpoint())) *
- NR::Matrix ((axis == NR::X)? NR::scale(-1, 1) : NR::scale(1, -1)) *
+ NR::Matrix t =
+ NR::Matrix (NR::translate(-box.midpoint())) *
+ NR::Matrix ((axis == NR::X)? NR::scale(-1, 1) : NR::scale(1, -1)) *
NR::Matrix (NR::translate(box.midpoint()));
- for (GList *l = nodepath->selected; l != NULL; l = l->next) {
+ for (GList *l = nodepath->selected; l != NULL; l = l->next) {
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
n->pos *= t;
n->n.pos *= t;
@@ -3252,7 +3293,7 @@ static void sp_nodepath_subpath_open(Inkscape::NodePath::SubPath *sp,Inkscape::N
* Returns area in triangle given by points; may be negative.
*/
inline double
-triangle_area (NR::Point p1, NR::Point p2, NR::Point p3)
+triangle_area (NR::Point p1, NR::Point p2, NR::Point p3)
{
return (p1[NR::X]*p2[NR::Y] + p1[NR::Y]*p3[NR::X] + p2[NR::X]*p3[NR::Y] - p2[NR::Y]*p3[NR::X] - p1[NR::Y]*p2[NR::X] - p1[NR::X]*p3[NR::Y]);
}
@@ -3304,7 +3345,7 @@ sp_nodepath_node_new(Inkscape::NodePath::SubPath *sp, Inkscape::NodePath::Node *
Inkscape::NodePath::Node *prev;
if (next) {
- g_assert(g_list_find(sp->nodes, next));
+ //g_assert(g_list_find(sp->nodes, next));
prev = next->p.other;
} else {
prev = sp->last;
@@ -3323,20 +3364,15 @@ sp_nodepath_node_new(Inkscape::NodePath::SubPath *sp, Inkscape::NodePath::Node *
n->p.other = prev;
n->n.other = next;
- n->knot = sp_knot_new(sp->nodepath->desktop);
+ n->knot = sp_knot_new(sp->nodepath->desktop, _("<b>Node</b>: drag to edit the path; with <b>Ctrl</b> to snap to horizontal/vertical; with <b>Ctrl+Alt</b> to snap to handles' directions"));
sp_knot_set_position(n->knot, pos, 0);
- g_object_set(G_OBJECT(n->knot),
- "anchor", GTK_ANCHOR_CENTER,
- "fill", NODE_FILL,
- "fill_mouseover", NODE_FILL_HI,
- "stroke", NODE_STROKE,
- "stroke_mouseover", NODE_STROKE_HI,
- "tip", _("<b>Node</b>: drag to edit the path; with <b>Ctrl</b> to snap to horizontal/vertical; with <b>Ctrl+Alt</b> to snap to handles' directions"),
- NULL);
- if (n->type == Inkscape::NodePath::NODE_CUSP)
- g_object_set(G_OBJECT(n->knot), "shape", SP_KNOT_SHAPE_DIAMOND, "size", 9, NULL);
- else
- g_object_set(G_OBJECT(n->knot), "shape", SP_KNOT_SHAPE_SQUARE, "size", 7, NULL);
+
+ n->knot->setShape ((n->type == Inkscape::NodePath::NODE_CUSP)? SP_KNOT_SHAPE_DIAMOND : SP_KNOT_SHAPE_SQUARE);
+ n->knot->setSize ((n->type == Inkscape::NodePath::NODE_CUSP)? 9 : 7);
+ n->knot->setAnchor (GTK_ANCHOR_CENTER);
+ n->knot->setFill(NODE_FILL, NODE_FILL_HI, NODE_FILL_HI);
+ n->knot->setStroke(NODE_STROKE, NODE_STROKE_HI, NODE_STROKE_HI);
+ sp_knot_update_ctrl(n->knot);
g_signal_connect(G_OBJECT(n->knot), "event", G_CALLBACK(node_event), n);
g_signal_connect(G_OBJECT(n->knot), "clicked", G_CALLBACK(node_clicked), n);
@@ -3345,52 +3381,11 @@ sp_nodepath_node_new(Inkscape::NodePath::SubPath *sp, Inkscape::NodePath::Node *
g_signal_connect(G_OBJECT(n->knot), "request", G_CALLBACK(node_request), n);
sp_knot_show(n->knot);
- n->p.knot = sp_knot_new(sp->nodepath->desktop);
- sp_knot_set_position(n->p.knot, ppos, 0);
- g_object_set(G_OBJECT(n->p.knot),
- "shape", SP_KNOT_SHAPE_CIRCLE,
- "size", 7,
- "anchor", GTK_ANCHOR_CENTER,
- "fill", KNOT_FILL,
- "fill_mouseover", KNOT_FILL_HI,
- "stroke", KNOT_STROKE,
- "stroke_mouseover", KNOT_STROKE_HI,
- "tip", _("<b>Node handle</b>: drag to shape the curve; with <b>Ctrl</b> to snap angle; with <b>Alt</b> to lock length; with <b>Shift</b> to rotate both handles"),
- NULL);
- g_signal_connect(G_OBJECT(n->p.knot), "clicked", G_CALLBACK(node_ctrl_clicked), n);
- g_signal_connect(G_OBJECT(n->p.knot), "grabbed", G_CALLBACK(node_ctrl_grabbed), n);
- g_signal_connect(G_OBJECT(n->p.knot), "ungrabbed", G_CALLBACK(node_ctrl_ungrabbed), n);
- g_signal_connect(G_OBJECT(n->p.knot), "request", G_CALLBACK(node_ctrl_request), n);
- g_signal_connect(G_OBJECT(n->p.knot), "moved", G_CALLBACK(node_ctrl_moved), n);
- g_signal_connect(G_OBJECT(n->p.knot), "event", G_CALLBACK(node_ctrl_event), n);
-
- sp_knot_hide(n->p.knot);
- n->p.line = sp_canvas_item_new(SP_DT_CONTROLS(n->subpath->nodepath->desktop),
- SP_TYPE_CTRLLINE, NULL);
- sp_canvas_item_hide(n->p.line);
-
- n->n.knot = sp_knot_new(sp->nodepath->desktop);
- sp_knot_set_position(n->n.knot, npos, 0);
- g_object_set(G_OBJECT(n->n.knot),
- "shape", SP_KNOT_SHAPE_CIRCLE,
- "size", 7,
- "anchor", GTK_ANCHOR_CENTER,
- "fill", KNOT_FILL,
- "fill_mouseover", KNOT_FILL_HI,
- "stroke", KNOT_STROKE,
- "stroke_mouseover", KNOT_STROKE_HI,
- "tip", _("<b>Node handle</b>: drag to shape the curve; with <b>Ctrl</b> to snap angle; with <b>Alt</b> to lock length; with <b>Shift</b> to rotate the opposite handle in sync"),
- NULL);
- g_signal_connect(G_OBJECT(n->n.knot), "clicked", G_CALLBACK(node_ctrl_clicked), n);
- g_signal_connect(G_OBJECT(n->n.knot), "grabbed", G_CALLBACK(node_ctrl_grabbed), n);
- g_signal_connect(G_OBJECT(n->n.knot), "ungrabbed", G_CALLBACK(node_ctrl_ungrabbed), n);
- g_signal_connect(G_OBJECT(n->n.knot), "request", G_CALLBACK(node_ctrl_request), n);
- g_signal_connect(G_OBJECT(n->n.knot), "moved", G_CALLBACK(node_ctrl_moved), n);
- g_signal_connect(G_OBJECT(n->n.knot), "event", G_CALLBACK(node_ctrl_event), n);
- sp_knot_hide(n->n.knot);
- n->n.line = sp_canvas_item_new(SP_DT_CONTROLS(n->subpath->nodepath->desktop),
- SP_TYPE_CTRLLINE, NULL);
- sp_canvas_item_hide(n->n.line);
+ // We only create side knots and lines on demand
+ n->p.knot = NULL;
+ n->p.line = NULL;
+ n->n.knot = NULL;
+ n->n.line = NULL;
sp->nodes = g_list_prepend(sp->nodes, n);
g_assert(node);
g_assert(node->subpath);
g_assert(SP_IS_KNOT(node->knot));
- g_assert(SP_IS_KNOT(node->p.knot));
- g_assert(SP_IS_KNOT(node->n.knot));
- g_assert(g_list_find(node->subpath->nodes, node));
+// g_assert(g_list_find(node->subpath->nodes, node));
Inkscape::NodePath::SubPath *sp = node->subpath;
node->subpath->nodes = g_list_remove(node->subpath->nodes, node);
g_object_unref(G_OBJECT(node->knot));
- g_object_unref(G_OBJECT(node->p.knot));
- g_object_unref(G_OBJECT(node->n.knot));
+ if (node->p.knot)
+ g_object_unref(G_OBJECT(node->p.knot));
+ if (node->n.knot)
+ g_object_unref(G_OBJECT(node->n.knot));
- gtk_object_destroy(GTK_OBJECT(node->p.line));
- gtk_object_destroy(GTK_OBJECT(node->n.line));
+ if (node->p.line)
+ gtk_object_destroy(GTK_OBJECT(node->p.line));
+ if (node->n.line)
+ gtk_object_destroy(GTK_OBJECT(node->n.line));
if (sp->nodes) { // there are others nodes on the subpath
if (sp->closed) {
@@ -3513,11 +3510,11 @@ static NRPathcode sp_node_path_code_from_side(Inkscape::NodePath::Node *node,Ink
/**
* Call sp_nodepath_line_add_node() at t on the segment denoted by piece
*/
-Inkscape::NodePath::Node *
+Inkscape::NodePath::Node *
sp_nodepath_get_node_by_index(int index)
{
Inkscape::NodePath::Node *e = NULL;
-
+
Inkscape::NodePath::Path *nodepath = sp_nodepath_current();
if (!nodepath) {
return e;
//find segment
for (GList *l = nodepath->subpaths; l ; l=l->next) {
-
+
Inkscape::NodePath::SubPath *sp = (Inkscape::NodePath::SubPath *)l->data;
int n = g_list_length(sp->nodes);
if (sp->closed) {
n++;
- }
-
+ }
+
//if the piece belongs to this subpath grab it
//otherwise move onto the next subpath
if (index < n) {
}
}
}
-
+
return e;
}