From: Krzysztof KosiƄski Date: Tue, 8 Dec 2009 02:21:08 +0000 (+0100) Subject: Fix LPEs and break mask transform undo X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=4738512f05259cc6016d0d3aea12ea6c55c9e438;p=inkscape.git Fix LPEs and break mask transform undo --- 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 @@ -664,13 +664,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) { 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 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 doEffect_path (std::vector 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 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 doEffect_path (std::vector 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 @@ -115,14 +115,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) { 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 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(dt->event_context); + std::set 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(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 const &s) { std::set shapes(s); @@ -165,9 +169,9 @@ void MultiPathManipulator::setItems(std::set const &s) // add newly selected items for (std::set::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 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 > &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 &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(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, Util::ptr_shared) { - 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 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(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(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 #include #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; }