From fcffbecabedd7c6bca1312918c918d57fee3cf8c Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 15:24:04 -0500 Subject: Added new swatches dialog (bzr r13090.1.16) --- live_effects.patch | 2008 +++ mkerror.txt | 11 + objects_dialog.patch | 3637 ++++ share/palettes/MLP/All.gpl | 10 + share/palettes/MLP/Applejack.gpl | 18 + share/palettes/MLP/Daisy.gpl | 16 + share/palettes/MLP/Fluttershy.gpl | 15 + share/palettes/MLP/Lily.gpl | 18 + share/palettes/MLP/Makefile | 520 + share/palettes/MLP/Makefile.am | 18 + share/palettes/MLP/Pinkie.gpl | 15 + share/palettes/MLP/Rainbow-Dash.gpl | 23 + share/palettes/MLP/Rarity.gpl | 18 + share/palettes/MLP/Roseluck.gpl | 21 + share/palettes/MLP/Silver-Rains.gpl | 17 + share/palettes/MLP/Spike.gpl | 17 + share/palettes/MLP/Twilight-Sparkle.gpl | 17 + share/palettes/Makefile.am | 4 +- share/palettes/README | 9 +- share/palettes/Tango-Palette.gpl | 2 - share/palettes/swatches.svg | 28382 ++++++++++++++++++++++++++++++ src/ui/dialog/color-item.cpp | 860 +- src/ui/dialog/color-item.h | 108 +- src/ui/dialog/filedialog.h | 1 + src/ui/dialog/swatches.cpp | 48 +- src/widgets/desktop-widget.cpp | 2 +- 26 files changed, 34989 insertions(+), 826 deletions(-) create mode 100644 live_effects.patch create mode 100644 mkerror.txt create mode 100644 objects_dialog.patch create mode 100644 share/palettes/MLP/All.gpl create mode 100644 share/palettes/MLP/Applejack.gpl create mode 100644 share/palettes/MLP/Daisy.gpl create mode 100644 share/palettes/MLP/Fluttershy.gpl create mode 100644 share/palettes/MLP/Lily.gpl create mode 100644 share/palettes/MLP/Makefile create mode 100644 share/palettes/MLP/Makefile.am create mode 100644 share/palettes/MLP/Pinkie.gpl create mode 100644 share/palettes/MLP/Rainbow-Dash.gpl create mode 100644 share/palettes/MLP/Rarity.gpl create mode 100644 share/palettes/MLP/Roseluck.gpl create mode 100644 share/palettes/MLP/Silver-Rains.gpl create mode 100644 share/palettes/MLP/Spike.gpl create mode 100644 share/palettes/MLP/Twilight-Sparkle.gpl create mode 100644 share/palettes/swatches.svg diff --git a/live_effects.patch b/live_effects.patch new file mode 100644 index 000000000..3d1091221 --- /dev/null +++ b/live_effects.patch @@ -0,0 +1,2008 @@ +=== modified file 'src/live_effects/CMakeLists.txt' +--- src/live_effects/CMakeLists.txt 2012-03-23 21:02:03 +0000 ++++ src/live_effects/CMakeLists.txt 2014-03-01 16:12:14 +0000 +@@ -2,8 +2,10 @@ + set(live_effects_SRC + effect.cpp + lpe-angle_bisector.cpp ++ lpe-attach-path.cpp + lpe-bendpath.cpp + lpe-boolops.cpp ++ lpe-bounding-box.cpp + lpe-circle_3pts.cpp + lpe-circle_with_radius.cpp + lpe-clone-original.cpp +@@ -11,8 +13,11 @@ + lpe-copy_rotate.cpp + lpe-curvestitch.cpp + lpe-dynastroke.cpp ++ lpe-ellipse-5pts.cpp + lpe-envelope.cpp + lpe-extrude.cpp ++ lpe-fill-between-many.cpp ++ lpe-fill-between-strokes.cpp + lpe-gears.cpp + lpe-interpolate.cpp + lpe-knot.cpp +@@ -47,11 +52,13 @@ + parameter/parameter.cpp + parameter/path.cpp + parameter/originalpath.cpp ++ parameter/originalpatharray.cpp + parameter/path-reference.cpp + parameter/point.cpp + parameter/powerstrokepointarray.cpp + parameter/random.cpp + parameter/text.cpp ++ paramter/transformedpoint.cpp + parameter/unit.cpp + parameter/vector.cpp + +@@ -61,8 +68,10 @@ + effect-enum.h + effect.h + lpe-angle_bisector.h ++ lpe-attach-path.h + lpe-bendpath.h + lpe-boolops.h ++ lpe-bounding-box.h + lpe-circle_3pts.h + lpe-circle_with_radius.h + lpe-clone-original.h +@@ -70,8 +79,11 @@ + lpe-copy_rotate.h + lpe-curvestitch.h + lpe-dynastroke.h ++ lpe-ellipse-5pts.h + lpe-envelope.h + lpe-extrude.h ++ lpe-fill-between-many.h ++ lpe-fill-between-strokes.h + lpe-gears.h + lpe-interpolate.h + lpe-knot.h +@@ -109,6 +121,7 @@ + parameter/path-reference.h + parameter/path.h + parameter/originalpath.h ++ parameter/originalpatharray.h + parameter/point.h + parameter/powerstrokepointarray.h + parameter/random.h + +=== modified file 'src/live_effects/Makefile_insert' +--- src/live_effects/Makefile_insert 2012-03-23 21:02:03 +0000 ++++ src/live_effects/Makefile_insert 2014-03-01 18:49:52 +0000 +@@ -82,4 +82,14 @@ + live_effects/lpe-path_length.cpp \ + live_effects/lpe-path_length.h \ + live_effects/lpe-line_segment.cpp \ +- live_effects/lpe-line_segment.h ++ live_effects/lpe-line_segment.h \ ++ live_effects/lpe-bounding-box.cpp \ ++ live_effects/lpe-bounding-box.h \ ++ live_effects/lpe-attach-path.cpp \ ++ live_effects/lpe-attach-path.h \ ++ live_effects/lpe-fill-between-strokes.cpp \ ++ live_effects/lpe-fill-between-stroke.h \ ++ live_effects/lpe-fill-between-many.cpp \ ++ live_effects/lpe-fill-between-many.h \ ++ live_effects/lpe-ellipse-5pts.cpp \ ++ live_effects/lpe-ellipse-5pts.h + +=== modified file 'src/live_effects/effect-enum.h' +--- src/live_effects/effect-enum.h 2012-01-12 21:06:16 +0000 ++++ src/live_effects/effect-enum.h 2014-03-01 02:07:48 +0000 +@@ -50,6 +50,11 @@ + EXTRUDE, + POWERSTROKE, + CLONE_ORIGINAL, ++ ATTACH_PATH, ++ FILL_BETWEEN_STROKES, ++ FILL_BETWEEN_MANY, ++ ELLIPSE_5PTS, ++ BOUNDING_BOX, + 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) + }; + + +=== modified file 'src/live_effects/effect.cpp' +--- src/live_effects/effect.cpp 2014-01-12 22:12:14 +0000 ++++ src/live_effects/effect.cpp 2014-03-01 02:27:38 +0000 +@@ -5,7 +5,7 @@ + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +-//#define LPE_ENABLE_TEST_EFFECTS ++#define LPE_ENABLE_TEST_EFFECTS + + #ifdef HAVE_CONFIG_H + # include "config.h" +@@ -47,6 +47,11 @@ + #include "live_effects/lpe-extrude.h" + #include "live_effects/lpe-powerstroke.h" + #include "live_effects/lpe-clone-original.h" ++#include "live_effects/lpe-attach-path.h" ++#include "live_effects/lpe-fill-between-strokes.h" ++#include "live_effects/lpe-fill-between-many.h" ++#include "live_effects/lpe-ellipse_5pts.h" ++#include "live_effects/lpe-bounding-box.h" + + #include "xml/node-event-vector.h" + #include "sp-object.h" +@@ -122,6 +127,12 @@ + /* 0.49 */ + {POWERSTROKE, N_("Power stroke"), "powerstroke"}, + {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, ++/* Ponyscape */ ++ {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"}, + }; + const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); + +@@ -245,6 +256,21 @@ + case CLONE_ORIGINAL: + neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); + break; ++ case ATTACH_PATH: ++ neweffect = static_cast ( new LPEAttachPath(lpeobj) ); ++ break; ++ case FILL_BETWEEN_STROKES: ++ neweffect = static_cast ( new LPEFillBetweenStrokes(lpeobj) ); ++ break; ++ case FILL_BETWEEN_MANY: ++ neweffect = static_cast ( new LPEFillBetweenMany(lpeobj) ); ++ break; ++ case ELLIPSE_5PTS: ++ neweffect = static_cast ( new LPEEllipse5Pts(lpeobj) ); ++ break; ++ case BOUNDING_BOX: ++ neweffect = static_cast ( new LPEBoundingBox(lpeobj) ); ++ break; + default: + g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); + neweffect = NULL; + +=== added file 'src/live_effects/lpe-attach-path.cpp' +--- src/live_effects/lpe-attach-path.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-attach-path.cpp 2014-03-01 22:47:28 +0000 +@@ -0,0 +1,203 @@ ++/* ++ * Copyright (C) Johan Engelen 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++#include ++ ++#include "live_effects/lpe-attach-path.h" ++ ++#include "display/curve.h" ++#include "sp-item.h" ++#include "2geom/path.h" ++#include "sp-shape.h" ++#include "sp-text.h" ++#include "2geom/bezier-curve.h" ++#include "2geom/path-sink.h" ++#include "parameter/parameter.h" ++#include "live_effects/parameter/point.h" ++#include "parameter/originalpath.h" ++#include "2geom/affine.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++LPEAttachPath::LPEAttachPath(LivePathEffectObject *lpeobject) : ++ Effect(lpeobject), ++ start_path(_("Start path:"), _("Path to attach to the start of this path"), "startpath", &wr, this), ++ start_path_position(_("Start path position:"), _("Position to attach path start to"), "startposition", &wr, this, 0.0), ++ start_path_curve_start(_("Start path curve start:"), _("Starting curve"), "startcurvestart", &wr, this, Geom::Point(20,0)/*, true*/), ++ start_path_curve_end(_("Start path curve end:"), _("Ending curve"), "startcurveend", &wr, this, Geom::Point(20,0)/*, true*/), ++ end_path(_("End path:"), _("Path to attach to the end of this path"), "endpath", &wr, this), ++ end_path_position(_("End path position:"), _("Position to attach path end to"), "endposition", &wr, this, 0.0), ++ end_path_curve_start(_("End path curve start:"), _("Starting curve"), "endcurvestart", &wr, this, Geom::Point(20,0)/*, true*/), ++ end_path_curve_end(_("End path curve end:"), _("Ending curve"), "endcurveend", &wr, this, Geom::Point(20,0)/*, true*/) ++{ ++ registerParameter( dynamic_cast(&start_path) ); ++ registerParameter( dynamic_cast(&start_path_position) ); ++ registerParameter( dynamic_cast(&start_path_curve_start) ); ++ registerParameter( dynamic_cast(&start_path_curve_end) ); ++ ++ registerParameter( dynamic_cast(&end_path) ); ++ registerParameter( dynamic_cast(&end_path_position) ); ++ registerParameter( dynamic_cast(&end_path_curve_start) ); ++ registerParameter( dynamic_cast(&end_path_curve_end) ); ++ ++ //perceived_path = true; ++ show_orig_path = true; ++ curve_start_previous_origin = start_path_curve_end.getOrigin(); ++ curve_end_previous_origin = end_path_curve_end.getOrigin(); ++} ++ ++LPEAttachPath::~LPEAttachPath() ++{ ++ ++} ++ ++void LPEAttachPath::resetDefaults(SPItem const * item) ++{ ++ curve_start_previous_origin = start_path_curve_end.getOrigin(); ++ curve_end_previous_origin = end_path_curve_end.getOrigin(); ++} ++ ++void LPEAttachPath::doBeforeEffect(const SPLPEItem *lpeitem) ++{ ++ lpe_effect = lpeitem; ++} ++ ++void LPEAttachPath::doEffect (SPCurve * curve) ++{ ++ std::vector this_pathv = curve->get_pathvector(); ++ if (lpe_effect && !this_pathv.empty()) { ++ Geom::Path p = Geom::Path(this_pathv.front().initialPoint()); ++ ++ bool set_start_end = start_path_curve_end.getOrigin() != curve_start_previous_origin; ++ bool set_end_end = end_path_curve_end.getOrigin() != curve_end_previous_origin; ++ ++ if (start_path.linksToPath()) { ++ ++ std::vector linked_pathv = start_path.get_pathvector(); ++ Geom::Affine linkedtransform = start_path.getObject()->getRelativeTransform(lpe_effect); ++ ++ if ( !linked_pathv.empty() ) ++ { ++ Geom::Path transformedpath = linked_pathv.front() * linkedtransform; ++ start_path_curve_start.setOrigin(this_pathv.front().initialPoint()); ++ ++ std::vector derivs = this_pathv.front().front().pointAndDerivatives(0, 3); ++ ++ for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) { ++ Geom::Coord length = derivs[deriv_n].length(); ++ if ( ! Geom::are_near(length, 0) ) { ++ if (set_start_end) { ++ start_path_position.param_set_value(transformedpath.nearestPoint(start_path_curve_end.getOrigin())); ++ } ++ ++ if (start_path_position > transformedpath.size()) { ++ start_path_position.param_set_value(transformedpath.size()); ++ } else if (start_path_position < 0) { ++ start_path_position.param_set_value(0); ++ } ++ const Geom::Curve *c = start_path_position >= transformedpath.size() ? &transformedpath.back() : &transformedpath.at_index((int)start_path_position); ++ ++ std::vector derivs_2 = c->pointAndDerivatives(start_path_position >= transformedpath.size() ? 1 : (start_path_position - (int)start_path_position), 3); ++ for (unsigned deriv_n_2 = 1; deriv_n_2 < derivs_2.size(); deriv_n_2++) { ++ Geom::Coord length_2 = derivs[deriv_n_2].length(); ++ if ( ! Geom::are_near(length_2, 0) ) { ++ start_path_curve_end.setOrigin(derivs_2[0]); ++ curve_start_previous_origin = start_path_curve_end.getOrigin(); ++ ++ double startangle = atan2(start_path_curve_start.getVector().y(), start_path_curve_start.getVector().x()); ++ double endangle = atan2(start_path_curve_end.getVector().y(), start_path_curve_end.getVector().x()); ++ double startderiv = atan2(derivs[deriv_n].y(), derivs[deriv_n].x()); ++ double endderiv = atan2(derivs_2[deriv_n_2].y(), derivs_2[deriv_n_2].x()); ++ Geom::Point pt1 = Geom::Point(start_path_curve_start.getVector().length() * cos(startangle + startderiv), start_path_curve_start.getVector().length() * sin(startangle + startderiv)); ++ Geom::Point pt2 = Geom::Point(start_path_curve_end.getVector().length() * cos(endangle + endderiv), start_path_curve_end.getVector().length() * sin(endangle + endderiv)); ++ p = Geom::Path(derivs_2[0]); ++ p.appendNew(-pt2 + derivs_2[0], -pt1 + this_pathv.front().initialPoint(), this_pathv.front().initialPoint()); ++ break; ++ ++ } ++ } ++ break; ++ } ++ } ++ } ++ } ++ ++ p.append(this_pathv.front()); ++ ++ if (end_path.linksToPath()) { ++ ++ std::vector linked_pathv = end_path.get_pathvector(); ++ Geom::Affine linkedtransform = end_path.getObject()->getRelativeTransform(lpe_effect); ++ ++ if ( !linked_pathv.empty() ) ++ { ++ Geom::Path transformedpath = linked_pathv.front() * linkedtransform; ++ Geom::Curve * last_seg_reverse = this_pathv.front().back().reverse(); ++ ++ end_path_curve_start.setOrigin(last_seg_reverse->initialPoint()); ++ ++ std::vector derivs = last_seg_reverse->pointAndDerivatives(0, 3); ++ for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) { ++ Geom::Coord length = derivs[deriv_n].length(); ++ if ( ! Geom::are_near(length, 0) ) { ++ if (set_end_end) { ++ end_path_position.param_set_value(transformedpath.nearestPoint(end_path_curve_end.getOrigin())); ++ } ++ ++ if (end_path_position > transformedpath.size()) { ++ end_path_position.param_set_value(transformedpath.size()); ++ } else if (end_path_position < 0) { ++ end_path_position.param_set_value(0); ++ } ++ const Geom::Curve *c = end_path_position >= transformedpath.size() ? &transformedpath.back() : &transformedpath.at_index((int)end_path_position); ++ ++ std::vector derivs_2 = c->pointAndDerivatives(end_path_position >= transformedpath.size() ? 1 : (end_path_position - (int)end_path_position), 3); ++ for (unsigned deriv_n_2 = 1; deriv_n_2 < derivs_2.size(); deriv_n_2++) { ++ Geom::Coord length_2 = derivs[deriv_n_2].length(); ++ if ( ! Geom::are_near(length_2, 0) ) { ++ ++ end_path_curve_end.setOrigin(derivs_2[0]); ++ curve_end_previous_origin = end_path_curve_end.getOrigin(); ++ ++ double startangle = atan2(end_path_curve_start.getVector().y(), end_path_curve_start.getVector().x()); ++ double endangle = atan2(end_path_curve_end.getVector().y(), end_path_curve_end.getVector().x()); ++ double startderiv = atan2(derivs[deriv_n].y(), derivs[deriv_n].x()); ++ double endderiv = atan2(derivs_2[deriv_n_2].y(), derivs_2[deriv_n_2].x()); ++ Geom::Point pt1 = Geom::Point(end_path_curve_start.getVector().length() * cos(startangle + startderiv), end_path_curve_start.getVector().length() * sin(startangle + startderiv)); ++ Geom::Point pt2 = Geom::Point(end_path_curve_end.getVector().length() * cos(endangle + endderiv), end_path_curve_end.getVector().length() * sin(endangle + endderiv)); ++ p.appendNew(-pt1 + this_pathv.front().finalPoint(), -pt2 + derivs_2[0], derivs_2[0]); ++ ++ break; ++ ++ } ++ } ++ break; ++ } ++ } ++ delete last_seg_reverse; ++ } ++ } ++ Geom::PathVector outvector; ++ outvector.push_back(p); ++ curve->set_pathvector(outvector); ++ } ++} ++ ++} // 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 : + +=== added file 'src/live_effects/lpe-attach-path.h' +--- src/live_effects/lpe-attach-path.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-attach-path.h 2014-03-01 22:40:18 +0000 +@@ -0,0 +1,54 @@ ++#ifndef INKSCAPE_LPE_ATTACH_PATH_H ++#define INKSCAPE_LPE_ATTACH_PATH_H ++ ++/* ++ * Inkscape::LPEAttachPath ++ * ++ * Copyright (C) Ted Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/effect.h" ++#include "live_effects/parameter/parameter.h" ++#include "live_effects/parameter/point.h" ++#include "live_effects/parameter/originalpath.h" ++#include "live_effects/parameter/vector.h" ++#include "live_effects/parameter/bool.h" ++#include "live_effects/parameter/transformedpoint.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++class LPEAttachPath : public Effect { ++public: ++ LPEAttachPath(LivePathEffectObject *lpeobject); ++ virtual ~LPEAttachPath(); ++ ++ virtual void doBeforeEffect(const SPLPEItem *lpeitem); ++ virtual void doEffect (SPCurve * curve); ++ virtual void resetDefaults(SPItem const * item); ++ ++private: ++ LPEAttachPath(const LPEAttachPath&); ++ LPEAttachPath& operator=(const LPEAttachPath&); ++ ++ Geom::Point curve_start_previous_origin; ++ Geom::Point curve_end_previous_origin; ++ ++ OriginalPathParam start_path; ++ ScalarParam start_path_position; ++ TransformedPointParam start_path_curve_start; ++ VectorParam start_path_curve_end; ++ ++ OriginalPathParam end_path; ++ ScalarParam end_path_position; ++ TransformedPointParam end_path_curve_start; ++ VectorParam end_path_curve_end; ++ const SPLPEItem * lpe_effect; ++}; ++ ++}; //namespace LivePathEffect ++}; //namespace Inkscape ++ ++#endif + +=== added file 'src/live_effects/lpe-bounding-box.cpp' +--- src/live_effects/lpe-bounding-box.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-bounding-box.cpp 2014-03-01 21:18:13 +0000 +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++ ++#include "live_effects/lpe-bounding-box.h" ++ ++#include "display/curve.h" ++#include "sp-item.h" ++#include "2geom/path.h" ++#include "sp-shape.h" ++#include "sp-text.h" ++#include "2geom/bezier-curve.h" ++#include "lpe-bounding-box.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++LPEBoundingBox::LPEBoundingBox(LivePathEffectObject *lpeobject) : ++ Effect(lpeobject), ++ linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this), ++ visual_bounds(_("Visual Bounds"), _("Uses the visual bounding box"), "visualbounds", &wr, this) ++{ ++ registerParameter( dynamic_cast(&linked_path) ); ++ registerParameter( dynamic_cast(&visual_bounds) ); ++ //perceived_path = true; ++} ++ ++LPEBoundingBox::~LPEBoundingBox() ++{ ++ ++} ++ ++void LPEBoundingBox::doEffect (SPCurve * curve) ++{ ++ if (curve) { ++ if ( linked_path.linksToPath() && linked_path.getObject() ) { ++ SPItem * item = linked_path.getObject(); ++ Geom::OptRect bbox = visual_bounds.get_value() ? item->visualBounds() : item->geometricBounds(); ++ Geom::Path p(Geom::Point(bbox->left(), bbox->top())); ++ p.appendNew(Geom::Point(bbox->right(), bbox->top())); ++ p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); ++ p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); ++ p.appendNew(Geom::Point(bbox->left(), bbox->top())); ++ std::vector out; ++ out.push_back(p); ++ curve->set_pathvector(out); ++ } ++ } ++} ++ ++} // 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 : + +=== added file 'src/live_effects/lpe-bounding-box.h' +--- src/live_effects/lpe-bounding-box.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-bounding-box.h 2014-03-01 19:37:36 +0000 +@@ -0,0 +1,37 @@ ++#ifndef INKSCAPE_LPE_BOUNDING_BOX_H ++#define INKSCAPE_LPE_BOUNDING_BOX_H ++ ++/* ++ * Inkscape::LPEFillBetweenStrokes ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/effect.h" ++#include "live_effects/parameter/originalpath.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++class LPEBoundingBox : public Effect { ++public: ++ LPEBoundingBox(LivePathEffectObject *lpeobject); ++ virtual ~LPEBoundingBox(); ++ ++ virtual void doEffect (SPCurve * curve); ++ ++private: ++ OriginalPathParam linked_path; ++ BoolParam visual_bounds; ++ ++private: ++ LPEBoundingBox(const LPEBoundingBox&); ++ LPEBoundingBox& operator=(const LPEBoundingBox&); ++}; ++ ++}; //namespace LivePathEffect ++}; //namespace Inkscape ++ ++#endif + +=== added file 'src/live_effects/lpe-ellipse_5pts.cpp' +--- src/live_effects/lpe-ellipse_5pts.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-ellipse_5pts.cpp 2013-09-07 18:46:36 +0000 +@@ -0,0 +1,214 @@ ++/** \file ++ * LPE "Ellipse through 5 points" implementation ++ */ ++ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/lpe-ellipse_5pts.h" ++ ++// You might need to include other 2geom files. You can add them here: ++#include ++#include <2geom/path.h> ++#include <2geom/circle.h> ++#include <2geom/ellipse.h> ++#include <2geom/svg-path.h> ++#include "inkscape.h" ++#include "desktop.h" ++#include "message-stack.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++LPEEllipse5Pts::LPEEllipse5Pts(LivePathEffectObject *lpeobject) : ++ Effect(lpeobject) ++{ ++ perceived_path = true; ++} ++ ++LPEEllipse5Pts::~LPEEllipse5Pts() ++{ ++} ++ ++static double _det3(double (*mat)[3]) ++{ ++ for (int i = 0; i < 2; i++) ++ { ++ for (int j = i + 1; j < 3; j++) ++ { ++ for (int k = i + 1; k < 3; k++) ++ { ++ mat[j][k] = (mat[j][k] * mat[i][i] - mat[j][i] * mat[i][k]); ++ if (i) mat[j][k] /= mat[i-1][i-1]; ++ } ++ } ++ } ++ return mat[2][2]; ++} ++static double _det5(double (*mat)[5]) ++{ ++ for (int i = 0; i < 4; i++) ++ { ++ for (int j = i + 1; j < 5; j++) ++ { ++ for (int k = i + 1; k < 5; k++) ++ { ++ mat[j][k] = (mat[j][k] * mat[i][i] - mat[j][i] * mat[i][k]); ++ if (i) mat[j][k] /= mat[i-1][i-1]; ++ } ++ } ++ } ++ return mat[4][4]; ++} ++ ++std::vector ++LPEEllipse5Pts::doEffect_path (std::vector const & path_in) ++{ ++ std::vector path_out = std::vector(); ++ ++ if (path_in[0].size() < 4) { ++ ++ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Five points required for constructing an ellipse")); ++ return path_in; ++ } ++ // we assume that the path has >= 3 nodes ++ Geom::Point A = path_in[0].initialPoint(); ++ Geom::Point B = path_in[0].pointAt(1); ++ Geom::Point C = path_in[0].pointAt(2); ++ Geom::Point D = path_in[0].pointAt(3); ++ Geom::Point E = path_in[0].pointAt(4); ++ ++ using namespace Geom; ++ ++ double rowmajor_matrix[5][6] = ++ { ++ {A.x()*A.x(), A.x()*A.y(), A.y()*A.y(), A.x(), A.y(), 1}, ++ {B.x()*B.x(), B.x()*B.y(), B.y()*B.y(), B.x(), B.y(), 1}, ++ {C.x()*C.x(), C.x()*C.y(), C.y()*C.y(), C.x(), C.y(), 1}, ++ {D.x()*D.x(), D.x()*D.y(), D.y()*D.y(), D.x(), D.y(), 1}, ++ {E.x()*E.x(), E.x()*E.y(), E.y()*E.y(), E.x(), E.y(), 1} ++ }; ++ ++ double mat_a[5][5] = ++ { ++ {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, ++ {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, ++ {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, ++ {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, ++ {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} ++ }; ++ double mat_b[5][5] = ++ { ++ {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, ++ {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, ++ {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, ++ {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, ++ {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} ++ }; ++ double mat_c[5][5] = ++ { ++ {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, ++ {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, ++ {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, ++ {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, ++ {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} ++ }; ++ double mat_d[5][5] = ++ { ++ {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, ++ {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, ++ {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, ++ {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, ++ {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} ++ }; ++ double mat_e[5][5] = ++ { ++ {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, ++ {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, ++ {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, ++ {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, ++ {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} ++ }; ++ double mat_f[5][5] = ++ { ++ {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, ++ {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, ++ {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, ++ {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, ++ {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]} ++ }; ++ ++ double a1 = _det5(mat_a); ++ double b1 = -_det5(mat_b); ++ double c1 = _det5(mat_c); ++ double d1 = -_det5(mat_d); ++ double e1 = _det5(mat_e); ++ double f1 = -_det5(mat_f); ++ ++ double mat_check[][3] = ++ { ++ {a1, b1/2, d1/2}, ++ {b1/2, c1, e1/2}, ++ {d1/2, e1/2, f1} ++ }; ++ ++ if (_det3(mat_check) == 0 || a1*c1 - b1*b1/4 <= 0) { ++ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No ellipse found for specified points")); ++ return path_in; ++ } ++ ++ Geom::Ellipse el(a1, b1, c1, d1, e1, f1); ++ ++ double s, e; ++ double x0, y0, x1, y1, x2, y2, x3, y3; ++ double len; ++ ++ // figure out if we have a slice, guarding against rounding errors ++ ++ Path p(Geom::Point(cos(0), sin(0))); ++ ++ double end = 2 * M_PI; ++ for (s = 0; s < end; s += M_PI_2) { ++ e = s + M_PI_2; ++ if (e > end) ++ e = end; ++ len = 4*tan((e - s)/4)/3; ++ x0 = cos(s); ++ y0 = sin(s); ++ x1 = x0 + len * cos(s + M_PI_2); ++ y1 = y0 + len * sin(s + M_PI_2); ++ x3 = cos(e); ++ y3 = sin(e); ++ x2 = x3 + len * cos(e - M_PI_2); ++ y2 = y3 + len * sin(e - M_PI_2); ++ p.appendNew(Geom::Point(x1,y1), Geom::Point(x2,y2), Geom::Point(x3,y3)); ++ } ++ ++ Geom::Affine aff = Geom::Scale(el.ray(Geom::X), el.ray(Geom::Y)) * Geom::Rotate(el.rot_angle()) * Geom::Translate(el.center()); ++ ++ path_out.push_back(p * aff); ++ ++ return path_out; ++} ++ ++/* ######################## */ ++ ++} //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 : + +=== added file 'src/live_effects/lpe-ellipse_5pts.h' +--- src/live_effects/lpe-ellipse_5pts.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-ellipse_5pts.h 2013-09-07 18:46:36 +0000 +@@ -0,0 +1,50 @@ ++#ifndef INKSCAPE_LPE_ELLIPSE_5PTS_H ++#define INKSCAPE_LPE_ELLIPSE_5PTS_H ++ ++/** \file ++ * LPE "Ellipse through 5 points" implementation ++ */ ++ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/effect.h" ++#include "live_effects/parameter/parameter.h" ++#include "live_effects/parameter/point.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++class LPEEllipse5Pts : public Effect { ++public: ++ LPEEllipse5Pts(LivePathEffectObject *lpeobject); ++ virtual ~LPEEllipse5Pts(); ++ ++ virtual std::vector doEffect_path (std::vector const & path_in); ++ ++private: ++ LPEEllipse5Pts(const LPEEllipse5Pts&); ++ LPEEllipse5Pts& operator=(const LPEEllipse5Pts&); ++}; ++ ++} //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 : + +=== added file 'src/live_effects/lpe-fill-between-many.cpp' +--- src/live_effects/lpe-fill-between-many.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-fill-between-many.cpp 2014-03-01 21:14:38 +0000 +@@ -0,0 +1,77 @@ ++/* ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++#include ++ ++#include "live_effects/lpe-fill-between-many.h" ++ ++#include "display/curve.h" ++#include "sp-item.h" ++#include "2geom/path.h" ++#include "sp-shape.h" ++#include "sp-text.h" ++#include "2geom/bezier-curve.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++LPEFillBetweenMany::LPEFillBetweenMany(LivePathEffectObject *lpeobject) : ++ Effect(lpeobject), ++ linked_paths(_("Linked path:"), _("Paths from which to take the original path data"), "linkedpaths", &wr, this) ++{ ++ registerParameter( dynamic_cast(&linked_paths) ); ++ //perceived_path = true; ++} ++ ++LPEFillBetweenMany::~LPEFillBetweenMany() ++{ ++ ++} ++ ++void LPEFillBetweenMany::doEffect (SPCurve * curve) ++{ ++ std::vector res_pathv; ++ SPItem * firstObj = NULL; ++ for (std::vector::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); iter++) { ++ SPObject *obj; ++ if ((*iter)->ref.isAttached() && (obj = (*iter)->ref.getObject()) && SP_IS_ITEM(obj) && !(*iter)->_pathvector.empty()) { ++ Geom::Path linked_path; ++ if ((*iter)->reversed) { ++ linked_path = (*iter)->_pathvector.front().reverse(); ++ } else { ++ linked_path = (*iter)->_pathvector.front(); ++ } ++ ++ if (!res_pathv.empty()) { ++ linked_path = linked_path * SP_ITEM(obj)->getRelativeTransform(firstObj); ++ res_pathv.front().appendNew(linked_path.initialPoint()); ++ res_pathv.front().append(linked_path); ++ } else { ++ firstObj = SP_ITEM(obj); ++ res_pathv.push_back(linked_path); ++ } ++ } ++ } ++ if (!res_pathv.empty()) { ++ res_pathv.front().close(); ++ } ++ curve->set_pathvector(res_pathv); ++} ++ ++} // 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 : + +=== added file 'src/live_effects/lpe-fill-between-many.h' +--- src/live_effects/lpe-fill-between-many.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-fill-between-many.h 2014-03-01 21:13:34 +0000 +@@ -0,0 +1,36 @@ ++#ifndef INKSCAPE_LPE_FILL_BETWEEN_MANY_H ++#define INKSCAPE_LPE_FILL_BETWEEN_MANY_H ++ ++/* ++ * Inkscape::LPEFillBetweenStrokes ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/effect.h" ++#include "live_effects/parameter/originalpatharray.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++class LPEFillBetweenMany : public Effect { ++public: ++ LPEFillBetweenMany(LivePathEffectObject *lpeobject); ++ virtual ~LPEFillBetweenMany(); ++ ++ virtual void doEffect (SPCurve * curve); ++ ++private: ++ OriginalPathArrayParam linked_paths; ++ ++private: ++ LPEFillBetweenMany(const LPEFillBetweenMany&); ++ LPEFillBetweenMany& operator=(const LPEFillBetweenMany&); ++}; ++ ++}; //namespace LivePathEffect ++}; //namespace Inkscape ++ ++#endif + +=== added file 'src/live_effects/lpe-fill-between-strokes.cpp' +--- src/live_effects/lpe-fill-between-strokes.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-fill-between-strokes.cpp 2014-03-01 21:13:06 +0000 +@@ -0,0 +1,116 @@ ++/* ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++ ++#include "live_effects/lpe-fill-between-strokes.h" ++ ++#include "display/curve.h" ++#include "sp-item.h" ++#include "2geom/path.h" ++#include "sp-shape.h" ++#include "sp-text.h" ++#include "2geom/bezier-curve.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++LPEFillBetweenStrokes::LPEFillBetweenStrokes(LivePathEffectObject *lpeobject) : ++ Effect(lpeobject), ++ linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this), ++ second_path(_("Second path:"), _("Second path from which to take the original path data"), "secondpath", &wr, this), ++ reverse_second(_("Reverse Second"), _("Reverses the second path order"), "reversesecond", &wr, this) ++{ ++ registerParameter( dynamic_cast(&linked_path) ); ++ registerParameter( dynamic_cast(&second_path) ); ++ registerParameter( dynamic_cast(&reverse_second) ); ++ //perceived_path = true; ++} ++ ++LPEFillBetweenStrokes::~LPEFillBetweenStrokes() ++{ ++ ++} ++ ++void LPEFillBetweenStrokes::doEffect (SPCurve * curve) ++{ ++ if (curve) { ++ if ( linked_path.linksToPath() && second_path.linksToPath() && linked_path.getObject() && second_path.getObject() ) { ++ std::vector linked_pathv = linked_path.get_pathvector(); ++ std::vector second_pathv = second_path.get_pathvector(); ++ std::vector result_linked_pathv; ++ std::vector result_second_pathv; ++ Geom::Affine second_transform = second_path.getObject()->getRelativeTransform(linked_path.getObject()); ++ ++ for (std::vector::iterator iter = linked_pathv.begin(); iter != linked_pathv.end(); ++iter) ++ { ++ result_linked_pathv.push_back((*iter)); ++ } ++ for (std::vector::iterator iter = second_pathv.begin(); iter != second_pathv.end(); ++iter) ++ { ++ result_second_pathv.push_back((*iter) * second_transform); ++ } ++ ++ if ( !result_linked_pathv.empty() && !result_second_pathv.empty() && !result_linked_pathv.front().closed() ) { ++ if (reverse_second.get_value()) ++ { ++ result_linked_pathv.front().appendNew(result_second_pathv.front().finalPoint()); ++ result_linked_pathv.front().append(result_second_pathv.front().reverse()); ++ } ++ else ++ { ++ result_linked_pathv.front().appendNew(result_second_pathv.front().initialPoint()); ++ result_linked_pathv.front().append(result_second_pathv.front()); ++ } ++ curve->set_pathvector(result_linked_pathv); ++ } ++ else if ( !result_linked_pathv.empty() ) { ++ curve->set_pathvector(result_linked_pathv); ++ } ++ else if ( !result_second_pathv.empty() ) { ++ curve->set_pathvector(result_second_pathv); ++ } ++ } ++ else if ( linked_path.linksToPath() && linked_path.getObject() ) { ++ std::vector linked_pathv = linked_path.get_pathvector(); ++ std::vector result_pathv; ++ ++ for (std::vector::iterator iter = linked_pathv.begin(); iter != linked_pathv.end(); ++iter) ++ { ++ result_pathv.push_back((*iter)); ++ } ++ if ( !result_pathv.empty() ) { ++ curve->set_pathvector(result_pathv); ++ } ++ } ++ else if ( second_path.linksToPath() && second_path.getObject() ) { ++ std::vector second_pathv = second_path.get_pathvector(); ++ std::vector result_pathv; ++ ++ for (std::vector::iterator iter = second_pathv.begin(); iter != second_pathv.end(); ++iter) ++ { ++ result_pathv.push_back((*iter)); ++ } ++ if ( !result_pathv.empty() ) { ++ curve->set_pathvector(result_pathv); ++ } ++ } ++ } ++} ++ ++} // 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 : + +=== added file 'src/live_effects/lpe-fill-between-strokes.h' +--- src/live_effects/lpe-fill-between-strokes.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/lpe-fill-between-strokes.h 2014-03-01 21:11:40 +0000 +@@ -0,0 +1,38 @@ ++#ifndef INKSCAPE_LPE_FILL_BETWEEN_STROKES_H ++#define INKSCAPE_LPE_FILL_BETWEEN_STROKES_H ++ ++/* ++ * Inkscape::LPEFillBetweenStrokes ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/effect.h" ++#include "live_effects/parameter/originalpath.h" ++ ++namespace Inkscape { ++namespace LivePathEffect { ++ ++class LPEFillBetweenStrokes : public Effect { ++public: ++ LPEFillBetweenStrokes(LivePathEffectObject *lpeobject); ++ virtual ~LPEFillBetweenStrokes(); ++ ++ virtual void doEffect (SPCurve * curve); ++ ++private: ++ OriginalPathParam linked_path; ++ OriginalPathParam second_path; ++ BoolParam reverse_second; ++ ++private: ++ LPEFillBetweenStrokes(const LPEFillBetweenStrokes&); ++ LPEFillBetweenStrokes& operator=(const LPEFillBetweenStrokes&); ++}; ++ ++}; //namespace LivePathEffect ++}; //namespace Inkscape ++ ++#endif + +=== added file 'src/live_effects/parameter/originalpatharray.cpp' +--- src/live_effects/parameter/originalpatharray.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/parameter/originalpatharray.cpp 2013-09-07 18:46:36 +0000 +@@ -0,0 +1,486 @@ ++/* ++ * Copyright (C) Johan Engelen 2008 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include "live_effects/parameter/originalpatharray.h" ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "inkscape.h" ++#include "icon-size.h" ++#include "widgets/icon.h" ++#include "ui/clipboard.h" ++#include "svg/svg.h" ++#include "svg/stringstream.h" ++#include "originalpath.h" ++#include "uri.h" ++#include "display/curve.h" ++ ++#include ++#include <2geom/coord.h> ++#include <2geom/point.h> ++#include "sp-shape.h" ++#include "sp-text.h" ++#include "live_effects/effect.h" ++ ++#include "verbs.h" ++#include "document-undo.h" ++#include "document.h" ++ ++namespace Inkscape { ++ ++namespace LivePathEffect { ++ ++class OriginalPathArrayParam::ModelColumns : public Gtk::TreeModel::ColumnRecord ++{ ++public: ++ ++ ModelColumns() ++ { ++ add(_colObject); ++ add(_colLabel); ++ add(_colReverse); ++ } ++ virtual ~ModelColumns() {} ++ ++ Gtk::TreeModelColumn _colObject; ++ Gtk::TreeModelColumn _colLabel; ++ Gtk::TreeModelColumn _colReverse; ++}; ++ ++OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, ++ const Glib::ustring& tip, ++ const Glib::ustring& key, ++ Inkscape::UI::Widget::Registry* wr, ++ Effect* effect ) ++: Parameter(label, tip, key, wr, effect), ++ _vector(), ++ _tree(), ++ _text_renderer(), ++ _toggle_renderer(), ++ _scroller() ++{ ++ _model = new ModelColumns(); ++ _store = Gtk::TreeStore::create(*_model); ++ _tree.set_model(_store); ++ ++ _tree.set_reorderable(true); ++ _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); ++ ++ _text_renderer = manage(new Gtk::CellRendererText()); ++ int nameColNum = _tree.append_column(_("Name"), *_text_renderer) - 1; ++ _name_column = _tree.get_column(nameColNum); ++ _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); ++ ++ _tree.set_expander_column( *_tree.get_column(nameColNum) ); ++ _tree.set_search_column(_model->_colLabel); ++ ++ Gtk::CellRendererToggle * _toggle_renderer = manage(new Gtk::CellRendererToggle()); ++ int toggleColNum = _tree.append_column(_("Reverse"), *_toggle_renderer) - 1; ++ Gtk::TreeViewColumn* col = _tree.get_column(toggleColNum); ++ _toggle_renderer->set_activatable(true); ++ _toggle_renderer->signal_toggled().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_reverse_toggled)); ++ col->add_attribute(_toggle_renderer->property_active(), _model->_colReverse); ++ ++ _scroller.add(_tree); ++ _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); ++ _scroller.set_shadow_type(Gtk::SHADOW_IN); ++ ++ oncanvas_editable = true; ++ ++} ++ ++OriginalPathArrayParam::~OriginalPathArrayParam() ++{ ++ while (!_vector.empty()) { ++ PathAndDirection *w = _vector.back(); ++ _vector.pop_back(); ++ unlink(w); ++ delete w; ++ } ++ delete _model; ++} ++ ++void OriginalPathArrayParam::on_reverse_toggled(const Glib::ustring& path) ++{ ++ Gtk::TreeModel::iterator iter = _store->get_iter(path); ++ Gtk::TreeModel::Row row = *iter; ++ PathAndDirection *w = row[_model->_colObject]; ++ row[_model->_colReverse] = !row[_model->_colReverse]; ++ w->reversed = row[_model->_colReverse]; ++ ++ gchar * full = param_getSVGValue(); ++ param_write_to_repr(full); ++ g_free(full); ++ DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, ++ _("Link path parameter to path")); ++} ++ ++void OriginalPathArrayParam::param_set_default() ++{ ++ ++} ++ ++Gtk::Widget* OriginalPathArrayParam::param_newWidget() ++{ ++ Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox()); ++ Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox()); ++ ++ vbox->pack_start(_scroller, Gtk::PACK_EXPAND_WIDGET); ++ ++ ++ { // Paste path to link button ++ Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_PASTE, Inkscape::ICON_SIZE_BUTTON) ); ++ Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); ++ pButton->set_relief(Gtk::RELIEF_NONE); ++ pIcon->show(); ++ pButton->add(*pIcon); ++ pButton->show(); ++ pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_link_button_click)); ++ hbox->pack_start(*pButton, Gtk::PACK_SHRINK); ++ pButton->set_tooltip_text(_("Link to path")); ++ } ++ ++ { // Remove linked path ++ Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_REMOVE, Inkscape::ICON_SIZE_BUTTON) ); ++ Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); ++ pButton->set_relief(Gtk::RELIEF_NONE); ++ pIcon->show(); ++ pButton->add(*pIcon); ++ pButton->show(); ++ pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_remove_button_click)); ++ hbox->pack_start(*pButton, Gtk::PACK_SHRINK); ++ pButton->set_tooltip_text(_("Remove Path")); ++ } ++ ++ { // Move Down ++ Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_GO_DOWN, Inkscape::ICON_SIZE_BUTTON) ); ++ Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); ++ pButton->set_relief(Gtk::RELIEF_NONE); ++ pIcon->show(); ++ pButton->add(*pIcon); ++ pButton->show(); ++ pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_down_button_click)); ++ hbox->pack_end(*pButton, Gtk::PACK_SHRINK); ++ pButton->set_tooltip_text(_("Move Down")); ++ } ++ ++ { // Move Down ++ Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_GO_UP, Inkscape::ICON_SIZE_BUTTON) ); ++ Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); ++ pButton->set_relief(Gtk::RELIEF_NONE); ++ pIcon->show(); ++ pButton->add(*pIcon); ++ pButton->show(); ++ pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_up_button_click)); ++ hbox->pack_end(*pButton, Gtk::PACK_SHRINK); ++ pButton->set_tooltip_text(_("Move Up")); ++ } ++ ++ vbox->pack_end(*hbox, Gtk::PACK_SHRINK); ++ ++ vbox->show_all_children(true); ++ ++ return vbox; ++} ++ ++bool OriginalPathArrayParam::_selectIndex(const Gtk::TreeIter& iter, int* i) ++{ ++ if ((*i)-- <= 0) { ++ _tree.get_selection()->select(iter); ++ return true; ++ } ++ return false; ++} ++ ++void OriginalPathArrayParam::on_up_button_click() ++{ ++ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); ++ if (iter) { ++ Gtk::TreeModel::Row row = *iter; ++ ++ int i = -1; ++ std::vector::iterator piter = _vector.begin(); ++ for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, iter++) { ++ if (*iter == row[_model->_colObject]) { ++ _vector.erase(iter); ++ _vector.insert(piter, row[_model->_colObject]); ++ break; ++ } ++ } ++ ++ gchar * full = param_getSVGValue(); ++ param_write_to_repr(full); ++ g_free(full); ++ ++ DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, ++ _("Move path up")); ++ ++ _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_selectIndex), &i)); ++ } ++} ++ ++void OriginalPathArrayParam::on_down_button_click() ++{ ++ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); ++ if (iter) { ++ Gtk::TreeModel::Row row = *iter; ++ ++ int i = 0; ++ for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); i++, iter++) { ++ if (*iter == row[_model->_colObject]) { ++ std::vector::iterator niter = _vector.erase(iter); ++ if (niter != _vector.end()) { ++ niter++; ++ i++; ++ } ++ _vector.insert(niter, row[_model->_colObject]); ++ break; ++ } ++ } ++ ++ gchar * full = param_getSVGValue(); ++ param_write_to_repr(full); ++ g_free(full); ++ ++ DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, ++ _("Move path down")); ++ ++ _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_selectIndex), &i)); ++ } ++} ++ ++void OriginalPathArrayParam::on_remove_button_click() ++{ ++ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); ++ if (iter) { ++ Gtk::TreeModel::Row row = *iter; ++ remove_link(row[_model->_colObject]); ++ ++ gchar * full = param_getSVGValue(); ++ param_write_to_repr(full); ++ g_free(full); ++ ++ DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, ++ _("Remove path")); ++ } ++ ++} ++ ++void ++OriginalPathArrayParam::on_link_button_click() ++{ ++ Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); ++ Glib::ustring pathid = cm->getShapeOrTextObjectId(SP_ACTIVE_DESKTOP); ++ ++ if (pathid == "") { ++ return; ++ } ++ // add '#' at start to make it an uri. ++ pathid.insert(pathid.begin(), '#'); ++ ++ Inkscape::SVGOStringStream os; ++ bool foundOne = false; ++ for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { ++ if (foundOne) { ++ os << "|"; ++ } else { ++ foundOne = true; ++ } ++ os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0"); ++ } ++ ++ if (foundOne) { ++ os << "|"; ++ } ++ ++ os << pathid.c_str() << ",0"; ++ ++ param_write_to_repr(os.str().c_str()); ++ DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, ++ _("Link path parameter to path")); ++} ++ ++void OriginalPathArrayParam::unlink(PathAndDirection* to) ++{ ++ to->linked_modified_connection.disconnect(); ++ to->linked_delete_connection.disconnect(); ++ to->ref.detach(); ++ to->_pathvector = Geom::PathVector(); ++ if (to->href) { ++ g_free(to->href); ++ to->href = NULL; ++ } ++} ++ ++void OriginalPathArrayParam::remove_link(PathAndDirection* to) ++{ ++ unlink(to); ++ for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); iter++) { ++ if (*iter == to) { ++ PathAndDirection *w = *iter; ++ _vector.erase(iter); ++ delete w; ++ return; ++ } ++ } ++} ++ ++void OriginalPathArrayParam::linked_delete(SPObject */*deleted*/, PathAndDirection* to) ++{ ++ //remove_link(to); ++ ++ gchar * full = param_getSVGValue(); ++ param_write_to_repr(full); ++ g_free(full); ++} ++ ++bool OriginalPathArrayParam::_updateLink(const Gtk::TreeIter& iter, PathAndDirection* pd) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ if (row[_model->_colObject] == pd) { ++ SPObject *obj = pd->ref.getObject(); ++ row[_model->_colLabel] = obj && obj->getId() ? ( obj->label() ? obj->label() : obj->getId() ) : pd->href; ++ return true; ++ } ++ return false; ++} ++ ++void OriginalPathArrayParam::linked_changed(SPObject */*old_obj*/, SPObject *new_obj, PathAndDirection* to) ++{ ++ to->linked_delete_connection.disconnect(); ++ to->linked_modified_connection.disconnect(); ++ to->linked_transformed_connection.disconnect(); ++ ++ if (new_obj && SP_IS_ITEM(new_obj)) { ++ to->linked_delete_connection = new_obj->connectDelete(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_delete), to)); ++ to->linked_modified_connection = new_obj->connectModified(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_modified), to)); ++ to->linked_transformed_connection = SP_ITEM(new_obj)->connectTransformed(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_transformed), to)); ++ ++ linked_modified(new_obj, SP_OBJECT_MODIFIED_FLAG, to); ++ } else { ++ to->_pathvector = Geom::PathVector(); ++ SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); ++ _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); ++ } ++} ++ ++void OriginalPathArrayParam::linked_transformed(Geom::Affine const *mp, SPItem* original, PathAndDirection* to) ++{ ++ ++} ++ ++void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint flags, PathAndDirection* to) ++{ ++ if (!to) { ++ return; ++ } ++ SPCurve *curve = NULL; ++ if (SP_IS_SHAPE(linked_obj)) { ++ curve = SP_SHAPE(linked_obj)->getCurvePerceived(); ++ } ++ if (SP_IS_TEXT(linked_obj)) { ++ curve = SP_TEXT(linked_obj)->getNormalizedBpath(); ++ } ++ ++ if (curve == NULL) { ++ // curve invalid, set empty pathvector ++ to->_pathvector = Geom::PathVector(); ++ } else { ++ to->_pathvector = curve->get_pathvector(); ++ curve->unref(); ++ } ++} ++ ++void OriginalPathArrayParam::linked_modified(SPObject *linked_obj, guint flags, PathAndDirection* to) ++{ ++ if (!to) { ++ return; ++ } ++ setPathVector(linked_obj, flags, to); ++ SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); ++ _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); ++} ++ ++//void PathParam::linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item) ++//{ ++// linked_transformed_callback(rel_transf, moved_item); ++//} ++ ++bool OriginalPathArrayParam::param_readSVGValue(const gchar* strvalue) ++{ ++ if (strvalue) { ++ while (!_vector.empty()) { ++ PathAndDirection *w = _vector.back(); ++ unlink(w); ++ _vector.pop_back(); ++ delete w; ++ } ++ _store->clear(); ++ ++ gchar ** strarray = g_strsplit(strvalue, "|", 0); ++ for (gchar ** iter = strarray; *iter != NULL; iter++) { ++ if ((*iter)[0] == '#') { ++ gchar ** substrarray = g_strsplit(*iter, ",", 0); ++ PathAndDirection* w = new PathAndDirection((SPObject *)param_effect->getLPEObj()); ++ w->href = g_strdup(*substrarray); ++ w->reversed = *(substrarray+1) != NULL && (*(substrarray+1))[0] == '1'; ++ ++ w->linked_changed_connection = w->ref.changedSignal().connect(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_changed), w)); ++ w->ref.attach(URI(w->href)); ++ ++ _vector.push_back(w); ++ ++ Gtk::TreeModel::iterator iter = _store->append(); ++ Gtk::TreeModel::Row row = *iter; ++ SPObject *obj = w->ref.getObject(); ++ ++ row[_model->_colObject] = w; ++ row[_model->_colLabel] = obj ? ( obj->label() ? obj->label() : obj->getId() ) : w->href; ++ row[_model->_colReverse] = w->reversed; ++ g_strfreev (substrarray); ++ } ++ } ++ g_strfreev (strarray); ++ return true; ++ } ++ return false; ++} ++ ++gchar * OriginalPathArrayParam::param_getSVGValue() const ++{ ++ Inkscape::SVGOStringStream os; ++ bool foundOne = false; ++ for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { ++ if (foundOne) { ++ os << "|"; ++ } else { ++ foundOne = true; ++ } ++ os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0"); ++ } ++ gchar * str = g_strdup(os.str().c_str()); ++ return str; ++} ++ ++} /* 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 : + +=== added file 'src/live_effects/parameter/originalpatharray.h' +--- src/live_effects/parameter/originalpatharray.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/parameter/originalpatharray.h 2013-09-07 18:46:36 +0000 +@@ -0,0 +1,123 @@ ++#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINALPATHARRAY_H ++#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINALPATHARRAY_H ++ ++/* ++ * Inkscape::LivePathEffectParameters ++ * ++* Copyright (C) Johan Engelen 2008 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "live_effects/parameter/parameter.h" ++#include "live_effects/parameter/path-reference.h" ++ ++#include "svg/svg.h" ++#include "svg/stringstream.h" ++#include "path-reference.h" ++#include "sp-object.h" ++ ++namespace Inkscape { ++ ++namespace LivePathEffect { ++ ++class PathAndDirection { ++public: ++ PathAndDirection(SPObject *owner) ++ : href(NULL), ++ ref(owner), ++ _pathvector(Geom::PathVector()), ++ reversed(false) ++ { ++ ++ } ++ gchar *href; ++ URIReference ref; ++ //SPItem *obj; ++ std::vector _pathvector; ++ bool reversed; ++ ++ sigc::connection linked_changed_connection; ++ sigc::connection linked_delete_connection; ++ sigc::connection linked_modified_connection; ++ sigc::connection linked_transformed_connection; ++}; ++ ++class OriginalPathArrayParam : public Parameter { ++public: ++ class ModelColumns; ++ ++ OriginalPathArrayParam( const Glib::ustring& label, ++ const Glib::ustring& tip, ++ const Glib::ustring& key, ++ Inkscape::UI::Widget::Registry* wr, ++ Effect* effect); ++ ++ virtual ~OriginalPathArrayParam(); ++ ++ virtual Gtk::Widget * param_newWidget(); ++ virtual bool param_readSVGValue(const gchar * strvalue); ++ virtual gchar * param_getSVGValue() const; ++ virtual void param_set_default(); ++ ++ /** Disable the canvas indicators of parent class by overriding this method */ ++ virtual void param_editOncanvas(SPItem * /*item*/, SPDesktop * /*dt*/) {}; ++ /** Disable the canvas indicators of parent class by overriding this method */ ++ virtual void addCanvasIndicators(SPLPEItem const* /*lpeitem*/, std::vector & /*hp_vec*/) {}; ++ ++ std::vector _vector; ++ ++protected: ++ bool _updateLink(const Gtk::TreeIter& iter, PathAndDirection* pd); ++ bool _selectIndex(const Gtk::TreeIter& iter, int* i); ++ void unlink(PathAndDirection* to); ++ void remove_link(PathAndDirection* to); ++ void setPathVector(SPObject *linked_obj, guint flags, PathAndDirection* to); ++ ++ void linked_changed(SPObject *old_obj, SPObject *new_obj, PathAndDirection* to); ++ void linked_modified(SPObject *linked_obj, guint flags, PathAndDirection* to); ++ void linked_transformed(Geom::Affine const *mp, SPItem *original, PathAndDirection* to); ++ void linked_delete(SPObject *deleted, PathAndDirection* to); ++ ++ ModelColumns *_model; ++ Glib::RefPtr _store; ++ Gtk::TreeView _tree; ++ Gtk::CellRendererText *_text_renderer; ++ Gtk::CellRendererToggle *_toggle_renderer; ++ Gtk::TreeView::Column *_name_column; ++ Gtk::ScrolledWindow _scroller; ++ ++ void on_link_button_click(); ++ void on_remove_button_click(); ++ void on_up_button_click(); ++ void on_down_button_click(); ++ void on_reverse_toggled(const Glib::ustring& path); ++ ++private: ++ OriginalPathArrayParam(const OriginalPathArrayParam&); ++ OriginalPathArrayParam& operator=(const OriginalPathArrayParam&); ++}; ++ ++} //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 : + +=== added file 'src/live_effects/parameter/transformedpoint.cpp' +--- src/live_effects/parameter/transformedpoint.cpp 1970-01-01 00:00:00 +0000 ++++ src/live_effects/parameter/transformedpoint.cpp 2013-09-07 18:46:36 +0000 +@@ -0,0 +1,182 @@ ++/* ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++ ++#include "ui/widget/registered-widget.h" ++#include "live_effects/parameter/transformedpoint.h" ++#include "sp-lpe-item.h" ++#include "knotholder.h" ++#include "svg/svg.h" ++#include "svg/stringstream.h" ++ ++#include "live_effects/effect.h" ++#include "desktop.h" ++#include "verbs.h" ++ ++namespace Inkscape { ++ ++namespace LivePathEffect { ++ ++TransformedPointParam::TransformedPointParam( const Glib::ustring& label, const Glib::ustring& tip, ++ const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, ++ Effect* effect, Geom::Point default_vector, ++ bool dontTransform) ++ : Parameter(label, tip, key, wr, effect), ++ defvalue(default_vector), ++ origin(0.,0.), ++ vector(default_vector), ++ noTransform(dontTransform) ++{ ++ vec_knot_shape = SP_KNOT_SHAPE_DIAMOND; ++ vec_knot_mode = SP_KNOT_MODE_XOR; ++ vec_knot_color = 0xffffb500; ++} ++ ++TransformedPointParam::~TransformedPointParam() ++{ ++ ++} ++ ++void ++TransformedPointParam::param_set_default() ++{ ++ setOrigin(Geom::Point(0.,0.)); ++ setVector(defvalue); ++} ++ ++bool ++TransformedPointParam::param_readSVGValue(const gchar * strvalue) ++{ ++ gchar ** strarray = g_strsplit(strvalue, ",", 4); ++ if (!strarray) { ++ return false; ++ } ++ double val[4]; ++ unsigned int i = 0; ++ while (i < 4 && strarray[i]) { ++ if (sp_svg_number_read_d(strarray[i], &val[i]) != 0) { ++ i++; ++ } else { ++ break; ++ } ++ } ++ g_strfreev (strarray); ++ if (i == 4) { ++ setOrigin( Geom::Point(val[0], val[1]) ); ++ setVector( Geom::Point(val[2], val[3]) ); ++ return true; ++ } ++ return false; ++} ++ ++gchar * ++TransformedPointParam::param_getSVGValue() const ++{ ++ Inkscape::SVGOStringStream os; ++ os << origin << " , " << vector; ++ gchar * str = g_strdup(os.str().c_str()); ++ return str; ++} ++ ++Gtk::Widget * ++TransformedPointParam::param_newWidget() ++{ ++ Inkscape::UI::Widget::RegisteredVector * pointwdg = Gtk::manage( ++ new Inkscape::UI::Widget::RegisteredVector( param_label, ++ param_tooltip, ++ param_key, ++ *param_wr, ++ param_effect->getRepr(), ++ param_effect->getSPDoc() ) ); ++ pointwdg->setPolarCoords(); ++ pointwdg->setValue( vector, origin ); ++ pointwdg->clearProgrammatically(); ++ pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change vector parameter")); ++ ++ Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); ++ static_cast(hbox)->pack_start(*pointwdg, true, true); ++ static_cast(hbox)->show_all_children(); ++ ++ return dynamic_cast (hbox); ++} ++ ++void ++TransformedPointParam::set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector) ++{ ++ setValues(new_origin, new_vector); ++ gchar * str = param_getSVGValue(); ++ param_write_to_repr(str); ++ g_free(str); ++} ++ ++void ++TransformedPointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) ++{ ++ if (!noTransform) { ++ set_and_write_new_values( origin * postmul, vector * postmul.withoutTranslation() ); ++ } ++} ++ ++ ++void ++TransformedPointParam::set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) ++{ ++ vec_knot_shape = shape; ++ vec_knot_mode = mode; ++ vec_knot_color = color; ++} ++ ++void ++TransformedPointParam::set_oncanvas_color(guint32 color) ++{ ++ vec_knot_color = color; ++} ++ ++class TransformedPointParamKnotHolderEntity_Vector : public KnotHolderEntity { ++public: ++ TransformedPointParamKnotHolderEntity_Vector(TransformedPointParam *p) : param(p) { } ++ virtual ~TransformedPointParamKnotHolderEntity_Vector() {} ++ ++ virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) { ++ Geom::Point const s = p - param->origin; ++ /// @todo implement angle snapping when holding CTRL ++ param->setVector(s); ++ sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); ++ }; ++ virtual Geom::Point knot_get() const{ ++ return param->origin + param->vector; ++ }; ++ virtual void knot_click(guint /*state*/){ ++ g_print ("This is the vector handle associated to parameter '%s'\n", param->param_key.c_str()); ++ }; ++ ++private: ++ TransformedPointParam *param; ++}; ++ ++void ++TransformedPointParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) ++{ ++ TransformedPointParamKnotHolderEntity_Vector *vector_e = new TransformedPointParamKnotHolderEntity_Vector(this); ++ vector_e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, handleTip(), vec_knot_shape, vec_knot_mode, vec_knot_color); ++ knotholder->add(vector_e); ++} ++ ++} /* 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 : + +=== added file 'src/live_effects/parameter/transformedpoint.h' +--- src/live_effects/parameter/transformedpoint.h 1970-01-01 00:00:00 +0000 ++++ src/live_effects/parameter/transformedpoint.h 2013-09-07 18:46:36 +0000 +@@ -0,0 +1,87 @@ ++#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_TRANSFORMED_POINT_H ++#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_TRANSFORMED_POINT_H ++ ++/* ++ * Inkscape::LivePathEffectParameters ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++#include <2geom/point.h> ++ ++#include "live_effects/parameter/parameter.h" ++ ++#include "knot-holder-entity.h" ++ ++namespace Inkscape { ++ ++namespace LivePathEffect { ++ ++ ++class TransformedPointParam : public Parameter { ++public: ++ TransformedPointParam( const Glib::ustring& label, ++ const Glib::ustring& tip, ++ const Glib::ustring& key, ++ Inkscape::UI::Widget::Registry* wr, ++ Effect* effect, ++ Geom::Point default_vector = Geom::Point(1,0), ++ bool dontTransform = false); ++ virtual ~TransformedPointParam(); ++ ++ virtual Gtk::Widget * param_newWidget(); ++ inline const gchar *handleTip() const { return param_tooltip.c_str(); } ++ ++ virtual bool param_readSVGValue(const gchar * strvalue); ++ virtual gchar * param_getSVGValue() const; ++ ++ Geom::Point getVector() const { return vector; }; ++ Geom::Point getOrigin() const { return origin; }; ++ void setValues(Geom::Point const &new_origin, Geom::Point const &new_vector) { setVector(new_vector); setOrigin(new_origin); }; ++ void setVector(Geom::Point const &new_vector) { vector = new_vector; }; ++ void setOrigin(Geom::Point const &new_origin) { origin = new_origin; }; ++ virtual void param_set_default(); ++ ++ void set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector); ++ ++ virtual void param_transform_multiply(Geom::Affine const &postmul, bool set); ++ ++ void set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); ++ //void set_origin_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); ++ void set_oncanvas_color(guint32 color); ++ ++ virtual bool providesKnotHolderEntities() const { return true; } ++ virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); ++ ++private: ++ TransformedPointParam(const TransformedPointParam&); ++ TransformedPointParam& operator=(const TransformedPointParam&); ++ ++ Geom::Point defvalue; ++ ++ Geom::Point origin; ++ Geom::Point vector; ++ ++ bool noTransform; ++ ++ /// The looks of the vector and origin knots oncanvas ++ SPKnotShapeType vec_knot_shape; ++ SPKnotModeType vec_knot_mode; ++ guint32 vec_knot_color; ++// SPKnotShapeType ori_knot_shape; ++// SPKnotModeType ori_knot_mode; ++// guint32 ori_knot_color; ++ ++// friend class VectorParamKnotHolderEntity_Origin; ++ friend class TransformedPointParamKnotHolderEntity_Vector; ++}; ++ ++ ++} //namespace LivePathEffect ++ ++} //namespace Inkscape ++ ++#endif + diff --git a/mkerror.txt b/mkerror.txt new file mode 100644 index 000000000..069535166 --- /dev/null +++ b/mkerror.txt @@ -0,0 +1,11 @@ +make all-recursive +make[1]: Entering directory `/home/inkscape-diff' +Making all in src +make[2]: Entering directory `/home/inkscape-diff/src' +make all-am +make[3]: Entering directory `/home/inkscape-diff/src' + CXXLD inkscape + CXXLD inkview +make[3]: Leaving directory `/home/inkscape-diff/src' +make[2]: Leaving directory `/home/inkscape-diff/src' +make[1]: Leaving directory `/home/inkscape-diff' diff --git a/objects_dialog.patch b/objects_dialog.patch new file mode 100644 index 000000000..1cdd09c34 --- /dev/null +++ b/objects_dialog.patch @@ -0,0 +1,3637 @@ +=== modified file 'src/attributes.cpp' +--- src/attributes.cpp 2012-12-22 16:34:31 +0000 ++++ src/attributes.cpp 2013-03-17 14:36:44 +0000 +@@ -41,6 +41,7 @@ + {SP_ATTR_TRANSFORM_CENTER_X, "inkscape:transform-center-x"}, + {SP_ATTR_TRANSFORM_CENTER_Y, "inkscape:transform-center-y"}, + {SP_ATTR_INKSCAPE_PATH_EFFECT, "inkscape:path-effect"}, ++ {SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, "inkscape:highlight-color"}, + /* SPAnchor */ + {SP_ATTR_XLINK_HREF, "xlink:href"}, + {SP_ATTR_XLINK_TYPE, "xlink:type"}, +@@ -50,7 +51,9 @@ + {SP_ATTR_XLINK_SHOW, "xlink:show"}, + {SP_ATTR_XLINK_ACTUATE, "xlink:actuate"}, + {SP_ATTR_TARGET, "target"}, ++ /* SPGroup */ + {SP_ATTR_INKSCAPE_GROUPMODE, "inkscape:groupmode"}, ++ {SP_ATTR_INKSCAPE_EXPANDED, "inkscape:expanded"}, + /* SPRoot */ + {SP_ATTR_VERSION, "version"}, + {SP_ATTR_WIDTH, "width"}, + +=== modified file 'src/attributes.h' +--- src/attributes.h 2012-12-22 16:34:31 +0000 ++++ src/attributes.h 2013-03-17 14:36:17 +0000 +@@ -40,6 +40,7 @@ + SP_ATTR_TRANSFORM_CENTER_X, + SP_ATTR_TRANSFORM_CENTER_Y, + SP_ATTR_INKSCAPE_PATH_EFFECT, ++ SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, + /* SPAnchor */ + SP_ATTR_XLINK_HREF, + SP_ATTR_XLINK_TYPE, +@@ -51,6 +52,7 @@ + SP_ATTR_TARGET, + /* SPGroup */ + SP_ATTR_INKSCAPE_GROUPMODE, ++ SP_ATTR_INKSCAPE_EXPANDED, + /* SPRoot */ + SP_ATTR_VERSION, + SP_ATTR_WIDTH, + +=== modified file 'src/desktop.cpp' +--- src/desktop.cpp 2013-01-27 14:19:11 +0000 ++++ src/desktop.cpp 2013-03-17 14:43:46 +0000 +@@ -1885,6 +1885,7 @@ + std::map mapVerbPreference; + std::map::const_iterator iter; + mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_LAYERS, "/dialogs/layers") ); ++ mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_OBJECTS, "/dialogs/objects") ); + mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_FILL_STROKE, "/dialogs/fillstroke") ); + mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_EXTENSIONEDITOR, "/dialogs/extensioneditor") ); + mapVerbPreference.insert(std::make_pair ((int)SP_VERB_DIALOG_ALIGN_DISTRIBUTE, "/dialogs/align") ); + +=== modified file 'src/menus-skeleton.h' +--- src/menus-skeleton.h 2013-03-16 16:26:03 +0000 ++++ src/menus-skeleton.h 2013-03-17 14:30:19 +0000 +@@ -180,6 +180,8 @@ + " \n" + " \n" + " \n" ++" \n" ++" \n" + " \n" + " \n" + " \n" + +=== modified file 'src/sp-item-group.cpp' +--- src/sp-item-group.cpp 2013-01-24 11:43:26 +0000 ++++ src/sp-item-group.cpp 2013-03-17 14:50:17 +0000 +@@ -123,6 +123,7 @@ + static void sp_group_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) + { + object->readAttr( "inkscape:groupmode" ); ++ object->readAttr( "inkscape:expanded" ); + + if (((SPObjectClass *)sp_group_parent_class)->build) { + ((SPObjectClass *)sp_group_parent_class)->build(object, document, repr); +@@ -221,7 +222,7 @@ + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove (l, l->data); + } +- } else { ++ } else if (!(flags & SP_OBJECT_WRITE_NO_CHILDREN)) { + for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { + if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) { + child->updateRepr(flags); +@@ -241,6 +242,12 @@ + value = NULL; + } + repr->setAttribute("inkscape:groupmode", value); ++ ++ if (group->_expanded) { ++ repr->setAttribute("inkscape:expanded", "true"); ++ } else { ++ repr->setAttribute("inkscape:expanded", NULL); ++ } + } + + if (((SPObjectClass *) (sp_group_parent_class))->write) { +@@ -280,6 +287,11 @@ + group->setLayerMode(SPGroup::GROUP); + } + break; ++ case SP_ATTR_INKSCAPE_EXPANDED: ++ if ( value && !strcmp(value, "true") ) { ++ group->setExpanded(true); ++ } ++ break; + default: { + if (((SPObjectClass *) (sp_group_parent_class))->set) { + (* ((SPObjectClass *) (sp_group_parent_class))->set)(object, key, value); +@@ -517,6 +529,12 @@ + } + } + ++void SPGroup::setExpanded(bool isexpanded) { ++ if ( _expanded != isexpanded ){ ++ _expanded = isexpanded; ++ } ++} ++ + SPGroup::LayerMode SPGroup::layerDisplayMode(unsigned int dkey) const { + std::map::const_iterator iter; + iter = _display_modes.find(dkey); + +=== modified file 'src/sp-item-group.h' +--- src/sp-item-group.h 2011-10-04 19:04:58 +0000 ++++ src/sp-item-group.h 2013-03-17 14:50:53 +0000 +@@ -36,11 +36,15 @@ + struct SPGroup : public SPLPEItem { + enum LayerMode { GROUP, LAYER, MASK_HELPER }; + ++ bool _expanded; + LayerMode _layer_mode; + std::map _display_modes; + + LayerMode layerMode() const { return _layer_mode; } + void setLayerMode(LayerMode mode); ++ ++ bool expanded() const { return _expanded; } ++ void setExpanded(bool isexpanded); + + LayerMode effectiveLayerMode(unsigned int display_key) const { + if ( _layer_mode == LAYER ) { + +=== modified file 'src/sp-item.cpp' +--- src/sp-item.cpp 2013-01-23 12:22:14 +0000 ++++ src/sp-item.cpp 2013-03-17 14:54:59 +0000 +@@ -72,6 +72,9 @@ + #include "live_effects/lpeobject.h" + #include "live_effects/effect.h" + #include "live_effects/lpeobject-reference.h" ++#include "ui/tool/node-tool.h" ++#include "ui/tool/multi-path-manipulator.h" ++#include "tools-switch.h" + + #define noSP_ITEM_DEBUG_IDLE + +@@ -135,6 +138,8 @@ + _is_evaluated = true; + _evaluated_status = StatusUnknown; + ++ _highlightColor = NULL; ++ + transform = Geom::identity(); + doc_bbox = Geom::OptRect(); + freeze_stroke_width = false; +@@ -210,6 +215,62 @@ + return true; + } + ++bool SPItem::isHighlightSet() const { ++ return _highlightColor != NULL; ++} ++ ++guint32 SPItem::highlight_color() const { ++ if (_highlightColor) ++ { ++ return atoi(_highlightColor) | 0x000000ff; ++ } ++ else if (parent && parent != this && SP_IS_ITEM(parent)) ++ { ++ return SP_ITEM(parent)->highlight_color(); ++ } ++ else ++ { ++ static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); ++ return prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) | 0x000000ff; ++ } ++} ++ ++void SPItem::setHighlightColor(guint32 const color) ++{ ++ g_free(_highlightColor); ++ if (color & 0x000000ff) ++ { ++ _highlightColor = g_strdup_printf("%u", color); ++ } ++ else ++ { ++ _highlightColor = NULL; ++ } ++ ++ InkNodeTool *tool = 0; ++ if (SP_ACTIVE_DESKTOP ) { ++ SPEventContext *ec = SP_ACTIVE_DESKTOP->event_context; ++ if (INK_IS_NODE_TOOL(ec)) { ++ tool = static_cast(ec); ++ tools_switch(tool->desktop, TOOLS_NODES); ++ } ++ } ++} ++ ++void SPItem::unsetHighlightColor() ++{ ++ g_free(_highlightColor); ++ _highlightColor = NULL; ++ InkNodeTool *tool = 0; ++ if (SP_ACTIVE_DESKTOP ) { ++ SPEventContext *ec = SP_ACTIVE_DESKTOP->event_context; ++ if (INK_IS_NODE_TOOL(ec)) { ++ tool = static_cast(ec); ++ tools_switch(tool->desktop, TOOLS_NODES); ++ } ++ } ++} ++ + void SPItem::setEvaluated(bool evaluated) { + _is_evaluated = evaluated; + _evaluated_status = StatusSet; +@@ -387,14 +448,30 @@ + while (target_ref->parent() != target_ref->root()) { + target_ref = target_ref->parent(); + } ++ if (target_ref) { ++ SPObject *obj = document->getObjectByRepr(target_ref); ++ if (SP_IS_ITEM(obj)) { ++ target = SP_ITEM(obj); ++ } ++ } + first = TRUE; + } ++ ++ g_assert(target_ref != NULL); + + if (intoafter) { ++ Geom::Affine t = getRelativeTransform(target); ++ doWriteTransform(our_ref, t); ++ our_ref = getRepr(); ++ + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { ++ Geom::Affine t = getRelativeTransform(target->parent); ++ doWriteTransform(our_ref, t); ++ our_ref = getRepr(); ++ + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); +@@ -424,6 +501,7 @@ + object->readAttr( "inkscape:transform-center-y" ); + object->readAttr( "inkscape:connector-avoid" ); + object->readAttr( "inkscape:connection-points" ); ++ object->readAttr( "inkscape:highlight-color" ); + + if ((SP_OBJECT_CLASS(sp_item_parent_class))->build) { + (* (SP_OBJECT_CLASS(sp_item_parent_class))->build)(object, document, repr); +@@ -510,6 +588,14 @@ + v->arenaitem->setSensitive(item->sensitive); + } + break; ++ case SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR: ++ g_free(item->_highlightColor); ++ if (value) { ++ item->_highlightColor = g_strdup(value); ++ } else { ++ item->_highlightColor = NULL; ++ } ++ break; + case SP_ATTR_CONNECTOR_AVOID: + item->avoidRef->setAvoid(value); + break; +@@ -720,6 +806,11 @@ + g_free ((void *) value); + } + } ++ if (item->_highlightColor){ ++ repr->setAttribute("inkscape:highlight-color", item->_highlightColor); ++ } else { ++ repr->setAttribute("inkscape:highlight-color", NULL); ++ } + + if ((SP_OBJECT_CLASS(sp_item_parent_class))->write) { + (SP_OBJECT_CLASS(sp_item_parent_class))->write(object, xml_doc, repr, flags); + +=== modified file 'src/sp-item.h' +--- src/sp-item.h 2013-03-14 23:24:17 +0000 ++++ src/sp-item.h 2013-03-17 14:51:37 +0000 +@@ -144,11 +144,21 @@ + + void init(); + bool isLocked() const; ++ bool isSensitive() const { ++ return sensitive; ++ }; + void setLocked(bool lock); + + bool isHidden() const; + void setHidden(bool hidden); + ++ bool isHighlightSet() const; ++ guint32 highlight_color() const; ++ ++ void setHighlightColor(guint32 color); ++ ++ void unsetHighlightColor(); ++ + bool isEvaluated() const; + void setEvaluated(bool visible); + void resetEvaluated(); +@@ -218,6 +228,7 @@ + Geom::Affine dt2i_affine() const; + void convert_to_guides(); + ++ gchar *_highlightColor; + private: + enum EvaluatedStatus + { + +=== modified file 'src/sp-object.h' +--- src/sp-object.h 2013-03-14 01:33:10 +0000 ++++ src/sp-object.h 2013-03-17 14:53:10 +0000 +@@ -48,6 +48,7 @@ + #define SP_OBJECT_WRITE_BUILD (1 << 0) + #define SP_OBJECT_WRITE_EXT (1 << 1) + #define SP_OBJECT_WRITE_ALL (1 << 2) ++#define SP_OBJECT_WRITE_NO_CHILDREN (1 << 3) + + #include + #include + +=== modified file 'src/ui/dialog/Makefile_insert' +--- src/ui/dialog/Makefile_insert 2012-10-11 17:54:14 +0000 ++++ src/ui/dialog/Makefile_insert 2013-03-17 13:55:34 +0000 +@@ -70,6 +70,8 @@ + ui/dialog/memory.h \ + ui/dialog/messages.cpp \ + ui/dialog/messages.h \ ++ ui/dialog/objects.cpp \ ++ ui/dialog/objects.h \ + ui/dialog/ocaldialogs.cpp \ + ui/dialog/ocaldialogs.h \ + ui/dialog/object-attributes.cpp \ + +=== modified file 'src/ui/dialog/dialog-manager.cpp' +--- src/ui/dialog/dialog-manager.cpp 2013-03-16 16:26:03 +0000 ++++ src/ui/dialog/dialog-manager.cpp 2013-03-17 14:03:02 +0000 +@@ -40,6 +40,7 @@ + #include "ui/dialog/undo-history.h" + #include "ui/dialog/panel-dialog.h" + #include "ui/dialog/layers.h" ++#include "ui/dialog/objects.h" + #include "ui/dialog/icon-preview.h" + #include "ui/dialog/floating-behavior.h" + #include "ui/dialog/dock-behavior.h" +@@ -108,6 +109,7 @@ + registerFactory("IconPreviewPanel", &create); + registerFactory("InkscapePreferences", &create); + registerFactory("LayersPanel", &create); ++ registerFactory("ObjectsPanel", &create); + registerFactory("LivePathEffect", &create); + registerFactory("Memory", &create); + registerFactory("Messages", &create); +@@ -142,6 +144,7 @@ + registerFactory("IconPreviewPanel", &create); + registerFactory("InkscapePreferences", &create); + registerFactory("LayersPanel", &create); ++ registerFactory("ObjectsPanel", &create); + registerFactory("LivePathEffect", &create); + registerFactory("Memory", &create); + registerFactory("Messages", &create); + +=== added file 'src/ui/dialog/objects.cpp' +--- src/ui/dialog/objects.cpp 1970-01-01 00:00:00 +0000 ++++ src/ui/dialog/objects.cpp 2013-03-17 15:01:22 +0000 +@@ -0,0 +1,2014 @@ ++/* ++ * A simple panel for objects ++ * ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#include "objects.h" ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "desktop.h" ++#include "desktop-style.h" ++#include "document.h" ++#include "document-undo.h" ++#include "helper/action.h" ++#include "inkscape.h" ++#include "preferences.h" ++#include "sp-item.h" ++#include "sp-object.h" ++#include "sp-shape.h" ++#include "svg/css-ostringstream.h" ++#include "ui/icon-names.h" ++#include "ui/widget/imagetoggler.h" ++#include "ui/widget/layertypeicon.h" ++#include "ui/widget/clipmaskicon.h" ++#include "ui/widget/highlight-picker.h" ++#include "verbs.h" ++#include "widgets/icon.h" ++#include "xml/node.h" ++#include "xml/node-observer.h" ++#include "xml/repr.h" ++#include "sp-root.h" ++#include "event-context.h" ++#include "selection.h" ++#include "dialogs/dialog-events.h" ++#include "widgets/sp-color-notebook.h" ++#include "style.h" ++#include "filter-chemistry.h" ++#include "filters/blend.h" ++#include "filters/gaussian-blur.h" ++#include "sp-clippath.h" ++#include "sp-mask.h" ++#include "layer-manager.h" ++ ++//#define DUMP_LAYERS 1 ++ ++namespace Inkscape { ++namespace UI { ++namespace Dialog { ++ ++using Inkscape::XML::Node; ++ ++/** ++ * Gets an instance of the Objects panel ++ */ ++ObjectsPanel& ObjectsPanel::getInstance() ++{ ++ return *new ObjectsPanel(); ++} ++ ++/** ++ * Column enumeration ++ */ ++enum { ++ COL_VISIBLE = 1, ++ COL_LOCKED, ++ COL_TYPE, ++ COL_CLIPMASK, ++ COL_HIGHLIGHT ++}; ++ ++/** ++ * Button enumeration ++ */ ++enum { ++ BUTTON_NEW = 0, ++ BUTTON_RENAME, ++ BUTTON_TOP, ++ BUTTON_BOTTOM, ++ BUTTON_UP, ++ BUTTON_DOWN, ++ BUTTON_DUPLICATE, ++ BUTTON_DELETE, ++ BUTTON_SOLO, ++ BUTTON_SHOW_ALL, ++ BUTTON_HIDE_ALL, ++ BUTTON_LOCK_OTHERS, ++ BUTTON_LOCK_ALL, ++ BUTTON_UNLOCK_ALL, ++ BUTTON_SETCLIP, ++ BUTTON_UNSETCLIP, ++ BUTTON_SETMASK, ++ BUTTON_UNSETMASK, ++ BUTTON_GROUP, ++ BUTTON_UNGROUP, ++ BUTTON_COLLAPSE_ALL, ++ DRAGNDROP ++}; ++ ++/** ++ * Xml node observer for observing objects in the document ++ */ ++class ObjectsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { ++public: ++ /** ++ * Creates a new object watcher ++ * @param pnl The panel to which the object watcher belongs ++ * @param obj The object to watch ++ */ ++ ObjectWatcher(ObjectsPanel* pnl, SPObject* obj) : ++ _pnl(pnl), ++ _obj(obj), ++ _repr(obj->getRepr()), ++ _highlightAttr(g_quark_from_string("inkscape:highlight-color")), ++ _lockedAttr(g_quark_from_string("sodipodi:insensitive")), ++ _labelAttr(g_quark_from_string("inkscape:label")), ++ _groupAttr(g_quark_from_string("inkscape:groupmode")), ++ _styleAttr(g_quark_from_string("style")), ++ _clipAttr(g_quark_from_string("clip-path")), ++ _maskAttr(g_quark_from_string("mask")) ++ {} ++ ++ virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) ++ { ++ if ( _pnl && _obj ) { ++ _pnl->_objectsChanged( _obj ); ++ } ++ } ++ virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) ++ { ++ if ( _pnl && _obj ) { ++ _pnl->_objectsChanged( _obj ); ++ } ++ } ++ virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) ++ { ++ if ( _pnl && _obj ) { ++ _pnl->_objectsChanged( _obj ); ++ } ++ } ++ virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} ++ virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { ++ if ( _pnl && _obj ) { ++ if ( name == _lockedAttr || name == _labelAttr || name == _highlightAttr || name == _groupAttr || name == _styleAttr || name == _clipAttr || name == _maskAttr ) { ++ _pnl->_updateObject(_obj, name == _highlightAttr); ++ if ( name == _styleAttr ) { ++ _pnl->_updateComposite(); ++ } ++ } ++ } ++ } ++ ++ /** ++ * Objects panel to which this watcher belongs ++ */ ++ ObjectsPanel* _pnl; ++ ++ /** ++ * The object that is being observed ++ */ ++ SPObject* _obj; ++ ++ /** ++ * The xml representation of the object that is being observed ++ */ ++ Inkscape::XML::Node* _repr; ++ ++ /* These are quarks which define the attributes that we are observing */ ++ GQuark _highlightAttr; ++ GQuark _lockedAttr; ++ GQuark _labelAttr; ++ GQuark _groupAttr; ++ GQuark _styleAttr; ++ GQuark _clipAttr; ++ GQuark _maskAttr; ++}; ++ ++class ObjectsPanel::InternalUIBounce ++{ ++public: ++ int _actionCode; ++}; ++ ++class ObjectsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord ++{ ++public: ++ ++ ModelColumns() ++ { ++ add(_colObject); ++ add(_colVisible); ++ add(_colLocked); ++ add(_colLabel); ++ add(_colType); ++ add(_colHighlight); ++ add(_colClipMask); ++ } ++ virtual ~ModelColumns() {} ++ ++ Gtk::TreeModelColumn _colObject; ++ Gtk::TreeModelColumn _colLabel; ++ Gtk::TreeModelColumn _colVisible; ++ Gtk::TreeModelColumn _colLocked; ++ Gtk::TreeModelColumn _colType; ++ Gtk::TreeModelColumn _colHighlight; ++ Gtk::TreeModelColumn _colClipMask; ++}; ++ ++/** ++ * Stylizes a button using the given icon name and tooltip ++ */ ++void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ) ++{ ++ GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); ++ gtk_widget_show( child ); ++ btn.add( *Gtk::manage(Glib::wrap(child)) ); ++ btn.set_relief(Gtk::RELIEF_NONE); ++ ++ btn.set_tooltip_text (tooltip); ++ ++} ++ ++/** ++ * Adds an item to the pop-up (right-click) menu ++ * @param desktop The active destktop ++ * @param code Action code ++ * @param iconName Icon name ++ * @param fallback Fallback text ++ * @param id Button id for callback function ++ * @return The generated menu item ++ */ ++Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) ++{ ++ GtkWidget* iconWidget = 0; ++ const char* label = 0; ++ ++ if ( iconName ) { ++ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); ++ } ++ ++ if ( desktop ) { ++ Verb *verb = Verb::get( code ); ++ if ( verb ) { ++ SPAction *action = verb->get_action(desktop); ++ if ( !iconWidget && action && action->image ) { ++ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); ++ } ++ ++ if ( action ) { ++ label = action->name; ++ } ++ } ++ } ++ ++ if ( !label && fallback ) { ++ label = fallback; ++ } ++ ++ Gtk::Widget* wrapped = 0; ++ if ( iconWidget ) { ++ wrapped = Gtk::manage(Glib::wrap(iconWidget)); ++ wrapped->show(); ++ } ++ ++ ++ Gtk::MenuItem* item = 0; ++ ++ if (wrapped) { ++ item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); ++ } else { ++ item = Gtk::manage(new Gtk::MenuItem(label, true)); ++ } ++ ++ item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_takeAction), id)); ++ _popupMenu.append(*item); ++ ++ return *item; ++} ++ ++/** ++ * Callback function for when an object changes. Essentially refreshes the entire tree ++ * @param obj Object which was changed (currently not used as the entire tree is recreated) ++ */ ++void ObjectsPanel::_objectsChanged(SPObject */*obj*/) ++{ ++ //First, unattach the watchers ++ while (!_objectWatchers.empty()) ++ { ++ ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); ++ w->_repr->removeObserver(*w); ++ _objectWatchers.pop_back(); ++ delete w; ++ } ++ ++ if (_desktop) { ++ //Get the current document's root and use that to enumerate the tree ++ SPDocument* document = _desktop->doc(); ++ SPRoot* root = document->getRoot(); ++ if ( root ) { ++ _selectedConnection.block(); ++ //Clear the tree store ++ _store->clear(); ++ //Add all items recursively ++ _addObject( root, 0 ); ++ _selectedConnection.unblock(); ++ //Set the tree selection ++ _objectsSelected(_desktop->selection); ++ //Handle button sensitivity ++ _checkTreeSelection(); ++ } ++ } ++} ++ ++/** ++ * Recursively adds the children of the given item to the tree ++ * @param obj Root object to add to the tree ++ * @param parentRow Parent tree row (or NULL if adding to tree root) ++ */ ++void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) ++{ ++ if ( _desktop && obj ) { ++ for ( SPObject *child = obj->children; child != NULL; child = child->next) { ++ ++ if (SP_IS_ITEM(child)) ++ { ++ SPItem * item = SP_ITEM(child); ++ SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0; ++ ++ //Add the item to the tree and set the column information ++ Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); ++ Gtk::TreeModel::Row row = *iter; ++ row[_model->_colObject] = item; ++ row[_model->_colLabel] = item->label() ? item->label() : item->getId(); ++ row[_model->_colVisible] = !item->isHidden(); ++ row[_model->_colLocked] = !item->isSensitive(); ++ row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; ++ row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; ++ row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); ++ ++ //If our parent object is a group and it's expanded, expand the tree ++ if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) ++ { ++ _tree.expand_to_path( _store->get_path(iter) ); ++ } ++ ++ //Add an object watcher to the item ++ ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child); ++ child->getRepr()->addObserver(*w); ++ _objectWatchers.push_back(w); ++ ++ //If the item is a group, recursively add its children ++ if (group) ++ { ++ _addObject( child, &row ); ++ } ++ } ++ } ++ } ++} ++ ++/** ++ * Updates an item in the tree and optionally recursively updates the item's children ++ * @param obj The item to update in the tree ++ * @param recurse Whether to recurse through the item's children ++ */ ++void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { ++ //Find the object in the tree store and update it ++ _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); ++ if (recurse) ++ { ++ for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) ++ { ++ _updateObject(iter, recurse); ++ } ++ } ++} ++ ++/** ++ * Checks items in the tree store and updates the given item ++ * @param iter Current item being looked at in the tree ++ * @param obj Object to update ++ * @return ++ */ ++bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ if ( obj == row[_model->_colObject] ) ++ { ++ //We found our item in the tree!! Update it! ++ SPItem * item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; ++ SPGroup * group = SP_IS_GROUP(obj) ? SP_GROUP(obj) : 0; ++ ++ row[_model->_colLabel] = obj->label() ? obj->label() : obj->getId(); ++ row[_model->_colVisible] = item ? !item->isHidden() : false; ++ row[_model->_colLocked] = item ? !item->isSensitive() : false; ++ row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; ++ row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; ++ row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; ++ ++ return true; ++ } ++ ++ return false; ++} ++ ++/** ++ * Updates the composite controls for the selected item ++ */ ++void ObjectsPanel::_updateComposite() { ++ if (!_blockCompositeUpdate) ++ { ++ //Set the default values ++ bool setValues = true; ++ ++ //Get/set the values ++ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_compositingChanged), &setValues)); ++ } ++} ++ ++/** ++ * Sets the compositing values for the first selected item in the tree ++ * @param iter Current tree item ++ * @param setValues Whether to set the compositing values ++ * @param blur Blur value to use ++ */ ++void ObjectsPanel::_compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ) ++{ ++ if (iter) { ++ Gtk::TreeModel::Row row = *iter; ++ SPItem *item = row[_model->_colObject]; ++ if (*setValues) ++ { ++ _setCompositingValues(item); ++ *setValues = false; ++ } ++ } ++} ++ ++/** ++ * Occurs when the current desktop selection changes ++ * @param sel The current selection ++ */ ++void ObjectsPanel::_objectsSelected( Selection *sel ) { ++ ++ bool setOpacity = true; ++ _selectedConnection.block(); ++ _tree.get_selection()->unselect_all(); ++ SPItem *item = NULL; ++ for (const GSList * iter = sel->itemList(); iter != NULL; iter = iter->next) ++ { ++ item = reinterpret_cast(iter->data); ++ if (setOpacity) ++ { ++ _setCompositingValues(item); ++ setOpacity = false; ++ } ++ _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, iter->next == NULL)); ++ } ++ if (!item) { ++ if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) { ++ item = SP_ITEM(_desktop->currentLayer()); ++ _setCompositingValues(item); ++ _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true)); ++ } ++ } ++ _selectedConnection.unblock(); ++ _checkTreeSelection(); ++} ++ ++/** ++ * Helper function for setting the compositing values ++ * @param item Item to use for setting the compositing values ++ */ ++void ObjectsPanel::_setCompositingValues(SPItem *item) ++{ ++ //Block the connections to avoid interference ++ _opacityConnection.block(); ++ _blendConnection.block(); ++ _blurConnection.block(); ++ ++ //Set the opacity ++ _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper()); ++ SPFeBlend *spblend = NULL; ++ SPGaussianBlur *spblur = NULL; ++ if (item->style->getFilter()) ++ { ++ for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { ++ if(SP_IS_FEBLEND(primitive_obj) && !spblend) { ++ //Get the blend mode ++ spblend = SP_FEBLEND(primitive_obj); ++ } ++ ++ if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) { ++ //Get the blur value ++ spblur = SP_GAUSSIANBLUR(primitive_obj); ++ } ++ } ++ } ++ ++ //Set the blend mode ++ _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); ++ ++ //Set the blur value ++ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); ++ if (bbox && spblur) { ++ double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? ++ _fe_blur.set_blur_value(spblur->stdDeviation.getNumber() * 400 / perimeter); ++ } else { ++ _fe_blur.set_blur_value(0); ++ } ++ ++ //Unblock connections ++ _blurConnection.unblock(); ++ _blendConnection.unblock(); ++ _opacityConnection.unblock(); ++} ++ ++/** ++ * Checks the tree and selects the specified item, optionally scrolling to the item ++ * @param path Current tree path ++ * @param iter Current tree item ++ * @param item Item to select in the tree ++ * @param scrollto Whether to scroll to the item ++ * @return Whether to continue searching the tree ++ */ ++bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto) ++{ ++ bool stopGoing = false; ++ ++ Gtk::TreeModel::Row row = *iter; ++ if ( item == row[_model->_colObject] ) ++ { ++ //We found the item! Expand to the path and select it in the tree. ++ _tree.expand_to_path( path ); ++ ++ Glib::RefPtr select = _tree.get_selection(); ++ ++ select->select(iter); ++ if (scrollto) { ++ //Scroll to the item in the tree ++ _tree.scroll_to_row(path); ++ } ++ ++ stopGoing = true; ++ } ++ ++ return stopGoing; ++} ++ ++/** ++ * Pushes the current tree selection to the canvas ++ */ ++void ObjectsPanel::_pushTreeSelectionToCurrent() ++{ ++ if ( _desktop && _desktop->currentRoot() ) { ++ //block connections for selection and compositing values to prevent interference ++ _selectionChangedConnection.block(); ++ ++ //Clear the selection and then iterate over the tree selection, pushing each item to the desktop ++ _desktop->selection->clear(); ++ bool setOpacity = true; ++ _tree.get_selection()->selected_foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity)); ++ //unblock connections ++ _selectionChangedConnection.unblock(); ++ ++ _checkTreeSelection(); ++ } ++} ++ ++/** ++ * Helper function for pushing the current tree selection to the current desktop ++ * @param iter Current tree item ++ * @param setCompositingValues Whether to set the compositing values ++ * @param blur ++ */ ++void ObjectsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setCompositingValues ) ++{ ++ if (iter) { ++ Gtk::TreeModel::Row row = *iter; ++ SPItem *item = row[_model->_colObject]; ++ if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) ++ { ++ //If the item is not a layer, then select it and set the current layer to its parent (if it's the first item) ++ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); ++ _desktop->selection->add(item); ++ } ++ else ++ { ++ //If the item is a layer, set the current layer ++ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); ++ } ++ if (*setCompositingValues) ++ { ++ //Only set the compositing values for the first item ++ _setCompositingValues(item); ++ *setCompositingValues = false; ++ } ++ } ++} ++ ++/** ++ * Handles button sensitivity ++ */ ++void ObjectsPanel::_checkTreeSelection() ++{ ++ bool sensitive = _tree.get_selection()->count_selected_rows() > 0; ++ //TODO: top/bottom sensitivity ++ bool sensitiveNonTop = true; ++ bool sensitiveNonBottom = true; ++ ++ for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { ++ (*it)->set_sensitive( sensitive ); ++ } ++ for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { ++ (*it)->set_sensitive( sensitiveNonTop ); ++ } ++ for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { ++ (*it)->set_sensitive( sensitiveNonBottom ); ++ } ++} ++ ++/** ++ * Sets visibility of items in the tree ++ * @param iter Current item in the tree ++ * @param visible Whether the item should be visible or not ++ */ ++void ObjectsPanel::_setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ item->setHidden( !visible ); ++ row[_model->_colVisible] = visible; ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++} ++ ++/** ++ * Sets sensitivity of items in the tree ++ * @param iter Current item in the tree ++ * @param locked Whether the item should be locked ++ */ ++void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ item->setLocked( locked ); ++ row[_model->_colLocked] = locked; ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++} ++ ++/** ++ * Handles keyboard events ++ * @param event Keyboard event passed in from GDK ++ * @return Whether the event should be eaten (om nom nom) ++ */ ++bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) ++{ ++ ++ switch (get_group0_keyval(event)) { ++ case GDK_KEY_Return: ++ case GDK_KEY_KP_Enter: ++ case GDK_KEY_F2: ++ { ++ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); ++ if (iter && !_text_renderer->property_editable()) { ++ //Rename item ++ Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); ++ _text_renderer->property_editable() = true; ++ _tree.set_cursor(*path, *_name_column, true); ++ grab_focus(); ++ return true; ++ } ++ } ++ break; ++ case GDK_Home: ++ { ++ //Move item(s) to top of containing group/layer ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_TO_TOP ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_SELECTION_TO_FRONT ); ++ } ++ return true; ++ } ++ case GDK_End: ++ { ++ //Move item(s) to bottom of containing group/layer ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_TO_BOTTOM ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_SELECTION_TO_BACK ); ++ } ++ return true; ++ } ++ case GDK_KEY_Page_Up: ++ { ++ //Move item(s) up in containing group/layer ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_RAISE ); ++ } ++ else ++ { ++ if (event->state & GDK_SHIFT_MASK) { ++ _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); ++ } else { ++ _fireAction( SP_VERB_SELECTION_RAISE ); ++ } ++ } ++ return true; ++ } ++ case GDK_KEY_Page_Down: ++ { ++ //Move item(s) down in containing group/layer ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_LOWER ); ++ } ++ else ++ { ++ if (event->state & GDK_SHIFT_MASK) { ++ _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); ++ } else { ++ _fireAction( SP_VERB_SELECTION_LOWER ); ++ } ++ } ++ return true; ++ } ++ //TODO: Handle Ctrl-A, etc. ++ } ++ return false; ++} ++ ++/** ++ * Handles mouse events ++ * @param event Mouse event from GDK ++ * @return whether to eat the event (om nom nom) ++ */ ++bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) ++{ ++ static unsigned doubleclick = 0; ++ static bool overVisible = false; ++ ++ //Right mouse button was clicked, launch the pop-up menu ++ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { ++ Gtk::TreeModel::Path path; ++ int x = static_cast(event->x); ++ int y = static_cast(event->y); ++ if ( _tree.get_path_at_pos( x, y, path ) ) { ++ _checkTreeSelection(); ++ _popupMenu.popup(event->button, event->time); ++ if (_tree.get_selection()->is_selected(path)) { ++ return true; ++ } ++ } ++ } ++ ++ //Left mouse button was pressed! In order to handle multiple item drag & drop, ++ //we need to defer selection by setting the select function so that the tree doesn't ++ //automatically select anything. In order to handle multiple item icon clicking, ++ //we need to eat the event. There might be a better way to do both of these... ++ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { ++ overVisible = false; ++ Gtk::TreeModel::Path path; ++ Gtk::TreeViewColumn* col = 0; ++ int x = static_cast(event->x); ++ int y = static_cast(event->y); ++ int x2 = 0; ++ int y2 = 0; ++ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { ++ if (col == _tree.get_column(COL_VISIBLE-1)) { ++ //Click on visible column, eat this event to keep row selection ++ overVisible = true; ++ return true; ++ } else if (col == _tree.get_column(COL_LOCKED-1) || ++ col == _tree.get_column(COL_TYPE-1) || ++ col == _tree.get_column(COL_HIGHLIGHT-1)) { ++ //Click on an icon column, eat this event to keep row selection ++ return true; ++ } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { ++ //Click on a selected item with no modifiers, defer selection to the mouse-up by ++ //setting the select function to _noSelection ++ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_noSelection)); ++ _defer_target = path; ++ } ++ } ++ } ++ ++ //Restore the selection function to allow tree selection on mouse button release ++ if ( event->type == GDK_BUTTON_RELEASE) { ++ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction)); ++ } ++ ++ //CellRenderers do not have good support for dealing with multiple items, so ++ //we handle all events on them here ++ if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { ++ ++ Gtk::TreeModel::Path path; ++ Gtk::TreeViewColumn* col = 0; ++ int x = static_cast(event->x); ++ int y = static_cast(event->y); ++ int x2 = 0; ++ int y2 = 0; ++ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { ++ if (_defer_target) { ++ //We had deferred a selection target, select it here (assuming no drag & drop) ++ if (_defer_target == path && !(event->x == 0 && event->y == 0)) ++ { ++ _tree.set_cursor(path, *col, false); ++ } ++ _defer_target = Gtk::TreeModel::Path(); ++ } ++ else { ++ if (event->state & GDK_SHIFT_MASK) { ++ // Shift left click on the visible/lock columns toggles "solo" mode ++ if (col == _tree.get_column(COL_VISIBLE - 1)) { ++ _takeAction(BUTTON_SOLO); ++ } else if (col == _tree.get_column(COL_LOCKED - 1)) { ++ _takeAction(BUTTON_LOCK_OTHERS); ++ } ++ } else if (event->state & GDK_MOD1_MASK) { ++ // Alt+left click on the visible/lock columns toggles "solo" mode and preserves selection ++ Gtk::TreeModel::iterator iter = _store->get_iter(path); ++ if (_store->iter_is_valid(iter)) { ++ Gtk::TreeModel::Row row = *iter; ++ SPItem *item = row[_model->_colObject]; ++ if (col == _tree.get_column(COL_VISIBLE - 1)) { ++ _desktop->toggleLayerSolo( item ); ++ DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo")); ++ } else if (col == _tree.get_column(COL_LOCKED - 1)) { ++ _desktop->toggleLockOtherLayers( item ); ++ DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); ++ } ++ } ++ } else { ++ Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); ++ Gtk::TreeModel::Row row = *iter; ++ ++ SPItem* item = row[_model->_colObject]; ++ ++ if (col == _tree.get_column(COL_VISIBLE - 1)) { ++ if (overVisible) { ++ //Toggle visibility ++ bool newValue = !row[_model->_colVisible]; ++ if (_tree.get_selection()->is_selected(path)) ++ { ++ //If the current row is selected, toggle the visibility ++ //for all selected items ++ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setVisibleIter), newValue)); ++ } ++ else ++ { ++ //If the current row is not selected, toggle just its visibility ++ row[_model->_colVisible] = newValue; ++ item->setHidden(!newValue); ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, ++ newValue? _("Unhide objects") : _("Hide objects")); ++ overVisible = false; ++ } ++ } else if (col == _tree.get_column(COL_LOCKED - 1)) { ++ //Toggle locking ++ bool newValue = !row[_model->_colLocked]; ++ if (_tree.get_selection()->is_selected(path)) ++ { ++ //If the current row is selected, toggle the sensitivity for ++ //all selected items ++ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setLockedIter), newValue)); ++ } ++ else ++ { ++ //If the current row is not selected, toggle just its sensitivity ++ row[_model->_colLocked] = newValue; ++ item->setLocked( newValue ); ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, ++ newValue? _("Lock objects") : _("Unlock objects")); ++ ++ } else if (col == _tree.get_column(COL_TYPE - 1)) { ++ if (SP_IS_GROUP(item)) ++ { ++ //Toggle the current item between a group and a layer ++ SPGroup * g = SP_GROUP(item); ++ bool newValue = g->layerMode() == SPGroup::LAYER; ++ row[_model->_colType] = newValue ? 1: 2; ++ g->setLayerMode(newValue ? SPGroup::GROUP : SPGroup::LAYER); ++ g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, ++ newValue? _("Layer to group") : _("Group to layer")); ++ } ++ } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { ++ //Clear the highlight targets ++ _highlight_target.clear(); ++ if (_tree.get_selection()->is_selected(path)) ++ { ++ //If the current item is selected, store all selected items ++ //in the highlight source ++ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeHighlightTarget)); ++ } else { ++ //If the current item is not selected, store only it in the highlight source ++ _storeHighlightTarget(iter); ++ } ++ if (_colorSelector) ++ { ++ //Set up the color selector ++ SPColor color; ++ color.set( row[_model->_colHighlight] ); ++ _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); ++ } ++ //Show the color selector dialog ++ _colorSelectorDialog.show(); ++ } ++ } ++ } ++ } ++ } ++ ++ //Second mouse button press, set double click status for when the mouse is released ++ if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { ++ doubleclick = 1; ++ } ++ ++ //Double click on mouse button release, if we're over the label column, edit ++ //the item name ++ if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { ++ doubleclick = 0; ++ Gtk::TreeModel::Path path; ++ Gtk::TreeViewColumn* col = 0; ++ int x = static_cast(event->x); ++ int y = static_cast(event->y); ++ int x2 = 0; ++ int y2 = 0; ++ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { ++ // Double click on the Layer name, enable editing ++ _text_renderer->property_editable() = true; ++ _tree.set_cursor (path, *_name_column, true); ++ grab_focus(); ++ } ++ } ++ ++ return false; ++} ++ ++/** ++ * Stores items in the highlight target vector to manipulate with the color selector ++ * @param iter Current tree item to store ++ */ ++void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ _highlight_target.push_back(item); ++ } ++} ++ ++/* ++ * Drap and drop within the tree ++ */ ++bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) ++{ ++ int cell_x = 0, cell_y = 0; ++ Gtk::TreeModel::Path target_path; ++ Gtk::TreeView::Column *target_column; ++ ++ //Set up our defaults and clear the source vector ++ _dnd_into = false; ++ _dnd_target = NULL; ++ _dnd_source.clear(); ++ ++ //Add all selected items to the source vector ++ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeDragSource)); ++ ++ if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { ++ // Are we before, inside or after the drop layer ++ Gdk::Rectangle rect; ++ _tree.get_background_area (target_path, *target_column, rect); ++ int cell_height = rect.get_height(); ++ _dnd_into = (cell_y > (int)(cell_height * 1/4) && cell_y <= (int)(cell_height * 3/4)); ++ if (cell_y > (int)(cell_height * 3/4)) { ++ Gtk::TreeModel::Path next_path = target_path; ++ next_path.next(); ++ if (_store->iter_is_valid(_store->get_iter(next_path))) { ++ target_path = next_path; ++ } else { ++ // Dragging to the "end" ++ Gtk::TreeModel::Path up_path = target_path; ++ up_path.up(); ++ if (_store->iter_is_valid(_store->get_iter(up_path))) { ++ // Drop into parent ++ target_path = up_path; ++ _dnd_into = true; ++ } else { ++ // Drop into the top level ++ _dnd_target = NULL; ++ } ++ } ++ } ++ Gtk::TreeModel::iterator iter = _store->get_iter(target_path); ++ if (_store->iter_is_valid(iter)) { ++ Gtk::TreeModel::Row row = *iter; ++ //Set the drop target. If we're not dropping into a group, we cannot ++ //drop into it, so set _dnd_into false. ++ _dnd_target = row[_model->_colObject]; ++ if (!(SP_IS_GROUP(_dnd_target))) _dnd_into = false; ++ } ++ } ++ ++ _takeAction(DRAGNDROP); ++ ++ return false; ++} ++ ++/** ++ * Stores all selected items as the drag source ++ * @param iter Current tree item ++ */ ++void ObjectsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ _dnd_source.push_back(item); ++ } ++} ++ ++/* ++ * Move a layer in response to a drag & drop action ++ */ ++void ObjectsPanel::_doTreeMove( ) ++{ ++ g_assert(_desktop != NULL); ++ g_assert(_document != NULL); ++ ++ std::vector idvector; ++ ++ //Clear the desktop selection ++ _desktop->selection->clear(); ++ while (!_dnd_source.empty()) ++ { ++ SPItem *obj = _dnd_source.back(); ++ _dnd_source.pop_back(); ++ ++ if (obj != _dnd_target) { ++ //Store the object id (for selection later) and move the object ++ idvector.push_back(g_strdup(obj->getId())); ++ obj->moveTo(_dnd_target, _dnd_into); ++ } ++ } ++ ++ //Select items ++ while (!idvector.empty()) { ++ //Grab the id from the vector, get the item in the document and select it ++ gchar * id = idvector.back(); ++ idvector.pop_back(); ++ SPObject *obj = _document->getObjectById(id); ++ g_free(id); ++ if (obj && SP_IS_ITEM(obj)) { ++ SPItem *item = SP_ITEM(obj); ++ if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) ++ { ++ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); ++ _desktop->selection->add(item); ++ } ++ else ++ { ++ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); ++ } ++ } ++ } ++ ++ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, ++ _("Moved objects")); ++} ++ ++/** ++ * Fires the action verb ++ */ ++void ObjectsPanel::_fireAction( unsigned int code ) ++{ ++ if ( _desktop ) { ++ Verb *verb = Verb::get( code ); ++ if ( verb ) { ++ SPAction *action = verb->get_action(_desktop); ++ if ( action ) { ++ sp_action_perform( action, NULL ); ++ } ++ } ++ } ++} ++ ++/** ++ * Executes the given button action during the idle time ++ */ ++void ObjectsPanel::_takeAction( int val ) ++{ ++ if ( !_pending ) { ++ _pending = new InternalUIBounce(); ++ _pending->_actionCode = val; ++ Glib::signal_timeout().connect( sigc::mem_fun(*this, &ObjectsPanel::_executeAction), 0 ); ++ } ++} ++ ++/** ++ * Executes the pending button action ++ */ ++bool ObjectsPanel::_executeAction() ++{ ++ // Make sure selected layer hasn't changed since the action was triggered ++ if ( _document && _pending) ++ { ++ int val = _pending->_actionCode; ++// SPObject* target = _pending->_target; ++ ++ switch ( val ) { ++ case BUTTON_NEW: ++ { ++ _fireAction( SP_VERB_LAYER_NEW ); ++ } ++ break; ++ case BUTTON_RENAME: ++ { ++ _fireAction( SP_VERB_LAYER_RENAME ); ++ } ++ break; ++ case BUTTON_TOP: ++ { ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_TO_TOP ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_SELECTION_TO_FRONT); ++ } ++ } ++ break; ++ case BUTTON_BOTTOM: ++ { ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_TO_BOTTOM ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_SELECTION_TO_BACK); ++ } ++ } ++ break; ++ case BUTTON_UP: ++ { ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_RAISE ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_SELECTION_RAISE ); ++ } ++ } ++ break; ++ case BUTTON_DOWN: ++ { ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_LOWER ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_SELECTION_LOWER ); ++ } ++ } ++ break; ++ case BUTTON_DUPLICATE: ++ { ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_DUPLICATE ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_EDIT_DUPLICATE ); ++ } ++ } ++ break; ++ case BUTTON_DELETE: ++ { ++ if (_desktop->selection->isEmpty()) ++ { ++ _fireAction( SP_VERB_LAYER_DELETE ); ++ } ++ else ++ { ++ _fireAction( SP_VERB_EDIT_DELETE ); ++ } ++ } ++ break; ++ case BUTTON_SOLO: ++ { ++ _fireAction( SP_VERB_LAYER_SOLO ); ++ } ++ break; ++ case BUTTON_SHOW_ALL: ++ { ++ _fireAction( SP_VERB_LAYER_SHOW_ALL ); ++ } ++ break; ++ case BUTTON_HIDE_ALL: ++ { ++ _fireAction( SP_VERB_LAYER_HIDE_ALL ); ++ } ++ break; ++ case BUTTON_LOCK_OTHERS: ++ { ++ _fireAction( SP_VERB_LAYER_LOCK_OTHERS ); ++ } ++ break; ++ case BUTTON_LOCK_ALL: ++ { ++ _fireAction( SP_VERB_LAYER_LOCK_ALL ); ++ } ++ break; ++ case BUTTON_UNLOCK_ALL: ++ { ++ _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); ++ } ++ break; ++ case BUTTON_SETCLIP: ++ { ++ _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); ++ } ++ break; ++ case BUTTON_UNSETCLIP: ++ { ++ _fireAction( SP_VERB_OBJECT_UNSET_CLIPPATH ); ++ } ++ break; ++ case BUTTON_SETMASK: ++ { ++ _fireAction( SP_VERB_OBJECT_SET_MASK ); ++ } ++ break; ++ case BUTTON_UNSETMASK: ++ { ++ _fireAction( SP_VERB_OBJECT_UNSET_MASK ); ++ } ++ break; ++ case BUTTON_GROUP: ++ { ++ _fireAction( SP_VERB_SELECTION_GROUP ); ++ } ++ break; ++ case BUTTON_UNGROUP: ++ { ++ _fireAction( SP_VERB_SELECTION_UNGROUP ); ++ } ++ break; ++ case BUTTON_COLLAPSE_ALL: ++ { ++ for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) { ++ if (SP_IS_GROUP(obj)) { ++ _setCollapsed(SP_GROUP(obj)); ++ } ++ } ++ _objectsChanged(_document->getRoot()); ++ } ++ break; ++ case DRAGNDROP: ++ { ++ _doTreeMove( ); ++ } ++ break; ++ } ++ ++ delete _pending; ++ _pending = 0; ++ } ++ ++ return false; ++} ++ ++/** ++ * Handles an unsuccessful item label edit (escape pressed, etc.) ++ */ ++void ObjectsPanel::_handleEditingCancelled() ++{ ++ _text_renderer->property_editable() = false; ++} ++ ++/** ++ * Handle a successful item label edit ++ * @param path Tree path of the item currently being edited ++ * @param new_text New label text ++ */ ++void ObjectsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) ++{ ++ Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); ++ Gtk::TreeModel::Row row = *iter; ++ ++ _renameObject(row, new_text); ++ _text_renderer->property_editable() = false; ++} ++ ++/** ++ * Renames an item in the tree ++ * @param row Tree row ++ * @param name New label to give to the item ++ */ ++void ObjectsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) ++{ ++ if ( row && _desktop) { ++ SPItem* item = row[_model->_colObject]; ++ if ( item ) { ++ gchar const* oldLabel = item->label(); ++ if ( !name.empty() && (!oldLabel || name != oldLabel) ) { ++ item->setLabel(name.c_str()); ++ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, ++ _("Rename object")); ++ } ++ } ++ } ++} ++ ++/** ++ * A row selection function used by the tree that doesn't allow any new items to be selected. ++ * Currently, this is used to allow multi-item drag & drop. ++ */ ++bool ObjectsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) ++{ ++ return false; ++} ++ ++/** ++ * Default row selection function taken from the layers dialog ++ */ ++bool ObjectsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) ++{ ++ bool val = true; ++ if ( !currentlySelected && _toggleEvent ) ++ { ++ GdkEvent* event = gtk_get_current_event(); ++ if ( event ) { ++ // (keep these checks separate, so we know when to call gdk_event_free() ++ if ( event->type == GDK_BUTTON_PRESS ) { ++ GdkEventButton const* target = reinterpret_cast(_toggleEvent); ++ GdkEventButton const* evtb = reinterpret_cast(event); ++ ++ if ( (evtb->window == target->window) ++ && (evtb->send_event == target->send_event) ++ && (evtb->time == target->time) ++ && (evtb->state == target->state) ++ ) ++ { ++ // Ooooh! It's a magic one ++ val = false; ++ } ++ } ++ gdk_event_free(event); ++ } ++ } ++ return val; ++} ++ ++/** ++ * Sets a group to be collapsed and recursively collapses its children ++ * @param group The group to collapse ++ */ ++void ObjectsPanel::_setCollapsed(SPGroup * group) ++{ ++ group->setExpanded(false); ++ group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ for (SPObject *iter = group->children; iter != NULL; iter = iter->next) ++ { ++ if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); ++ } ++} ++ ++/** ++ * Sets a group to be expanded or collapsed ++ * @param iter Current tree item ++ * @param isexpanded Whether to expand or collapse ++ */ ++void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ ++ SPItem* item = row[_model->_colObject]; ++ if (item && SP_IS_GROUP(item)) ++ { ++ if (isexpanded) ++ { ++ //If we're expanding, simply perform the expansion ++ SP_GROUP(item)->setExpanded(isexpanded); ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++ else ++ { ++ //If we're collapsing, we need to recursively collapse, so call our helper function ++ _setCollapsed(SP_GROUP(item)); ++ } ++ } ++} ++ ++/** ++ * Callback for when the highlight color is changed ++ * @param csel Color selector ++ * @param cp Objects panel ++ */ ++void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) ++{ ++ SPColor color; ++ float alpha = 0; ++ csel->base->getColorAlpha(color, alpha); ++ guint32 rgba = color.toRGBA32( alpha ); ++ ++ ObjectsPanel *ptr = reinterpret_cast(cp); ++ ++ //Set the highlight color for all items in the _highlight_target (all selected items) ++ for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) ++ { ++ SPItem * target = *iter; ++ target->setHighlightColor(rgba); ++ target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); ++} ++ ++/** ++ * Callback for when the opacity value is changed ++ */ ++void ObjectsPanel::_opacityValueChanged() ++{ ++ _blockCompositeUpdate = true; ++ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_opacityChangedIter)); ++ DocumentUndo::maybeDone(_document, "opacity", SP_VERB_DIALOG_OBJECTS, _("Set object opacity")); ++ _blockCompositeUpdate = false; ++} ++ ++/** ++ * Change the opacity of the selected items in the tree ++ * @param iter Current tree item ++ */ ++void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ item->style->opacity.set = TRUE; ++ item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper()); ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++} ++ ++/** ++ * Callback for when the blend mode is changed ++ */ ++void ObjectsPanel::_blendValueChanged() ++{ ++ _blockCompositeUpdate = true; ++ const Glib::ustring blendmode = _fe_cb.get_blend_mode(); ++ ++ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blendChangedIter), blendmode)); ++ DocumentUndo::done(_document, SP_VERB_DIALOG_OBJECTS, _("Set object blend mode")); ++ _blockCompositeUpdate = false; ++} ++ ++/** ++ * Sets the blend mode of the selected tree items ++ * @param iter Current tree item ++ * @param blendmode Blend mode to set ++ */ ++void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ //Since blur and blend are both filters, we need to set both at the same time ++ SPStyle *style = item->style; ++ g_assert(style != NULL); ++ ++ if (blendmode != "normal") { ++ gdouble radius = 0; ++ if (item->style->getFilter()) { ++ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { ++ if (SP_IS_GAUSSIANBLUR(primitive)) { ++ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); ++ if (bbox) { ++ radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber(); ++ } ++ } ++ } ++ } ++ SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); ++ sp_style_set_property_url(item, "filter", filter, false); ++ } else { ++ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { ++ if (SP_IS_FEBLEND(primitive)) { ++ primitive->deleteObject(); ++ break; ++ } ++ } ++ if (!item->style->getFilter()->children) { ++ remove_filter(item, false); ++ } ++ } ++ ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++} ++ ++/** ++ * Callback for when the blur value has changed ++ */ ++void ObjectsPanel::_blurValueChanged() ++{ ++ _blockCompositeUpdate = true; ++ _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blurChangedIter), _fe_blur.get_blur_value())); ++ DocumentUndo::maybeDone(_document, "blur", SP_VERB_DIALOG_OBJECTS, _("Set object blur")); ++ _blockCompositeUpdate = false; ++} ++ ++/** ++ * Sets the blur value for the selected items in the tree ++ * @param iter Current tree item ++ * @param blur Blur value to set ++ */ ++void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) ++{ ++ Gtk::TreeModel::Row row = *iter; ++ SPItem* item = row[_model->_colObject]; ++ if (item) ++ { ++ //Since blur and blend are both filters, we need to set both at the same time ++ SPStyle *style = item->style; ++ if (style) { ++ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); ++ double radius; ++ if (bbox) { ++ double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? ++ radius = blur * perimeter / 400; ++ } else { ++ radius = 0; ++ } ++ ++ if (radius != 0) { ++ SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); ++ sp_style_set_property_url(item, "filter", filter, false); ++ } else if (item->style->filter.set && item->style->getFilter()) { ++ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { ++ if (SP_IS_GAUSSIANBLUR(primitive)) { ++ primitive->deleteObject(); ++ break; ++ } ++ } ++ if (!item->style->getFilter()->children) { ++ remove_filter(item, false); ++ } ++ } ++ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); ++ } ++ } ++} ++ ++/** ++ * Constructor ++ */ ++ObjectsPanel::ObjectsPanel() : ++ UI::Widget::Panel("", "/dialogs/objects", SP_VERB_DIALOG_OBJECTS), ++ _rootWatcher(0), ++ _deskTrack(), ++ _desktop(0), ++ _document(0), ++ _model(0), ++ _pending(0), ++ _toggleEvent(0), ++ _defer_target(), ++ _composite_vbox(false, 0), ++ _opacity_vbox(false, 0), ++ _opacity_label(_("Opacity:")), ++ _opacity_label_unit(_("%")), ++#if WITH_GTKMM_3_0 ++ _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)), ++#else ++ _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), ++#endif ++ _opacity_hscale(_opacity_adjustment), ++ _opacity_spin_button(_opacity_adjustment, 0.01, 1), ++ _fe_cb(UI::Widget::SimpleFilterModifier::BLEND), ++ _fe_vbox(false, 0), ++ _fe_alignment(1, 1, 1, 1), ++ _fe_blur(UI::Widget::SimpleFilterModifier::BLUR), ++ _blur_vbox(false, 0), ++ _blur_alignment(1, 1, 1, 1), ++ _colorSelectorDialog("dialogs.colorpickerwindow") ++{ ++ //Create the tree model and store ++ ModelColumns *zoop = new ModelColumns(); ++ _model = zoop; ++ ++ _store = Gtk::TreeStore::create( *zoop ); ++ ++ //Set up the tree ++ _tree.set_model( _store ); ++ _tree.set_headers_visible(false); ++ _tree.set_reorderable(true); ++ _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); ++ ++ //Create the column CellRenderers ++ //Visible ++ Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( ++ INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); ++ int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; ++ eyeRenderer->property_activatable() = true; ++ Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); ++ if ( col ) { ++ col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); ++ } ++ ++ //Locked ++ Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( ++ INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); ++ int lockedColNum = _tree.append_column("lock", *renderer) - 1; ++ renderer->property_activatable() = true; ++ col = _tree.get_column(lockedColNum); ++ if ( col ) { ++ col->add_attribute( renderer->property_active(), _model->_colLocked ); ++ } ++ ++ //Type ++ Inkscape::UI::Widget::LayerTypeIcon * typeRenderer = Gtk::manage( new Inkscape::UI::Widget::LayerTypeIcon()); ++ int typeColNum = _tree.append_column("type", *typeRenderer) - 1; ++ typeRenderer->property_activatable() = true; ++ col = _tree.get_column(typeColNum); ++ if ( col ) { ++ col->add_attribute( typeRenderer->property_active(), _model->_colType ); ++ } ++ ++ //Clip/mask ++ Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); ++ int clipColNum = _tree.append_column("clipmask", *clipRenderer) - 1; ++ col = _tree.get_column(clipColNum); ++ if ( col ) { ++ col->add_attribute( clipRenderer->property_active(), _model->_colClipMask ); ++ } ++ ++ //Highlight ++ Inkscape::UI::Widget::HighlightPicker * highlightRenderer = Gtk::manage( new Inkscape::UI::Widget::HighlightPicker()); ++ int highlightColNum = _tree.append_column("highlight", *highlightRenderer) - 1; ++ col = _tree.get_column(highlightColNum); ++ if ( col ) { ++ col->add_attribute( highlightRenderer->property_active(), _model->_colHighlight ); ++ } ++ ++ //Label ++ _text_renderer = Gtk::manage(new Gtk::CellRendererText()); ++ int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; ++ _name_column = _tree.get_column(nameColNum); ++ _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); ++ ++ //Set the expander and search columns ++ _tree.set_expander_column( *_tree.get_column(nameColNum) ); ++ _tree.set_search_column(_model->_colLabel); ++ ++ //Set up the tree selection ++ _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); ++ _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &ObjectsPanel::_pushTreeSelectionToCurrent) ); ++ _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction) ); ++ ++ //Set up tree signals ++ _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); ++ _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); ++ _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false ); ++ _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleDragDrop), false); ++ _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), false)); ++ _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), true)); ++ ++ //Set up the label editing signals ++ _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEdited) ); ++ _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEditingCancelled) ); ++ ++ //Set up the scroller window and pack the page ++ _scroller.add( _tree ); ++ _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); ++ _scroller.set_shadow_type(Gtk::SHADOW_IN); ++ Gtk::Requisition sreq; ++#if WITH_GTKMM_3_0 ++ Gtk::Requisition sreq_natural; ++ _scroller.get_preferred_size(sreq_natural, sreq); ++#else ++ sreq = _scroller.size_request(); ++#endif ++ int minHeight = 70; ++ if (sreq.height < minHeight) { ++ // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar ++ _scroller.set_size_request(sreq.width, minHeight); ++ } ++ ++ _page.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); ++ ++ //Set up the compositing items ++ //Blend mode filter effect ++ _composite_vbox.pack_start(_fe_vbox, false, false, 2); ++ _fe_alignment.set_padding(0, 0, 4, 0); ++ _fe_alignment.add(_fe_cb); ++ _fe_vbox.pack_start(_fe_alignment, false, false, 0); ++ _blendConnection = _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blendValueChanged)); ++ ++ //Blur filter effect ++ _composite_vbox.pack_start(_blur_vbox, false, false, 2); ++ _blur_alignment.set_padding(0, 0, 4, 0); ++ _blur_alignment.add(_fe_blur); ++ _blur_vbox.pack_start(_blur_alignment, false, false, 0); ++ _blurConnection = _fe_blur.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blurValueChanged)); ++ ++ //Opacity ++ _composite_vbox.pack_start(_opacity_vbox, false, false, 2); ++ _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); ++ _opacity_hbox.pack_start(_opacity_label, false, false, 3); ++ _opacity_vbox.pack_start(_opacity_hbox, false, false, 0); ++ _opacity_hbox.pack_start(_opacity_hscale, true, true, 0); ++ _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0); ++ _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); ++ _opacity_hscale.set_draw_value(false); ++#if WITH_GTKMM_3_0 ++ _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); ++ _opacity_label.set_mnemonic_widget(_opacity_hscale); ++#else ++ _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); ++ _opacity_label.set_mnemonic_widget(_opacity_hscale); ++#endif ++ ++ //Keep the labels aligned ++// GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); ++// gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj())); ++// gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj())); ++// gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_blur.get_blur_label()->gobj())); ++ ++ //Pack the compositing functions and the button row ++ _page.pack_end(_composite_vbox, Gtk::PACK_SHRINK); ++ _page.pack_end(_buttonsRow, Gtk::PACK_SHRINK); ++ ++ //Pack into the panel contents ++ _getContents()->pack_start(_page, Gtk::PACK_EXPAND_WIDGET); ++ ++ SPDesktop* targetDesktop = getDesktop(); ++ ++ //Set up the button row ++ Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); ++ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); ++ ++ btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); ++ _watching.push_back( btn ); ++ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); ++ ++ btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); ++ _watchingNonBottom.push_back( btn ); ++ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); ++ ++ btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); ++ _watchingNonBottom.push_back( btn ); ++ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); ++ ++ btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); ++ _watchingNonTop.push_back( btn ); ++ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); ++ ++ btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); ++ _watchingNonTop.push_back( btn ); ++ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); ++ ++ btn = Gtk::manage( new Gtk::Button() ); ++ _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); ++ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); ++ _watchingNonBottom.push_back( btn ); ++ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); ++ ++ _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); ++ _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); ++ ++ _watching.push_back(&_composite_vbox); ++ ++ //Set up the pop-up menu ++ // ------------------------------------------------------- ++ { ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_EDIT_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); ++ ++ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); ++ ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) ); ++ ++ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); ++ ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) ); ++ ++ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); ++ ++ _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) ); ++ _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) ); ++ ++ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); ++ ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_GROUP, 0, "Group", (int)BUTTON_GROUP ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_UNGROUP, 0, "Ungroup", (int)BUTTON_UNGROUP ) ); ++ ++ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); ++ ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_CLIPPATH, 0, "Unset Clip", (int)BUTTON_UNSETCLIP ) ); ++ ++ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); ++ ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_MASK, 0, "Set Mask", (int)BUTTON_SETMASK ) ); ++ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_MASK, 0, "Unset Mask", (int)BUTTON_UNSETMASK ) ); ++ ++ _popupMenu.show_all_children(); ++ } ++ // ------------------------------------------------------- ++ ++ //Set initial sensitivity of buttons ++ for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { ++ (*it)->set_sensitive( false ); ++ } ++ for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { ++ (*it)->set_sensitive( false ); ++ } ++ for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { ++ (*it)->set_sensitive( false ); ++ } ++ ++ //Set up the color selection dialog ++ GtkWidget *dlg = GTK_WIDGET(_colorSelectorDialog.gobj()); ++ sp_transientize(dlg); ++ ++ _colorSelectorDialog.hide(); ++ _colorSelectorDialog.set_title (_("Select Highlight Color")); ++ _colorSelectorDialog.set_border_width (4); ++ _colorSelectorDialog.property_modal() = true; ++ _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); ++ _colorSelectorDialog.get_vbox()->pack_start ( ++ *Glib::wrap(&_colorSelector->vbox), true, true, 0); ++ ++ g_signal_connect(G_OBJECT(_colorSelector), "dragged", ++ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); ++ g_signal_connect(G_OBJECT(_colorSelector), "released", ++ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); ++ g_signal_connect(G_OBJECT(_colorSelector), "changed", ++ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); ++ ++ gtk_widget_show(GTK_WIDGET(_colorSelector)); ++ ++ setDesktop( targetDesktop ); ++ ++ show_all_children(); ++ ++ //Connect the desktop changed connection ++ desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectsPanel::setDesktop) ); ++ _deskTrack.connect(GTK_WIDGET(gobj())); ++} ++ ++/** ++ * Destructor ++ */ ++ObjectsPanel::~ObjectsPanel() ++{ ++ //Close the highlight selection dialog ++ _colorSelectorDialog.hide(); ++ _colorSelector = NULL; ++ ++ //Set the desktop to null, which will disconnect all object watchers ++ setDesktop(NULL); ++ ++ if ( _model ) ++ { ++ delete _model; ++ _model = 0; ++ } ++ ++ if (_pending) { ++ delete _pending; ++ _pending = 0; ++ } ++ ++ if ( _toggleEvent ) ++ { ++ gdk_event_free( _toggleEvent ); ++ _toggleEvent = 0; ++ } ++ ++ desktopChangeConn.disconnect(); ++ _deskTrack.disconnect(); ++} ++ ++/** ++ * Sets the current document ++ */ ++void ObjectsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) ++{ ++ //Clear all object watchers ++ while (!_objectWatchers.empty()) ++ { ++ ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); ++ w->_repr->removeObserver(*w); ++ _objectWatchers.pop_back(); ++ delete w; ++ } ++ ++ //Delete the root watcher ++ if (_rootWatcher) ++ { ++ _rootWatcher->_repr->removeObserver(*_rootWatcher); ++ delete _rootWatcher; ++ _rootWatcher = NULL; ++ } ++ ++ _document = document; ++ ++ if (document && document->getRoot() && document->getRoot()->getRepr()) ++ { ++ //Create a new root watcher for the document and then call _objectsChanged to fill the tree ++ _rootWatcher = new ObjectsPanel::ObjectWatcher(this, document->getRoot()); ++ document->getRoot()->getRepr()->addObserver(*_rootWatcher); ++ _objectsChanged(document->getRoot()); ++ } ++} ++ ++/** ++ * Set the current panel desktop ++ */ ++void ObjectsPanel::setDesktop( SPDesktop* desktop ) ++{ ++ Panel::setDesktop(desktop); ++ ++ if ( desktop != _desktop ) { ++ _documentChangedConnection.disconnect(); ++ _selectionChangedConnection.disconnect(); ++ if ( _desktop ) { ++ _desktop = 0; ++ } ++ ++ _desktop = Panel::getDesktop(); ++ if ( _desktop ) { ++ //Connect desktop signals ++ _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument)); ++ _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected)); ++ ++ setDocument(_desktop, _desktop->doc()); ++ } else { ++ setDocument(NULL, NULL); ++ } ++ } ++ _deskTrack.setBase(desktop); ++} ++} //namespace Dialogs ++} //namespace UI ++} //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:fileencoding=utf-8:textwidth=99 : + +=== added file 'src/ui/dialog/objects.h' +--- src/ui/dialog/objects.h 1970-01-01 00:00:00 +0000 ++++ src/ui/dialog/objects.h 2013-03-17 13:42:01 +0000 +@@ -0,0 +1,255 @@ ++/* ++ * A simple dialog for objects UI. ++ * ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#ifndef SEEN_OBJECTS_PANEL_H ++#define SEEN_OBJECTS_PANEL_H ++ ++#include ++#include ++#include ++#include ++#include ++#include "ui/widget/spinbutton.h" ++#include "ui/widget/panel.h" ++#include "ui/widget/object-composite-settings.h" ++#include "desktop-tracker.h" ++#include "ui/widget/style-subject.h" ++#include "selection.h" ++#include "ui/widget/filter-effect-chooser.h" ++ ++class SPObject; ++class SPGroup; ++struct SPColorSelector; ++ ++namespace Inkscape { ++ ++namespace UI { ++namespace Dialog { ++ ++ ++/** ++ * A panel that displays objects. ++ */ ++class ObjectsPanel : public UI::Widget::Panel ++{ ++public: ++ ObjectsPanel(); ++ virtual ~ObjectsPanel(); ++ ++ static ObjectsPanel& getInstance(); ++ ++ void setDesktop( SPDesktop* desktop ); ++ void setDocument( SPDesktop* desktop, SPDocument* document); ++ ++private: ++ //Internal Classes: ++ class ModelColumns; ++ class InternalUIBounce; ++ class ObjectWatcher; ++ ++ //Connections, Watchers, Trackers: ++ ++ //Document root watcher ++ ObjectsPanel::ObjectWatcher* _rootWatcher; ++ ++ //All object watchers ++ std::vector _objectWatchers; ++ ++ //Connection for when the desktop changes ++ sigc::connection desktopChangeConn; ++ ++ //Connection for when the document changes ++ sigc::connection _documentChangedConnection; ++ ++ //Connection for when the active selection in the document changes ++ sigc::connection _selectionChangedConnection; ++ ++ //Connection for when the selection in the dialog changes ++ sigc::connection _selectedConnection; ++ ++ //Connections for when the opacity/blend/blur of the active selection in the document changes ++ sigc::connection _opacityConnection; ++ sigc::connection _blendConnection; ++ sigc::connection _blurConnection; ++ ++ //Desktop tracker for grabbing the desktop changed connection ++ DesktopTracker _deskTrack; ++ ++ //Members: ++ ++ //The current desktop ++ SPDesktop* _desktop; ++ ++ //The current document ++ SPDocument* _document; ++ ++ //Tree data model ++ ModelColumns* _model; ++ ++ //Prevents the composite controls from updating ++ bool _blockCompositeUpdate; ++ ++ // ++ InternalUIBounce* _pending; ++ ++ //Whether the drag & drop was dragged into an item ++ gboolean _dnd_into; ++ ++ //List of drag & drop source items ++ std::vector _dnd_source; ++ ++ //Drag & drop target item ++ SPItem* _dnd_target; ++ ++ //List of items to change the highlight on ++ std::vector _highlight_target; ++ ++ //GUI Members: ++ ++ GdkEvent* _toggleEvent; ++ ++ Gtk::TreeModel::Path _defer_target; ++ ++ Glib::RefPtr _store; ++ std::vector _watching; ++ std::vector _watchingNonTop; ++ std::vector _watchingNonBottom; ++ ++ Gtk::TreeView _tree; ++ Gtk::CellRendererText *_text_renderer; ++ Gtk::TreeView::Column *_name_column; ++#if WITH_GTKMM_3_0 ++ Gtk::Box _buttonsRow; ++ Gtk::Box _buttonsPrimary; ++ Gtk::Box _buttonsSecondary; ++#else ++ Gtk::HBox _buttonsRow; ++ Gtk::HBox _buttonsPrimary; ++ Gtk::HBox _buttonsSecondary; ++#endif ++ Gtk::ScrolledWindow _scroller; ++ Gtk::Menu _popupMenu; ++ Inkscape::UI::Widget::SpinButton _spinBtn; ++ Gtk::VBox _page; ++ ++ /* Composite Settings */ ++ Gtk::VBox _composite_vbox; ++ Gtk::VBox _opacity_vbox; ++ Gtk::HBox _opacity_hbox; ++ Gtk::Label _opacity_label; ++ Gtk::Label _opacity_label_unit; ++#if WITH_GTKMM_3_0 ++ Glib::RefPtr _opacity_adjustment; ++#else ++ Gtk::Adjustment _opacity_adjustment; ++#endif ++ Gtk::HScale _opacity_hscale; ++ Inkscape::UI::Widget::SpinButton _opacity_spin_button; ++ ++ Inkscape::UI::Widget::SimpleFilterModifier _fe_cb; ++ Gtk::VBox _fe_vbox; ++ Gtk::Alignment _fe_alignment; ++ Inkscape::UI::Widget::SimpleFilterModifier _fe_blur; ++ Gtk::VBox _blur_vbox; ++ Gtk::Alignment _blur_alignment; ++ ++ Gtk::Dialog _colorSelectorDialog; ++ SPColorSelector *_colorSelector; ++ ++ ++ //Methods: ++ ++ ObjectsPanel(ObjectsPanel const &); // no copy ++ ObjectsPanel &operator=(ObjectsPanel const &); // no assign ++ ++ void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ); ++ void _fireAction( unsigned int code ); ++ ++ Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); ++ ++ void _setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ); ++ void _setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ); ++ ++ bool _handleButtonEvent(GdkEventButton *event); ++ bool _handleKeyEvent(GdkEventKey *event); ++ ++ void _storeHighlightTarget(const Gtk::TreeModel::iterator& iter); ++ void _storeDragSource(const Gtk::TreeModel::iterator& iter); ++ bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); ++ void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); ++ void _handleEditingCancelled(); ++ ++ void _doTreeMove(); ++ void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); ++ ++ void _pushTreeSelectionToCurrent(); ++ void _selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setOpacity ); ++ ++ void _checkTreeSelection(); ++ ++ void _takeAction( int val ); ++ bool _executeAction(); ++ ++ void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); ++ void _setCollapsed(SPGroup * group); ++ ++ bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); ++ bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); ++ ++ void _compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ); ++ void _updateComposite(); ++ void _setCompositingValues(SPItem *item); ++ ++ void _updateObject(SPObject *obj, bool recurse); ++ bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj); ++ ++ void _objectsSelected(Selection *sel); ++ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto); ++ ++ void _objectsChanged(SPObject *obj); ++ void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow ); ++ ++ void _opacityChangedIter(const Gtk::TreeIter& iter); ++ void _opacityValueChanged(); ++ ++ void _blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode); ++ void _blendValueChanged(); ++ ++ void _blurChangedIter(const Gtk::TreeIter& iter, double blur); ++ void _blurValueChanged(); ++ ++ ++ void setupDialog(const Glib::ustring &title); ++ ++ friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); ++ ++}; ++ ++ ++ ++} //namespace Dialogs ++} //namespace UI ++} //namespace Inkscape ++ ++ ++ ++#endif // SEEN_OBJECTS_PANEL_H ++ ++/* ++ 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 : + +=== modified file 'src/ui/tool/multi-path-manipulator.cpp' +--- src/ui/tool/multi-path-manipulator.cpp 2012-09-06 02:25:16 +0000 ++++ src/ui/tool/multi-path-manipulator.cpp 2013-03-19 00:31:09 +0000 +@@ -195,7 +195,7 @@ + ShapeRecord const &r = *i; + if (!SP_IS_PATH(r.item) && !IS_LIVEPATHEFFECT(r.item)) continue; + boost::shared_ptr newpm(new PathManipulator(*this, (SPPath*) r.item, +- r.edit_transform, _getOutlineColor(r.role), r.lpe_key)); ++ r.edit_transform, _getOutlineColor(r.role, r.item), r.lpe_key)); + newpm->showHandles(_show_handles); + // always show outlines for clips and masks + newpm->showOutline(_show_outline || r.role != SHAPE_ROLE_NORMAL); +@@ -834,7 +834,7 @@ + } + + /** Get an outline color based on the shape's role (normal, mask, LPE parameter, etc.). */ +-guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role) ++guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role, SPItem *item) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + switch(role) { +@@ -846,7 +846,7 @@ + return prefs->getColor("/tools/nodes/lpe_param_color", 0x009000ff); + case SHAPE_ROLE_NORMAL: + default: +- return prefs->getColor("/tools/nodes/outline_color", 0xff0000ff); ++ return item->highlight_color(); + } + } + + +=== modified file 'src/ui/tool/multi-path-manipulator.h' +--- src/ui/tool/multi-path-manipulator.h 2012-05-17 09:10:15 +0000 ++++ src/ui/tool/multi-path-manipulator.h 2013-03-19 00:31:16 +0000 +@@ -106,7 +106,7 @@ + void _commit(CommitEvent cps); + void _done(gchar const *reason, bool alert_LPE = false); + void _doneWithCleanup(gchar const *reason, bool alert_LPE = false); +- guint32 _getOutlineColor(ShapeRole role); ++ guint32 _getOutlineColor(ShapeRole role, SPItem *item); + + MapType _mmap; + public: + +=== modified file 'src/ui/tool/node-tool.cpp' +--- src/ui/tool/node-tool.cpp 2013-01-26 19:33:04 +0000 ++++ src/ui/tool/node-tool.cpp 2013-03-19 00:31:25 +0000 +@@ -488,7 +488,7 @@ + c->transform(over_item->i2dt_affine()); + SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), +- prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, ++ over_item->highlight_color(), 1.0, + SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(flash), 0, SP_WIND_RULE_NONZERO); + nt->flash_tempitem = desktop->add_temporary_canvasitem(flash, + +=== modified file 'src/ui/widget/Makefile_insert' +--- src/ui/widget/Makefile_insert 2013-01-08 12:06:44 +0000 ++++ src/ui/widget/Makefile_insert 2013-03-17 14:17:34 +0000 +@@ -4,6 +4,8 @@ + ui/widget/attr-widget.h \ + ui/widget/button.h \ + ui/widget/button.cpp \ ++ ui/widget/clipmaskicon.cpp \ ++ ui/widget/clipmaskicon.h \ + ui/widget/color-picker.cpp \ + ui/widget/color-picker.h \ + ui/widget/color-preview.cpp \ +@@ -23,6 +25,8 @@ + ui/widget/gimpspinscale.h \ + ui/widget/gimpcolorwheel.c \ + ui/widget/gimpcolorwheel.h \ ++ ui/widget/highlight-picker.cpp \ ++ ui/widget/highlight-picker.h \ + ui/widget/frame.cpp \ + ui/widget/frame.h \ + ui/widget/imageicon.cpp \ +@@ -33,6 +37,8 @@ + ui/widget/labelled.h \ + ui/widget/layer-selector.cpp \ + ui/widget/layer-selector.h \ ++ ui/widget/layertypeicon.cpp \ ++ ui/widget/layertypeicon.h \ + ui/widget/licensor.cpp \ + ui/widget/licensor.h \ + ui/widget/notebook-page.cpp \ + +=== added file 'src/ui/widget/clipmaskicon.cpp' +--- src/ui/widget/clipmaskicon.cpp 1970-01-01 00:00:00 +0000 ++++ src/ui/widget/clipmaskicon.cpp 2013-03-14 23:36:37 +0000 +@@ -0,0 +1,177 @@ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++ ++#include "ui/widget/clipmaskicon.h" ++ ++#include ++ ++#include "widgets/icon.h" ++#include "widgets/toolbox.h" ++#include "ui/icon-names.h" ++#include "layertypeicon.h" ++ ++namespace Inkscape { ++namespace UI { ++namespace Widget { ++ ++ClipMaskIcon::ClipMaskIcon() : ++ Glib::ObjectBase(typeid(ClipMaskIcon)), ++ Gtk::CellRendererPixbuf(), ++ _pixClipName(INKSCAPE_ICON("path-intersection")), ++ _pixInverseName(INKSCAPE_ICON("path-difference")), ++ _pixMaskName(INKSCAPE_ICON("mask-intersection")), ++ _property_active(*this, "active", 0), ++ _property_pixbuf_clip(*this, "pixbuf_on", Glib::RefPtr(0)), ++ _property_pixbuf_inverse(*this, "pixbuf_on", Glib::RefPtr(0)), ++ _property_pixbuf_mask(*this, "pixbuf_off", Glib::RefPtr(0)) ++{ ++ ++ property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; ++ phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); ++ Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); ++ ++ if (!icon_theme->has_icon(_pixClipName)) { ++ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixClipName.data()), Inkscape::ICON_SIZE_DECORATION ); ++ } ++ if (!icon_theme->has_icon(_pixInverseName)) { ++ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixInverseName.data()), Inkscape::ICON_SIZE_DECORATION ); ++ } ++ if (!icon_theme->has_icon(_pixMaskName)) { ++ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixMaskName.data()), Inkscape::ICON_SIZE_DECORATION ); ++ } ++ ++ if (icon_theme->has_icon(_pixClipName)) { ++ _property_pixbuf_clip = icon_theme->load_icon(_pixClipName, phys, (Gtk::IconLookupFlags)0); ++ } ++ if (icon_theme->has_icon(_pixInverseName)) { ++ _property_pixbuf_inverse = icon_theme->load_icon(_pixInverseName, phys, (Gtk::IconLookupFlags)0); ++ } ++ if (icon_theme->has_icon(_pixMaskName)) { ++ _property_pixbuf_mask = icon_theme->load_icon(_pixMaskName, phys, (Gtk::IconLookupFlags)0); ++ } ++ ++ property_pixbuf() = Glib::RefPtr(0); ++} ++ ++ ++#if WITH_GTKMM_3_0 ++void ClipMaskIcon::get_preferred_height_vfunc(Gtk::Widget& widget, ++ int& min_h, ++ int& nat_h) const ++{ ++ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); ++ ++ if (min_h) { ++ min_h += (min_h) >> 1; ++ } ++ ++ if (nat_h) { ++ nat_h += (nat_h) >> 1; ++ } ++} ++ ++void ClipMaskIcon::get_preferred_width_vfunc(Gtk::Widget& widget, ++ int& min_w, ++ int& nat_w) const ++{ ++ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); ++ ++ if (min_w) { ++ min_w += (min_w) >> 1; ++ } ++ ++ if (nat_w) { ++ nat_w += (nat_w) >> 1; ++ } ++} ++#else ++void ClipMaskIcon::get_size_vfunc(Gtk::Widget& widget, ++ const Gdk::Rectangle* cell_area, ++ int* x_offset, ++ int* y_offset, ++ int* width, ++ int* height ) const ++{ ++ Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); ++ ++ if ( width ) { ++ *width = phys;//+= (*width) >> 1; ++ } ++ if ( height ) { ++ *height =phys;//+= (*height) >> 1; ++ } ++} ++#endif ++ ++#if WITH_GTKMM_3_0 ++void ClipMaskIcon::render_vfunc( const Cairo::RefPtr& cr, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ Gtk::CellRendererState flags ) ++#else ++void ClipMaskIcon::render_vfunc( const Glib::RefPtr& window, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ const Gdk::Rectangle& expose_area, ++ Gtk::CellRendererState flags ) ++#endif ++{ ++ switch (_property_active.get_value()) ++ { ++ case 1: ++ property_pixbuf() = _property_pixbuf_clip; ++ break; ++ case 2: ++ property_pixbuf() = _property_pixbuf_mask; ++ break; ++ case 3: ++ property_pixbuf() = _property_pixbuf_inverse; ++ break; ++ default: ++ property_pixbuf() = Glib::RefPtr(0); ++ break; ++ } ++#if WITH_GTKMM_3_0 ++ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); ++#else ++ Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); ++#endif ++} ++ ++bool ++ClipMaskIcon::activate_vfunc(GdkEvent* event, ++ Gtk::Widget& /*widget*/, ++ const Glib::ustring& path, ++ const Gdk::Rectangle& /*background_area*/, ++ const Gdk::Rectangle& /*cell_area*/, ++ Gtk::CellRendererState /*flags*/) ++{ ++ return false; ++} ++ ++ ++} // namespace Widget ++} // namespace UI ++} // 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:fileencoding=utf-8:textwidth=99 : ++ ++ + +=== added file 'src/ui/widget/clipmaskicon.h' +--- src/ui/widget/clipmaskicon.h 1970-01-01 00:00:00 +0000 ++++ src/ui/widget/clipmaskicon.h 2013-03-08 04:27:35 +0000 +@@ -0,0 +1,102 @@ ++#ifndef __UI_DIALOG_CLIPMASKICON_H__ ++#define __UI_DIALOG_CLIPMASKICON_H__ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++ ++namespace Inkscape { ++namespace UI { ++namespace Widget { ++ ++class ClipMaskIcon : public Gtk::CellRendererPixbuf { ++public: ++ ClipMaskIcon(); ++ virtual ~ClipMaskIcon() {}; ++ ++ Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } ++ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); ++ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); ++ ++protected: ++ ++#if WITH_GTKMM_3_0 ++ virtual void render_vfunc( const Cairo::RefPtr& cr, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ Gtk::CellRendererState flags ); ++ ++ virtual void get_preferred_width_vfunc(Gtk::Widget& widget, ++ int& min_w, ++ int& nat_w) const; ++ ++ virtual void get_preferred_height_vfunc(Gtk::Widget& widget, ++ int& min_h, ++ int& nat_h) const; ++#else ++ virtual void render_vfunc( const Glib::RefPtr& window, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ const Gdk::Rectangle& expose_area, ++ Gtk::CellRendererState flags ); ++ ++ virtual void get_size_vfunc( Gtk::Widget &widget, ++ Gdk::Rectangle const *cell_area, ++ int *x_offset, int *y_offset, int *width, int *height ) const; ++#endif ++ ++ virtual bool activate_vfunc(GdkEvent *event, ++ Gtk::Widget &widget, ++ const Glib::ustring &path, ++ const Gdk::Rectangle &background_area, ++ const Gdk::Rectangle &cell_area, ++ Gtk::CellRendererState flags); ++ ++ ++private: ++ int phys; ++ ++ Glib::ustring _pixClipName; ++ Glib::ustring _pixInverseName; ++ Glib::ustring _pixMaskName; ++ ++ Glib::Property _property_active; ++ Glib::Property< Glib::RefPtr > _property_pixbuf_clip; ++ Glib::Property< Glib::RefPtr > _property_pixbuf_inverse; ++ Glib::Property< Glib::RefPtr > _property_pixbuf_mask; ++ ++}; ++ ++ ++ ++} // namespace Widget ++} // namespace UI ++} // namespace Inkscape ++ ++ ++#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ ++ ++/* ++ 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 : + +=== added file 'src/ui/widget/highlight-picker.cpp' +--- src/ui/widget/highlight-picker.cpp 1970-01-01 00:00:00 +0000 ++++ src/ui/widget/highlight-picker.cpp 2013-03-08 04:27:35 +0000 +@@ -0,0 +1,176 @@ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#include ++#include "display/cairo-utils.h" ++ ++#include ++ ++#include "highlight-picker.h" ++#include "widgets/icon.h" ++#include "widgets/toolbox.h" ++#include "ui/icon-names.h" ++ ++namespace Inkscape { ++namespace UI { ++namespace Widget { ++ ++HighlightPicker::HighlightPicker() : ++ Glib::ObjectBase(typeid(HighlightPicker)), ++ Gtk::CellRendererPixbuf(), ++ _property_active(*this, "active", 0) ++{ ++ ++ property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; ++} ++ ++HighlightPicker::~HighlightPicker() ++{ ++} ++ ++ ++#if WITH_GTKMM_3_0 ++void HighlightPicker::get_preferred_height_vfunc(Gtk::Widget& widget, ++ int& min_h, ++ int& nat_h) const ++{ ++ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); ++ ++ if (min_h) { ++ min_h += (min_h) >> 1; ++ } ++ ++ if (nat_h) { ++ nat_h += (nat_h) >> 1; ++ } ++} ++ ++void HighlightPicker::get_preferred_width_vfunc(Gtk::Widget& widget, ++ int& min_w, ++ int& nat_w) const ++{ ++ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); ++ ++ if (min_w) { ++ min_w += (min_w) >> 1; ++ } ++ ++ if (nat_w) { ++ nat_w += (nat_w) >> 1; ++ } ++} ++#else ++void HighlightPicker::get_size_vfunc(Gtk::Widget& widget, ++ const Gdk::Rectangle* cell_area, ++ int* x_offset, ++ int* y_offset, ++ int* width, ++ int* height ) const ++{ ++ Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); ++ ++ if ( width ) { ++ *width = 10;//+= (*width) >> 1; ++ } ++ if ( height ) { ++ *height = 20; //cell_area ? cell_area->get_height() / 2 : 50; //+= (*height) >> 1; ++ } ++} ++#endif ++ ++#if WITH_GTKMM_3_0 ++void HighlightPicker::render_vfunc( const Cairo::RefPtr& cr, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ Gtk::CellRendererState flags ) ++#else ++void HighlightPicker::render_vfunc( const Glib::RefPtr& window, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ const Gdk::Rectangle& expose_area, ++ Gtk::CellRendererState flags ) ++#endif ++{ ++ GdkRectangle carea; ++ ++ cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 20); ++ cairo_t *ct = cairo_create(s); ++ ++ /* Transparent area */ ++ carea.x = 0; ++ carea.y = 0; ++ carea.width = 10; ++ carea.height = 20; ++ ++ cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard(); ++ ++ cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height / 2); ++ cairo_set_source(ct, checkers); ++ cairo_fill_preserve(ct); ++ ink_cairo_set_source_rgba32(ct, _property_active.get_value()); ++ cairo_fill(ct); ++ ++ cairo_pattern_destroy(checkers); ++ ++ cairo_rectangle(ct, carea.x, carea.y + carea.height / 2, carea.width, carea.height / 2); ++ ink_cairo_set_source_rgba32(ct, _property_active.get_value() | 0x000000ff); ++ cairo_fill(ct); ++ ++ cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height); ++ ink_cairo_set_source_rgba32(ct, 0x333333ff); ++ cairo_set_line_width(ct, 2); ++ cairo_stroke(ct); ++ ++ cairo_destroy(ct); ++ cairo_surface_flush(s); ++ ++ GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), ++ GDK_COLORSPACE_RGB, TRUE, 8, ++ 10, 20, cairo_image_surface_get_stride(s), ++ ink_cairo_pixbuf_cleanup, s); ++ convert_pixbuf_argb32_to_normal(pixbuf); ++ ++ property_pixbuf() = Glib::wrap(pixbuf); ++#if WITH_GTKMM_3_0 ++ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); ++#else ++ Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); ++#endif ++} ++ ++bool ++HighlightPicker::activate_vfunc(GdkEvent* event, ++ Gtk::Widget& /*widget*/, ++ const Glib::ustring& path, ++ const Gdk::Rectangle& /*background_area*/, ++ const Gdk::Rectangle& /*cell_area*/, ++ Gtk::CellRendererState /*flags*/) ++{ ++ return false; ++} ++ ++ ++} // namespace Widget ++} // namespace UI ++} // 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:fileencoding=utf-8:textwidth=99 : ++ ++ + +=== added file 'src/ui/widget/highlight-picker.h' +--- src/ui/widget/highlight-picker.h 1970-01-01 00:00:00 +0000 ++++ src/ui/widget/highlight-picker.h 2013-03-08 04:27:35 +0000 +@@ -0,0 +1,90 @@ ++#ifndef __UI_DIALOG_HIGHLIGHT_PICKER_H__ ++#define __UI_DIALOG_HIGHLIGHT_PICKER_H__ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++ ++namespace Inkscape { ++namespace UI { ++namespace Widget { ++ ++class HighlightPicker : public Gtk::CellRendererPixbuf { ++public: ++ HighlightPicker(); ++ virtual ~HighlightPicker(); ++ ++ Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } ++ ++protected: ++ ++#if WITH_GTKMM_3_0 ++ virtual void render_vfunc( const Cairo::RefPtr& cr, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ Gtk::CellRendererState flags ); ++ ++ virtual void get_preferred_width_vfunc(Gtk::Widget& widget, ++ int& min_w, ++ int& nat_w) const; ++ ++ virtual void get_preferred_height_vfunc(Gtk::Widget& widget, ++ int& min_h, ++ int& nat_h) const; ++#else ++ virtual void render_vfunc( const Glib::RefPtr& window, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ const Gdk::Rectangle& expose_area, ++ Gtk::CellRendererState flags ); ++ ++ virtual void get_size_vfunc( Gtk::Widget &widget, ++ Gdk::Rectangle const *cell_area, ++ int *x_offset, int *y_offset, int *width, int *height ) const; ++#endif ++ ++ virtual bool activate_vfunc(GdkEvent *event, ++ Gtk::Widget &widget, ++ const Glib::ustring &path, ++ const Gdk::Rectangle &background_area, ++ const Gdk::Rectangle &cell_area, ++ Gtk::CellRendererState flags); ++ ++private: ++ ++ Glib::Property _property_active; ++}; ++ ++ ++ ++} // namespace Widget ++} // namespace UI ++} // namespace Inkscape ++ ++ ++#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ ++ ++/* ++ 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 : + +=== added file 'src/ui/widget/layertypeicon.cpp' +--- src/ui/widget/layertypeicon.cpp 1970-01-01 00:00:00 +0000 ++++ src/ui/widget/layertypeicon.cpp 2013-03-08 04:27:35 +0000 +@@ -0,0 +1,167 @@ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++ ++#include "ui/widget/layertypeicon.h" ++ ++#include ++ ++#include "widgets/icon.h" ++#include "widgets/toolbox.h" ++#include "ui/icon-names.h" ++#include "layertypeicon.h" ++ ++namespace Inkscape { ++namespace UI { ++namespace Widget { ++ ++LayerTypeIcon::LayerTypeIcon() : ++ Glib::ObjectBase(typeid(LayerTypeIcon)), ++ Gtk::CellRendererPixbuf(), ++ _pixLayerName(INKSCAPE_ICON("dialog-layers")), ++ _pixGroupName(INKSCAPE_ICON("layer-duplicate")), ++ _pixPathName(INKSCAPE_ICON("layer-rename")), ++ _property_active(*this, "active", false), ++ _property_activatable(*this, "activatable", true), ++ _property_pixbuf_layer(*this, "pixbuf_on", Glib::RefPtr(0)), ++ _property_pixbuf_group(*this, "pixbuf_off", Glib::RefPtr(0)), ++ _property_pixbuf_path(*this, "pixbuf_off", Glib::RefPtr(0)) ++{ ++ ++ property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; ++ int phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); ++ Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); ++ ++ if (!icon_theme->has_icon(_pixLayerName)) { ++ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixLayerName.data()), Inkscape::ICON_SIZE_DECORATION ); ++ } ++ if (!icon_theme->has_icon(_pixGroupName)) { ++ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixGroupName.data()), Inkscape::ICON_SIZE_DECORATION ); ++ } ++ if (!icon_theme->has_icon(_pixPathName)) { ++ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixPathName.data()), Inkscape::ICON_SIZE_DECORATION ); ++ } ++ ++ if (icon_theme->has_icon(_pixLayerName)) { ++ _property_pixbuf_layer = icon_theme->load_icon(_pixLayerName, phys, (Gtk::IconLookupFlags)0); ++ } ++ if (icon_theme->has_icon(_pixGroupName)) { ++ _property_pixbuf_group = icon_theme->load_icon(_pixGroupName, phys, (Gtk::IconLookupFlags)0); ++ } ++ if (icon_theme->has_icon(_pixPathName)) { ++ _property_pixbuf_path = icon_theme->load_icon(_pixPathName, phys, (Gtk::IconLookupFlags)0); ++ } ++ ++ property_pixbuf() = _property_pixbuf_path.get_value(); ++} ++ ++ ++#if WITH_GTKMM_3_0 ++void LayerTypeIcon::get_preferred_height_vfunc(Gtk::Widget& widget, ++ int& min_h, ++ int& nat_h) const ++{ ++ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); ++ ++ if (min_h) { ++ min_h += (min_h) >> 1; ++ } ++ ++ if (nat_h) { ++ nat_h += (nat_h) >> 1; ++ } ++} ++ ++void LayerTypeIcon::get_preferred_width_vfunc(Gtk::Widget& widget, ++ int& min_w, ++ int& nat_w) const ++{ ++ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); ++ ++ if (min_w) { ++ min_w += (min_w) >> 1; ++ } ++ ++ if (nat_w) { ++ nat_w += (nat_w) >> 1; ++ } ++} ++#else ++void LayerTypeIcon::get_size_vfunc(Gtk::Widget& widget, ++ const Gdk::Rectangle* cell_area, ++ int* x_offset, ++ int* y_offset, ++ int* width, ++ int* height ) const ++{ ++ Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); ++ ++ if ( width ) { ++ *width += (*width) >> 1; ++ } ++ if ( height ) { ++ *height += (*height) >> 1; ++ } ++} ++#endif ++ ++#if WITH_GTKMM_3_0 ++void LayerTypeIcon::render_vfunc( const Cairo::RefPtr& cr, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ Gtk::CellRendererState flags ) ++#else ++void LayerTypeIcon::render_vfunc( const Glib::RefPtr& window, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ const Gdk::Rectangle& expose_area, ++ Gtk::CellRendererState flags ) ++#endif ++{ ++ property_pixbuf() = _property_active.get_value() == 1 ? _property_pixbuf_group : (_property_active.get_value() == 2 ? _property_pixbuf_layer : _property_pixbuf_path); ++#if WITH_GTKMM_3_0 ++ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); ++#else ++ Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); ++#endif ++} ++ ++bool ++LayerTypeIcon::activate_vfunc(GdkEvent* event, ++ Gtk::Widget& /*widget*/, ++ const Glib::ustring& path, ++ const Gdk::Rectangle& /*background_area*/, ++ const Gdk::Rectangle& /*cell_area*/, ++ Gtk::CellRendererState /*flags*/) ++{ ++ _signal_pre_toggle.emit(event); ++ _signal_toggled.emit(path); ++ ++ return false; ++} ++ ++ ++} // namespace Widget ++} // namespace UI ++} // 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:fileencoding=utf-8:textwidth=99 : ++ ++ + +=== added file 'src/ui/widget/layertypeicon.h' +--- src/ui/widget/layertypeicon.h 1970-01-01 00:00:00 +0000 ++++ src/ui/widget/layertypeicon.h 2013-03-08 04:27:35 +0000 +@@ -0,0 +1,108 @@ ++#ifndef __UI_DIALOG_LAYERTYPEICON_H__ ++#define __UI_DIALOG_LAYERTYPEICON_H__ ++/* ++ * Authors: ++ * Theodore Janeczko ++ * ++ * Copyright (C) Theodore Janeczko 2012 ++ * ++ * Released under GNU GPL, read the file 'COPYING' for more information ++ */ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++ ++namespace Inkscape { ++namespace UI { ++namespace Widget { ++ ++class LayerTypeIcon : public Gtk::CellRendererPixbuf { ++public: ++ LayerTypeIcon(); ++ virtual ~LayerTypeIcon() {}; ++ ++ sigc::signal signal_toggled() { return _signal_toggled;} ++ sigc::signal signal_pre_toggle() { return _signal_pre_toggle; } ++ ++ Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } ++ Glib::PropertyProxy property_activatable() { return _property_activatable.get_proxy(); } ++ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); ++ Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); ++ ++protected: ++ ++#if WITH_GTKMM_3_0 ++ virtual void render_vfunc( const Cairo::RefPtr& cr, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ Gtk::CellRendererState flags ); ++ ++ virtual void get_preferred_width_vfunc(Gtk::Widget& widget, ++ int& min_w, ++ int& nat_w) const; ++ ++ virtual void get_preferred_height_vfunc(Gtk::Widget& widget, ++ int& min_h, ++ int& nat_h) const; ++#else ++ virtual void render_vfunc( const Glib::RefPtr& window, ++ Gtk::Widget& widget, ++ const Gdk::Rectangle& background_area, ++ const Gdk::Rectangle& cell_area, ++ const Gdk::Rectangle& expose_area, ++ Gtk::CellRendererState flags ); ++ ++ virtual void get_size_vfunc( Gtk::Widget &widget, ++ Gdk::Rectangle const *cell_area, ++ int *x_offset, int *y_offset, int *width, int *height ) const; ++#endif ++ ++ virtual bool activate_vfunc(GdkEvent *event, ++ Gtk::Widget &widget, ++ const Glib::ustring &path, ++ const Gdk::Rectangle &background_area, ++ const Gdk::Rectangle &cell_area, ++ Gtk::CellRendererState flags); ++ ++ ++private: ++ Glib::ustring _pixLayerName; ++ Glib::ustring _pixGroupName; ++ Glib::ustring _pixPathName; ++ ++ Glib::Property _property_active; ++ Glib::Property _property_activatable; ++ Glib::Property< Glib::RefPtr > _property_pixbuf_layer; ++ Glib::Property< Glib::RefPtr > _property_pixbuf_group; ++ Glib::Property< Glib::RefPtr > _property_pixbuf_path; ++ ++ sigc::signal _signal_toggled; ++ sigc::signal _signal_pre_toggle; ++ ++}; ++ ++ ++ ++} // namespace Widget ++} // namespace UI ++} // namespace Inkscape ++ ++ ++#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ ++ ++/* ++ 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 : + +=== modified file 'src/verbs.cpp' +--- src/verbs.cpp 2013-03-04 17:21:11 +0000 ++++ src/verbs.cpp 2013-03-17 14:29:16 +0000 +@@ -1980,6 +1980,9 @@ + case SP_VERB_DIALOG_LAYERS: + dt->_dlg_mgr->showDialog("LayersPanel"); + break; ++ case SP_VERB_DIALOG_OBJECTS: ++ dt->_dlg_mgr->showDialog("ObjectsPanel"); ++ break; + case SP_VERB_DIALOG_LIVE_PATH_EFFECT: + dt->_dlg_mgr->showDialog("LivePathEffect"); + break; +@@ -2791,6 +2794,8 @@ + N_("Query information about extensions"), NULL), + new DialogVerb(SP_VERB_DIALOG_LAYERS, "DialogLayers", N_("Layer_s..."), + N_("View Layers"), INKSCAPE_ICON("dialog-layers")), ++ new DialogVerb(SP_VERB_DIALOG_OBJECTS, "DialogObjects", N_("Object_s..."), ++ N_("View Objects"), INKSCAPE_ICON("dialog-layers")), + new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), + N_("Manage, edit, and apply path effects"), NULL), + new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), + +=== modified file 'src/verbs.h' +--- src/verbs.h 2013-03-04 17:21:11 +0000 ++++ src/verbs.h 2013-03-17 14:28:15 +0000 +@@ -285,6 +285,7 @@ + SP_VERB_DIALOG_INPUT, + SP_VERB_DIALOG_EXTENSIONEDITOR, + SP_VERB_DIALOG_LAYERS, ++ SP_VERB_DIALOG_OBJECTS, + SP_VERB_DIALOG_LIVE_PATH_EFFECT, + SP_VERB_DIALOG_FILTER_EFFECTS, + SP_VERB_DIALOG_SVG_FONTS, + diff --git a/share/palettes/MLP/All.gpl b/share/palettes/MLP/All.gpl new file mode 100644 index 000000000..d408e0c10 --- /dev/null +++ b/share/palettes/MLP/All.gpl @@ -0,0 +1,10 @@ +GIMP Palette +Name: All +Columns: 0 +# +255 255 255 White + 0 0 0 Black +255 255 255 Teeth Fill +185 224 247 Teeth Stroke +197 52 116 Mouth +246 112 51 Tongue diff --git a/share/palettes/MLP/Applejack.gpl b/share/palettes/MLP/Applejack.gpl new file mode 100644 index 000000000..03845416f --- /dev/null +++ b/share/palettes/MLP/Applejack.gpl @@ -0,0 +1,18 @@ +GIMP Palette +Name: Applejack +Columns: 0 +# +250 186 97 Body Fill +242 171 84 Body Shadow +233 113 53 Body Stroke +245 239 179 Mane Fill +229 215 97 Mane Stroke +234 64 63 Hair Band +203 154 91 Hat Fill +176 134 79 Hat Stroke + 96 189 80 Eye Grad Light + 38 119 22 Eye Grad Dark +125 217 103 Eye Accent +209 236 201 Eye Highlight +234 64 63 Cutie Mark Apple + 96 189 80 Cutie Mark Stem diff --git a/share/palettes/MLP/Daisy.gpl b/share/palettes/MLP/Daisy.gpl new file mode 100644 index 000000000..deab92e56 --- /dev/null +++ b/share/palettes/MLP/Daisy.gpl @@ -0,0 +1,16 @@ +GIMP Palette +Name: Daisy +Columns: 0 +# +255 170 250 Body Fill +250 148 242 Body fill Shadow +242 104 219 Body stroke +203 244 140 Mane Fill +153 222 60 Mane Stroke + 58 183 109 Eye Grad Light + 39 95 76 Eye Grad Dark +111 229 144 Eye Accent +198 243 193 Eye Highlight +255 255 255 CM Fill +194 192 193 CM Stroke +255 255 1 CM Centre diff --git a/share/palettes/MLP/Fluttershy.gpl b/share/palettes/MLP/Fluttershy.gpl new file mode 100644 index 000000000..cf525b5a9 --- /dev/null +++ b/share/palettes/MLP/Fluttershy.gpl @@ -0,0 +1,15 @@ +GIMP Palette +Name: Fluttershy +Columns: 0 +# +253 246 175 Body Fill +254 231 133 Body Shadow +234 212 99 Body Stroke +243 185 216 Mane Fill +235 129 180 Mane Stroke + 0 173 168 Eye Grad Light + 3 83 80 Eye Grad Dark +104 200 198 Eye Accent +158 216 213 Eye Highlight +104 200 198 Cutie Mark Body +243 185 216 Cutie Mark Wings diff --git a/share/palettes/MLP/Lily.gpl b/share/palettes/MLP/Lily.gpl new file mode 100644 index 000000000..3ec72fe16 --- /dev/null +++ b/share/palettes/MLP/Lily.gpl @@ -0,0 +1,18 @@ +GIMP Palette +Name: Lily +Columns: 0 +# +239 148 186 Body Fill +231 129 174 Body fill Shadow +211 90 138 Body stroke +247 225 141 Mane Fill +220 197 97 Mane Stroke +250 236 181 Mane Highlight +251 244 172 Eye Grad Light +246 181 65 Eye Grad Dark +235 227 103 Eye Accent +255 255 254 Eye Highlight +251 252 250 CM Fill +192 220 232 CM Stroke +246 212 68 CM stem +243 155 63 CM pollin diff --git a/share/palettes/MLP/Makefile b/share/palettes/MLP/Makefile new file mode 100644 index 000000000..17028e01d --- /dev/null +++ b/share/palettes/MLP/Makefile @@ -0,0 +1,520 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# share/palettes/MLP/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +pkgdatadir = $(datadir)/ponyscape +pkgincludedir = $(includedir)/ponyscape +pkglibdir = $(libdir)/ponyscape +pkglibexecdir = $(libexecdir)/ponyscape +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-unknown-linux-gnu +host_triplet = x86_64-unknown-linux-gnu +subdir = share/palettes/MLP +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/m4/ac_define_dir.m4 \ + $(top_srcdir)/m4/relaytool.m4 \ + $(top_srcdir)/m4/ink_bzr_snapshot_build.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(MLPdir)" +DATA = $(MLP_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/ponyscape-src/build-aux/missing --run aclocal-1.11 +ALL_LINGUAS = +AMTAR = ${SHELL} /home/ponyscape-src/build-aux/missing --run tar +AM_DEFAULT_VERBOSITY = 0 +AR = ar +AUTOCONF = ${SHELL} /home/ponyscape-src/build-aux/missing --run autoconf +AUTOHEADER = ${SHELL} /home/ponyscape-src/build-aux/missing --run autoheader +AUTOMAKE = ${SHELL} /home/ponyscape-src/build-aux/missing --run automake-1.11 +AWK = mawk +CAIRO_PDF_CFLAGS = -pthread -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 +CAIRO_PDF_LIBS = -lz -lcairo +CAIRO_SVG_CFLAGS = -pthread -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 +CAIRO_SVG_LIBS = -lcairo +CAIRO_USER_FONTS_CFLAGS = -pthread -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 +CAIRO_USER_FONTS_LIBS = -lcairo +CARBON_LDFLAGS = +CC = gcc +CCAS = gcc +CCASDEPMODE = depmode=gcc3 +CCASFLAGS = -g -O2 +CCDEPMODE = depmode=gcc3 +CFLAGS = -Wno-pointer-sign -g -O2 +CPP = gcc -E +CPPFLAGS = -DG_DISABLE_DEPRECATED -DGLIBMM_DISABLE_DEPRECATED -DGDKMM_DISABLE_DEPRECATED -DGTK_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_DEPRECATED -DGTKMM_DISABLE_DEPRECATED -Werror=format-security -DGSEAL_ENABLE -DG_DISABLE_SINGLE_INCLUDES -Wall -Wformat -Wformat-security -W -D_FORTIFY_SOURCE=2 +CXX = g++ +CXXCPP = g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -Wpointer-arith -Wcast-align -Wsign-compare -Woverloaded-virtual -Wswitch -Wno-unused-parameter -g -O2 -fopenmp +CYGPATH_W = echo +DATADIRNAME = share +DBUSSERVICEDIR = +DBUS_CFLAGS = +DBUS_LIBS = +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DLLTOOL = false +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +EXIF_CFLAGS = -I/usr/include/libexif +EXIF_LIBS = -lexif +FGREP = /bin/grep -F +FREETYPE_CFLAGS = -I/usr/include/freetype2 +FREETYPE_CONFIG = /usr/bin/freetype-config +FREETYPE_LIBS = -L/usr/lib/x86_64-linux-gnu -lfreetype -lz +GETTEXT_MACRO_VERSION = 0.17 +GETTEXT_PACKAGE = ponyscape +GLIBMM_USES_DEPRECATED_GLIB_SYMBOLS_CFLAGS = +GLIBMM_USES_DEPRECATED_GLIB_SYMBOLS_LIBS = +GMSGFMT = /usr/bin/msgfmt +GMSGFMT_015 = /usr/bin/msgfmt +GNOME_VFS_CFLAGS = -pthread -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gnome-vfs-2.0 -I/usr/lib/gnome-vfs-2.0/include -I/usr/include/gconf/2 +GNOME_VFS_LIBS = -pthread -lgnomevfs-2 -lgconf-2 -lgmodule-2.0 -lgobject-2.0 -lgthread-2.0 -lrt -lglib-2.0 +GREP = /bin/grep +IMAGEMAGICK_CFLAGS = -fopenmp -I/usr/include/ImageMagick +IMAGEMAGICK_LIBS = -lMagick++ -lMagickCore +INKSCAPE_CFLAGS = -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gtk-unix-print-2.0 -I/usr/include/libxml2 -I/usr/include/cairomm-1.0 -I/usr/lib/cairomm-1.0/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/giomm-2.4 -I/usr/lib/giomm-2.4/include -I/usr/include/gdkmm-2.4 -I/usr/lib/gdkmm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib/pangomm-1.4/include -I/usr/include/gtkmm-2.4 -I/usr/lib/gtkmm-2.4/include -I/usr/include/atkmm-1.6 +INKSCAPE_DATADIR = /usr/local/share +INKSCAPE_LIBS = -pthread -lgc -lxslt -lxml2 -lpng12 -lgsl -lgslcblas -lm -lgtkmm-2.4 -latkmm-1.6 -lgdkmm-2.4 -lgiomm-2.4 -lpangomm-1.4 -lgtk-x11-2.0 -lglibmm-2.4 -lcairomm-1.0 -lsigc-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpangoft2-1.0 -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 -lX11 -lz -lxml2 -ldl -lgomp -lpopt -laspell +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +INTLLIBS = +INTLTOOL_EXTRACT = /usr/bin/intltool-extract +INTLTOOL_MERGE = /usr/bin/intltool-merge +INTLTOOL_PERL = /usr/bin/perl +INTLTOOL_UPDATE = /usr/bin/intltool-update +INTL_MACOSX_LIBS = +LCMS2_CFLAGS = +LCMS2_LIBS = +LCMS_CFLAGS = +LCMS_LIBS = -llcms +LD = /usr/bin/ld -m elf_x86_64 +LDFLAGS = -Wl,-z,relro +LIBCDR_CFLAGS = +LIBCDR_LIBS = +LIBICONV = -liconv +LIBINTL = +LIBOBJS = +LIBS = -ljpeg -llcms -lpoppler -pthread -lpoppler-glib -lgdk-x11-2.0 -lpoppler -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgmodule-2.0 -lgobject-2.0 -lgthread-2.0 -lrt -lglib-2.0 +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIBVISIO_CFLAGS = +LIBVISIO_LIBS = +LIBWPG01_CFLAGS = +LIBWPG01_LIBS = +LIBWPG02_CFLAGS = -I/usr/include/libwpg-0.2 -I/usr/include/libwpd-0.9 +LIBWPG02_LIBS = -lwpg-0.2 -lwpd-0.9 -lwpd-stream-0.9 +LIBWPG_CFLAGS = -I/usr/include/libwpg-0.2 -I/usr/include/libwpd-0.9 +LIBWPG_LIBS = -lwpg-0.2 -lwpd-0.9 -lwpd-stream-0.9 +LIPO = +LN_S = ln -s +LTLIBICONV = -liconv +LTLIBINTL = +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/ponyscape-src/build-aux/missing --run makeinfo +MANIFEST_TOOL = : +MKDIR_P = /bin/mkdir -p +MSGFMT = /usr/bin/msgfmt +MSGFMT_015 = /usr/bin/msgfmt +MSGMERGE = /usr/bin/msgmerge +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OPENMP_CXXFLAGS = -fopenmp +OTOOL = +OTOOL64 = +PACKAGE = ponyscape +PACKAGE_BUGREPORT = http://bugs.launchpad.net/inkscape/+filebug +PACKAGE_LOCALE_DIR = /usr/local/share/locale +PACKAGE_NAME = ponyscape +PACKAGE_STRING = ponyscape 0.4 +PACKAGE_TARNAME = ponyscape +PACKAGE_URL = http://ponyscape.org/ +PACKAGE_VERSION = 0.4 +PANGO_USES_DEPRECATED_GLIB_SYMBOLS_CFLAGS = +PANGO_USES_DEPRECATED_GLIB_SYMBOLS_LIBS = +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +POPPLER_CAIRO_CFLAGS = -pthread -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/poppler +POPPLER_CAIRO_LIBS = -lpoppler -lcairo +POPPLER_CFLAGS = -I/usr/include/poppler +POPPLER_GFXFONT_CFLAGS = -I/usr/include/poppler +POPPLER_GFXFONT_LIBS = -lpoppler +POPPLER_GLIB_CFLAGS = -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/cairo -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gio-unix-2.0/ -I/usr/include/pango-1.0 -I/usr/include/poppler/glib -I/usr/include/poppler +POPPLER_GLIB_LIBS = -pthread -lpoppler-glib -lgdk-x11-2.0 -lpoppler -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgmodule-2.0 -lgobject-2.0 -lgthread-2.0 -lrt -lglib-2.0 +POPPLER_LIBS = -lpoppler -pthread -lpoppler-glib -lgdk-x11-2.0 -lpoppler -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgmodule-2.0 -lgobject-2.0 -lgthread-2.0 -lrt -lglib-2.0 +POPPLER_NEWERRORAPI_CFLAGS = +POPPLER_NEWERRORAPI_LIBS = +POSUB = po +POW_LIB = +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/bash +STRIP = strip +USE_NLS = yes +VERSION = 0.4 +WIN32_CFLAGS = +XGETTEXT = /usr/bin/xgettext +XGETTEXT_015 = /usr/bin/xgettext +XGETTEXT_EXTRA_OPTIONS = +abs_builddir = /home/ponyscape-src/share/palettes/MLP +abs_srcdir = /home/ponyscape-src/share/palettes/MLP +abs_top_builddir = /home/ponyscape-src +abs_top_srcdir = /home/ponyscape-src +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__tar = tar --format=posix -chf - "$$tardir" +am__untar = tar -xf - +bindir = ${exec_prefix}/bin +build = x86_64-unknown-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = unknown +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = x86_64-unknown-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = unknown +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/ponyscape-src/build-aux/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../../../ +top_builddir = ../../.. +top_srcdir = ../../.. +MLPdir = $(datadir)/ponyscape/palettes/MLP +MLP_DATA = \ + All.gpl \ + Applejack.gpl \ + Daisy.gpl \ + Fluttershy.gpl \ + Lily.gpl \ + Pinkie.gpl \ + Rainbow-Dash.gpl \ + Rarity.gpl \ + Roseluck.gpl \ + Silver-Rains.gpl \ + Spike.gpl \ + Twilight-Sparkle.gpl + +EXTRA_DIST = $(MLP_DATA) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu share/palettes/MLP/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu share/palettes/MLP/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-MLPDATA: $(MLP_DATA) + @$(NORMAL_INSTALL) + test -z "$(MLPdir)" || $(MKDIR_P) "$(DESTDIR)$(MLPdir)" + @list='$(MLP_DATA)'; test -n "$(MLPdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(MLPdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(MLPdir)" || exit $$?; \ + done + +uninstall-MLPDATA: + @$(NORMAL_UNINSTALL) + @list='$(MLP_DATA)'; test -n "$(MLPdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(MLPdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(MLPdir)" && rm -f $$files +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(MLPdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-MLPDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-MLPDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-MLPDATA \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-MLPDATA uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/share/palettes/MLP/Makefile.am b/share/palettes/MLP/Makefile.am new file mode 100644 index 000000000..cfd45878c --- /dev/null +++ b/share/palettes/MLP/Makefile.am @@ -0,0 +1,18 @@ + +MLPdir = $(datadir)/ponyscape/palettes/MLP + +MLP_DATA = \ + All.gpl \ + Applejack.gpl \ + Daisy.gpl \ + Fluttershy.gpl \ + Lily.gpl \ + Pinkie.gpl \ + Rainbow-Dash.gpl \ + Rarity.gpl \ + Roseluck.gpl \ + Silver-Rains.gpl \ + Spike.gpl \ + Twilight-Sparkle.gpl + +EXTRA_DIST = $(MLP_DATA) diff --git a/share/palettes/MLP/Pinkie.gpl b/share/palettes/MLP/Pinkie.gpl new file mode 100644 index 000000000..ca7b46d4d --- /dev/null +++ b/share/palettes/MLP/Pinkie.gpl @@ -0,0 +1,15 @@ +GIMP Palette +Name: Pinkie +Columns: 0 +# +249 184 210 Body Fill +237 157 194 Body Shadow +234 128 176 Body Stroke +240 67 140 Mane Fill +192 27 117 Mane Stroke +127 210 244 Eye Grad Light + 24 113 149 Eye Grad Dark +157 226 249 Eye Accent +223 249 254 Eye Highlight +255 247 173 Cutie Mark Yellow +123 212 249 Cutie Mark Blue diff --git a/share/palettes/MLP/Rainbow-Dash.gpl b/share/palettes/MLP/Rainbow-Dash.gpl new file mode 100644 index 000000000..7f398cf23 --- /dev/null +++ b/share/palettes/MLP/Rainbow-Dash.gpl @@ -0,0 +1,23 @@ +GIMP Palette +Name: Rainbow Dash +Columns: 0 +# +157 217 248 Body Fill +145 190 231 Body Shadow +106 170 221 Body Stroke +241 62 50 Mane Red +246 118 52 Mane Orange +245 235 126 Mane Yellow +122 194 64 Mane Green + 1 147 207 Mane Blue +102 46 138 Mane Purple + 1 147 207 Mane Stroke +198 0 111 Eye Grad Light + 87 0 48 Eye Grad Dark +214 74 153 Eye Accent +240 174 208 Eye Highlight +255 255 255 Cutie Mark Cloud Fill + 1 147 207 Cutie Mark Cloud Stroke +241 62 50 Cutie Mark Red +245 235 126 Cutie Mark Yellow + 1 147 207 Cutie Mark Blue diff --git a/share/palettes/MLP/Rarity.gpl b/share/palettes/MLP/Rarity.gpl new file mode 100644 index 000000000..9ecbd2bed --- /dev/null +++ b/share/palettes/MLP/Rarity.gpl @@ -0,0 +1,18 @@ +GIMP Palette +Name: Rarity +Columns: 0 +# +240 242 243 Body Fill +226 228 230 Body Shadow +194 197 198 Body Stroke + 94 81 163 Mane Fill + 75 21 102 Mane Stroke +126 74 153 Mane Grad Light + 75 21 102 Mane Grad Dark + 55 119 190 Eye Grad Light + 26 70 106 Eye Grad Dark + 85 149 211 Eye Accent +122 172 236 Eye Highlight +188 228 247 Eyeshadow +115 212 253 Cutie Mark Fill + 44 143 183 Cutie Mark Stroke diff --git a/share/palettes/MLP/Roseluck.gpl b/share/palettes/MLP/Roseluck.gpl new file mode 100644 index 000000000..9ca484f94 --- /dev/null +++ b/share/palettes/MLP/Roseluck.gpl @@ -0,0 +1,21 @@ +GIMP Palette +Name: Roseluck +Columns: 0 +# +255 255 217 Body Fill +226 226 195 Body Fill Shadow +201 192 148 Body Stroke +187 42 87 Mane Fill +152 35 69 Mane Stroke +227 131 159 Mane Highlight +221 104 139 Mane Highlight Stroke +189 232 135 Eye Grad Light + 57 84 31 Eye Grad Dark +253 255 246 Eye Highlight +214 237 178 Eye Accent + 73 118 36 CM Stem +110 162 55 CM leaf stroke +151 205 99 CM leaf fill +211 54 102 CM Rose fill +152 35 69 CM rose Stroke +187 42 87 CM rose Shadow fill diff --git a/share/palettes/MLP/Silver-Rains.gpl b/share/palettes/MLP/Silver-Rains.gpl new file mode 100644 index 000000000..8affb0e7c --- /dev/null +++ b/share/palettes/MLP/Silver-Rains.gpl @@ -0,0 +1,17 @@ +GIMP Palette +Name: Silver Rains +Columns: 0 +# +201 201 201 Body Fill +190 190 190 Body Shadow +168 168 168 Body Stroke +151 177 250 Mane Fill +120 142 202 Mane Streak + 74 100 174 Mane Stroke +118 244 192 Eye Grad Light + 2 198 161 Eye Grad Dark +180 252 226 Eye Accent +205 249 233 Eye Highlight +154 160 177 Cutie Mark Cloud +138 195 255 Cutie Mark Drops + 52 93 136 Cutie Mark Notes diff --git a/share/palettes/MLP/Spike.gpl b/share/palettes/MLP/Spike.gpl new file mode 100644 index 000000000..91b827a3b --- /dev/null +++ b/share/palettes/MLP/Spike.gpl @@ -0,0 +1,17 @@ +GIMP Palette +Name: Spike +Columns: 0 +# +198 147 201 Body Fill +176 116 185 Body Shadow +153 95 160 Body Stroke +219 236 180 Body Green Fill +152 210 124 Body Green Stroke + 82 196 88 Spike Fill + 44 151 47 Spike Stroke +178 217 100 Ear Fill +226 236 139 Ear Stroke + 98 187 77 Eye Grad Light + 39 117 20 Eye Grad Dark +127 217 104 Eye Accent +203 240 196 Eye Highlight diff --git a/share/palettes/MLP/Twilight-Sparkle.gpl b/share/palettes/MLP/Twilight-Sparkle.gpl new file mode 100644 index 000000000..59acf5dac --- /dev/null +++ b/share/palettes/MLP/Twilight-Sparkle.gpl @@ -0,0 +1,17 @@ +GIMP Palette +Name: Twilight Sparkle +Columns: 0 +# +212 164 232 Body Fill +174 133 193 Body Shadow +166 110 190 Body Stroke + 39 55 113 Mane Fill + 19 32 66 Mane Stroke + 98 46 134 Mane Highlight Purple +230 69 139 Mane Highlight Pink + 99 49 131 Eye Grad Light + 41 10 75 Eye Grad Dark +150 107 171 Eye Accent +206 183 215 Eye Highlight +230 69 139 Cutie Mark Pink +255 255 255 Cutie Mark White diff --git a/share/palettes/Makefile.am b/share/palettes/Makefile.am index b25b35a06..2e6560bb1 100644 --- a/share/palettes/Makefile.am +++ b/share/palettes/Makefile.am @@ -1,5 +1,6 @@ +SUBDIRS = MLP -palettesdir = $(datadir)/inkscape/palettes +palettesdir = $(datadir)/ponyscape/palettes palettes_DATA = \ README \ @@ -17,6 +18,7 @@ palettes_DATA = \ Reds.gpl \ Royal.gpl \ svg.gpl \ + swatches.svg \ Tango-Palette.gpl \ Topographic.gpl \ Ubuntu.gpl \ diff --git a/share/palettes/README b/share/palettes/README index b6e7fd759..8b04470b7 100644 --- a/share/palettes/README +++ b/share/palettes/README @@ -1,11 +1,4 @@ This is the directory with the Inkscape color palettes. They are in Gimp format (.gpl). Within Inkscape, they can be accessed by a drop-down menu in the Swatches -dialog (Ctrl+Shift+W). - -Internationalization - -This file is internationalized the same way as share/filters/filters/svg -The i18n.py script called from the makefile will extract strings from the *.svg -into a *.svg.h file. Intltool is then able to extracts these strings just like -from normal .h files. +dialog (Ctrl+Shift+W). \ No newline at end of file diff --git a/share/palettes/Tango-Palette.gpl b/share/palettes/Tango-Palette.gpl index 7e626737b..22dc46676 100644 --- a/share/palettes/Tango-Palette.gpl +++ b/share/palettes/Tango-Palette.gpl @@ -23,11 +23,9 @@ Columns: 3 239 41 41 Scarlet Red 1 204 0 0 Scarlet Red 2 164 0 0 Scarlet Red 3 -255 255 255 Snowy White 238 238 236 Aluminium 1 211 215 207 Aluminium 2 186 189 182 Aluminium 3 136 138 133 Aluminium 4 85 87 83 Aluminium 5 46 52 54 Aluminium 6 - 0 0 0 Jet Black diff --git a/share/palettes/swatches.svg b/share/palettes/swatches.svg new file mode 100644 index 000000000..ac007b507 --- /dev/null +++ b/share/palettes/swatches.svg @@ -0,0 +1,28382 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 7940c28ae..6eece0c17 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,18 +11,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - -#include #include +#include #include #include @@ -45,6 +36,7 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" +#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE @@ -53,756 +45,206 @@ namespace Inkscape { namespace UI { namespace Dialogs { -static std::vector mimeStrings; -static std::map mimeToInt; - -#if ENABLE_MAGIC_COLORS -// TODO remove this soon: -extern std::vector possible; -#endif // ENABLE_MAGIC_COLORS - - -#if ENABLE_MAGIC_COLORS -static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) +bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) { - bool changed = false; - - if ( node ) { - gchar const * val = node->attribute("inkscape:x-fill-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "fill", c ); - - sp_desktop_apply_css_recursive( obj, css, true ); - static_cast(obj)->updateRepr(); - - changed = true; - } - - val = node->attribute("inkscape:x-stroke-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "stroke", c ); - - sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); - ((SPItem*)obj)->updateRepr(); - - changed = true; - } - - Inkscape::XML::Node* first = node->firstChild(); - changed |= bruteForce( document, first, match, r, g, b ); - - changed |= bruteForce( document, node->next(), match, r, g, b ); - } - - return changed; -} -#endif // ENABLE_MAGIC_COLORS - -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); - } -} - -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); - } -} - -static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), - item->def.descr.c_str()); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); - } - } - return FALSE; -} - -static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); } - return FALSE; + return Gtk::Widget::on_enter_notify_event(event); } -static void dieDieDie( GObject *obj, gpointer user_data ) +bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) { - g_message("die die die %p %p", obj, user_data ); -} - -static bool getBlock( std::string& dst, guchar ch, std::string const & str ) -{ - bool good = false; - std::string::size_type pos = str.find(ch); - if ( pos != std::string::npos ) - { - std::string::size_type pos2 = str.find( '(', pos ); - if ( pos2 != std::string::npos ) { - std::string::size_type endPos = str.find( ')', pos2 ); - if ( endPos != std::string::npos ) { - dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); - good = true; - } - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); } - return good; + return Gtk::Widget::on_leave_notify_event(event); } -static bool popVal( guint64& numVal, std::string& str ) +void ColorItem::selection_modified(Selection* selection, guint flags) { - bool good = false; - std::string::size_type endPos = str.find(','); - if ( endPos == std::string::npos ) { - endPos = str.length(); - } - - if ( endPos != std::string::npos && endPos > 0 ) { - std::string xxx = str.substr( 0, endPos ); - const gchar* ptr = xxx.c_str(); - gchar* endPtr = 0; - numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == ptr) ) { - // failed conversion - } else { - good = true; - str.erase( 0, endPos + 1 ); - } - } - - return good; + selection_changed(selection); } -// TODO resolve this more cleanly: -extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); - -static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) +void ColorItem::selection_changed(Selection* selection) { - ColorItem* item = reinterpret_cast(data); - if ( item ) + SPItem* item = selection->singleItem(); + SPPaintServer* grad; + if (item && + ( + (item->style->fill.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) + && SP_GRADIENT(grad)->getVector() == gradient) || + + (item->style->stroke.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && + SP_GRADIENT(grad)->getVector() == gradient) + ) + ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - int width = 32; - int height = 24; - - if (item->def.getType() != ege::PaintDef::RGB){ - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); - g_free(localFilename); - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); - } else { - GdkPixbuf* pixbuf = 0; - if ( item->getGradient() ){ - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, gradient); - cairo_paint(ct); - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_surface_flush(s); - - pixbuf = ink_pixbuf_create_from_cairo_surface(s); - } else { - Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); - guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) - | (0x00ff0000 & (item->def.getG() << 16)) - | (0x0000ff00 & (item->def.getB() << 8)); - thumb->fill( fillWith ); - pixbuf = thumb->gobj(); - g_object_ref(G_OBJECT(pixbuf)); - } - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + if (!_isSelected) { + _isSelected = true; + queue_draw(); } + } else if (_isSelected) { + _isSelected = false; + queue_draw(); } - -} - -//"drag-drop" -// gboolean dragDropColorData( GtkWidget *widget, -// GdkDragContext *drag_context, -// gint x, -// gint y, -// guint time, -// gpointer user_data) -// { -// // TODO finish - -// return TRUE; -// } - - -SwatchPage::SwatchPage() - : _prefWidth(0) -{ -} - -SwatchPage::~SwatchPage() -{ -} - - -ColorItem::ColorItem(ege::PaintDef::ColorType type) : - def(type), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : - def( r, g, b, name ), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::~ColorItem() -{ - if (_pattern != NULL) { - cairo_pattern_destroy(_pattern); - } -} - -ColorItem::ColorItem(ColorItem const &other) : - Inkscape::UI::Previewable() -{ - if ( this != &other ) { - *this = other; - } -} - -ColorItem &ColorItem::operator=(ColorItem const &other) -{ - if ( this != &other ) { - def = other.def; - - // TODO - correct linkage - _linkSrc = other._linkSrc; - g_message("Erk!"); - } - return *this; } -void ColorItem::setState( bool fill, bool stroke ) +ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : + Glib::ObjectBase("coloritem"), + Gtk::Widget(), + def( name ), + gradient(grad), + _isSelected(false) { - if ( (_isFill != fill) || (_isStroke != stroke) ) { - _isFill = fill; - _isStroke = stroke; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - int val = eek_preview_get_linked( preview ); - val &= ~(PREVIEW_FILL | PREVIEW_STROKE); - if ( _isFill ) { - val |= PREVIEW_FILL; - } - if ( _isStroke ) { - val |= PREVIEW_STROKE; - } - eek_preview_set_linked( preview, static_cast(val) ); - } - } - } + set_has_window(true); + add_events(Gdk::BUTTON_PRESS_MASK); + add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); + mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); + selection_changed(desktop->selection); } -void ColorItem::setGradient(SPGradient *grad) +void ColorItem::on_size_request(Gtk::Requisition* requisition) { - if (_grad != grad) { - _grad = grad; - // TODO regen and push to listeners - } - - setName( gr_prepare_label(_grad) ); + requisition->height = 20; + requisition->width = 20; } -void ColorItem::setName(const Glib::ustring name) +void ColorItem::on_size_allocate(Gtk::Allocation& allocation) { - //def.descr = name; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str()); - } - else if ( GTK_IS_LABEL(widget->gobj()) ) { - gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str()); - } + set_allocation(allocation); + if (m_refGdkWindow) + { + m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); } } -void ColorItem::setPattern(cairo_pattern_t *pattern) +void ColorItem::on_map() { - if (pattern) { - cairo_pattern_reference(pattern); - } - if (_pattern) { - cairo_pattern_destroy(_pattern); - } - _pattern = pattern; - - _updatePreviews(); + Gtk::Widget::on_map(); } -void ColorItem::_dragGetColorData( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - GtkSelectionData *data, - guint info, - guint /*time*/, - gpointer user_data) +void ColorItem::on_unmap() { - ColorItem* item = reinterpret_cast(user_data); - std::string key; - if ( info < mimeStrings.size() ) { - key = mimeStrings[info]; - } else { - g_warning("ERROR: unknown value (%d)", info); - } - - if ( !key.empty() ) { - char* tmp = 0; - int len = 0; - int format = 0; - item->def.getMIMEData(key, tmp, len, format); - if ( tmp ) { - GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); - gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); - delete[] tmp; - } - } + Gtk::Widget::on_unmap(); } -void ColorItem::_dropDataIn( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - gint /*x*/, gint /*y*/, - GtkSelectionData */*data*/, - guint /*info*/, - guint /*event_time*/, - gpointer /*user_data*/) +void ColorItem::on_realize() { + set_realized(); + ensure_style(); + + if(!m_refGdkWindow) + { + //Create the GdkWindow: + + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); + + Gtk::Allocation allocation = get_allocation(); + + //Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + + m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, + GDK_WA_X | GDK_WA_Y); + set_window(m_refGdkWindow); + + //Attach this widget's style to its Gdk::Window. + style_attach(); + + //make the widget receive expose events + m_refGdkWindow->set_user_data(gobj()); + } } -void ColorItem::_colorDefChanged(void* data) +void ColorItem::on_unrealize() { - ColorItem* item = reinterpret_cast(data); - if ( item ) { - item->_updatePreviews(); - } + m_refGdkWindow.reset(); + + Gtk::Widget::on_unrealize(); } -void ColorItem::_updatePreviews() +bool ColorItem::on_expose_event(GdkEventExpose* event) { - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - _regenPreview(preview); - - widget->queue_draw(); - } - } - - for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { - guint r = def.getR(); - guint g = def.getG(); - guint b = def.getB(); - - if ( (*it)->_linkIsTone ) { - r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } else { - r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } - - (*it)->def.setRGB( r, g, b ); - } - - -#if ENABLE_MAGIC_COLORS - // Look for objects using this color + if(m_refGdkWindow) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - SPDocument* document = sp_desktop_document( desktop ); - Inkscape::XML::Node *rroot = document->getReprRoot(); - if ( rroot ) { - - // Find where this thing came from - Glib::ustring paletteName; - bool found = false; - int index = 0; - for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { - SwatchPage* curr = *it2; - index = 0; - for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { - if ( this == &*zz ) { - found = true; - paletteName = curr->_name; - break; - } else { - index++; - } - } - } - - if ( !paletteName.empty() ) { - gchar* str = g_strdup_printf("%d|", index); - paletteName.insert( 0, str ); - g_free(str); - str = 0; - - if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { - SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, - _("Change color definition")); - } - } - } - } - } -#endif // ENABLE_MAGIC_COLORS - -} - -void ColorItem::_regenPreview(EekPreview * preview) -{ - if ( def.getType() != ege::PaintDef::RGB ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); - if (!pixbuf) { - g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); - } - g_free(localFilename); - - eek_preview_set_pixbuf( preview, pixbuf ); - } - else if ( !_pattern ){ - eek_preview_set_color( preview, - (def.getR() << 8) | def.getR(), - (def.getG() << 8) | def.getG(), - (def.getB() << 8) | def.getB() ); - } else { - // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp - // TODO: the pattern to draw should be in the widget that draws the preview, - // so the preview can be scalable - int w = 128; - int h = 16; - - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, _pattern); - cairo_paint(ct); - cairo_destroy(ct); - cairo_surface_flush(s); - - GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); - eek_preview_set_pixbuf( preview, pixbuf ); - } - - eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) - | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) - | (_isLive ? PREVIEW_LINK_OTHER:0)) ); -} - -Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) -{ - Gtk::Widget* widget = 0; - if ( style == PREVIEW_STYLE_BLURB) { - Gtk::Label *lbl = new Gtk::Label(def.descr); - lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - widget = lbl; - } else { - GtkWidget* eekWidget = eek_preview_new(); - EekPreview * preview = EEK_PREVIEW(eekWidget); - Gtk::Widget* newBlot = Glib::wrap(eekWidget); - _regenPreview(preview); - - eek_preview_set_details( preview, - (::ViewType)view, - (::PreviewSize)size, - ratio, - border ); - - def.addCallback( _colorDefChanged, this ); - eek_preview_set_focus_on_click(preview, FALSE); - newBlot->set_tooltip_text(def.descr); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "clicked", - G_CALLBACK(handleClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "alt-clicked", - G_CALLBACK(handleSecondaryClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "button-press-event", - G_CALLBACK(colorItemHandleButtonPress), - this); - + Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); + if(event) { - std::vector listing = def.getMIMETypes(); - int entryCount = listing.size(); - GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; - GtkTargetEntry* curr = entries; - for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { - curr->target = g_strdup(it->c_str()); - curr->flags = 0; - if ( mimeToInt.find(*it) == mimeToInt.end() ){ - // these next lines are order-dependent: - mimeToInt[*it] = mimeStrings.size(); - mimeStrings.push_back(*it); - } - curr->info = mimeToInt[curr->target]; - curr++; - } - gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), - GDK_BUTTON1_MASK, - entries, entryCount, - GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); - for ( int i = 0; i < entryCount; i++ ) { - g_free(entries[i].target); - } - delete[] entries; + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); + cr->clip(); } - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-data-get", - G_CALLBACK(ColorItem::_dragGetColorData), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-begin", - G_CALLBACK(colorItemDragBegin), - this ); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "enter-notify-event", - G_CALLBACK(handleEnterNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "leave-notify-event", - G_CALLBACK(handleLeaveNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "destroy", - G_CALLBACK(dieDieDie), - this); - - - widget = newBlot; - } - - _previews.push_back( widget ); - - return widget; -} - -void ColorItem::buttonClicked(bool secondary) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - char const * attrName = secondary ? "stroke" : "fill"; - - SPCSSAttr *css = sp_repr_css_attr_new(); - Glib::ustring descr; - switch (def.getType()) { - case ege::PaintDef::CLEAR: { - // TODO actually make this clear - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Remove stroke color") : _("Remove fill color"); - break; - } - case ege::PaintDef::NONE: { - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); - break; - } - case ege::PaintDef::RGB: { - Glib::ustring colorspec; - if ( _grad ){ - colorspec = "url(#"; - colorspec += _grad->getId(); - colorspec += ")"; - } else { - gchar c[64]; - guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; - sp_svg_write_color(c, sizeof(c), rgba); - colorspec = c; - } - sp_repr_css_set_property( css, attrName, colorspec.c_str() ); - descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); - break; - } - } - sp_desktop_set_style(desktop, css); - sp_repr_css_attr_unref(css); - - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); - } -} - -void ColorItem::_wireMagicColors( SwatchPage *colorSet ) -{ - if ( colorSet ) - { - for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) - { - std::string::size_type pos = it->def.descr.find("*{"); - if ( pos != std::string::npos ) - { - std::string subby = it->def.descr.substr( pos + 2 ); - std::string::size_type endPos = subby.find("}*"); - if ( endPos != std::string::npos ) - { - subby.erase( endPos ); - //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); - //g_message(" '%s'", subby.c_str()); - - if ( subby.find('E') != std::string::npos ) - { - it->def.setEditable( true ); - } - - if ( subby.find('L') != std::string::npos ) - { - it->_isLive = true; - } - - std::string part; - // Tint. index + 1 more val. - if ( getBlock( part, 'T', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - it->_linkTint( colorSet->_colors[colorIndex], percent ); - } - } - } - - // Shade/tone. index + 1 or 2 more val. - if ( getBlock( part, 'S', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - guint64 grayLevel = 0; - if ( !popVal( grayLevel, part ) ) { - grayLevel = 0; - } - it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); - } - } - } - - } + if (gradient) { + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + + Cairo::RefPtr checkpat(new Cairo::Pattern(check)); + + cr->set_source(checkpat); + cr->paint(); + + cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); + Cairo::RefPtr gpat(new Cairo::Pattern(g)); + cr->set_source(gpat); + cr->paint(); + gpat.clear(); + cairo_pattern_destroy(g); + + checkpat.clear(); + + cairo_pattern_destroy(check); + + if (_isSelected) { + cr->set_source_rgb(0, 0, 0); + cr->set_line_width(3); + cr->move_to(0, get_allocation().get_height()); + cr->line_to(0,0); + cr->line_to(get_allocation().get_width(), 0); + cr->stroke(); + cr->move_to(get_allocation().get_width(), 0); + cr->set_source_rgb(1, 1, 1); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->line_to(0, get_allocation().get_height()); + //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); + cr->stroke(); } + } else { + cr->set_source_rgb(1, 1, 1); + cr->paint(); + cr->set_source_rgb(1, 0, 0); + cr->set_line_width(3); + cr->move_to(0,0); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->move_to(get_allocation().get_width(), 0); + cr->line_to(0, get_allocation().get_height()); + cr->stroke(); } } + return true; } - -void ColorItem::_linkTint( ColorItem& other, int percent ) -{ - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = false; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = 0; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } -} - -void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) +ColorItem::~ColorItem() { - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = true; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = grayLevel; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } + sel_connection.disconnect(); + mod_connection.disconnect(); } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 3a0b33193..5d97d8803 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,7 +15,11 @@ #include #include "widgets/ege-paint-def.h" -#include "ui/previewable.h" +#include "widgets/eek-preview.h" +#include +#include +#include "desktop.h" +#include "selection.h" class SPGradient; @@ -23,89 +27,43 @@ namespace Inkscape { namespace UI { namespace Dialogs { -class ColorItem; - -class SwatchPage -{ -public: - SwatchPage(); - ~SwatchPage(); - - Glib::ustring _name; - int _prefWidth; - boost::ptr_vector _colors; -}; - /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Inkscape::UI::Previewable +class ColorItem : public Gtk::Widget { - friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( ege::PaintDef::ColorType type ); - ColorItem( unsigned int r, unsigned int g, unsigned int b, - Glib::ustring& name ); + ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); virtual ~ColorItem(); - ColorItem(ColorItem const &other); - virtual ColorItem &operator=(ColorItem const &other); - virtual Gtk::Widget* getPreview(PreviewStyle style, - ViewType view, - ::PreviewSize size, - guint ratio, - guint border); - void buttonClicked(bool secondary = false); - - void setGradient(SPGradient *grad); - SPGradient * getGradient() const { return _grad; } - void setPattern(cairo_pattern_t *pattern); - void setName(const Glib::ustring name); - - void setState( bool fill, bool stroke ); - bool isFill() { return _isFill; } - bool isStroke() { return _isStroke; } - - ege::PaintDef def; - + + SPGradient * getGradient() { return gradient; } + +protected: + + const gchar* def; + SPGradient * gradient; + virtual bool on_enter_notify_event(GdkEventCrossing* event); + virtual bool on_leave_notify_event(GdkEventCrossing* event); + + virtual void on_size_request(Gtk::Requisition* requisition); + virtual void on_size_allocate(Gtk::Allocation& allocation); + virtual void on_map(); + virtual void on_unmap(); + virtual void on_realize(); + virtual void on_unrealize(); + virtual bool on_expose_event(GdkEventExpose* event); + + Glib::RefPtr m_refGdkWindow; + + private: + void selection_changed(Selection* selection); + void selection_modified(Selection* selection, guint flags); - static void _dropDataIn( GtkWidget *widget, - GdkDragContext *drag_context, - gint x, gint y, - GtkSelectionData *data, - guint info, - guint event_time, - gpointer user_data); - - static void _dragGetColorData( GtkWidget *widget, - GdkDragContext *drag_context, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data); - - static void _wireMagicColors( SwatchPage *colorSet ); - static void _colorDefChanged(void* data); - - void _updatePreviews(); - void _regenPreview(EekPreview * preview); - - void _linkTint( ColorItem& other, int percent ); - void _linkTone( ColorItem& other, int percent, int grayLevel ); - - std::vector _previews; - - bool _isFill; - bool _isStroke; - bool _isLive; - bool _linkIsTone; - int _linkPercent; - int _linkGray; - ColorItem* _linkSrc; - SPGradient* _grad; - cairo_pattern_t *_pattern; - std::vector _listeners; + sigc::connection sel_connection; + sigc::connection mod_connection; + bool _isSelected; }; } // namespace Dialogs diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 8dfcf5dce..175031bcf 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -48,6 +48,7 @@ typedef enum { IMPORT_TYPES, EXPORT_TYPES, EXE_TYPES, + SWATCH_TYPES, CUSTOM_TYPE } FileDialogType; diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2956c6d17..efea4b869 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -67,14 +67,14 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" +#include "ui/tools/tool-base.h" #include "svg/css-ostringstream.h" -#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include #endif -guint get_group0_keyval(GdkEventKey *event); +//lazy! void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); namespace Inkscape { @@ -1335,10 +1335,10 @@ void SwatchesPanel::_defsChanged() eb->add(*lbl); _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); } - Glib::ustring str1 = Glib::ustring(_("[None]")); - ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->setName(_("[None]")); + + ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->set_tooltip_text(_("[None]")); _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); unsigned int i = 1; @@ -1365,11 +1365,10 @@ void SwatchesPanel::_defsChanged() GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); } - Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); - item->setGradient(grad); - //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(it->label() ? it->label() : it->getId()); + + item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1432,11 +1431,10 @@ void SwatchesPanel::_defsChanged() _editDoc.expand_to_path(_storeDoc->get_path(iter)); } - Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); - item->setGradient(grad); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(cit->label() ? cit->label() : cit->getId()); + + item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1643,7 +1641,7 @@ bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -1815,7 +1813,7 @@ void SwatchesPanel::_deleteButtonClickedDoc() bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -2323,18 +2321,8 @@ void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) } //namespace UI } //namespace Inkscape -//should be okay to add this here -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - -void -sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +//really lazy! +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) { bool intercepted = false; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 583dbec85..2eba8bb8c 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -358,7 +358,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) { using Inkscape::UI::Dialogs::SwatchesPanel; - dtw->panels = new SwatchesPanel("/embedded/swatches"); + dtw->panels = new SwatchesPanel("/embedded/swatches", false); dtw->panels->setOrientation(SP_ANCHOR_SOUTH); #if GTK_CHECK_VERSION(3,0,0) -- cgit v1.2.3