summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2009-12-08 02:21:08 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2009-12-08 02:21:08 +0000
commite2b9f78d271e5fea988138d49020e704e72c83b1 (patch)
treed5c1c53cefce4a2f126718cdf2d95707309446e5 /src
parentFix mask editing behavior on undo and outline display for masks/clips; (diff)
downloadinkscape-e2b9f78d271e5fea988138d49020e704e72c83b1.tar.gz
inkscape-e2b9f78d271e5fea988138d49020e704e72c83b1.zip
Fix LPEs and break mask transform undo
(bzr r8846.2.3)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect.cpp7
-rw-r--r--src/live_effects/effect.h2
-rw-r--r--src/live_effects/lpe-constructgrid.cpp7
-rw-r--r--src/live_effects/lpe-constructgrid.h2
-rw-r--r--src/live_effects/lpe-gears.cpp7
-rw-r--r--src/live_effects/lpe-gears.h2
-rw-r--r--src/live_effects/lpe-spiro.cpp8
-rw-r--r--src/live_effects/lpe-spiro.h1
-rw-r--r--src/live_effects/lpe-vonkoch.cpp6
-rw-r--r--src/live_effects/parameter/path.cpp33
-rw-r--r--src/nodepath.cpp2
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp11
-rw-r--r--src/ui/tool/node-tool.cpp32
-rw-r--r--src/ui/tool/path-manipulator.cpp121
-rw-r--r--src/ui/tool/path-manipulator.h11
-rw-r--r--src/ui/tool/shape-record.h3
16 files changed, 164 insertions, 91 deletions
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 9232792f6..dfa9fe6b2 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -665,13 +665,6 @@ Effect::resetDefaults(SPItem * /*item*/)
}
void
-Effect::setup_nodepath(Inkscape::NodePath::Path *np)
-{
- np->helperpath_rgba = 0xff0000ff;
- np->helperpath_width = 1.0;
-}
-
-void
Effect::transform_multiply(Geom::Matrix const& postmul, bool set)
{
// cycle through all parameters. Most parameters will not need transformation, but path and point params do.
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 5d67ed016..a8d34a233 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -92,8 +92,6 @@ public:
*/
virtual void resetDefaults(SPItem * item);
- virtual void setup_nodepath(Inkscape::NodePath::Path *np);
-
/// /todo: is this method really necessary? it causes UI inconsistensies... (johan)
virtual void transform_multiply(Geom::Matrix const& postmul, bool set);
diff --git a/src/live_effects/lpe-constructgrid.cpp b/src/live_effects/lpe-constructgrid.cpp
index 144f4720d..d83529957 100644
--- a/src/live_effects/lpe-constructgrid.cpp
+++ b/src/live_effects/lpe-constructgrid.cpp
@@ -81,13 +81,6 @@ LPEConstructGrid::doEffect_path (std::vector<Geom::Path> const & path_in)
}
}
-void
-LPEConstructGrid::setup_nodepath(Inkscape::NodePath::Path *np)
-{
- Effect::setup_nodepath(np);
- sp_nodepath_make_straight_path(np);
-}
-
} //namespace LivePathEffect
} /* namespace Inkscape */
diff --git a/src/live_effects/lpe-constructgrid.h b/src/live_effects/lpe-constructgrid.h
index 716960d32..c7e695794 100644
--- a/src/live_effects/lpe-constructgrid.h
+++ b/src/live_effects/lpe-constructgrid.h
@@ -27,8 +27,6 @@ public:
virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in);
- virtual void setup_nodepath(Inkscape::NodePath::Path *np);
-
private:
ScalarParam nr_x;
ScalarParam nr_y;
diff --git a/src/live_effects/lpe-gears.cpp b/src/live_effects/lpe-gears.cpp
index e211483c6..bd1ce7998 100644
--- a/src/live_effects/lpe-gears.cpp
+++ b/src/live_effects/lpe-gears.cpp
@@ -261,13 +261,6 @@ LPEGears::doEffect_path (std::vector<Geom::Path> const & path_in)
return path_out;
}
-void
-LPEGears::setup_nodepath(Inkscape::NodePath::Path *np)
-{
- Effect::setup_nodepath(np);
- sp_nodepath_make_straight_path(np);
-}
-
} // namespace LivePathEffect
} /* namespace Inkscape */
diff --git a/src/live_effects/lpe-gears.h b/src/live_effects/lpe-gears.h
index 4c3a9938b..bd5e4c4f9 100644
--- a/src/live_effects/lpe-gears.h
+++ b/src/live_effects/lpe-gears.h
@@ -24,8 +24,6 @@ public:
virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in);
- virtual void setup_nodepath(Inkscape::NodePath::Path *np);
-
private:
ScalarParam teeth;
ScalarParam phi;
diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp
index 794fd980e..087b88351 100644
--- a/src/live_effects/lpe-spiro.cpp
+++ b/src/live_effects/lpe-spiro.cpp
@@ -116,14 +116,6 @@ LPESpiro::~LPESpiro()
}
void
-LPESpiro::setup_nodepath(Inkscape::NodePath::Path *np)
-{
- Effect::setup_nodepath(np);
- sp_nodepath_show_handles(np, false);
-// sp_nodepath_show_helperpath(np, false);
-}
-
-void
LPESpiro::doEffect(SPCurve * curve)
{
using Geom::X;
diff --git a/src/live_effects/lpe-spiro.h b/src/live_effects/lpe-spiro.h
index 7256665a2..4fcd9eaaa 100644
--- a/src/live_effects/lpe-spiro.h
+++ b/src/live_effects/lpe-spiro.h
@@ -24,7 +24,6 @@ public:
virtual LPEPathFlashType pathFlashType() { return SUPPRESS_FLASH; }
- virtual void setup_nodepath(Inkscape::NodePath::Path *np);
virtual void doEffect(SPCurve * curve);
private:
diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp
index 7fd0ac0b4..b2a5d56fa 100644
--- a/src/live_effects/lpe-vonkoch.cpp
+++ b/src/live_effects/lpe-vonkoch.cpp
@@ -19,7 +19,7 @@ void
VonKochPathParam::param_setup_nodepath(Inkscape::NodePath::Path *np)
{
PathParam::param_setup_nodepath(np);
- sp_nodepath_make_straight_path(np);
+ //sp_nodepath_make_straight_path(np);
}
//FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug.
@@ -27,12 +27,12 @@ void
VonKochRefPathParam::param_setup_nodepath(Inkscape::NodePath::Path *np)
{
PathParam::param_setup_nodepath(np);
- sp_nodepath_make_straight_path(np);
+ //sp_nodepath_make_straight_path(np);
}
bool
VonKochRefPathParam::param_readSVGValue(const gchar * strvalue)
{
- std::vector<Geom::Path> old = _pathvector;
+ Geom::PathVector old = _pathvector;
bool res = PathParam::param_readSVGValue(strvalue);
if (res && _pathvector.size()==1 && _pathvector.front().size()==1){
return true;
diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp
index 93dfd2667..3a03de51c 100644
--- a/src/live_effects/parameter/path.cpp
+++ b/src/live_effects/parameter/path.cpp
@@ -40,6 +40,10 @@
#include "sp-text.h"
#include "display/curve.h"
+#include "ui/tool/node-tool.h"
+#include "ui/tool/multi-path-manipulator.h"
+#include "ui/tool/shape-record.h"
+
namespace Inkscape {
@@ -195,16 +199,33 @@ PathParam::param_newWidget(Gtk::Tooltips * tooltips)
void
PathParam::param_editOncanvas(SPItem * item, SPDesktop * dt)
{
- // TODO this whole method is broken!
+ using namespace Inkscape::UI;
+
+ // TODO remove the tools_switch atrocity.
+ if (!tools_isactive(dt, TOOLS_NODES)) {
+ tools_switch(dt, TOOLS_NODES);
+ }
+
+ InkNodeTool *nt = static_cast<InkNodeTool*>(dt->event_context);
+ std::set<ShapeRecord> shapes;
+ ShapeRecord r;
+
+ r.role = SHAPE_ROLE_LPE_PARAM;
+ r.edit_transform = Geom::identity(); // TODO this is almost certainly wrong
+ if (!href) {
+ r.item = reinterpret_cast<SPItem*>(param_effect->getLPEObj());
+ r.lpe_key = param_key;
+ } else {
+ r.item = ref.getObject();
+ }
+ shapes.insert(r);
+ nt->_multipath->setItems(shapes);
}
void
-PathParam::param_setup_nodepath(Inkscape::NodePath::Path *np)
+PathParam::param_setup_nodepath(Inkscape::NodePath::Path *)
{
- // TODO this too!
- np->show_helperpath = true;
- np->helperpath_rgba = 0x009000ff;
- np->helperpath_width = 1.0;
+ // TODO this method should not exist at all!
}
void
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index 8f17ae013..36e4e0d8c 100644
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -352,7 +352,7 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object,
Inkscape::LivePathEffect::Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(np->object));
if (lpe) {
- lpe->setup_nodepath(np);
+ //lpe->setup_nodepath(np);
}
} else {
np->repr_key = g_strdup("d");
diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp
index 7c539f6b9..aaf7e413c 100644
--- a/src/ui/tool/multi-path-manipulator.cpp
+++ b/src/ui/tool/multi-path-manipulator.cpp
@@ -15,6 +15,7 @@
#include "desktop.h"
#include "desktop-handles.h"
#include "document.h"
+#include "live_effects/lpeobject.h"
#include "message-stack.h"
#include "preferences.h"
#include "sp-path.h"
@@ -131,6 +132,9 @@ void MultiPathManipulator::cleanup()
}
}
+/** @brief Change the set of items to edit.
+ *
+ * This method attempts to preserve as much of the state as possible. */
void MultiPathManipulator::setItems(std::set<ShapeRecord> const &s)
{
std::set<ShapeRecord> shapes(s);
@@ -165,9 +169,9 @@ void MultiPathManipulator::setItems(std::set<ShapeRecord> const &s)
// add newly selected items
for (std::set<ShapeRecord>::iterator i = shapes.begin(); i != shapes.end(); ++i) {
ShapeRecord const &r = *i;
- if (!SP_IS_PATH(r.item)) continue;
+ if (!SP_IS_PATH(r.item) && !IS_LIVEPATHEFFECT(r.item)) continue;
boost::shared_ptr<PathManipulator> newpm(new PathManipulator(_path_data, (SPPath*) r.item,
- r.edit_transform, _getOutlineColor(r.role)));
+ r.edit_transform, _getOutlineColor(r.role), r.lpe_key));
newpm->showHandles(_show_handles);
// always show outlines for clips and masks
newpm->showOutline(_show_outline || r.role != SHAPE_ROLE_NORMAL);
@@ -241,6 +245,7 @@ void MultiPathManipulator::insertNodes()
void MultiPathManipulator::joinNodes()
{
+ invokeForAll(&PathManipulator::hideDragPoint);
// Node join has two parts. In the first one we join two subpaths by fusing endpoints
// into one. In the second we fuse nodes in each subpath.
IterPairList joins;
@@ -585,7 +590,7 @@ guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role)
case SHAPE_ROLE_MASK:
return prefs->getColor("/tools/nodes/mask_color", 0x0000ffff);
case SHAPE_ROLE_LPE_PARAM:
- return prefs->getColor("/tools/nodes/lpe_param_color", 0xb700ffff);
+ return prefs->getColor("/tools/nodes/lpe_param_color", 0x009000ff);
case SHAPE_ROLE_NORMAL:
default:
return prefs->getColor("/tools/nodes/outline_color", 0xff0000ff);
diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp
index 31c722744..9103f066f 100644
--- a/src/ui/tool/node-tool.cpp
+++ b/src/ui/tool/node-tool.cpp
@@ -16,6 +16,7 @@
#include "display/curve.h"
#include "display/sp-canvas.h"
#include "document.h"
+#include "live_effects/lpeobject.h"
#include "message-context.h"
#include "selection.h"
#include "shape-editor.h" // temporary!
@@ -187,12 +188,12 @@ void ink_node_tool_setup(SPEventContext *ec)
sigc::bind<0>(
sigc::ptr_fun(&ink_node_tool_selection_changed),
nt));
- nt->_selection_modified_connection.disconnect();
+ /*nt->_selection_modified_connection.disconnect();
nt->_selection_modified_connection =
selection->connectModified(
sigc::hide(sigc::bind<0>(
- sigc::ptr_fun(&ink_node_tool_selection_changed),
- nt)));
+ sigc::ptr_fun(&ink_node_tool_selection_modified),
+ nt)));*/
nt->_mouseover_changed_connection.disconnect();
nt->_mouseover_changed_connection =
Inkscape::UI::ControlPoint::signal_mouseover_change.connect(
@@ -293,28 +294,20 @@ void ink_node_tool_set(SPEventContext *ec, Inkscape::Preferences::Entry *value)
}
}
-void store_clip_mask_items(SPItem *clipped, SPObject *obj, std::map<SPItem*,
- std::pair<Geom::Matrix, guint32> > &s, Geom::Matrix const &postm, guint32 color)
-{
- if (!obj) return;
- if (SP_IS_GROUP(obj) || SP_IS_OBJECTGROUP(obj)) {
- //TODO is checking for obj->children != NULL above better?
- for (SPObject *c = obj->children; c; c = c->next) {
- store_clip_mask_items(clipped, c, s, postm, color);
- }
- } else if (SP_IS_ITEM(obj)) {
- s.insert(std::make_pair(SP_ITEM(obj),
- std::make_pair(sp_item_i2d_affine(clipped) * postm, color)));
- }
-}
-
/** Recursively collect ShapeRecords */
void gather_items(InkNodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::ShapeRole role,
std::set<Inkscape::UI::ShapeRecord> &s)
{
using namespace Inkscape::UI;
if (!obj) return;
- if (role != SHAPE_ROLE_NORMAL && (SP_IS_GROUP(obj) || SP_IS_OBJECTGROUP(obj))) {
+
+ if (SP_IS_PATH(obj) && obj->repr->attribute("inkscape:original-d") != NULL) {
+ ShapeRecord r;
+ r.item = static_cast<SPItem*>(obj);
+ r.edit_transform = Geom::identity(); // TODO wrong?
+ r.role = SHAPE_ROLE_LPE_PARAM;
+ s.insert(r);
+ } else if (role != SHAPE_ROLE_NORMAL && (SP_IS_GROUP(obj) || SP_IS_OBJECTGROUP(obj))) {
for (SPObject *c = obj->children; c; c = c->next) {
gather_items(nt, base, c, role, s);
}
@@ -325,7 +318,6 @@ void gather_items(InkNodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Sh
// TODO add support for objectBoundingBox
r.edit_transform = base ? sp_item_i2doc_affine(base) : Geom::identity();
r.role = role;
- r.edit_original = false;
if (s.insert(r).second) {
// this item was encountered the first time
if (nt->edit_clipping_paths && item->clip_ref) {
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index e9ec78b2e..0ad509a9b 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -26,6 +26,9 @@
#include "display/curve.h"
#include "display/canvas-bpath.h"
#include "document.h"
+#include "live_effects/effect.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/parameter/path.h"
#include "sp-path.h"
#include "helper/geom.h"
#include "preferences.h"
@@ -59,13 +62,15 @@ public:
virtual void notifyAttributeChanged(Inkscape::XML::Node &, GQuark attr,
Util::ptr_shared<char>, Util::ptr_shared<char>)
{
- GQuark path_d = g_quark_from_static_string("d");
- GQuark path_transform = g_quark_from_static_string("transform");
// do nothing if blocked
if (_blocked) return;
+ GQuark path_d = g_quark_from_static_string("d");
+ GQuark path_transform = g_quark_from_static_string("transform");
+ GQuark lpe_quark = _pm->_lpe_key.empty() ? 0 : g_quark_from_string(_pm->_lpe_key.data());
+
// only react to "d" (path data) and "transform" attribute changes
- if (attr == path_d) {
+ if (attr == lpe_quark || attr == path_d) {
_pm->_externalChange(PATH_CHANGE_D);
} else if (attr == path_transform) {
_pm->_externalChange(PATH_CHANGE_TRANSFORM);
@@ -81,22 +86,29 @@ private:
void build_segment(Geom::PathBuilder &, Node *, Node *);
PathManipulator::PathManipulator(PathSharedData const &data, SPPath *path,
- Geom::Matrix const &et, guint32 outline_color)
+ Geom::Matrix const &et, guint32 outline_color, Glib::ustring lpe_key)
: PointManipulator(data.node_data.desktop, *data.node_data.selection)
, _path_data(data)
, _path(path)
- , _spcurve(sp_path_get_curve_for_edit(path))
+ , _spcurve(NULL)
, _dragpoint(new CurveDragPoint(*this))
, _observer(new PathManipulatorObserver(this))
, _edit_transform(et)
, _show_handles(true)
, _show_outline(false)
+ , _lpe_key(lpe_key)
{
/* Because curve drag point is always created first, it does not cover nodes */
- _i2d_transform = sp_item_i2d_affine(SP_ITEM(path));
+ if (_lpe_key.empty()) {
+ _i2d_transform = sp_item_i2d_affine(SP_ITEM(path));
+ } else {
+ _i2d_transform = Geom::identity();
+ }
_d2i_transform = _i2d_transform.inverse();
_dragpoint->setVisible(false);
+ _getGeometry();
+
_outline = sp_canvas_bpath_new(_path_data.outline_group, NULL);
sp_canvas_item_hide(_outline);
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(_outline), outline_color, 1.0,
@@ -127,7 +139,7 @@ PathManipulator::~PathManipulator()
if (_path) _path->repr->removeObserver(*_observer);
delete _observer;
gtk_object_destroy(_outline);
- _spcurve->unref();
+ if (_spcurve) _spcurve->unref();
clear();
}
@@ -163,11 +175,11 @@ void PathManipulator::writeXML()
if (!_path) return;
_observer->block();
if (!empty()) {
- _path->updateRepr();
- _path->repr->setAttribute("sodipodi:nodetypes", _createTypeString().data());
+ SP_OBJECT(_path)->updateRepr();
+ _getXMLNode()->setAttribute(_nodetypesKey().data(), _createTypeString().data());
} else {
// this manipulator will have to be destroyed right after this call
- _path->repr->removeObserver(*_observer);
+ _getXMLNode()->removeObserver(*_observer);
sp_object_ref(_path);
_path->deleteObject(true, true);
sp_object_unref(_path);
@@ -333,6 +345,9 @@ void PathManipulator::insertNodes()
/** Replace contiguous selections of nodes in each subpath with one node. */
void PathManipulator::weldNodes(NodeList::iterator const &preserve_pos)
{
+ if (!_num_selected) return;
+ _dragpoint->setVisible(false);
+
bool pos_valid = preserve_pos;
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
SubpathPtr sp = *i;
@@ -458,7 +473,8 @@ void PathManipulator::breakNodes()
void PathManipulator::deleteNodes(bool keep_shape)
{
if (!_num_selected) return;
-
+ hideDragPoint();
+
unsigned const samples_per_segment = 10;
double const t_step = 1.0 / samples_per_segment;
@@ -472,7 +488,10 @@ void PathManipulator::deleteNodes(bool keep_shape)
if (j->selected()) ++num_selected;
else ++num_unselected;
}
- if (num_selected == 0) continue;
+ if (num_selected == 0) {
+ ++i;
+ continue;
+ }
if (sp->closed() ? (num_unselected < 1) : (num_unselected < 2)) {
_subpaths.erase(i++);
continue;
@@ -500,8 +519,8 @@ void PathManipulator::deleteNodes(bool keep_shape)
// 2. we are deleting at the end or beginning of an open path
// if !sel_end then sel_beg.prev() must be valid, otherwise the entire subpath
// would be deleted before we get here
- if (keep_shape || !sel_end) sel_beg.prev()->setType(NODE_CUSP, false);
- if (keep_shape || !sel_beg.prev()) sel_end->setType(NODE_CUSP, false);
+ if ((keep_shape || !sel_end) && sel_beg.prev()) sel_beg.prev()->setType(NODE_CUSP, false);
+ if ((keep_shape || !sel_beg.prev()) && sel_end) sel_end->setType(NODE_CUSP, false);
if (keep_shape && sel_beg.prev() && sel_end) {
// Fill fit data
@@ -520,7 +539,7 @@ void PathManipulator::deleteNodes(bool keep_shape)
// Fill last point
bezier_data[num_samples - 1] = sel_end->position();
// Compute replacement bezier curve
- // TODO find out optimal error value
+ // TODO the fitting algorithm sucks - rewrite it to be awesome
bezier_fit_cubic(result, bezier_data, num_samples, 0.5);
delete[] bezier_data;
@@ -544,6 +563,8 @@ void PathManipulator::deleteNodes(bool keep_shape)
void PathManipulator::deleteSegments()
{
if (_num_selected == 0) return;
+ hideDragPoint();
+
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end();) {
SubpathPtr sp = *i;
bool has_unselected = false;
@@ -702,6 +723,12 @@ void PathManipulator::setControlsTransform(Geom::Matrix const &tnew)
_createGeometryFromControlPoints();
}
+void PathManipulator::hideDragPoint()
+{
+ _dragpoint->setVisible(false);
+ _dragpoint->setIterator(NodeList::iterator());
+}
+
/** Insert a node in the segment beginning with the supplied iterator,
* at the given time value */
NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, double t)
@@ -749,8 +776,7 @@ void PathManipulator::_externalChange(unsigned type)
{
switch (type) {
case PATH_CHANGE_D: {
- _spcurve->unref();
- _spcurve = sp_path_get_curve_for_edit(_path);
+ _getGeometry();
// ugly: stored offsets of selected nodes in a vector
// vector<bool> should be specialized so that it takes only 1 bit per value
@@ -851,7 +877,7 @@ void PathManipulator::_createControlPointsFromGeometry()
// we need to set the nodetypes after all the handles are in place,
// so that pickBestType works correctly
// TODO maybe migrate to inkscape:node-types?
- gchar const *nts_raw = _path ? _path->repr->attribute("sodipodi:nodetypes") : 0;
+ gchar const *nts_raw = _path ? _path->repr->attribute(_nodetypesKey().data()) : 0;
std::string nodetype_string = nts_raw ? nts_raw : "";
/* Calculate the needed length of the nodetype string.
* For closed paths, the entry is duplicated for the starting node,
@@ -913,7 +939,7 @@ void PathManipulator::_createGeometryFromControlPoints()
builder.finish();
_spcurve->set_pathvector(builder.peek() * (_edit_transform * _i2d_transform).inverse());
_updateOutline();
- if (!empty()) sp_shape_set_curve(SP_SHAPE(_path), _spcurve, false);
+ _setGeometry();
}
/** Build one segment of the geometric representation.
@@ -990,6 +1016,63 @@ void PathManipulator::_updateOutline()
_hc->unref();
}
+/** Retrieve the geometry of the edited object from the object tree */
+void PathManipulator::_getGeometry()
+{
+ using namespace Inkscape::LivePathEffect;
+ if (!_lpe_key.empty()) {
+ Effect *lpe = LIVEPATHEFFECT(_path)->get_lpe();
+ if (lpe) {
+ PathParam *pathparam = dynamic_cast<PathParam *>(lpe->getParameter(_lpe_key.data()));
+ if (!_spcurve)
+ _spcurve = new SPCurve(pathparam->get_pathvector());
+ else
+ _spcurve->set_pathvector(pathparam->get_pathvector());
+ }
+ } else {
+ if (_spcurve) _spcurve->unref();
+ _spcurve = sp_path_get_curve_for_edit(_path);
+ }
+}
+
+/** Set the geometry of the edited object in the object tree, but do not commit to XML */
+void PathManipulator::_setGeometry()
+{
+ using namespace Inkscape::LivePathEffect;
+ if (empty()) return;
+
+ if (!_lpe_key.empty()) {
+ // LPE brain damage follows - copied from nodepath.cpp
+ // NOTE: if we are editing an LPE param, _path is not actually an SPPath, it is
+ // a LivePathEffectObject.
+ Effect *lpe = LIVEPATHEFFECT(_path)->get_lpe();
+ if (lpe) {
+ PathParam *pathparam = dynamic_cast<PathParam *>(lpe->getParameter(_lpe_key.data()));
+ pathparam->set_new_value(_spcurve->get_pathvector(), false);
+ LIVEPATHEFFECT(_path)->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ } else {
+ if (_path->repr->attribute("inkscape:original-d"))
+ sp_path_set_original_curve(_path, _spcurve, true, false);
+ else
+ sp_shape_set_curve(SP_SHAPE(_path), _spcurve, false);
+ }
+}
+
+/** LPE brain damage */
+Glib::ustring PathManipulator::_nodetypesKey()
+{
+ if (_lpe_key.empty()) return "sodipodi:nodetypes";
+ return _lpe_key + "-nodetypes";
+}
+
+/** LPE brain damage */
+Inkscape::XML::Node *PathManipulator::_getXMLNode()
+{
+ if (_lpe_key.empty()) return _path->repr;
+ return LIVEPATHEFFECT(_path)->repr;
+}
+
void PathManipulator::_attachNodeHandlers(Node *node)
{
Handle *handles[2] = { node->front(), node->back() };
diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h
index 01a2b6cbf..e0d8c68ca 100644
--- a/src/ui/tool/path-manipulator.h
+++ b/src/ui/tool/path-manipulator.h
@@ -25,6 +25,7 @@
struct SPCanvasItem;
namespace Inkscape {
+namespace XML { class Node; }
namespace UI {
class PathManipulator;
@@ -48,8 +49,8 @@ class PathManipulator : public PointManipulator {
public:
typedef SPPath *ItemType;
- PathManipulator(PathSharedData const &data, SPPath *path,
- Geom::Matrix const &edit_trans, guint32 outline_color);
+ PathManipulator(PathSharedData const &data, SPPath *path, Geom::Matrix const &edit_trans,
+ guint32 outline_color, Glib::ustring lpe_key);
~PathManipulator();
virtual bool event(GdkEvent *);
@@ -81,6 +82,7 @@ public:
void showHandles(bool show);
void showPathDirection(bool show);
void setControlsTransform(Geom::Matrix const &);
+ void hideDragPoint();
NodeList::iterator subdivideSegment(NodeList::iterator after, double t);
@@ -94,6 +96,10 @@ private:
std::string _createTypeString();
void _updateOutline();
//void _setOutline(Geom::PathVector const &);
+ void _getGeometry();
+ void _setGeometry();
+ Glib::ustring _nodetypesKey();
+ Inkscape::XML::Node *_getXMLNode();
void _attachNodeHandlers(Node *n);
void _removeNodeHandlers(Node *n);
@@ -124,6 +130,7 @@ private:
bool _show_handles;
bool _show_outline;
bool _show_path_direction;
+ Glib::ustring _lpe_key;
friend class PathManipulatorObserver;
friend class CurveDragPoint;
diff --git a/src/ui/tool/shape-record.h b/src/ui/tool/shape-record.h
index cc2f8be40..96c1551f6 100644
--- a/src/ui/tool/shape-record.h
+++ b/src/ui/tool/shape-record.h
@@ -12,6 +12,7 @@
#ifndef SEEN_UI_TOOL_SHAPE_RECORD_H
#define SEEN_UI_TOOL_SHAPE_RECORD_H
+#include <glibmm/ustring.h>
#include <boost/operators.hpp>
#include <2geom/matrix.h>
@@ -33,7 +34,7 @@ struct ShapeRecord :
SPItem *item; // SP node for the edited shape
Geom::Matrix edit_transform; // how to transform controls - used for clipping paths and masks
ShapeRole role;
- bool edit_original; // whether to use original-d instead of d for editing
+ Glib::ustring lpe_key; // This is LPE brain damage that I do not want to speak of
inline bool operator==(ShapeRecord const &o) const { return item == o.item; }
inline bool operator<(ShapeRecord const &o) const { return item < o.item; }