summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2019-01-25 00:04:08 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2019-01-27 00:37:54 +0000
commiteab7157c28648171c0b68e96d41478443c267f9f (patch)
tree1b108140d21541942c1e037b055a5ac6c21bd26d /src
parentImprovements to icon loader code (diff)
downloadinkscape-eab7157c28648171c0b68e96d41478443c267f9f.tar.gz
inkscape-eab7157c28648171c0b68e96d41478443c267f9f.zip
Initial work of LPESelector
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect-enum.h908
-rw-r--r--src/live_effects/effect.cpp70
-rw-r--r--src/ui/dialog/livepatheffect-add.cpp222
-rw-r--r--src/ui/dialog/livepatheffect-add.h69
-rw-r--r--src/ui/dialog/lpe-selector.cpp69
-rw-r--r--src/ui/dialog/lpe-selector.h38
6 files changed, 1169 insertions, 207 deletions
diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h
index b662d3263..595c81a78 100644
--- a/src/live_effects/effect-enum.h
+++ b/src/live_effects/effect-enum.h
@@ -11,6 +11,10 @@
*/
#include "util/enums.h"
+#include <glibmm/i18n.h>
+
+
+
namespace Inkscape {
namespace LivePathEffect {
@@ -75,8 +79,908 @@ enum EffectType {
INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan)
};
-extern const Util::EnumData<EffectType> LPETypeData[]; /// defined in effect.cpp
-extern const Util::EnumDataConverter<EffectType> LPETypeConverter; /// defined in effect.cpp
+template<typename E>
+ struct EnumEffectData
+ {
+ E id;
+ const Glib::ustring label;
+ const Glib::ustring key;
+ const Glib::ustring icon;
+ const Glib::ustring description;
+ const bool on_path;
+ const bool on_shape;
+ const bool on_group;
+ const bool on_use;
+ const bool on_image;
+ const bool on_text;
+ };
+
+const Glib::ustring empty_string("");
+
+/**
+ * Simplified management of enumerations of LPE items with UI labels.
+ *
+ * @note that get_id_from_key and get_id_from_label return 0 if it cannot find an entry for that key string.
+ * @note that get_label and get_key return an empty string when the requested id is not in the list.
+ */
+template<typename E> class EnumEffectDataConverter
+{
+public:
+ typedef EnumEffectData<E> Data;
+
+ EnumEffectDataConverter(const EnumEffectData<E>* cd, const unsigned int length)
+ : _length(length), _data(cd)
+ {}
+
+ E get_id_from_label(const Glib::ustring& label) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].label == label)
+ return _data[i].id;
+ }
+
+ return (E)0;
+ }
+
+ E get_id_from_key(const Glib::ustring& key) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].key == key)
+ return _data[i].id;
+ }
+
+ return (E)0;
+ }
+
+ bool is_valid_key(const Glib::ustring& key) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].key == key)
+ return true;
+ }
+
+ return false;
+ }
+
+ bool is_valid_id(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return true;
+ }
+ return false;
+ }
+
+ const Glib::ustring& get_label(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].label;
+ }
+
+ return empty_string;
+ }
+
+ const Glib::ustring& get_key(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].key;
+ }
+
+ return empty_string;
+ }
+
+ const Glib::ustring& get_icon(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].icon;
+ }
+
+ return empty_string;
+ }
+
+ const Glib::ustring& get_description(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].description;
+ }
+
+ return empty_string;
+ }
+
+ const bool& get_on_path(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].path;
+ }
+
+ return false;
+ }
+
+ const bool& get_on_shape(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].shape;
+ }
+
+ return false;
+ }
+
+ const bool& get_on_group(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].group;
+ }
+
+ return false;
+ }
+
+ const bool& get_on_text(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].shape;
+ }
+
+ return false;
+ }
+
+ const bool& get_on_use(const E id) const
+ {
+ for(unsigned int i = 0; i < _length; ++i) {
+ if(_data[i].id == id)
+ return _data[i].use;
+ }
+
+ return false;
+ }
+
+ const EnumEffectData<E>& data(const unsigned int i) const
+ {
+ return _data[i];
+ }
+
+ const unsigned int _length;
+private:
+ const EnumEffectData<E>* _data;
+};
+
+const EnumEffectData<EffectType> LPETypeData[] = {
+ // {constant defined in effect-enum.h, N_("name of your effect"), "name of your effect in SVG"}
+/* 0.46 */
+ {
+ BEND_PATH
+ , N_("Bend") //label
+ , "bend_path" //key
+ , "bend-path" //icon
+ , N_("Curve a item based on skeleton path") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ GEARS
+ , N_("Gears") //label
+ , "gears" //key
+ , "gears" //icon
+ , N_("Create configurable gears") //description
+ , true //on_path
+ , true //on_shape
+ , false //on_group
+ , false //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ PATTERN_ALONG_PATH
+ , N_("Pattern Along Path") //label
+ , "skeletal" //key
+ , "skeletal" //icon
+ , N_("transform a tiem along path with or without repeating") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ }, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
+ {
+ CURVE_STITCH
+ , N_("Stitch Sub-Paths") //label
+ , "curvestitching" //key
+ , "curvestitching" //icon
+ , N_("curvestitching") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+/* 0.47 */
+ {
+ VONKOCH
+ , N_("VonKoch") //label
+ , "vonkoch" //key
+ , "vonkoch" //icon
+ , N_("vonkoch") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ KNOT
+ , N_("Knot") //label
+ , "knot" //key
+ , "knot" //icon
+ , N_("knot") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ CONSTRUCT_GRID
+ , N_("Construct grid") //label
+ , "construct_grid" //key
+ , "construct-grid" //icon
+ , N_("construct_grid") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ SPIRO
+ , N_("Spiro spline") //label
+ , "spiro" //key
+ , "spiro" //icon
+ , N_("spiro") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ ENVELOPE
+ , N_("Envelope Deformation") //label
+ , "envelope" //key
+ , "envelope" //icon
+ , N_("Envelope Deformation") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ INTERPOLATE
+ , N_("Interpolate Sub-Paths") //label
+ , "interpolate" //key
+ , "interpolate" //icon
+ , N_("Interpolate Sub-Paths") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ ROUGH_HATCHES
+ , N_("Hatches (rough)") //label
+ , "rough_hatches" //key
+ , "rough-hatches" //icon
+ , N_("Hatches (rough)") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ SKETCH
+ , N_("Sketch") //label
+ , "sketch" //key
+ , "sketch" //icon
+ , N_("Sketch") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ RULER
+ , N_("Ruler") //label
+ , "ruler" //key
+ , "ruler" //icon
+ , N_("Ruler") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+/* 0.91 */
+ {
+ POWERSTROKE
+ , N_("Power stroke") //label
+ , "powerstroke" //key
+ , "powerstroke" //icon
+ , N_("Power stroke") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ CLONE_ORIGINAL
+ , N_("Clone original") //label
+ , "clone_original" //key
+ , "clone-original" //icon
+ , N_("Clone original") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+/* 0.92 */
+ {
+ SIMPLIFY
+ , N_("Simplify") //label
+ , "simplify" //key
+ , "simplify" //icon
+ , N_("Simplify") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ LATTICE2
+ , N_("Lattice Deformation 2") //label
+ , "lattice2" //key
+ , "lattice2" //icon
+ , N_("Lattice Deformation 2") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ PERSPECTIVE_ENVELOPE
+ , N_("Perspective/Envelope") //label
+ , "perspective-envelope" //key wrong key with "-" retain because historic
+ , "perspective-envelope" //icon
+ , N_("Perspective/Envelope") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ INTERPOLATE_POINTS
+ , N_("Interpolate points") //label
+ , "interpolate_points" //key
+ , "interpolate-points" //icon
+ , N_("Interpolate points") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ TRANSFORM_2PTS
+ , N_("Transform by 2 points") //label
+ , "transform_2pts" //key
+ , "transform-2pts" //icon
+ , N_("Transform by 2 points") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ SHOW_HANDLES
+ , N_("Show handles") //label
+ , "show_handles" //key
+ , "show-handles" //icon
+ , N_("Show handles") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ ROUGHEN
+ , N_("Roughen") //label
+ , "roughen" //key
+ , "roughen" //icon
+ , N_("Roughen") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ BSPLINE
+ , N_("BSpline") //label
+ , "bspline" //key
+ , "bspline" //icon
+ , N_("BSpline") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ JOIN_TYPE
+ , N_("Join type") //label
+ , "join_type" //key
+ , "join-type" //icon
+ , N_("Join type") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ TAPER_STROKE
+ , N_("Taper stroke") //label
+ , "taper_stroke" //key
+ , "taper-stroke" //icon
+ , N_("Taper stroke") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ MIRROR_SYMMETRY
+ , N_("Mirror symmetry") //label
+ , "mirror_symmetry" //key
+ , "mirror-symmetry" //icon
+ , N_("Mirror symmetry") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ COPY_ROTATE
+ , N_("Rotate copies") //label
+ , "copy_rotate" //key
+ , "copy-rotate" //icon
+ , N_("Rotate copies") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+/* Ponyscape -> Inkscape 0.92*/
+ {
+ ATTACH_PATH
+ , N_("Attach path") //label
+ , "attach_path" //key
+ , "attach-path" //icon
+ , N_("Attach path") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ FILL_BETWEEN_STROKES
+ , N_("Fill between strokes") //label
+ , "fill_between_strokes" //key
+ , "fill-between-strokes" //icon
+ , N_("Fill between strokes") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ FILL_BETWEEN_MANY
+ , N_("Fill between many") //label
+ , "fill_between_many" //key
+ , "fill-between-many" //icon
+ , N_("Fill between many") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ ELLIPSE_5PTS
+ , N_("Ellipse by 5 points") //label
+ , "ellipse_5pts" //key
+ , "ellipse-5pts" //icon
+ , N_("Ellipse by 5 points") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ BOUNDING_BOX
+ , N_("Bounding Box") //label
+ , "bounding_box" //key
+ , "bounding-box" //icon
+ , N_("Bounding Box") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+/* 1.0 */
+ {
+ MEASURE_SEGMENTS
+ , N_("Measure Segments") //label
+ , "measure_segments" //key
+ , "measure-segments" //icon
+ , N_("Measure Segments") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ FILLET_CHAMFER
+ , N_("Fillet/Chamfer") //label
+ , "fillet_chamfer" //key
+ , "fillet-chamfer" //icon
+ , N_("Fillet/Chamfer") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ BOOL_OP
+ , N_("Boolean operation") //label
+ , "bool_op" //key
+ , "bool-op" //icon
+ , N_("Boolean operation") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ EMBRODERY_STITCH
+ , N_("Embroidery stitch") //label
+ , "embrodery_stitch" //key
+ , "embrodery-stitch" //icon
+ , N_("Embroidery stitch") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ POWERCLIP
+ , N_("Power clip") //label
+ , "powerclip" //key
+ , "powerclip" //icon
+ , N_("Power clip") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ POWERMASK
+ , N_("Power mask") //label
+ , "powermask" //key
+ , "powermask" //icon
+ , N_("Power mask") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ PTS2ELLIPSE
+ , N_("Ellipse from points") //label
+ , "pts2ellipse" //key
+ , "pts2ellipse" //icon
+ , N_("Ellipse from points") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ OFFSET
+ , N_("Offset") //label
+ , "offset" //key
+ , "offset" //icon
+ , N_("Offset") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ DASH_STROKE
+ , N_("Dash Stroke") //label
+ , "dash_stroke" //key
+ , "dash-stroke" //icon
+ , N_("Dash Stroke") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+#ifdef LPE_ENABLE_TEST_EFFECTS
+ {
+ DOEFFECTSTACK_TEST
+ , N_("doEffect stack test") //label
+ , "doeffectstacktest" //key
+ , "experimental" //icon
+ , N_("doEffect stack test") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ ANGLE_BISECTOR
+ , N_("Angle bisector") //label
+ , "angle_bisector" //key
+ , "experimental" //icon
+ , N_("Angle bisector") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ CIRCLE_WITH_RADIUS
+ , N_("Circle (by center and radius)") //label
+ , "circle_with_radius" //key
+ , "experimental" //icon
+ , N_("Circle (by center and radius)") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ CIRCLE_3PTS
+ , N_("Circle by 3 points") //label
+ , "circle_3pts" //key
+ , "experimental" //icon
+ , N_("Circle by 3 points") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ DYNASTROKE
+ , N_("Dynamic stroke") //label
+ , "dynastroke" //key
+ , "experimental" //icon
+ , N_("Dynamic stroke") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ EXTRUDE
+ , N_("Extrude") //label
+ , "extrude" //key
+ , "experimental" //icon
+ , N_("Extrude") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ LATTICE
+ , N_("Lattice Deformation") //label
+ , "lattice" //key
+ , "experimental" //icon
+ , N_("Lattice Deformation") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ LINE_SEGMENT
+ , N_("Line Segment") //label
+ , "line_segment" //key
+ , "experimental" //icon
+ , N_("Line Segment") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ PARALLEL
+ , N_("Parallel") //label
+ , "parallel" //key
+ , "experimental" //icon
+ , N_("Parallel") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ PATH_LENGTH
+ , N_("Path length") //label
+ , "path_length" //key
+ , "experimental" //icon
+ , N_("Path length") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ PERP_BISECTOR
+ , N_("Perpendicular bisector") //label
+ , "perp_bisector" //key
+ , "experimental" //icon
+ , N_("Perpendicular bisector") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ RECURSIVE_SKELETON
+ , N_("Recursive skeleton") //label
+ , "recursive_skeleton" //key
+ , "experimental" //icon
+ , N_("Recursive skeleton") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ TANGENT_TO_CURVE
+ , N_("Tangent to curve") //label
+ , "tangent_to_curve" //key
+ , "experimental" //icon
+ , N_("Tangent to curve") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+ {
+ TEXT_LABEL
+ , N_("Text label") //label
+ , "text_label" //key
+ , "experimental" //icon
+ , N_("Text label") //description
+ , true //on_path
+ , true //on_shape
+ , true //on_group
+ , true //on_use
+ , false //on_image
+ , false //on_text
+ },
+#endif
+
+};
+
+extern const EnumEffectData<EffectType> LPETypeData[]; /// defined in effect.cpp
+extern const EnumEffectDataConverter<EffectType> LPETypeConverter; /// defined in effect.cpp
} //namespace LivePathEffect
} //namespace Inkscape
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 92f5a781a..f83d07c6d 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -94,74 +94,10 @@ namespace Inkscape {
namespace LivePathEffect {
-const Util::EnumData<EffectType> LPETypeData[] = {
- // {constant defined in effect-enum.h, N_("name of your effect"), "name of your effect in SVG"}
-/* 0.46 */
- {BEND_PATH, N_("Bend"), "bend_path"},
- {GEARS, N_("Gears"), "gears"},
- {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
- {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"},
-/* 0.47 */
- {VONKOCH, N_("VonKoch"), "vonkoch"},
- {KNOT, N_("Knot"), "knot"},
- {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"},
- {SPIRO, N_("Spiro spline"), "spiro"},
- {ENVELOPE, N_("Envelope Deformation"), "envelope"},
- {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"},
- {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"},
- {SKETCH, N_("Sketch"), "sketch"},
- {RULER, N_("Ruler"), "ruler"},
-/* 0.91 */
- {POWERSTROKE, N_("Power stroke"), "powerstroke"},
- {CLONE_ORIGINAL, N_("Clone original"), "clone_original"},
-/* 0.92 */
- {SIMPLIFY, N_("Simplify"), "simplify"},
- {LATTICE2, N_("Lattice Deformation 2"), "lattice2"},
- {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, //TODO:Wrong name with "-"
- {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"},
- {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"},
- {SHOW_HANDLES, N_("Show handles"), "show_handles"},
- {ROUGHEN, N_("Roughen"), "roughen"},
- {BSPLINE, N_("BSpline"), "bspline"},
- {JOIN_TYPE, N_("Join type"), "join_type"},
- {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"},
- {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
- {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
-/* Ponyscape -> Inkscape 0.92*/
- {ATTACH_PATH, N_("Attach path"), "attach_path"},
- {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"},
- {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"},
- {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"},
- {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"},
-/* 0.93 */
- {MEASURE_SEGMENTS, N_("Measure Segments"), "measure_segments"},
- {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"},
- {BOOL_OP, N_("Boolean operation"), "bool_op"},
- {EMBRODERY_STITCH, N_("Embroidery stitch"), "embrodery_stitch"},
- {POWERCLIP, N_("Power clip"), "powerclip"},
- {POWERMASK, N_("Power mask"), "powermask"},
- {PTS2ELLIPSE, N_("Ellipse from points"), "pts2ellipse"},
- {OFFSET, N_("Offset"), "offset"},
- {DASH_STROKE, N_("Dash Stroke"), "dash_stroke"},
-#ifdef LPE_ENABLE_TEST_EFFECTS
- {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"},
- {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"},
- {CIRCLE_WITH_RADIUS, N_("Circle (by center and radius)"), "circle_with_radius"},
- {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"},
- {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"},
- {EXTRUDE, N_("Extrude"), "extrude"},
- {LATTICE, N_("Lattice Deformation"), "lattice"},
- {LINE_SEGMENT, N_("Line Segment"), "line_segment"},
- {PARALLEL, N_("Parallel"), "parallel"},
- {PATH_LENGTH, N_("Path length"), "path_length"},
- {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
- {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"},
- {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"},
- {TEXT_LABEL, N_("Text label"), "text_label"},
-#endif
-};
-const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
+
+
+const EnumEffectDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
int
Effect::acceptsNumClicks(EffectType type) {
diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp
index 1fae9a513..f930199cf 100644
--- a/src/ui/dialog/livepatheffect-add.cpp
+++ b/src/ui/dialog/livepatheffect-add.cpp
@@ -13,9 +13,10 @@
# include "config.h" // only include where actually required!
#endif
+#include "live_effects/effect.h"
#include "livepatheffect-add.h"
#include <glibmm/i18n.h>
-
+#include "io/resource.h"
#include "desktop.h"
namespace Inkscape {
@@ -23,87 +24,147 @@ namespace UI {
namespace Dialog {
LivePathEffectAdd::LivePathEffectAdd() :
- add_button(_("_Add"), true),
- close_button(_("_Cancel"), true),
- converter(Inkscape::LivePathEffect::LPETypeConverter),
- applied(false)
+ _add_button(_("_Add"), true),
+ _close_button(_("_Cancel"), true),
+ converter(Inkscape::LivePathEffect::LPETypeConverter)
{
- set_title(_("Add Path Effect"));
-
- /**
- * Scrolled Window
- */
- scrolled_window.add(effectlist_treeview);
- scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- scrolled_window.set_shadow_type(Gtk::SHADOW_IN);
- scrolled_window.set_size_request(250, 200);
- scrolled_window.set_can_focus();
-
- /**
- * Effect Store and Tree
- */
- effectlist_store = Gtk::ListStore::create(_columns);
- effectlist_store->set_sort_column (_columns.name, Gtk::SORT_ASCENDING );
-
- effectlist_treeview.set_model(effectlist_store);
- effectlist_treeview.set_headers_visible(false);
- effectlist_treeview.append_column("Name", _columns.name);
- //effectlist_treeview.set_activates_default(true);
+ const std::string req_widgets[] = {"LPESelector", "LPESelectorFlowBox"};
+ Glib::ustring gladefile = get_filename(Inkscape::IO::Resource::UIS, "lpe-selector.glade");
+ try {
+ _builder = Gtk::Builder::create_from_file(gladefile);
+ } catch(const Glib::Error& ex) {
+ g_warning("Glade file loading failed for filter effect dialog");
+ return;
+ }
+ Gtk::Object* test;
+ for(std::string w:req_widgets) {
+ _builder->get_widget(w,test);
+ if(!test){
+ g_warning("Required widget %s does not exist", w.c_str());
+ return;
+ }
+ }
+ _builder->get_widget("LPESelector", _LPESelector);
+ auto mainVBox = get_content_area();
+ mainVBox->pack_start(*_LPESelector, true, true);
/**
* Initialize Effect list
*/
- int show = LivePathEffect::ATTACH_PATH;
-#ifdef LPE_ENABLE_TEST_EFFECTS
- //TODO: Handle when showing the experimental effects without setting flag
- show = LivePathEffect::ANGLE_BISECTOR;
-#elif WITH_LPETOOL
- //TODO: Handle when showing the experimental effects without setting flag
- show = LivePathEffect::ANGLE_BISECTOR;
-#endif
-
+ _builder->get_widget("LPESelectorFlowBox", _LPESelectorFlowBox);
+ _builder->get_widget("LPEFilter", _LPEFilter);
+ _builder->get_widget("LPEInfo", _LPEInfo);
+ _LPEFilter->signal_search_changed().connect(sigc::mem_fun(*this, &LivePathEffectAdd::on_search));
+ const std::string le_widgets[] = {"LPESelectorItem", "LPEName","LPEDescription"};
+ Glib::ustring le_gladefile = get_filename(Inkscape::IO::Resource::UIS, "lpe-selector-item.glade");
for(int i = 0; i < static_cast<int>(converter._length); ++i) {
- Gtk::TreeModel::Row row = *(effectlist_store->append());
- const Util::EnumData<LivePathEffect::EffectType>* data = &converter.data(i);
- row[_columns.name] = _( converter.get_label(data->id).c_str() );
- row[_columns.data] = data;
- if (i == show) {
- Glib::RefPtr<Gtk::TreeSelection> select = effectlist_treeview.get_selection();
- select->select(row);
+
+ try {
+ _builder = Gtk::Builder::create_from_file(le_gladefile);
+ } catch(const Glib::Error& ex) {
+ g_warning("Glade file loading failed for filter effect dialog");
+ return;
}
- }
-
- /**
- * Buttons
- */
- //close_button.set_can_default();
- add_button.set_use_underline(true);
- add_button.set_can_default();
- auto mainVBox = get_content_area();
-
- mainVBox->pack_start(scrolled_window, true, true);
- add_action_widget(close_button, Gtk::RESPONSE_CLOSE);
- add_action_widget(add_button, Gtk::RESPONSE_APPLY);
+ Gtk::Object* test;
+ for(std::string w:le_widgets) {
+ _builder->get_widget(w,test);
+ if(!test){
+ g_warning("Required widget %s does not exist", w.c_str());
+ return;
+ }
+ }
+ const LivePathEffect::EnumEffectData<LivePathEffect::EffectType>* data = &converter.data(i);
+ Gtk::Label * LPEName;
+ _builder->get_widget("LPEName", LPEName);
+ Glib::ustring newid = "LPEName_" + Glib::ustring::format(i);
+ (*LPEName).set_name(newid);
+ (*LPEName).set_text(converter.get_label(data->id).c_str());
+ Gtk::Label * LPEDescription;
+ _builder->get_widget("LPEDescription", LPEDescription);
+ newid = "LPEDescription_" + Glib::ustring::format(i);
+ (*LPEDescription).set_name(newid);
+ (*LPEDescription).set_text(converter.get_description(data->id));
+ Gtk::Image * LPEIcon;
+ _builder->get_widget("LPEIcon", LPEIcon);
+ newid = "LPEIcon_" + Glib::ustring::format(i);
+ (*LPEIcon).set_name(newid);
+ (*LPEIcon).set_from_icon_name(converter.get_icon(data->id),Gtk::BuiltinIconSize(Gtk::ICON_SIZE_DIALOG));
+ Gtk::Box * LPESelectorItem;
+ _builder->get_widget("LPESelectorItem", LPESelectorItem);
+ newid = "LPESelectorItem" + Glib::ustring::format(i);
+ (*LPESelectorItem).set_name(newid);
+ _LPESelectorFlowBox->insert(*LPESelectorItem, i);
+ }
+ _visiblelpe = _LPESelectorFlowBox->get_children().size();
+ _LPESelectorFlowBox->signal_child_activated().connect(sigc::mem_fun(*this, &LivePathEffectAdd::on_activate));
+ set_title(_("Live Efects Selector"));
+ show_all_children();
+ _LPEInfo->set_visible(false);
+}
-
- /**
- * Signal handlers
- */
- effectlist_treeview.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LivePathEffectAdd::onButtonEvent) );
- effectlist_treeview.signal_key_press_event().connect_notify(sigc::mem_fun(*this, &LivePathEffectAdd::onKeyEvent));
- close_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onClose));
- add_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onAdd));
- signal_delete_event().connect( sigc::bind_return(sigc::hide(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)), true ) );
+void LivePathEffectAdd::on_activate(Gtk::FlowBoxChild *child){
+ for (auto i:_LPESelectorFlowBox->get_children()) {
+ Gtk::FlowBoxChild * leitem = dynamic_cast<Gtk::FlowBoxChild *>(i);
+ leitem->get_style_context()->remove_class("lpeactive");
+ Gtk::Box *box = dynamic_cast<Gtk::Box *>(leitem->get_child());
+ if (box) {
+ std::vector<Gtk::Widget*> contents = box->get_children();
+ Gtk::Box *actions = dynamic_cast<Gtk::Box *>(contents[3]);
+ if (actions) {
+ actions->set_visible(false);
+ }
+ }
+ }
+ child->get_style_context()->add_class("lpeactive");
+ child->show_all_children();
+}
- add_button.grab_default();
+bool LivePathEffectAdd::on_filter(Gtk::FlowBoxChild *child)
+{
+ if (_LPEFilter->get_text().length() < 4) {
+ _visiblelpe = _LPESelectorFlowBox->get_children().size();
+ return true;
+ }
+ Gtk::Box *box = dynamic_cast<Gtk::Box *>(child->get_child());
+ if (box) {
+ std::vector<Gtk::Widget*> contents = box->get_children();
+ Gtk::Label *lpename = dynamic_cast<Gtk::Label *>(contents[1]);
+ if (lpename) {
+ size_t s = lpename->get_text().uppercase().find(_LPEFilter->get_text().uppercase(),0);
+ if(s != -1) {
+ _visiblelpe++;
+ return true;
+ }
+ }
+ Gtk::Label *lpedesc = dynamic_cast<Gtk::Label *>(contents[2]);
+ if (lpedesc) {
+ size_t s = lpedesc->get_text().uppercase().find(_LPEFilter->get_text().uppercase(),0);
+ if(s != -1) {
+ _visiblelpe++;
+ return true;
+ }
+ }
+ }
+ return false;
+}
- show_all_children();
+void LivePathEffectAdd::on_search()
+{
+ _visiblelpe = 0;
+ _LPESelectorFlowBox->set_filter_func(sigc::mem_fun(*this, &LivePathEffectAdd::on_filter));
+ if (_visiblelpe == 0) {
+ _LPEInfo->set_text(_("Your search do a empty result, please try again"));
+ _LPEInfo->set_visible(true);
+ _LPEInfo->get_style_context()->add_class("lpeinfowarn");
+ } else {
+ _LPEInfo->set_visible(false);
+ _LPEInfo->get_style_context()->remove_class("lpeinfowarn");
+ }
}
void LivePathEffectAdd::onAdd()
{
- applied = true;
onClose();
}
@@ -122,35 +183,14 @@ void LivePathEffectAdd::onKeyEvent(GdkEventKey* evt)
}
}
-void LivePathEffectAdd::onButtonEvent(GdkEventButton* evt)
-{
- // Double click on tree is same as clicking the add button
- if (evt->type == GDK_2BUTTON_PRESS) {
- onAdd();
- }
-}
-
-const Util::EnumData<LivePathEffect::EffectType>*
-LivePathEffectAdd::getActiveData()
-{
- Gtk::TreeModel::iterator iter = instance().effectlist_treeview.get_selection()->get_selected();
- if ( iter ) {
- Gtk::TreeModel::Row row = *iter;
- return row[instance()._columns.data];
- }
-
- return nullptr;
-}
-
-
void LivePathEffectAdd::show(SPDesktop *desktop)
{
LivePathEffectAdd &dial = instance();
- dial.applied=false;
dial.set_modal(true);
- desktop->setWindowTransient (dial.gobj());
+ //dial.set_decorated(false);
+ dial.set_name("lpedialogselector");
+ //desktop->setWindowTransient (dial.gobj());
dial.property_destroy_with_parent() = true;
- dial.effectlist_treeview.grab_focus();
dial.run();
}
diff --git a/src/ui/dialog/livepatheffect-add.h b/src/ui/dialog/livepatheffect-add.h
index 84901385c..88aca58b2 100644
--- a/src/ui/dialog/livepatheffect-add.h
+++ b/src/ui/dialog/livepatheffect-add.h
@@ -12,10 +12,14 @@
#ifndef INKSCAPE_DIALOG_LIVEPATHEFFECT_ADD_H
#define INKSCAPE_DIALOG_LIVEPATHEFFECT_ADD_H
+#include <gtkmm/box.h>
+#include <gtkmm/builder.h>
+#include <gtkmm/label.h>
+#include <gtkmm/flowbox.h>
+#include <gtkmm/stylecontext.h>
+#include <gtkmm/flowboxchild.h>
+#include <gtkmm/searchentry.h>
#include <gtkmm/dialog.h>
-#include <gtkmm/liststore.h>
-#include <gtkmm/treeview.h>
-#include <gtkmm/scrolledwindow.h>
#include "live_effects/effect-enum.h"
class SPDesktop;
@@ -37,31 +41,23 @@ public:
* Show the dialog
*/
static void show(SPDesktop *desktop);
-
- /**
- * Returns true is the "Add" button was pressed
- */
static bool isApplied() {
- return instance().applied;
+ return false;
}
- /**
- * Return the data associated with the currently selected item
- */
- static const Util::EnumData<LivePathEffect::EffectType>* getActiveData();
-
+ static const Util::EnumData<LivePathEffect::EffectType>* getActiveData(){return NULL;};
protected:
-
/**
* Close button was clicked
*/
void onClose();
-
+ bool on_filter(Gtk::FlowBoxChild *child);
+ void on_search();
+ void on_activate(Gtk::FlowBoxChild *child);
/**
* Add button was clicked
*/
void onAdd();
-
/**
* Tree was clicked
*/
@@ -72,37 +68,16 @@ protected:
*/
void onKeyEvent(GdkEventKey* evt);
private:
-
- Gtk::TreeView effectlist_treeview;
- Gtk::ScrolledWindow scrolled_window;
- Gtk::Button add_button;
- Gtk::Button close_button;
-
- class ModelColumns : public Gtk::TreeModel::ColumnRecord
- {
- public:
- ModelColumns()
- {
- add(name);
- //add(desc);
- add(data);
- }
- ~ModelColumns() override = default;
-
- Gtk::TreeModelColumn<Glib::ustring> name;
- /**
- * TODO - Get detailed descriptions of each Effect to show in the dialog
- */
- //Gtk::TreeModelColumn<Glib::ustring> desc;
- Gtk::TreeModelColumn<const Util::EnumData<LivePathEffect::EffectType>*> data;
- };
-
- ModelColumns _columns;
- Glib::RefPtr<Gtk::ListStore> effectlist_store;
- const Util::EnumDataConverter<LivePathEffect::EffectType>& converter;
-
- bool applied;
-
+ Gtk::Button _add_button;
+ Gtk::Button _close_button;
+ Glib::RefPtr<Gtk::Builder> _builder;
+ Gtk::FlowBox * _LPESelectorFlowBox;
+ Gtk::SearchEntry *_LPEFilter;
+ Gtk::Label *_LPEInfo;
+ Gtk::Box *_LPESelector;
+ guint _visiblelpe;
+ class Effect;
+ const LivePathEffect::EnumEffectDataConverter<LivePathEffect::EffectType>& converter;
static LivePathEffectAdd &instance() {
static LivePathEffectAdd instance_;
return instance_;
diff --git a/src/ui/dialog/lpe-selector.cpp b/src/ui/dialog/lpe-selector.cpp
new file mode 100644
index 000000000..5a2f39db4
--- /dev/null
+++ b/src/ui/dialog/lpe-selector.cpp
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/**
+ * @file
+ * Filter Effects dialog.
+ */
+/* Authors:
+ * Marc Jeanmougin
+ *
+ * Copyright (C) 2017 Authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include <glibmm/convert.h>
+#include <glibmm/error.h>
+#include <glibmm/i18n.h>
+#include <glibmm/main.h>
+#include <glibmm/stringutils.h>
+#include "io/sys.h"
+#include "io/resource.h"
+
+namespace Inkscape {
+namespace UI {
+
+LPESelector::LPESelector() : Gtk::Box()
+{
+
+ const std::string req_widgets[] = {"LPESelector", "FilterList", "FilterFERX", "FilterFERY", "FilterFERH", "FilterFERW", "FilterPreview", "FilterPrimitiveDescImage", "FilterPrimitiveList", "FilterPrimitiveDescText", "FilterPrimitiveAdd"};
+ Glib::ustring gladefile = get_filename(UIS, "lpe-selector.glade");
+ try {
+ builder = Gtk::Builder::create_from_file(gladefile);
+ } catch(const Glib::Error& ex) {
+ g_warning("Glade file loading failed for filter effect dialog");
+ return;
+ }
+
+ Gtk::Object* test;
+ for(std::string w:req_widgets) {
+ builder->get_widget(w,test);
+ if(!test){
+ g_warning("Required widget %s does not exist", w.c_str());
+ return;
+ }
+ }
+
+ builder->get_widget("LPESelector", LPESelector);
+ _getContents()->add(*LPESelector);
+
+}
+LPESelector::~LPESelector()= default;
+
+
+
+
+
+
+} // Never put these namespaces together unless you are using gcc 6+
+}
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/lpe-selector.h b/src/ui/dialog/lpe-selector.h
new file mode 100644
index 000000000..cc6d80f5a
--- /dev/null
+++ b/src/ui/dialog/lpe-selector.h
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * @brief Filter Editor dialog
+ */
+/* Authors:
+ * Marc Jeanmougin
+ *
+ * Copyright (C) 2017 Authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_LPE_SELECTOR_H
+#define INKSCAPE_UI_LPE_SELECTOR_H
+
+#include <gtkmm/gtkmm.h>
+
+namespace Inkscape {
+namespace UI {
+
+class LPESelector : public Gtk::Box {
+public:
+
+ LPESelector();
+ ~LPESelector() override;
+
+ static LPESelector &getInstance()
+ { return *new LPESelector(); }
+
+// void set_attrs_locked(const bool);
+private:
+ Glib::RefPtr<Gtk::Builder> builder;
+ Glib::RefPtr<Glib::Object> FilterStore;
+ Gtk::Box *LPESelector;
+};
+}
+}
+#endif