Code

LPE knotholder refactoring: PointParams are not knotholder entities any more; instead...
[inkscape.git] / src / live_effects / effect.cpp
index 11e5b504871bfc13a7968f2c355f069ff16a2ac0..c4bbc31e10d57198c30bfed72b856171908a3257 100644 (file)
 #include "live_effects/lpe-constructgrid.h"
 #include "live_effects/lpe-perp_bisector.h"
 #include "live_effects/lpe-tangent_to_curve.h"
-#include "live_effects/lpe-mirror_reflect.h"
+#include "live_effects/lpe-mirror_symmetry.h"
 #include "live_effects/lpe-circle_3pts.h"
 #include "live_effects/lpe-angle_bisector.h"
 #include "live_effects/lpe-parallel.h"
 #include "live_effects/lpe-copy_rotate.h"
 #include "live_effects/lpe-offset.h"
+#include "live_effects/lpe-ruler.h"
+#include "live_effects/lpe-boolops.h"
+#include "live_effects/lpe-interpolate.h"
 // end of includes
 
 namespace Inkscape {
 
 namespace LivePathEffect {
 
-const Util::EnumData<EffectType> LPETypeData[INVALID_LPE] = {
+const Util::EnumData<EffectType> LPETypeData[] = {
     // {constant defined in effect.h, N_("name of your effect"), "name of your effect in SVG"}
-    {BEND_PATH,             N_("Bend"),                  "bend_path"},
-    {PATTERN_ALONG_PATH,    N_("Pattern Along Path"),    "skeletal"},   // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
-    {SKETCH,                N_("Sketch"),                "sketch"},
-    {VONKOCH,               N_("VonKoch"),               "vonkoch"},
-    {KNOT,                  N_("Knot"),                  "knot"},
+    {ANGLE_BISECTOR,        N_("Angle bisector"),          "angle_bisector"},
+    {BEND_PATH,             N_("Bend"),                     "bend_path"},
+    {BOOLOPS,               N_("Boolops"),                 "boolops"},
+    {CIRCLE_WITH_RADIUS,    N_("Circle (center+radius)"),   "circle_with_radius"},
+    {CIRCLE_3PTS,           N_("Circle through 3 points"), "circle_3pts"},
+    {CONSTRUCT_GRID,        N_("Construct grid"),          "construct_grid"},
 #ifdef LPE_ENABLE_TEST_EFFECTS
-    {DOEFFECTSTACK_TEST,    N_("doEffect stack test"),   "doeffectstacktest"},
+    {DOEFFECTSTACK_TEST,    N_("doEffect stack test"),     "doeffectstacktest"},
 #endif
-    {GEARS,                 N_("Gears"),                 "gears"},
-    {CURVE_STITCH,          N_("Stitch Sub-Paths"),       "curvestitching"},
-    {CIRCLE_WITH_RADIUS,    N_("Circle (center+radius)"), "circle_with_radius"},
-    {PERSPECTIVE_PATH,      N_("Perspective path"),      "perspective_path"},
-    {SPIRO,      N_("Spiro spline"),      "spiro"},
-    {LATTICE,               N_("Lattice Deformation"),   "lattice"},
-    {ENVELOPE,              N_("Envelope Deformation"),  "envelope"},
-    {CONSTRUCT_GRID,        N_("Construct grid"),        "construct_grid"},
-    {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
-    {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"},
-    {MIRROR_REFLECT, N_("Mirror reflection"), "mirror_reflect"},
-    {CIRCLE_3PTS, N_("Circle through 3 points"), "circle_3pts"},
-    {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"},
-    {PARALLEL, N_("Parallel"), "parallel"},
-    {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
-    {OFFSET, N_("Offset"), "offset"},
+    {ENVELOPE,              N_("Envelope Deformation"),    "envelope"},
+    {FREEHAND_SHAPE,        N_("Freehand Shape"),          "freehand_shape"}, // this is actually a special type of PatternAlongPath, used to paste shapes in pen/pencil tool
+    {GEARS,                 N_("Gears"),                   "gears"},
+    {INTERPOLATE,           N_("Interpolate Sub-Paths"),   "interpolate"},
+    {KNOT,                  N_("Knot"),                    "knot"},
+    {LATTICE,               N_("Lattice Deformation"),     "lattice"},
+    {MIRROR_SYMMETRY,       N_("Mirror symmetry"),         "mirror_symmetry"},
+    {OFFSET,                N_("Offset"),                  "offset"},
+    {PARALLEL,              N_("Parallel"),                "parallel"},
+    {PATTERN_ALONG_PATH,    N_("Pattern Along Path"),      "skeletal"},   // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
+    {PERP_BISECTOR,         N_("Perpendicular bisector"),  "perp_bisector"},
+    {PERSPECTIVE_PATH,      N_("Perspective path"),        "perspective_path"},
+    {COPY_ROTATE,           N_("Rotate copies"),           "copy_rotate"},
+    {RULER,                 N_("Ruler"),                   "ruler"},
+    {SKETCH,                N_("Sketch"),                  "sketch"},
+    {SPIRO,                 N_("Spiro spline"),            "spiro"},
+    {CURVE_STITCH,          N_("Stitch Sub-Paths"),        "curvestitching"},
+    {TANGENT_TO_CURVE,      N_("Tangent to curve"),        "tangent_to_curve"},
+    {VONKOCH,               N_("VonKoch"),                 "vonkoch"},
 };
-const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, INVALID_LPE);
+const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
 
 Effect*
 Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
@@ -104,6 +111,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case PATTERN_ALONG_PATH:
             neweffect = static_cast<Effect*> ( new LPEPatternAlongPath(lpeobj) );
             break;
+        case FREEHAND_SHAPE:
+            neweffect = static_cast<Effect*> ( new LPEFreehandShape(lpeobj) );
+            break;
         case BEND_PATH:
             neweffect = static_cast<Effect*> ( new LPEBendPath(lpeobj) );
             break;
@@ -151,8 +161,8 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case TANGENT_TO_CURVE:
             neweffect = static_cast<Effect*> ( new LPETangentToCurve(lpeobj) );
             break;
-        case MIRROR_REFLECT:
-            neweffect = static_cast<Effect*> ( new LPEMirrorReflect(lpeobj) );
+        case MIRROR_SYMMETRY:
+            neweffect = static_cast<Effect*> ( new LPEMirrorSymmetry(lpeobj) );
             break;
         case CIRCLE_3PTS:
             neweffect = static_cast<Effect*> ( new LPECircle3Pts(lpeobj) );
@@ -169,6 +179,15 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case OFFSET:
             neweffect = static_cast<Effect*> ( new LPEOffset(lpeobj) );
             break;
+        case RULER:
+            neweffect = static_cast<Effect*> ( new LPERuler(lpeobj) );
+            break;
+        case BOOLOPS:
+            neweffect = static_cast<Effect*> ( new LPEBoolops(lpeobj) );
+            break;
+        case INTERPOLATE:
+            neweffect = static_cast<Effect*> ( new LPEInterpolate(lpeobj) );
+            break;
         default:
             g_warning("LivePathEffect::Effect::New   called with invalid patheffect type (%d)", lpenr);
             neweffect = NULL;
@@ -197,9 +216,6 @@ Effect::createAndApply(const char* name, SPDocument *doc, SPItem *item)
     gchar *href = g_strdup_printf("#%s", repr_id);
     sp_lpe_item_add_path_effect(SP_LPE_ITEM(item), href, true);
     g_free(href);
-
-    sp_document_done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT,
-                     _("Create and apply path effect"));
 }
 
 void
@@ -227,7 +243,7 @@ Effect::~Effect()
 Glib::ustring
 Effect::getName()
 {
-    if (lpeobj->effecttype_set && lpeobj->effecttype < INVALID_LPE)
+    if (lpeobj->effecttype_set && LPETypeConverter.is_valid_id(lpeobj->effecttype) )
         return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) );
     else
         return Glib::ustring( _("No effect") );
@@ -295,7 +311,7 @@ Effect::writeParamsToSVG() {
  * your LPE. But don't forget to call the parent method so that done_pathparam_set is set to true!
  */
 void
-Effect::acceptParamPath (SPPath *param_path) {
+Effect::acceptParamPath (SPPath */*param_path*/) {
     done_pathparam_set = true;
 }
 
@@ -406,6 +422,9 @@ Effect::registerKnotHolderHandle(KnotHolderEntity* entity, const char* descr)
  */
 void
 Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
+    using namespace Inkscape::LivePathEffect;
+
+    // add handles provided by the effect itself
     std::vector<std::pair<KnotHolderEntity*, const char*> >::iterator i;
     for (i = kh_entity_vector.begin(); i != kh_entity_vector.end(); ++i) {
         KnotHolderEntity *entity = i->first;
@@ -414,19 +433,10 @@ Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
         entity->create(desktop, item, knotholder, descr);
         knotholder->add(entity);
     }
-}
 
-void
-Effect::addPointParamHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
-    using namespace Inkscape::LivePathEffect;
+    // add handles provided by the effect's parameters (if any)
     for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
-        if ((*p)->paramType() == POINT_PARAM) {
-            PointParam *pparam = static_cast<PointParam *>(*p);
-            KnotHolderEntity *e = dynamic_cast<KnotHolderEntity *>(*p);
-            e->create(desktop, item, knotholder, pparam->handleTip(),
-                      pparam->knotShape(), pparam->knotMode(), pparam->knotColor());
-            knotholder->add(e);
-        }
+        (*p)->addKnotHolderEntities(knotholder, desktop, item);
     }
 }
 
@@ -446,8 +456,8 @@ Effect::addHelperPaths(SPLPEItem *lpeitem, SPDesktop *desktop)
     }
 
     for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
-        if ((*p)->paramType() == Inkscape::LivePathEffect::PATH_PARAM) {
-            SPCurve *c = new SPCurve(static_cast<Inkscape::LivePathEffect::PathParam*>(*p)->get_pathvector());
+        if ( Inkscape::LivePathEffect::PathParam *pathparam = dynamic_cast<Inkscape::LivePathEffect::PathParam*>(*p) ) {
+            SPCurve *c = new SPCurve(pathparam->get_pathvector());
 
             // TODO: factor this out (also the copied code above); see also lpe-lattice.cpp
             SPCanvasItem *canvasitem = sp_nodepath_generate_helperpath(desktop, c, SP_ITEM(lpeitem), 0x009000ff);
@@ -460,7 +470,7 @@ Effect::addHelperPaths(SPLPEItem *lpeitem, SPDesktop *desktop)
 }
 
 void
-Effect::addHelperPathsImpl(SPLPEItem *lpeitem, SPDesktop *desktop)
+Effect::addHelperPathsImpl(SPLPEItem */*lpeitem*/, SPDesktop */*desktop*/)
 {
     // if this method is overloaded in derived classes, provides_own_flash_paths will be true
     provides_own_flash_paths = false;
@@ -597,6 +607,7 @@ Effect::transform_multiply(Geom::Matrix const& postmul, bool set)
     }
 }
 
+// TODO: take _all_ parameters into account, not only PointParams
 bool
 Effect::providesKnotholder()
 {
@@ -606,7 +617,7 @@ Effect::providesKnotholder()
 
     // otherwise: are there any PointParams?
     for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
-        if ((*p)->paramType() == Inkscape::LivePathEffect::POINT_PARAM) {
+        if ( Inkscape::LivePathEffect::PointParam *pointparam = dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p) ) {
             return true;
         }
     }