summaryrefslogtreecommitdiffstats
path: root/src/live_effects/effect.h
blob: ac1f0b8dc62b819f719d02ca898e1091c4790010 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#ifndef INKSCAPE_LIVEPATHEFFECT_H
#define INKSCAPE_LIVEPATHEFFECT_H

/*
 * Copyright (C) Johan Engelen 2007-2012 <j.b.c.engelen@alumnus.utwente.nl>
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

#include <glibmm/ustring.h>
#include <2geom/forward.h>
#include "ui/widget/registry.h"
#include "parameter/bool.h"
#include "effect-enum.h"


#define  LPE_CONVERSION_TOLERANCE 0.01    // FIXME: find good solution for this.

class  SPDocument;
class  SPDesktop;
class  SPItem;
class LivePathEffectObject;
class  SPLPEItem;
class  KnotHolder;
class  KnotHolderEntity;
class  SPPath;
class  SPCurve;

namespace Gtk {
    class Widget;
}

namespace Inkscape {

namespace XML {
    class Node;
}

namespace LivePathEffect {

enum LPEPathFlashType {
    SUPPRESS_FLASH,
//    PERMANENT_FLASH,
    DEFAULT
};

class Effect {
public:
    static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj);
    static void createAndApply(const char* name, SPDocument *doc, SPItem *item);
    static void createAndApply(EffectType type, SPDocument *doc, SPItem *item);

    virtual ~Effect();

    EffectType effectType() const;

    //basically, to get this method called before the derived classes, a bit
    //of indirection is needed. We first call these methods, then the below.
    void doOnApply_impl(SPLPEItem const* lpeitem);
    void doBeforeEffect_impl(SPLPEItem const* lpeitem);
    void setCurrentZoom(double cZ);
    void setSelectedNodePoints(std::vector<Geom::Point> sNP);
    bool isNodePointSelected(Geom::Point const &nodePoint) const;
    virtual void doOnApply (SPLPEItem const* lpeitem);
    virtual void doBeforeEffect (SPLPEItem const* lpeitem);
    
    virtual void doAfterEffect (SPLPEItem const* lpeitem);
    virtual void doOnRemove (SPLPEItem const* lpeitem);

    void writeParamsToSVG();

    virtual void acceptParamPath (SPPath const* param_path);
    static int acceptsNumClicks(EffectType type);
    int acceptsNumClicks() const { return acceptsNumClicks(effectType()); }
    void doAcceptPathPreparations(SPLPEItem *lpeitem);

    /*
     * isReady() indicates whether all preparations which are necessary to apply the LPE are done,
     * e.g., waiting for a parameter path either before the effect is created or when it needs a
     * path as argument. This is set in SPLPEItem::addPathEffect().
     */
    inline bool isReady() const { return is_ready; }
    inline void setReady(bool ready = true) { is_ready = ready; }

    virtual void doEffect (SPCurve * curve);

    virtual Gtk::Widget * newWidget();

    /**
     * Sets all parameters to their default values and writes them to SVG.
     */
    virtual void resetDefaults(SPItem const* item);

    /// /todo: is this method really necessary? it causes UI inconsistensies... (johan)
    virtual void transform_multiply(Geom::Affine const& postmul, bool set);

    // /TODO: providesKnotholder() is currently used as an indicator of whether a nodepath is
    // created for an item or not. When we allow both at the same time, this needs rethinking!
    bool providesKnotholder() const;
    // /TODO: in view of providesOwnFlashPaths() below, this is somewhat redundant
    //       (but spiro lpe still needs it!)
    virtual LPEPathFlashType pathFlashType() const { return DEFAULT; }
    void addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
    std::vector<Geom::PathVector> getCanvasIndicators(SPLPEItem const* lpeitem);

    inline bool providesOwnFlashPaths() const {
        return provides_own_flash_paths || show_orig_path;
    }
    inline bool showOrigPath() const { return show_orig_path; }

    Glib::ustring          getName() const;
    Inkscape::XML::Node *  getRepr();
    SPDocument *           getSPDoc();
    LivePathEffectObject * getLPEObj() {return lpeobj;};
    LivePathEffectObject const * getLPEObj() const {return lpeobj;};
    Parameter *            getParameter(const char * key);

    void readallParameters(Inkscape::XML::Node const* repr);
    void setParameter(const gchar * key, const gchar * new_value);

    inline bool isVisible() const { return is_visible; }

    void editNextParamOncanvas(SPItem * item, SPDesktop * desktop);

protected:
    Effect(LivePathEffectObject *lpeobject);

    // provide a set of doEffect functions so the developer has a choice
    // of what kind of input/output parameters he desires.
    // the order in which they appear is the order in which they are
    // called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling
    // doEffect(std::vector<Geom::Path> )
    virtual std::vector<Geom::Path>
            doEffect_path (std::vector<Geom::Path> const & path_in);
    virtual Geom::Piecewise<Geom::D2<Geom::SBasis> >
            doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);

    void registerParameter(Parameter * param);
    Parameter * getNextOncanvasEditableParam();

    virtual void addKnotHolderEntities(KnotHolder * /*knotholder*/, SPDesktop * /*desktop*/, SPItem * /*item*/) {};

    virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector<Geom::PathVector> &hp_vec);

    std::vector<Parameter *> param_vector;
    bool _provides_knotholder_entities;
    int oncanvasedit_it;
    BoolParam is_visible;

    bool show_orig_path; // set this to true in derived effects to automatically have the original
                         // path displayed as helperpath

    Inkscape::UI::Widget::Registry wr;

    LivePathEffectObject *lpeobj;

    // this boolean defaults to false, it concatenates the input path to one pwd2,
    // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each.
    bool concatenate_before_pwd2;

    SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
    Glib::ustring defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
    double current_zoom;
    std::vector<Geom::Point> selectedNodesPoints;
    SPCurve * sp_curve;
    std::vector<Geom::Path> pathvector_before_effect;
private:
    bool provides_own_flash_paths; // if true, the standard flash path is suppressed

    bool is_ready;

    Effect(const Effect&);
    Effect& operator=(const Effect&);
};

} //namespace LivePathEffect
} //namespace Inkscape

#endif

/*
  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 :