Code

Mnemonics in "Input devices", and LPE dialogs (Bug 170765)
[inkscape.git] / src / live_effects / lpe-bendpath.cpp
index 49569d4b52d854ceb5a00566478f25e23b3e08a7..2d6bbeb220195989120af857c2a96b6f610beb7d 100644 (file)
 #include "sp-item.h"
 #include "sp-path.h"
 #include "sp-item-group.h"
-#include "display/curve.h"
-#include <libnr/n-art-bpath.h>
-#include <libnr/nr-matrix-fns.h>
-#include "libnr/n-art-bpath-2geom.h"
 #include "svg/svg.h"
 #include "ui/widget/scalar.h"
 
@@ -39,7 +35,7 @@ B is a map t --> B(t) = ( a(t), b(t) ).
 The first step is to re-parametrize B by its arc length: this is the parametrization in which a point p on B is located by its distance s from start. One obtains a new map s --> U(s) = (a'(s),b'(s)), that still describes the same path B, but where the distance along B from start to
 U(s) is s itself.
 
-We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90°. Call this normal vector N(s).
+We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90. Call this normal vector N(s).
 
 The basic deformation associated to B is then given by:
 
@@ -56,10 +52,10 @@ namespace LivePathEffect {
 
 LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) :
     Effect(lpeobject),
-    bend_path(_("Bend path"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"),
-    prop_scale(_("Width"), _("Width of the path"), "prop_scale", &wr, this, 1),
-    scale_y_rel(_("Width in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false),
-    vertical_pattern(_("Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false)
+    bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"),
+    prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1),
+    scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false),
+    vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false)
 {
     registerParameter( dynamic_cast<Parameter *>(&bend_path) );
     registerParameter( dynamic_cast<Parameter *>(&prop_scale) );
@@ -70,8 +66,6 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) :
     prop_scale.param_set_increments(0.01, 0.10);
 
     concatenate_before_pwd2 = true;
-
-    groupSpecialBehavior = false;
 }
 
 LPEBendPath::~LPEBendPath()
@@ -82,25 +76,8 @@ LPEBendPath::~LPEBendPath()
 void
 LPEBendPath::doBeforeEffect (SPLPEItem *lpeitem)
 {
-    if(SP_IS_GROUP(lpeitem))
-    {
-        groupSpecialBehavior = true;
-
-        using namespace Geom;
-        Piecewise<D2<SBasis> > pwd2;
-        std::vector<Geom::Path> temppath;
-
-        recursive_original_bbox(SP_GROUP(lpeitem), pwd2, temppath);
-
-        for (unsigned int i=0; i < temppath.size(); i++) {
-            pwd2.concat( temppath[i].toPwSb() );
-        }
-
-        D2<Piecewise<SBasis> > d2pw = make_cuts_independant(pwd2);
-        boundingbox_X = bounds_exact(d2pw[0]);
-        boundingbox_Y = bounds_exact(d2pw[1]);
-    }
-
+    // get the item bounding box
+    original_bbox(lpeitem);
 }
 
 Geom::Piecewise<Geom::D2<Geom::SBasis> >
@@ -110,25 +87,27 @@ LPEBendPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd
 
 /* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */
 
-    Piecewise<D2<SBasis> > uskeleton = arc_length_parametrization(Piecewise<D2<SBasis> >(bend_path.get_pwd2()),2,.1);
-    uskeleton = remove_short_cuts(uskeleton,.01);
-    Piecewise<D2<SBasis> > n = rot90(derivative(uskeleton));
-    n = force_continuity(remove_short_cuts(n,.1));
+    if (bend_path.changed) {
+        uskeleton = arc_length_parametrization(Piecewise<D2<SBasis> >(bend_path.get_pwd2()),2,.1);
+        uskeleton = remove_short_cuts(uskeleton,.01);
+        n = rot90(derivative(uskeleton));
+        n = force_continuity(remove_short_cuts(n,.1));
+
+        bend_path.changed = false;
+    }
 
-    D2<Piecewise<SBasis> > patternd2 = make_cuts_independant(pwd2_in);
+    D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(pwd2_in);
     Piecewise<SBasis> x = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]);
     Piecewise<SBasis> y = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]);
 
-//We use the group bounding box size or the path bbox size to translate well x and y
-    if(groupSpecialBehavior == false)
-    {
-        boundingbox_X = bounds_exact(x);
-        boundingbox_Y = bounds_exact(y);
-    }
-    x-= boundingbox_X.min();
-    y-= boundingbox_Y.middle();
+    Interval bboxHorizontal = vertical_pattern.get_value() ? boundingbox_Y : boundingbox_X;
+    Interval bboxVertical = vertical_pattern.get_value() ? boundingbox_X : boundingbox_Y;
+
+    //We use the group bounding box size or the path bbox size to translate well x and y
+    x-= bboxHorizontal.min();
+    y-= bboxVertical.middle();
 
-  double scaling = uskeleton.cuts.back()/boundingbox_X.extent();
+  double scaling = uskeleton.cuts.back()/bboxHorizontal.extent();
 
   if (scaling != 1.0) {
         x*=scaling;
@@ -148,50 +127,21 @@ LPEBendPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd
 void
 LPEBendPath::resetDefaults(SPItem * item)
 {
-    if (SP_IS_PATH(item) || SP_IS_GROUP(item))
-    {
-        // set the bend path to run horizontally in the middle of the bounding box of the original path
-        using namespace Geom;
-        Piecewise<D2<SBasis> > pwd2;
-        std::vector<Geom::Path> temppath;
-
-        if (SP_IS_PATH(item))
-        {
-            //TODO : this won't work well with LPE stacking
-            temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
-        }
-        else if (SP_IS_GROUP(item))
-        {
-            recursive_original_bbox(SP_GROUP(item), pwd2, temppath);
-        }
-
-        for (unsigned int i=0; i < temppath.size(); i++) {
-            pwd2.concat( temppath[i].toPwSb() );
-        }
-
-        D2<Piecewise<SBasis> > d2pw = make_cuts_independant(pwd2);
-        boundingbox_X = bounds_exact(d2pw[0]);
-        boundingbox_Y = bounds_exact(d2pw[1]);
-
-        Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
-        Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
-
-        if ( Geom::are_near(start,end) ) {
-           end += Point(1.,0.);
-        }
-
-        Geom::Path path;
-        path.start( start );
-        path.appendNew<Geom::LineSegment>( end );
-        bend_path.param_set_and_write_new_value( path.toPwSb() );
-    }
-}
+    Effect::resetDefaults(item);
 
-void
-LPEBendPath::transform_multiply(Geom::Matrix const& postmul, bool set)
-{
-    // TODO: implement correct transformation instead of this default behavior
-    Effect::transform_multiply(postmul, set);
+    original_bbox(SP_LPE_ITEM(item));
+
+    Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
+    Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
+
+    if ( Geom::are_near(start,end) ) {
+        end += Geom::Point(1.,0.);
+    }
+     
+    Geom::Path path;
+    path.start( start );
+    path.appendNew<Geom::LineSegment>( end );
+    bend_path.set_new_value( path.toPwSb(), true );
 }