1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #ifndef INKSCAPE_LIVEPATHEFFECT_H
3 #define INKSCAPE_LIVEPATHEFFECT_H
4 
5 /*
6  * Copyright (C) Johan Engelen 2007-2012 <j.b.c.engelen@alumnus.utwente.nl>
7  *
8  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9  */
10 
11 #include "effect-enum.h"
12 #include "parameter/bool.h"
13 #include "parameter/hidden.h"
14 #include "ui/widget/registry.h"
15 #include <2geom/forward.h>
16 #include <glibmm/ustring.h>
17 #include <gtkmm/eventbox.h>
18 #include <gtkmm/expander.h>
19 
20 
21 #define  LPE_CONVERSION_TOLERANCE 0.01    // FIXME: find good solution for this.
22 
23 class  SPDocument;
24 class  SPDesktop;
25 class  SPItem;
26 class  LivePathEffectObject;
27 class  SPLPEItem;
28 class  KnotHolder;
29 class  KnotHolderEntity;
30 class  SPPath;
31 class  SPCurve;
32 
33 namespace Gtk {
34     class Widget;
35 }
36 
37 namespace Inkscape {
38 
39 namespace XML {
40     class Node;
41 }
42 
43 namespace LivePathEffect {
44 
45 enum LPEPathFlashType {
46     SUPPRESS_FLASH,
47 //    PERMANENT_FLASH,
48     DEFAULT
49 };
50 
51 enum LPEAction {
52     LPE_ERASE = 0,
53     LPE_TO_OBJECTS,
54     LPE_VISIBILITY
55 };
56 
57 class Effect {
58 public:
59     static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj);
60     static void createAndApply(const char* name, SPDocument *doc, SPItem *item);
61     static void createAndApply(EffectType type, SPDocument *doc, SPItem *item);
62 
63     virtual ~Effect();
64     Effect(const Effect&) = delete;
65     Effect& operator=(const Effect&) = delete;
66 
67     EffectType effectType() const;
68 
69     //basically, to get this method called before the derived classes, a bit
70     //of indirection is needed. We first call these methods, then the below.
71     void doAfterEffect_impl(SPLPEItem const *lpeitem, SPCurve *curve);
72     void doOnApply_impl(SPLPEItem const* lpeitem);
73     void doBeforeEffect_impl(SPLPEItem const* lpeitem);
74     void setCurrentZoom(double cZ);
75     void setSelectedNodePoints(std::vector<Geom::Point> sNP);
76     bool isNodePointSelected(Geom::Point const &nodePoint) const;
77     bool isOnClipboard();
78     virtual void doOnApply (SPLPEItem const* lpeitem);
79     virtual void doBeforeEffect (SPLPEItem const* lpeitem);
80     std::vector<SPLPEItem *> getCurrrentLPEItems() const;
81 
82 private:
83     virtual void transform_multiply(Geom::Affine const &postmul, bool set);
84 
85 public:
86     void transform_multiply(Geom::Affine const &postmul, SPLPEItem *);
87     virtual void doAfterEffect (SPLPEItem const* lpeitem, SPCurve *curve);
88     virtual void doOnException(SPLPEItem const *lpeitem);
89     virtual void doOnRemove (SPLPEItem const* lpeitem);
90     virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem);
91     void writeParamsToSVG();
92 
93     virtual void acceptParamPath (SPPath const* param_path);
94     static int acceptsNumClicks(EffectType type);
acceptsNumClicks()95     int acceptsNumClicks() const { return acceptsNumClicks(effectType()); }
getCurrentShape()96     SPShape * getCurrentShape() const { return current_shape; };
setCurrentShape(SPShape * shape)97     void setCurrentShape(SPShape * shape) { current_shape = shape; }
98     void processObjects(LPEAction lpe_action);
99 
100     /*
101      * isReady() indicates whether all preparations which are necessary to apply the LPE are done,
102      * e.g., waiting for a parameter path either before the effect is created or when it needs a
103      * path as argument. This is set in SPLPEItem::addPathEffect().
104      */
isReady()105     inline bool isReady() const { return is_ready; }
106     inline void setReady(bool ready = true) { is_ready = ready; }
107 
108     virtual void doEffect (SPCurve * curve);
109 
110     virtual Gtk::Widget * newWidget();
111     virtual Gtk::Widget * defaultParamSet();
112     /**
113      * Sets all parameters to their default values and writes them to SVG.
114      */
115     virtual void resetDefaults(SPItem const* item);
116 
117     // /TODO: providesKnotholder() is currently used as an indicator of whether a nodepath is
118     // created for an item or not. When we allow both at the same time, this needs rethinking!
119     bool providesKnotholder() const;
120     // /TODO: in view of providesOwnFlashPaths() below, this is somewhat redundant
121     //       (but spiro lpe still needs it!)
pathFlashType()122     virtual LPEPathFlashType pathFlashType() const { return DEFAULT; }
123     void addHandles(KnotHolder *knotholder, SPItem *item);
124     std::vector<Geom::PathVector> getCanvasIndicators(SPLPEItem const* lpeitem);
125     void update_helperpath();
126     bool has_exception;
127 
providesOwnFlashPaths()128     inline bool providesOwnFlashPaths() const {
129         return provides_own_flash_paths || show_orig_path;
130     }
showOrigPath()131     inline bool showOrigPath() const { return show_orig_path; }
132 
133     Glib::ustring          getName() const;
134     Inkscape::XML::Node *  getRepr();
135     SPDocument *           getSPDoc();
getLPEObj()136     LivePathEffectObject * getLPEObj() {return lpeobj;};
getLPEObj()137     LivePathEffectObject const * getLPEObj() const {return lpeobj;};
138     Parameter *            getParameter(const char * key);
139 
140     void readallParameters(Inkscape::XML::Node const* repr);
141     void setParameter(const gchar * key, const gchar * new_value);
142 
isVisible()143     inline bool isVisible() const { return is_visible; }
144 
145     void editNextParamOncanvas(SPItem * item, SPDesktop * desktop);
146     bool apply_to_clippath_and_mask;
147     bool keep_paths; // set this to false allow retain extra generated objects, see measure line LPE
148     bool is_load;
149     bool on_remove_all;
150     bool refresh_widgets;
151     BoolParam is_visible;
152     HiddenParam lpeversion;
153     Geom::PathVector pathvector_before_effect;
154     Geom::PathVector pathvector_after_effect;
155     SPLPEItem *sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with
156                             // them.
157     SPShape *current_shape; // these get stored in performPathEffects.
158   protected:
159     Effect(LivePathEffectObject *lpeobject);
160 
161     // provide a set of doEffect functions so the developer has a choice
162     // of what kind of input/output parameters he desires.
163     // the order in which they appear is the order in which they are
164     // called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling
165     // doEffect(Geom::PathVector )
166     virtual Geom::PathVector
167             doEffect_path (Geom::PathVector const & path_in);
168     virtual Geom::Piecewise<Geom::D2<Geom::SBasis> >
169             doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
170 
171     void registerParameter(Parameter * param);
172     Parameter * getNextOncanvasEditableParam();
173 
addKnotHolderEntities(KnotHolder *,SPItem *)174     virtual void addKnotHolderEntities(KnotHolder * /*knotholder*/, SPItem * /*item*/) {};
175 
176     virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector<Geom::PathVector> &hp_vec);
177 
178     std::vector<Parameter *> param_vector;
179     bool _provides_knotholder_entities;
180 
181     int oncanvasedit_it;
182     bool is_applied;
183     bool show_orig_path; // set this to true in derived effects to automatically have the original
184                          // path displayed as helperpath
185 
186     Inkscape::UI::Widget::Registry wr;
187 
188     LivePathEffectObject *lpeobj;
189 
190     // this boolean defaults to false, it concatenates the input path to one pwd2,
191     // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each.
192     bool concatenate_before_pwd2;
193     std::vector<Glib::ustring> items;
194     double current_zoom;
195     std::vector<Geom::Point> selectedNodesPoints;
196 
197 private:
198     void onDefaultsExpanderChanged(Gtk::Expander * expander);
199     void setDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Parameter *param, Gtk::Image *info,
200                          Gtk::Button *set, Gtk::Button *unset);
201     void unsetDefaultParam(Glib::ustring pref_path, Glib::ustring tooltip, Parameter *param, Gtk::Image *info,
202                            Gtk::Button *set, Gtk::Button *unset);
203     bool provides_own_flash_paths; // if true, the standard flash path is suppressed
204 
205     bool is_ready;
206     bool defaultsopen;
207 };
208 
209 } //namespace LivePathEffect
210 } //namespace Inkscape
211 
212 #endif
213 
214 /*
215   Local Variables:
216   mode:c++
217   c-file-style:"stroustrup"
218   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
219   indent-tabs-mode:nil
220   fill-column:99
221   End:
222 */
223 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
224