summaryrefslogtreecommitdiffstats
path: root/src/ui/tool/path-manipulator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tool/path-manipulator.cpp')
-rw-r--r--src/ui/tool/path-manipulator.cpp53
1 files changed, 37 insertions, 16 deletions
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index 7c2013872..96b3a1bb1 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -1,5 +1,6 @@
-/** @file
- * Path manipulator - implementation
+/**
+ * @file
+ * Path manipulator - implementation.
*/
/* Authors:
* Krzysztof KosiƄski <tweenk.pl@gmail.com>
@@ -29,7 +30,9 @@
#include "document.h"
#include "live_effects/effect.h"
#include "live_effects/lpeobject.h"
+#include "live_effects/lpeobject-reference.h"
#include "live_effects/parameter/path.h"
+#include "live_effects/lpe-powerstroke.h"
#include "sp-path.h"
#include "helper/geom.h"
#include "preferences.h"
@@ -120,7 +123,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path,
, _lpe_key(lpe_key)
{
if (_lpe_key.empty()) {
- _i2d_transform = SP_ITEM(path)->i2d_affine();
+ _i2d_transform = path->i2dt_affine();
} else {
_i2d_transform = Geom::identity();
}
@@ -136,7 +139,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path,
sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_outline), 0, SP_WIND_RULE_NONZERO);
_selection.signal_update.connect(
- sigc::mem_fun(*this, &PathManipulator::update));
+ sigc::bind(sigc::mem_fun(*this, &PathManipulator::update), false));
_selection.signal_point_changed.connect(
sigc::mem_fun(*this, &PathManipulator::_selectionChanged));
_desktop->signal_zoom_changed.connect(
@@ -174,10 +177,12 @@ bool PathManipulator::empty() {
return !_path || _subpaths.empty();
}
-/** Update the display and the outline of the path. */
-void PathManipulator::update()
+/** Update the display and the outline of the path.
+ * \param alert_LPE if true, alerts an applied LPE to what the path is going to be changed to, so it can adjust its parameters for nicer user interfacing
+ */
+void PathManipulator::update(bool alert_LPE)
{
- _createGeometryFromControlPoints();
+ _createGeometryFromControlPoints(alert_LPE);
}
/** Store the changes to the path in XML. */
@@ -534,13 +539,15 @@ void PathManipulator::deleteNodes(bool keep_shape)
}
}
-/** @brief Delete nodes between the two iterators.
+/**
+ * Delete nodes between the two iterators.
* The given range can cross the beginning of the subpath in closed subpaths.
* @param start Beginning of the range to delete
* @param end End of the range
* @param keep_shape Whether to fit the handles at surrounding nodes to approximate
* the shape before deletion
- * @return Number of deleted nodes */
+ * @return Number of deleted nodes
+ */
unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::iterator end, bool keep_shape)
{
unsigned const samples_per_segment = 10;
@@ -727,7 +734,7 @@ void PathManipulator::scaleHandle(Node *n, int which, int dir, bool pixel)
length_change = 1.0 / _desktop->current_zoom() * dir;
} else {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- length_change = prefs->getDoubleLimited("/options/defaultscale/value", 2, 1, 1000);
+ length_change = prefs->getDoubleLimited("/options/defaultscale/value", 2, 1, 1000, "px");
length_change *= dir;
}
@@ -976,7 +983,7 @@ void PathManipulator::_externalChange(unsigned type)
} break;
case PATH_CHANGE_TRANSFORM: {
Geom::Affine i2d_change = _d2i_transform;
- _i2d_transform = SP_ITEM(_path)->i2d_affine();
+ _i2d_transform = _path->i2dt_affine();
_d2i_transform = _i2d_transform.inverse();
i2d_change *= _i2d_transform;
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
@@ -1003,7 +1010,7 @@ void PathManipulator::_createControlPointsFromGeometry()
// When we erase an element, the next one slides into position,
// so we do not increment the iterator even though it is theoretically invalidated.
if (i->empty()) {
- pathv.erase(i);
+ i = pathv.erase(i);
} else {
++i;
}
@@ -1091,8 +1098,10 @@ void PathManipulator::_createControlPointsFromGeometry()
}
/** Construct the geometric representation of nodes and handles, update the outline
- * and display */
-void PathManipulator::_createGeometryFromControlPoints()
+ * and display
+ * \param alert_LPE if true, first the LPE is warned what the new path is going to be before updating it
+ */
+void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE)
{
Geom::PathBuilder builder;
for (std::list<SubpathPtr>::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) {
@@ -1120,7 +1129,18 @@ void PathManipulator::_createGeometryFromControlPoints()
++spi;
}
builder.finish();
- _spcurve->set_pathvector(builder.peek() * (_edit_transform * _i2d_transform).inverse());
+ Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse();
+ _spcurve->set_pathvector(pathv);
+ if (alert_LPE) {
+ if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) {
+ PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path));
+ LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast<LivePathEffect::LPEPowerStroke*>( effect_list.front()->lpeobject->get_lpe() );
+ if (lpe_pwr) {
+ lpe_pwr->adjustForNewPath(pathv);
+ }
+ }
+ }
+
if (_live_outline)
_updateOutline();
if (_live_objects)
@@ -1278,8 +1298,9 @@ bool PathManipulator::_nodeClicked(Node *n, GdkEventButton *event)
}
if (!empty()) {
- update();
+ update(true);
}
+
// We need to call MPM's method because it could have been our last node
_multi_path_manipulator._doneWithCleanup(_("Delete node"));