effect.cpp revision 4afe3fc6b9c122bc5c02b27aea3845ba41384d2a
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#define INKSCAPE_LIVEPATHEFFECT_CPP
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Released under GNU GPL, read the file 'COPYING' for more information
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/effect.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "xml/node-event-vector.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "sp-object.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "attributes.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "message-stack.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "desktop.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "inkscape.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "document.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "document-private.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "xml/document.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <glibmm/i18n.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "pen-context.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "tools-switch.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "message-stack.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "desktop.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "nodepath.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpeobject.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/parameter/parameter.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <glibmm/ustring.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "libnr/n-art-bpath-2geom.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "display/curve.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <gtkmm.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <exception>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <2geom/sbasis-to-bezier.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <2geom/matrix.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <2geom/pathvector.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster// include effects:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-patternalongpath.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-bendpath.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-sketch.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-vonkoch.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-knot.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-test-doEffect-stack.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-gears.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-curvestitch.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-circle_with_radius.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-perspective_path.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-spiro.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-lattice.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-envelope.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-constructgrid.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-perp_bisector.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-tangent_to_curve.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-mirror_symmetry.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-circle_3pts.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-angle_bisector.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-parallel.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-copy_rotate.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-offset.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-ruler.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-boolops.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-interpolate.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "live_effects/lpe-text_label.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster// end of includes
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosternamespace Inkscape {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosternamespace LivePathEffect {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterconst Util::EnumData<EffectType> LPETypeData[] = {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // {constant defined in effect.h, N_("name of your effect"), "name of your effect in SVG"}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {BEND_PATH, N_("Bend"), "bend_path"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {BOOLOPS, N_("Boolops"), "boolops"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {CIRCLE_WITH_RADIUS, N_("Circle (center+radius)"), "circle_with_radius"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {CIRCLE_3PTS, N_("Circle through 3 points"), "circle_3pts"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#ifdef LPE_ENABLE_TEST_EFFECTS
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#endif
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {ENVELOPE, N_("Envelope Deformation"), "envelope"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {FREEHAND_SHAPE, N_("Freehand Shape"), "freehand_shape"}, // this is actually a special type of PatternAlongPath, used to paste shapes in pen/pencil tool
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {GEARS, N_("Gears"), "gears"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {KNOT, N_("Knot"), "knot"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {LATTICE, N_("Lattice Deformation"), "lattice"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {OFFSET, N_("Offset"), "offset"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {PARALLEL, N_("Parallel"), "parallel"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {RULER, N_("Ruler"), "ruler"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {SKETCH, N_("Sketch"), "sketch"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {SPIRO, N_("Spiro spline"), "spiro"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {TEXT_LABEL, N_("Text label"), "text_label"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {VONKOCH, N_("VonKoch"), "vonkoch"},
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterconst Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Effect* neweffect = NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster switch (lpenr) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case PATTERN_ALONG_PATH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEPatternAlongPath(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case FREEHAND_SHAPE:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEFreehandShape(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case BEND_PATH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEBendPath(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case SKETCH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPESketch(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case VONKOCH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEVonKoch(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case KNOT:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEKnot(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#ifdef LPE_ENABLE_TEST_EFFECTS
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DOEFFECTSTACK_TEST:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEdoEffectStackTest(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#endif
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case GEARS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEGears(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case CURVE_STITCH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPECurveStitch(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case LATTICE:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPELattice(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case ENVELOPE:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEEnvelope(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case CIRCLE_WITH_RADIUS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPECircleWithRadius(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case PERSPECTIVE_PATH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEPerspectivePath(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case SPIRO:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPESpiro(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case CONSTRUCT_GRID:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEConstructGrid(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case PERP_BISECTOR:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEPerpBisector(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case TANGENT_TO_CURVE:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPETangentToCurve(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case MIRROR_SYMMETRY:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEMirrorSymmetry(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case CIRCLE_3PTS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPECircle3Pts(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case ANGLE_BISECTOR:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEAngleBisector(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case PARALLEL:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEParallel(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case COPY_ROTATE:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPECopyRotate(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case OFFSET:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEOffset(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case RULER:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPERuler(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case BOOLOPS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEBoolops(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case INTERPOLATE:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPEInterpolate(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case TEXT_LABEL:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = static_cast<Effect*> ( new LPETextLabel(lpeobj) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster default:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect = NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (neweffect) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster neweffect->readallParameters(SP_OBJECT_REPR(lpeobj));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return neweffect;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::createAndApply(const char* name, SPDocument *doc, SPItem *item)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Path effect definition
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster repr->setAttribute("effect", name);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->addChild(repr, NULL); // adds to <defs> and assigns the 'id' attribute
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster const gchar * repr_id = repr->attribute("id");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Inkscape::GC::release(repr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster gchar *href = g_strdup_printf("#%s", repr_id);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sp_lpe_item_add_path_effect(SP_LPE_ITEM(item), href, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster g_free(href);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::createAndApply(EffectType type, SPDocument *doc, SPItem *item)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster createAndApply(LPETypeConverter.get_key(type).c_str(), doc, item);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::Effect(LivePathEffectObject *lpeobject)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster : oncanvasedit_it(0),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster done_pathparam_set(false),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster show_orig_path(false),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster lpeobj(lpeobject),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster concatenate_before_pwd2(false),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster provides_own_flash_paths(true) // is automatically set to false if providesOwnFlashPaths() is not overridden
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster registerParameter( dynamic_cast<Parameter *>(&is_visible) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::~Effect()
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterGlib::ustring
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::getName()
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (lpeobj->effecttype_set && LPETypeConverter.is_valid_id(lpeobj->effecttype) )
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster else
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return Glib::ustring( _("No effect") );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffectType
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::effectType() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return lpeobj->effecttype;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Is performed a single time when the effect is freshly applied to a path
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::doOnApply (SPLPEItem */*lpeitem*/)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Is performed each time before the effect is updated.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::doBeforeEffect (SPLPEItem */*lpeitem*/)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster //Do nothing for simple effects
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Effects can have a parameter path set before they are applied by accepting a nonzero number of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * mouse clicks. This method activates the pen context, which waits for the specified number of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * clicks. Override Effect::acceptsNumParams() to return the number of expected mouse clicks.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::doAcceptPathPreparations(SPLPEItem *lpeitem)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // switch to pen context
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop?
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!tools_isactive(desktop, TOOLS_FREEHAND_PEN)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster tools_switch(desktop, TOOLS_FREEHAND_PEN);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPEventContext *ec = desktop->event_context;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPPenContext *pc = SP_PEN_CONTEXT(ec);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pc->expecting_clicks_for_LPE = this->acceptsNumParams();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pc->waiting_LPE = this;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pc->waiting_item = lpeitem;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pc->polylines_only = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ec->desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster g_strdup_printf(_("Please specify a parameter path for the LPE '%s' with %d mouse clicks"),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster getName().c_str(), acceptsNumParams()));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::writeParamsToSVG() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster std::vector<Inkscape::LivePathEffect::Parameter *>::iterator p;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (p = param_vector.begin(); p != param_vector.end(); ++p) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (*p)->write_to_SVG();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If the effect expects a path parameter (specified by a number of mouse clicks) before it is
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * applied, this is the method that processes the resulting path. Override it to customize it for
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your LPE. But don't forget to call the parent method so that done_pathparam_set is set to true!
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::acceptParamPath (SPPath */*param_path*/) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster done_pathparam_set = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Here be the doEffect function chain:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::doEffect (SPCurve * curve)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster std::vector<Geom::Path> orig_pathv = curve->get_pathvector();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster std::vector<Geom::Path> result_pathv = doEffect_path(orig_pathv);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster curve->set_pathvector(result_pathv);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstd::vector<Geom::Path>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::doEffect_path (std::vector<Geom::Path> const & path_in)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster std::vector<Geom::Path> path_out;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ( !concatenate_before_pwd2 ) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // default behavior
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (unsigned int i=0; i < path_in.size(); i++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = path_in[i].toPwSb();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect_pwd2(pwd2_in);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster std::vector<Geom::Path> path = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // add the output path vector to the already accumulated vector:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (unsigned int j=0; j < path.size(); j++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster path_out.push_back(path[j]);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // concatenate the path into possibly discontinuous pwd2
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (unsigned int i=0; i < path_in.size(); i++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster pwd2_in.concat( path_in[i].toPwSb() );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect_pwd2(pwd2_in);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster path_out = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return path_out;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterGeom::Piecewise<Geom::D2<Geom::SBasis> >
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster g_warning("Effect has no doEffect implementation");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return pwd2_in;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterEffect::readallParameters(Inkscape::XML::Node * repr)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster std::vector<Parameter *>::iterator it = param_vector.begin();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (it != param_vector.end()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Parameter * param = *it;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster const gchar * key = param->param_key.c_str();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster const gchar * value = repr->attribute(key);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (value) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster bool accepted = param->param_readSVGValue(value);
if (!accepted) {
g_warning("Effect::readallParameters - '%s' not accepted for %s", value, key);
}
} else {
// set default value
param->param_set_default();
}
it++;
}
}
/* This function does not and SHOULD NOT write to XML */
void
Effect::setParameter(const gchar * key, const gchar * new_value)
{
Parameter * param = getParameter(key);
if (param) {
if (new_value) {
bool accepted = param->param_readSVGValue(new_value);
if (!accepted) {
g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key);
}
} else {
// set default value
param->param_set_default();
}
}
}
void
Effect::registerParameter(Parameter * param)
{
param_vector.push_back(param);
}
// TODO: should we provide a way to alter the handle's appearance?
void
Effect::registerKnotHolderHandle(KnotHolderEntity* entity, const char* descr)
{
kh_entity_vector.push_back(std::make_pair(entity, descr));
}
/**
* Add all registered LPE knotholder handles to the knotholder
*/
void
Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
using namespace Inkscape::LivePathEffect;
// add handles provided by the effect itself
addKnotHolderEntities(knotholder, desktop, item);
// add handles provided by the effect's parameters (if any)
for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
(*p)->addKnotHolderEntities(knotholder, desktop, item);
}
}
void
Effect::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
// TODO: The entities in kh_entity_vector are already instantiated during the call
// to registerKnotHolderHandle(), but they are recreated here. Also, we must not
// delete them when the knotholder is destroyed, whence the clumsy function
// isDeletable(). If we could create entities of different classes dynamically,
// this would be much nicer. How to do this?
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;
const char *descr = i->second;
entity->create(desktop, item, knotholder, descr);
knotholder->add(entity);
}
}
/**
* Return a vector of PathVectors which contain all helperpaths that should be drawn by the effect.
* This is the function called by external code like SPLPEItem.
*/
std::vector<Geom::PathVector>
Effect::getHelperPaths(SPLPEItem *lpeitem)
{
std::vector<Geom::PathVector> hp_vec;
if (!SP_IS_SHAPE(lpeitem)) {
g_print ("How to handle helperpaths for non-shapes?\n");
return hp_vec;
}
// TODO: we can probably optimize this by using a lot more references
// rather than copying PathVectors all over the place
if (show_orig_path) {
// add original path to helperpaths
SPCurve* curve = sp_shape_get_curve (SP_SHAPE(lpeitem));
hp_vec.push_back(curve->get_pathvector());
}
// add other helperpaths provided by the effect itself
addCanvasIndicators(lpeitem, hp_vec);
// add helperpaths provided by the effect's parameters
for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
(*p)->addCanvasIndicators(lpeitem, hp_vec);
}
return hp_vec;
}
/**
* Add possible canvas indicators (i.e., helperpaths other than the original path) to \a hp_vec
* This function should be overwritten by derived effects if they want to provide their own helperpaths.
*/
void
Effect::addCanvasIndicators(SPLPEItem *lpeitem, std::vector<Geom::PathVector> &hp_vec)
{
}
/**
* This *creates* a new widget, management of deletion should be done by the caller
*/
Gtk::Widget *
Effect::newWidget(Gtk::Tooltips * tooltips)
{
// use manage here, because after deletion of Effect object, others might still be pointing to this widget.
Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() );
vbox->set_border_width(5);
std::vector<Parameter *>::iterator it = param_vector.begin();
while (it != param_vector.end()) {
Parameter * param = *it;
Gtk::Widget * widg = param->param_newWidget(tooltips);
Glib::ustring * tip = param->param_getTooltip();
if (widg) {
vbox->pack_start(*widg, true, true, 2);
if (tip != NULL) {
tooltips->set_tip(*widg, *tip);
}
}
it++;
}
return dynamic_cast<Gtk::Widget *>(vbox);
}
Inkscape::XML::Node *
Effect::getRepr()
{
return SP_OBJECT_REPR(lpeobj);
}
SPDocument *
Effect::getSPDoc()
{
if (SP_OBJECT_DOCUMENT(lpeobj) == NULL) g_message("Effect::getSPDoc() returns NULL");
return SP_OBJECT_DOCUMENT(lpeobj);
}
Parameter *
Effect::getParameter(const char * key)
{
Glib::ustring stringkey(key);
std::vector<Parameter *>::iterator it = param_vector.begin();
while (it != param_vector.end()) {
Parameter * param = *it;
if ( param->param_key == key) {
return param;
}
it++;
}
return NULL;
}
Parameter *
Effect::getNextOncanvasEditableParam()
{
if (param_vector.size() == 0) // no parameters
return NULL;
oncanvasedit_it++;
if (oncanvasedit_it >= static_cast<int>(param_vector.size())) {
oncanvasedit_it = 0;
}
int old_it = oncanvasedit_it;
do {
Parameter * param = param_vector[oncanvasedit_it];
if(param && param->oncanvas_editable) {
return param;
} else {
oncanvasedit_it++;
if (oncanvasedit_it == static_cast<int>(param_vector.size())) { // loop round the map
oncanvasedit_it = 0;
}
}
} while (oncanvasedit_it != old_it); // iterate until complete loop through map has been made
return NULL;
}
void
Effect::editNextParamOncanvas(SPItem * item, SPDesktop * desktop)
{
if (!desktop) return;
Parameter * param = getNextOncanvasEditableParam();
if (param) {
param->param_editOncanvas(item, desktop);
gchar *message = g_strdup_printf(_("Editing parameter <b>%s</b>."), param->param_label.c_str());
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, message);
g_free(message);
} else {
desktop->messageStack()->flash( Inkscape::WARNING_MESSAGE,
_("None of the applied path effect's parameters can be edited on-canvas.") );
}
}
/* This function should reset the defaults and is used for example to initialize an effect right after it has been applied to a path
* The nice thing about this is that this function can use knowledge of the original path and set things accordingly for example to the size or origin of the original path!
*/
void
Effect::resetDefaults(SPItem * /*item*/)
{
// do nothing for simple effects
}
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)
{
// cycle through all parameters. Most parameters will not need transformation, but path and point params do.
for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); it++) {
Parameter * param = *it;
param->param_transform_multiply(postmul, 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<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
// if ( Inkscape::LivePathEffect::PointParam *pointparam = dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p) ) {
if (dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p)) {
return true;
}
}
return false;
}
} /* namespace LivePathEffect */
} /* namespace Inkscape */
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :