summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2007-10-20 15:43:07 +0000
committerjohanengelen <johanengelen@users.sourceforge.net>2007-10-20 15:43:07 +0000
commit82a86b15d8cdd5040d65fa27ea59237d6e7c7ed3 (patch)
treef2607d956b1ce9c96bf57193b77913e074039ea9 /src
parentAdding config option to block use of libpoppler-cairo (for misdetected situta... (diff)
downloadinkscape-82a86b15d8cdd5040d65fa27ea59237d6e7c7ed3.tar.gz
inkscape-82a86b15d8cdd5040d65fa27ea59237d6e7c7ed3.zip
LPE: add on-canvas editing of path parameters!
(bzr r3934)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect.cpp8
-rw-r--r--src/live_effects/effect.h3
-rw-r--r--src/live_effects/lpeobject.cpp2
-rw-r--r--src/live_effects/parameter/path.cpp22
-rw-r--r--src/live_effects/parameter/path.h6
-rw-r--r--src/nodepath.cpp49
-rw-r--r--src/nodepath.h6
-rw-r--r--src/shape-editor.cpp22
-rw-r--r--src/shape-editor.h2
9 files changed, 75 insertions, 45 deletions
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 1c0f5318f..cfabc88b4 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -186,14 +186,15 @@ Effect::readallParameters(Inkscape::XML::Node * repr)
const gchar * key = (*it).first.c_str();
const gchar * value = repr->attribute(key);
if(value) {
- setParameter(repr, key, NULL, value);
+ setParameter(key, value);
}
it++;
}
}
+/* This function does not and SHOULD NOT write to XML */
void
-Effect::setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar * old_value, const gchar * new_value)
+Effect::setParameter(const gchar * key, const gchar * new_value)
{
Glib::ustring stringkey(key);
@@ -203,9 +204,6 @@ Effect::setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar
bool accepted = it->second->param_readSVGValue(new_value);
if (!accepted) {
g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key);
- // change was not accepted, so change it back.
- // think: can this backfire and create infinite loop when started with unacceptable old_value?
- // repr->setAttribute(key, old_value);
}
} else {
// set default value
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 5169ff22f..8c647e599 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -70,9 +70,10 @@ public:
Inkscape::XML::Node * getRepr();
SPDocument * getSPDoc();
+ LivePathEffectObject * getLPEObj() {return lpeobj;};
void readallParameters(Inkscape::XML::Node * repr);
- void setParameter(Inkscape::XML::Node * repr, const gchar * key, const gchar * old_value, const gchar * new_value);
+ void setParameter(const gchar * key, const gchar * new_value);
protected:
Effect(LivePathEffectObject *lpeobject);
diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp
index a8321b72d..90a49e2ff 100644
--- a/src/live_effects/lpeobject.cpp
+++ b/src/live_effects/lpeobject.cpp
@@ -246,7 +246,7 @@ livepatheffect_on_repr_attr_changed ( Inkscape::XML::Node * repr,
if (!lpeobj->lpe)
return;
- lpeobj->lpe->setParameter(repr, key, oldval, newval);
+ lpeobj->lpe->setParameter(key, newval);
lpeobj->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp
index ff596bfc6..15ba663be 100644
--- a/src/live_effects/parameter/path.cpp
+++ b/src/live_effects/parameter/path.cpp
@@ -25,7 +25,12 @@
#include "verbs.h"
#include "document.h"
-#define noLPEPATHPARAM_DEBUG
+#define LPEPATHPARAM_DEBUG
+#include "tools-switch.h"
+#include "shape-editor.h"
+#include "node-context.h"
+#include "desktop-handles.h"
+#include "selection.h"
namespace Inkscape {
@@ -38,6 +43,7 @@ PathParam::PathParam( const Glib::ustring& label, const Glib::ustring& tip,
{
_widget = NULL;
_tooltips = NULL;
+ edit_button = NULL;
defvalue = g_strdup(default_value);
param_readSVGValue(defvalue);
}
@@ -103,8 +109,9 @@ PathParam::param_getWidget()
pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_edit_button_click));
static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);
_tooltips->set_tip(*pButton, _("Edit on-canvas"));
+ edit_button = pButton;
#ifndef LPEPATHPARAM_DEBUG
- pButton->set_sensitive(false);
+ edit_button->set_sensitive(false);
#endif
pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_PASTE, Inkscape::ICON_SIZE_BUTTON) );
@@ -126,7 +133,13 @@ PathParam::param_getWidget()
void
PathParam::on_edit_button_click()
{
- g_message("give this path to edit on canvas!");
+ // Switch to node edit tool:
+ tools_switch_current(TOOLS_NODES);
+
+ // set this parameter to edit:
+ ShapeEditor * shape_editor = SP_NODE_CONTEXT( SP_ACTIVE_DESKTOP->event_context )->shape_editor;
+ SPItem * item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem();
+ shape_editor->set_item_livepatheffect_parameter(item, SP_OBJECT(param_effect->getLPEObj()), param_key.c_str());
}
void
@@ -146,6 +159,7 @@ PathParam::on_paste_button_click()
if (strchr(svgd,'A')) { // FIXME: temporary hack until 2Geom supports arcs in SVGD
SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE,
_("This effect does not support arcs yet, try to convert to path.") );
+ return;
} else {
param_write_to_repr(svgd);
signal_path_pasted.emit();
@@ -155,8 +169,8 @@ PathParam::on_paste_button_click()
}
} else {
SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Clipboard does not contain a path."));
+ return;
}
-
}
void
diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h
index e966b7ebd..14387f419 100644
--- a/src/live_effects/parameter/path.h
+++ b/src/live_effects/parameter/path.h
@@ -19,6 +19,10 @@
#include <sigc++/sigc++.h>
+namespace Gtk {
+ class Button;
+}
+
namespace Inkscape {
namespace LivePathEffect {
@@ -56,6 +60,8 @@ private:
void on_paste_button_click();
gchar * defvalue;
+
+ Gtk::Button * edit_button;
};
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index 09c030aec..fa80f3baa 100644
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -139,16 +139,15 @@ 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);
static SPCurve* sp_nodepath_object_get_curve(SPObject *object, const gchar *key);
-static void sp_nodepath_object_set_curve (SPObject *object, SPCurve *curve);
+static void sp_nodepath_set_curve (Inkscape::NodePath::Path *np, SPCurve *curve);
// active_node indicates mouseover node
Inkscape::NodePath::Node * Inkscape::NodePath::Path::active_node = NULL;
/**
* \brief Creates new nodepath from item
-* repr_key_in should be NULL, unless you are called Johan or really know what you are doing! (See "if (repr_key_in)" below)
*/
-Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, bool show_handles, const char * repr_key_in)
+Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, bool show_handles, const char * repr_key_in, SPItem *item)
{
Inkscape::XML::Node *repr = object->repr;
@@ -201,18 +200,22 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object,
np->curve = sp_curve_copy(curve);
np->show_helperpath = false;
np->straight_path = false;
-
+ if (IS_LIVEPATHEFFECT(object) && item) {
+ np->item = item;
+ } else {
+ np->item = SP_ITEM(object);
+ }
// we need to update item's transform from the repr here,
// because they may be out of sync when we respond
// to a change in repr by regenerating nodepath --bb
- sp_object_read_attr(object, "transform");
+ sp_object_read_attr(SP_OBJECT(np->item), "transform");
- np->i2d = sp_item_i2d_affine(SP_ITEM(object));
+ np->i2d = sp_item_i2d_affine(np->item);
np->d2i = np->i2d.inverse();
np->repr = repr;
- if (repr_key_in) {
+ if (repr_key_in) { // apparantly the object is an LPEObject
np->repr_key = g_strdup(repr_key_in);
np->repr_nodetypes_key = g_strconcat(np->repr_key, "-nodetypes", NULL);
np->show_helperpath = true;
@@ -308,7 +311,7 @@ void sp_nodepath_destroy(Inkscape::NodePath::Path *np) {
void sp_nodepath_ensure_livarot_path(Inkscape::NodePath::Path *np)
{
- if (np && np->livarot_path == NULL && np->object && SP_IS_ITEM(np->object)) {
+ if (np && np->livarot_path == NULL) {
SPCurve *curve = create_curve(np);
NArtBpath *bpath = SP_CURVE_BPATH(curve);
np->livarot_path = bpath_to_Path(bpath);
@@ -516,7 +519,7 @@ static void update_object(Inkscape::NodePath::Path *np)
sp_curve_unref(np->curve);
np->curve = create_curve(np);
- sp_nodepath_object_set_curve(np->object, np->curve);
+ sp_nodepath_set_curve(np, np->curve);
if (np->show_helperpath) {
SPCurve * helper_curve = sp_curve_copy(np->curve);
@@ -1077,7 +1080,7 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
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::SNAPPOINT_NODE, n->pos + delta, SP_PATH(n->subpath->nodepath->object));
+ Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, n->pos + delta, SP_PATH(n->subpath->nodepath->item));
if (s.getDistance() < best) {
best = s.getDistance();
best_pt = s.getPoint() - n->pos;
@@ -3455,9 +3458,9 @@ static gboolean node_handle_request(SPKnot *knot, NR::Point *p, guint state, gpo
NR::Coord const scal = dot(delta, ndelta) / linelen;
(*p) = n->pos + (scal / linelen) * ndelta;
}
- *p = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, Inkscape::Snapper::ConstraintLine(*p, ndelta), SP_ITEM(n->subpath->nodepath->object)).getPoint();
+ *p = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, Inkscape::Snapper::ConstraintLine(*p, ndelta), n->subpath->nodepath->item).getPoint();
} else {
- *p = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, SP_ITEM(n->subpath->nodepath->object)).getPoint();
+ *p = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, n->subpath->nodepath->item).getPoint();
}
sp_node_adjust_handle(n, -which);
@@ -4443,18 +4446,24 @@ SPCurve* sp_nodepath_object_get_curve(SPObject *object, const gchar *key) {
return curve;
}
-void sp_nodepath_object_set_curve (SPObject *object, SPCurve *curve) {
- if (!object || !curve)
+void sp_nodepath_set_curve (Inkscape::NodePath::Path *np, SPCurve *curve) {
+ if (!np || !np->object || !curve)
return;
- if (SP_IS_PATH(object)) {
- if (SP_SHAPE(object)->path_effect_href) {
- sp_path_set_original_curve(SP_PATH(object), curve, true, false);
+ if (SP_IS_PATH(np->object)) {
+ if (SP_SHAPE(np->object)->path_effect_href) {
+ sp_path_set_original_curve(SP_PATH(np->object), curve, true, false);
} else {
- sp_shape_set_curve(SP_SHAPE(object), curve, true);
+ sp_shape_set_curve(SP_SHAPE(np->object), curve, true);
}
- } else if ( IS_LIVEPATHEFFECT(object) ) {
- g_warning("sp_nodepath_set_curve not implemented yet for lpeobjects");
+ } else if ( IS_LIVEPATHEFFECT(np->object) ) {
+ // FIXME: this writing to string and then reading from string is bound to be slow.
+ // create a method to convert from curve directly to 2geom...
+ gchar *svgpath = sp_svg_write_path(SP_CURVE_BPATH(np->curve));
+ LIVEPATHEFFECT(np->object)->lpe->setParameter(np->repr_key, svgpath);
+ g_free(svgpath);
+
+ np->object->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
}
diff --git a/src/nodepath.h b/src/nodepath.h
index 8c6c4ff8b..6ed9e2225 100644
--- a/src/nodepath.h
+++ b/src/nodepath.h
@@ -24,6 +24,7 @@
class SPDesktop;
class SPPath;
class SPKnot;
+class LivePathEffectObject;
namespace Inkscape {
namespace XML {
@@ -208,6 +209,8 @@ class Path {
SPDesktop * desktop;
/** The parent path of this nodepath */
SPObject * object;
+/** The parent livepatheffect of this nodepath, if applicable */
+ SPItem * item;
/** The context which created this nodepath. Important if this nodepath is deleted */
ShapeEditor *shape_editor;
/** The subpaths which comprise this NodePath */
@@ -242,6 +245,7 @@ class Path {
bool show_handles;
/// true if the path cannot contain curves, just straight lines
+ // FIXME: NOT IMPLEMENTED YET
bool straight_path;
/// active_node points to the node that is currently mouseovered (= NULL if
@@ -260,7 +264,7 @@ enum {
};
// Do function documentation in nodepath.cpp
-Inkscape::NodePath::Path * sp_nodepath_new (SPDesktop * desktop, SPObject *object, bool show_handles, const char * repr_key = NULL);
+Inkscape::NodePath::Path * sp_nodepath_new (SPDesktop * desktop, SPObject *object, bool show_handles, const char * repr_key = NULL, SPItem *item = NULL);
void sp_nodepath_destroy (Inkscape::NodePath::Path * nodepath);
void sp_nodepath_ensure_livarot_path(Inkscape::NodePath::Path *np);
void sp_nodepath_deselect (Inkscape::NodePath::Path *nodepath);
diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp
index d0dbb8937..abffeefc4 100644
--- a/src/shape-editor.cpp
+++ b/src/shape-editor.cpp
@@ -16,6 +16,7 @@
#include "sp-object.h"
#include "sp-item.h"
+#include "live_effects/lpeobject.h"
#include "selection.h"
#include "desktop.h"
#include "desktop-handles.h"
@@ -113,7 +114,7 @@ void ShapeEditor::decrement_local_change () {
SPItem *ShapeEditor::get_item () {
SPItem *item = NULL;
if (this->has_nodepath()) {
- item = SP_ITEM(this->nodepath->object);
+ item = this->nodepath->item;
} else if (this->has_knotholder()) {
item = SP_ITEM(this->knotholder->item);
}
@@ -208,29 +209,26 @@ void ShapeEditor::set_item(SPItem *item) {
}
}
-void ShapeEditor::set_livepatheffect_parameter(SPObject *lpeobject, const char * key) {
+/** Please note that this function only works for path parameters.
+* All other parameters probably will crash Inkscape!
+* Fortunately, there are no other on-canvas edittable objects at this moment :)
+*/
+void ShapeEditor::set_item_livepatheffect_parameter(SPItem *item, SPObject *lpeobject, const char * key) {
unset_item();
this->grab_node = -1;
if (lpeobject) {
+ this->knotholder = NULL; // it's a path, no special knotholder needed.
this->nodepath = sp_nodepath_new( desktop, lpeobject,
(prefs_get_int_attribute("tools.nodes", "show_handles", 1) != 0),
- key);
+ key, item);
if (this->nodepath) {
this->nodepath->shape_editor = this;
- }
- //this->knotholder = sp_item_knot_holder(item, desktop);
- g_message("create knotholder?");
- if (this->nodepath || this->knotholder) {
// setting new listener
- Inkscape::XML::Node *repr;
- if (this->knotholder)
- repr = this->knotholder->repr;
- else
- repr = SP_OBJECT_REPR(lpeobject);
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeobject);
if (repr) {
Inkscape::GC::anchor(repr);
sp_repr_add_listener(repr, &shapeeditor_repr_events, this);
diff --git a/src/shape-editor.h b/src/shape-editor.h
index 0e5bc22ef..2df1bb0e0 100644
--- a/src/shape-editor.h
+++ b/src/shape-editor.h
@@ -36,7 +36,7 @@ public:
~ShapeEditor();
void set_item (SPItem *item);
- void set_livepatheffect_parameter(SPObject *lpeobject, const char * key);
+ void set_item_livepatheffect_parameter(SPItem *item, SPObject *lpeobject, const char * key);
void unset_item ();
SPItem *get_item ();