X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Flive_effects%2Feffect.cpp;h=c4bbc31e10d57198c30bfed72b856171908a3257;hb=797bee69297bbdd86c5cff2e0771a71d1e2ac69d;hp=164447387a2a80c3989419dc4eb961b089a3b3e1;hpb=9ce14357bb94b9dd92ad40bf43ef435a257b355a;p=inkscape.git diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 164447387..c4bbc31e1 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -55,40 +55,53 @@ #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 LPETypeData[INVALID_LPE] = { +const Util::EnumData 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"}, + {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 LPETypeConverter(LPETypeData, INVALID_LPE); +const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); Effect* Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) @@ -98,6 +111,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case PATTERN_ALONG_PATH: neweffect = static_cast ( new LPEPatternAlongPath(lpeobj) ); break; + case FREEHAND_SHAPE: + neweffect = static_cast ( new LPEFreehandShape(lpeobj) ); + break; case BEND_PATH: neweffect = static_cast ( new LPEBendPath(lpeobj) ); break; @@ -145,8 +161,8 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case TANGENT_TO_CURVE: neweffect = static_cast ( new LPETangentToCurve(lpeobj) ); break; - case MIRROR_REFLECT: - neweffect = static_cast ( new LPEMirrorReflect(lpeobj) ); + case MIRROR_SYMMETRY: + neweffect = static_cast ( new LPEMirrorSymmetry(lpeobj) ); break; case CIRCLE_3PTS: neweffect = static_cast ( new LPECircle3Pts(lpeobj) ); @@ -154,6 +170,24 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case ANGLE_BISECTOR: neweffect = static_cast ( new LPEAngleBisector(lpeobj) ); break; + case PARALLEL: + neweffect = static_cast ( new LPEParallel(lpeobj) ); + break; + case COPY_ROTATE: + neweffect = static_cast ( new LPECopyRotate(lpeobj) ); + break; + case OFFSET: + neweffect = static_cast ( new LPEOffset(lpeobj) ); + break; + case RULER: + neweffect = static_cast ( new LPERuler(lpeobj) ); + break; + case BOOLOPS: + neweffect = static_cast ( new LPEBoolops(lpeobj) ); + break; + case INTERPOLATE: + neweffect = static_cast ( new LPEInterpolate(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; @@ -182,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 @@ -212,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") ); @@ -241,9 +272,9 @@ Effect::doBeforeEffect (SPLPEItem */*lpeitem*/) } /** - * Effects have a parameter path set before they are applied by accepting a nonzero number of mouse - * clicks. This method activates the pen context, which waits for the specified number of clicks. - * Override Effect::acceptsNumParams() to set the number of expected mouse clicks. + * Effects can have a parameter path set before they are applied by accepting a nonzero number of + * mouse clicks. This method activates the pen context, which waits for the specified number of + * clicks. Override Effect::acceptsNumParams() to return the number of expected mouse clicks. */ void Effect::doAcceptPathPreparations(SPLPEItem *lpeitem) @@ -280,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; } @@ -294,7 +325,7 @@ Effect::doEffect (SPCurve * curve) std::vector result_pathv = doEffect_path(orig_pathv); - curve->set_pathv(result_pathv); + curve->set_pathvector(result_pathv); } std::vector @@ -391,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 >::iterator i; for (i = kh_entity_vector.begin(); i != kh_entity_vector.end(); ++i) { KnotHolderEntity *entity = i->first; @@ -399,40 +433,44 @@ 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 std; + // add handles provided by the effect's parameters (if any) for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { - if ((*p)->paramType() == Inkscape::LivePathEffect::POINT_PARAM) { - KnotHolderEntity *e = dynamic_cast(*p); - e->create(desktop, item, knotholder); - knotholder->add(e); - } + (*p)->addKnotHolderEntities(knotholder, desktop, item); } } void Effect::addHelperPaths(SPLPEItem *lpeitem, SPDesktop *desktop) { + g_return_if_fail(desktop); g_return_if_fail(SP_IS_PATH(lpeitem)); if (providesKnotholder() && showOrigPath()) { // TODO: we assume that if the LPE provides its own knotholder, there is no nodepath so we - // must create the helper curve for the original path manually; when we allow nodepaths and + // must create the helper curve for the original path manually; once we allow nodepaths and // knotholders alongside each other, this needs to be rethought! SPCanvasItem *canvasitem = sp_nodepath_generate_helperpath(desktop, SP_PATH(lpeitem)); - // TODO: Make sure the tempitem doesn't get destroyed when the mouse leaves the item Inkscape::Display::TemporaryItem* tmpitem = desktop->add_temporary_canvasitem (canvasitem, 0); lpeitem->lpe_helperpaths.push_back(tmpitem); } + for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { + if ( Inkscape::LivePathEffect::PathParam *pathparam = dynamic_cast(*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); + Inkscape::Display::TemporaryItem* tmpitem = desktop->add_temporary_canvasitem (canvasitem, 0); + lpeitem->lpe_helperpaths.push_back(tmpitem); + } + } + addHelperPathsImpl(lpeitem, 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; @@ -569,6 +607,24 @@ Effect::transform_multiply(Geom::Matrix const& postmul, bool set) } } +// TODO: take _all_ parameters into account, not only PointParams +bool +Effect::providesKnotholder() +{ + // does the effect actively provide any knotholder entities of its own? + if (kh_entity_vector.size() > 0) + return true; + + // otherwise: are there any PointParams? + for (std::vector::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { + if ( Inkscape::LivePathEffect::PointParam *pointparam = dynamic_cast(*p) ) { + return true; + } + } + + return false; +} + } /* namespace LivePathEffect */ } /* namespace Inkscape */