diff options
| author | Shlomi Fish <shlomif@shlomifish.org> | 2016-10-08 15:39:06 +0000 |
|---|---|---|
| committer | Shlomi Fish <shlomif@shlomifish.org> | 2016-10-08 15:39:06 +0000 |
| commit | 2a5534a166dff8bfe6b56c8a3b496e989280fbd1 (patch) | |
| tree | dbd8330a6b3dcfb201ee751dbf283a17a41a2dfa /src/live_effects | |
| parent | Merged. (diff) | |
| parent | [Bug #770681] KEY MAPPING: Comma and period hijacked by scaling. (diff) | |
| download | inkscape-2a5534a166dff8bfe6b56c8a3b496e989280fbd1.tar.gz inkscape-2a5534a166dff8bfe6b56c8a3b496e989280fbd1.zip | |
Merged.
(bzr r15100.1.31)
Diffstat (limited to 'src/live_effects')
26 files changed, 1291 insertions, 57 deletions
diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 9a2f06a76..784317090 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -27,6 +27,7 @@ set(live_effects_SRC lpe-lattice.cpp lpe-lattice2.cpp lpe-line_segment.cpp + lpe-measure-line.cpp lpe-mirror_symmetry.cpp lpe-offset.cpp lpe-parallel.cpp @@ -68,6 +69,7 @@ set(live_effects_SRC parameter/powerstrokepointarray.cpp parameter/random.cpp parameter/text.cpp + parameter/fontbutton.cpp parameter/togglebutton.cpp parameter/transformedpoint.cpp parameter/unit.cpp @@ -105,6 +107,7 @@ set(live_effects_SRC lpe-lattice.h lpe-lattice2.h lpe-line_segment.h + lpe-measure-line.h lpe-mirror_symmetry.h lpe-offset.h lpe-parallel.h @@ -148,6 +151,7 @@ set(live_effects_SRC parameter/powerstrokepointarray.h parameter/random.h parameter/text.h + parameter/fontbutton.h parameter/togglebutton.h parameter/transformedpoint.h parameter/unit.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index eea26184c..3682aa1bd 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -36,6 +36,7 @@ enum EffectType { CONSTRUCT_GRID, PERP_BISECTOR, TANGENT_TO_CURVE, + MEASURE_LINE, MIRROR_SYMMETRY, CIRCLE_3PTS, TRANSFORM_2PTS, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 007a8ca38..792bb5d7a 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -39,6 +39,7 @@ #include "live_effects/lpe-lattice2.h" #include "live_effects/lpe-lattice.h" #include "live_effects/lpe-line_segment.h" +#include "live_effects/lpe-measure-line.h" #include "live_effects/lpe-mirror_symmetry.h" #include "live_effects/lpe-offset.h" #include "live_effects/lpe-parallel.h" @@ -135,6 +136,8 @@ const Util::EnumData<EffectType> LPETypeData[] = { {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"}, +/* 9.93 */ + {MEASURE_LINE, N_("Measure Line"), "measure-line"}, }; const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -303,6 +306,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case TRANSFORM_2PTS: neweffect = static_cast<Effect*> ( new LPETransform2Pts(lpeobj) ); break; + case MEASURE_LINE: + neweffect = static_cast<Effect*> ( new LPEMeasureLine(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; @@ -348,6 +354,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) concatenate_before_pwd2(false), sp_lpe_item(NULL), current_zoom(1), + upd_params(true), sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden @@ -431,7 +438,9 @@ void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/) void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) { } - +void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ +} //secret impl methods (shhhh!) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { @@ -690,7 +699,7 @@ Effect::newWidget() ++it; } - + upd_params = false; return dynamic_cast<Gtk::Widget *>(vbox); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 840f723fa..5ca53486c 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -66,7 +66,7 @@ public: virtual void doAfterEffect (SPLPEItem const* lpeitem); virtual void doOnRemove (SPLPEItem const* lpeitem); - + virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem); void writeParamsToSVG(); virtual void acceptParamPath (SPPath const* param_path); @@ -123,6 +123,7 @@ public: void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); bool apply_to_clippath_and_mask; + bool upd_params; protected: Effect(LivePathEffectObject *lpeobject); diff --git a/src/live_effects/lpe-ellipse_5pts.cpp b/src/live_effects/lpe-ellipse_5pts.cpp index 8f0f8e18a..0371fc313 100644 --- a/src/live_effects/lpe-ellipse_5pts.cpp +++ b/src/live_effects/lpe-ellipse_5pts.cpp @@ -170,7 +170,7 @@ LPEEllipse5Pts::doEffect_path (Geom::PathVector const & path_in) // figure out if we have a slice, guarding against rounding errors - Path p(Geom::Point(cos(0), sin(0))); + Geom::Path p(Geom::Point(cos(0), sin(0))); double end = 2 * M_PI; for (s = 0; s < end; s += M_PI_2) { diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp index 22cdf3c3e..d22007f76 100644 --- a/src/live_effects/lpe-extrude.cpp +++ b/src/live_effects/lpe-extrude.cpp @@ -61,7 +61,7 @@ LPEExtrude::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2 using namespace Geom; // generate connecting lines (the 'sides' of the extrusion) - Path path(Point(0.,0.)); + Geom::Path path(Point(0.,0.)); path.appendNew<Geom::LineSegment>( extrude_vector.getVector() ); Piecewise<D2<SBasis> > connector = path.toPwSb(); diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 221d03ebf..fbc32cf3e 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -94,7 +94,7 @@ findShadowedTime(Geom::Path const &patha, std::vector<Geom::Point> const &pt_and Affine mat = from_basis( T, N, pt_and_dir[0] ); mat = mat.inverse(); - Path p = patha * mat; + Geom::Path p = patha * mat; std::vector<double> times; @@ -477,7 +477,7 @@ LPEKnot::doEffect_path (Geom::PathVector const &path_in) // std::cout<<"fusing first and last component\n"; ++beg_comp; --end_comp; - Path first = gpaths[i0].portion(dom.back()); + Geom::Path first = gpaths[i0].portion(dom.back()); //FIXME: stitching should not be necessary (?!?) first.setStitching(true); first.append(gpaths[i0].portion(dom.front())); diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp new file mode 100644 index 000000000..e8ceb7e51 --- /dev/null +++ b/src/live_effects/lpe-measure-line.cpp @@ -0,0 +1,892 @@ +/* + * Author(s): + * Jabiertxo Arraiza Cenoz <jabier.arraiza@marker.es> + * Some code and ideas migrated from dimensioning.py by + * Johannes B. Rutzmoser, johannes.rutzmoser (at) googlemail (dot) com + * https://github.com/Rutzmoser/inkscape_dimensioning + * Copyright (C) 2014 Author(s) + + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "live_effects/lpe-measure-line.h" +#include <pangomm/fontdescription.h> +#include "ui/dialog/livepatheffect-editor.h" +#include <libnrtype/font-lister.h> +#include "inkscape.h" +#include "xml/node.h" +#include "uri.h" +#include "uri-references.h" +#include "preferences.h" +#include "util/units.h" +#include "svg/svg-length.h" +#include "svg/svg-color.h" +#include "svg/svg.h" +#include "display/curve.h" +#include "2geom/affine.h" +#include "style.h" +#include "sp-root.h" +#include "sp-defs.h" +#include "sp-item.h" +#include "sp-shape.h" +#include "sp-path.h" +#include "desktop.h" +#include "document.h" +#include <iomanip> + +// TODO due to internal breakage in glibmm headers, this must be last: +#include <glibmm/i18n.h> + +using namespace Geom; +namespace Inkscape { +namespace LivePathEffect { + +static const Util::EnumData<OrientationMethod> OrientationMethodData[] = { + { OM_HORIZONTAL, N_("Horizontal"), "horizontal" }, + { OM_VERTICAL, N_("Vertical"), "vertical" }, + { OM_PARALLEL, N_("Parallel"), "parallel" } +}; +static const Util::EnumDataConverter<OrientationMethod> OMConverter(OrientationMethodData, OM_END); + +LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + unit(_("Unit*"), _("Unit"), "unit", &wr, this, "px"), + fontbutton(_("Font*"), _("Font Selector"), "fontbutton", &wr, this), + orientation(_("Orientation"), _("Orientation method"), "orientation", OMConverter, &wr, this, OM_PARALLEL, false), + curve_linked(_("Curve on origin"), _("Curve on origin, set 0 to start/end"), "curve_linked", &wr, this, 1), + precision(_("Precision*"), _("Precision"), "precision", &wr, this, 2), + position(_("Positon*"), _("Positon"), "position", &wr, this, 5), + text_top_bottom(_("Text top/bottom*"), _("Text top/bottom"), "text_top_bottom", &wr, this, 0), + text_right_left(_("Text right/left*"), _("Text right/left"), "text_right_left", &wr, this, 0), + helpline_distance(_("Helpline distance*"), _("Helpline distance"), "helpline_distance", &wr, this, 0.0), + helpline_overlap(_("Helpline overlap*"), _("Helpline overlap"), "helpline_overlap", &wr, this, 2.0), + scale(_("Scale*"), _("Scaling factor"), "scale", &wr, this, 1.0), + format(_("Format*"), _("Format the number ex:{measure} {unit}, return to save"), "format", &wr, this,"measure unit"), + arrows_outside(_("Arrows outside"), _("Arrows outside"), "arrows_outside", &wr, this, false), + flip_side(_("Flip side*"), _("Flip side"), "flip_side", &wr, this, false), + scale_insensitive(_("Scale insensitive*"), _("Scale insensitive to transforms in element, parents..."), "scale_insensitive", &wr, this, true), + local_locale(_("Local Number Format*"), _("Local number format"), "local_locale", &wr, this, true), + line_group_05(_("Line Group 0.5*"), _("Line Group 0.5, from 0.7"), "line_group_05", &wr, this, true), + rotate_anotation(_("Rotate Anotation*"), _("Rotate Anotation"), "rotate_anotation", &wr, this, true), + hide_back(_("Hide if label over*"), _("Hide DIN line if label over"), "hide_back", &wr, this, true), + dimline_format(_("CSS DIN line*"), _("Override CSS to DIN line, return to save, empty to reset to DIM"), "dimline_format", &wr, this,""), + helperlines_format(_("CSS helpers*"), _("Override CSS to helper lines, return to save, empty to reset to DIM"), "helperlines_format", &wr, this,""), + anotation_format(_("CSS anotation*"), _("Override CSS to anotation text, return to save, empty to reset to DIM"), "anotation_format", &wr, this,""), + arrows_format(_("CSS arrows*"), _("Override CSS to arrows, return to save, empty to reset DIM"), "arrows_format", &wr, this,""), + expanded(false) +{ + registerParameter(&unit); + registerParameter(&fontbutton); + registerParameter(&orientation); + registerParameter(&curve_linked); + registerParameter(&precision); + registerParameter(&position); + registerParameter(&text_top_bottom); + registerParameter(&text_right_left); + registerParameter(&helpline_distance); + registerParameter(&helpline_overlap); + registerParameter(&scale); + registerParameter(&format); + registerParameter(&arrows_outside); + registerParameter(&flip_side); + registerParameter(&scale_insensitive); + registerParameter(&local_locale); + registerParameter(&line_group_05); + registerParameter(&rotate_anotation); + registerParameter(&hide_back); + registerParameter(&dimline_format); + registerParameter(&helperlines_format); + registerParameter(&anotation_format); + registerParameter(&arrows_format); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring fontbutton_value = prefs->getString("/live_effects/measure-line/fontbutton"); + if(fontbutton_value.empty()){ + fontbutton_value = "Sans 10"; + } + fontbutton.param_update_default(fontbutton_value); + scale.param_update_default(prefs->getDouble("/live_effects/measure-line/scale", 1.0)); + precision.param_update_default(prefs->getInt("/live_effects/measure-line/precision", 2)); + position.param_update_default(prefs->getDouble("/live_effects/measure-line/position", 10.0)); + text_top_bottom.param_update_default(prefs->getDouble("/live_effects/measure-line/text_top_bottom", 5.0)); + helpline_distance.param_update_default(prefs->getDouble("/live_effects/measure-line/helpline_distance", 0.0)); + helpline_overlap.param_update_default(prefs->getDouble("/live_effects/measure-line/helpline_overlap", 0.0)); + Glib::ustring unit_value = prefs->getString("/live_effects/measure-line/unit"); + if(unit_value.empty()){ + unit_value = "px"; + } + unit.param_update_default(unit_value); + Glib::ustring format_value = prefs->getString("/live_effects/measure-line/format"); + if(format_value.empty()){ + format_value = "{measure}{unit}"; + } + format.param_update_default(format_value); + dimline_format.param_update_default(prefs->getString("/live_effects/measure-line/dimline_format")); + helperlines_format.param_update_default(prefs->getString("/live_effects/measure-line/helperlines_format")); + anotation_format.param_update_default(prefs->getString("/live_effects/measure-line/anotation_format")); + arrows_format.param_update_default(prefs->getString("/live_effects/measure-line/arrows_format")); + flip_side.param_update_default(prefs->getBool("/live_effects/measure-line/flip_side")); + scale_insensitive.param_update_default(prefs->getBool("/live_effects/measure-line/scale_insensitive")); + local_locale.param_update_default(prefs->getBool("/live_effects/measure-line/local_locale")); + line_group_05.param_update_default(prefs->getBool("/live_effects/measure-line/line_group_05")); + rotate_anotation.param_update_default(prefs->getBool("/live_effects/measure-line/rotate_anotation")); + hide_back.param_update_default(prefs->getBool("/live_effects/measure-line/hide_back")); + format.param_hide_canvas_text(); + dimline_format.param_hide_canvas_text(); + helperlines_format.param_hide_canvas_text(); + anotation_format.param_hide_canvas_text(); + arrows_format.param_hide_canvas_text(); + precision.param_set_range(0, 100); + precision.param_set_increments(1, 1); + precision.param_set_digits(0); + precision.param_make_integer(true); + curve_linked.param_set_range(0, 999); + curve_linked.param_set_increments(1, 1); + curve_linked.param_set_digits(0); + curve_linked.param_make_integer(true); + precision.param_make_integer(true); + position.param_set_range(-999999.0, 999999.0); + position.param_set_increments(1, 1); + position.param_set_digits(2); + text_top_bottom.param_set_range(-999999.0, 999999.0); + text_top_bottom.param_set_increments(1, 1); + text_top_bottom.param_set_digits(2); + text_right_left.param_set_range(-999999.0, 999999.0); + text_right_left.param_set_increments(1, 1); + text_right_left.param_set_digits(2); + helpline_distance.param_set_range(-999999.0, 999999.0); + helpline_distance.param_set_increments(1, 1); + helpline_distance.param_set_digits(2); + helpline_overlap.param_set_range(-999999.0, 999999.0); + helpline_overlap.param_set_increments(1, 1); + helpline_overlap.param_set_digits(2); + erase = true; +} + +LPEMeasureLine::~LPEMeasureLine() {} + +void swap(Geom::Point &A, Geom::Point &B){ + Geom::Point tmp = A; + A = B; + B = tmp; +} +void +LPEMeasureLine::doOnApply(SPLPEItem const* lpeitem) +{ + if (!SP_IS_SHAPE(lpeitem)) { + g_warning("LPE measure line can only be applied to shapes (not groups)."); + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + item->removeCurrentPathEffect(false); + } +} + +void +LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *node = NULL; + if (elemref = SVGElemRef->getObject()) { + node = elemref->getRepr(); + if (!this->isVisible()) { + node->setAttribute("style", "display:none"); + } else { + node->setAttribute("style", NULL); + } + } + Inkscape::URI SVGElem_uri2(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri2); + if (elemref = SVGElemRef->getObject()) { + node = elemref->getRepr(); + if (!this->isVisible()) { + node->setAttribute("style", "display:none"); + } else { + node->setAttribute("style", NULL); + } + } + Inkscape::URI SVGElem_uri3(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri3); + if (elemref = SVGElemRef->getObject()) { + node = elemref->getRepr(); + if (!this->isVisible()) { + node->setAttribute("style", "display:none"); + } else { + node->setAttribute("style", NULL); + } + } + Inkscape::URI SVGElem_uri4(((Glib::ustring)"#" + (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri4); + if (elemref = SVGElemRef->getObject()) { + node = elemref->getRepr(); + if (!this->isVisible()) { + node->setAttribute("style", "display:none"); + } else { + node->setAttribute("style", NULL); + } + } + Inkscape::URI SVGElem_uri5(((Glib::ustring)"#" + (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri5); + if (elemref = SVGElemRef->getObject()) { + node = elemref->getRepr(); + if (!this->isVisible()) { + node->setAttribute("style", "display:none"); + } else { + node->setAttribute("style", NULL); + } + } + } +} + +void +LPEMeasureLine::createArrowMarker(Glib::ustring mode) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + mode).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *arrow = NULL; + if (!(elemref = SVGElemRef->getObject())) { + arrow = xml_doc->createElement("svg:marker"); + arrow->setAttribute("id", mode.c_str()); + arrow->setAttribute("inkscape:stockid", mode.c_str()); + arrow->setAttribute("orient", "auto"); + arrow->setAttribute("refX", "0.0"); + arrow->setAttribute("refY", "0.0"); + arrow->setAttribute("style", "overflow:visible"); + arrow->setAttribute("sodipodi:insensitive", "true"); + /* Create <path> */ + Inkscape::XML::Node *arrow_path = xml_doc->createElement("svg:path"); + if (mode == (Glib::ustring)"ArrowDIN-start") { + arrow_path->setAttribute("d", "M -8,0 8,-2.11 8,2.11 z"); + } else if (mode == (Glib::ustring)"ArrowDIN-end") { + arrow_path->setAttribute("d", "M 8,0 -8,2.11 -8,-2.11 z"); + } else if (mode == (Glib::ustring)"ArrowDINout-start") { + arrow_path->setAttribute("d", "M 0,0 -16,2.11 -16,0.5 -26,0.5 -26,-0.5 -16,-0.5 -16,-2.11 z"); + } else { + arrow_path->setAttribute("d", "M 0,0 16,2.11 16,0.5 26,0.5 26,-0.5 16,-0.5 16,-2.11 z"); + } + + arrow_path->setAttribute("id", (mode + (Glib::ustring)"_path").c_str()); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property (css, "fill","#000000"); + sp_repr_css_set_property (css, "stroke","none" ); + sp_repr_css_attr_add_from_string(css, arrows_format.param_getSVGValue()); + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + arrow_path->setAttribute("style", css_str.c_str()); + arrow->addChild(arrow_path, NULL); + Inkscape::GC::release(arrow_path); + elemref = SP_OBJECT(desktop->getDocument()->getDefs()->appendChildRepr(arrow)); + Inkscape::GC::release(arrow); + } else { + Inkscape::XML::Node *arrow= elemref->getRepr(); + if (arrow) { + arrow->setAttribute("sodipodi:insensitive", "true"); + Inkscape::XML::Node *arrow_data = arrow->firstChild(); + if (arrow_data) { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property (css, "fill","#000000"); + sp_repr_css_set_property (css, "stroke","none" ); + sp_repr_css_attr_add_from_string(css, arrows_format.param_getSVGValue()); + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + arrow_data->setAttribute("style", css_str.c_str()); + } + } + } + } +} + +void +LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Node *rtext = NULL; + double doc_w = desktop->getDocument()->getRoot()->width.value; + Geom::Scale scale = desktop->getDocument()->getDocumentScale(); + SPNamedView *nv = desktop->getNamedView(); + Glib::ustring display_unit = nv->display_units->abbr; + if (display_unit.empty()) { + display_unit = "px"; + } + //only check constrain viewbox on X + doc_scale = Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units ); + if( doc_scale > 0 ) { + doc_scale= 1.0/doc_scale; + } else { + doc_scale = 1.0; + } + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *rtspan = NULL; + + if (elemref = SVGElemRef->getObject()) { + if (remove) { + elemref->deleteObject(); + return; + } + pos = pos - Point::polar(angle, text_right_left); + rtext = elemref->getRepr(); + sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); + sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); + rtext->setAttribute("sodipodi:insensitive", "true"); + } else { + if (remove) { + return; + } + rtext = xml_doc->createElement("svg:text"); + rtext->setAttribute("xml:space", "preserve"); + rtext->setAttribute("id", ( (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + rtext->setAttribute("sodipodi:insensitive", "true"); + pos = pos - Point::polar(angle, text_right_left); + sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); + sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); + rtspan = xml_doc->createElement("svg:tspan"); + rtspan->setAttribute("sodipodi:role", "line"); + } + gchar * transform; + Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse()); + angle = std::fmod(angle, 2*M_PI); + if (angle < 0) angle += 2*M_PI; + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { + angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); + if (angle < 0) angle += 2*M_PI; + } + affine *= Geom::Rotate(angle); + affine *= Geom::Translate(pos); + if (rotate_anotation) { + transform = sp_svg_transform_write(affine); + } else { + transform = NULL; + } + rtext->setAttribute("transform", transform); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, anotation_format.param_getSVGValue()); + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->fill_css( css, (Glib::ustring)fontbutton.param_getSVGValue() ); + std::stringstream font_size; + font_size.imbue(std::locale::classic()); + font_size << fontsize << "pt"; + + sp_repr_css_set_property (css, "font-size",font_size.str().c_str()); + sp_repr_css_set_property (css, "line-height","125%"); + sp_repr_css_set_property (css, "letter-spacing","0"); + sp_repr_css_set_property (css, "word-spacing", "0"); + sp_repr_css_set_property (css, "text-align", "center"); + sp_repr_css_set_property (css, "text-anchor", "middle"); + sp_repr_css_set_property (css, "fill", "#000000"); + sp_repr_css_set_property (css, "fill-opacity", "1"); + sp_repr_css_set_property (css, "stroke", "none"); + sp_repr_css_attr_add_from_string(css, anotation_format.param_getSVGValue()); + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + if (!rtspan) { + rtspan = rtext->firstChild(); + } + rtext->setAttribute("style", css_str.c_str()); + rtspan->setAttribute("style", NULL); + sp_repr_css_attr_unref (css); + if (!elemref) { + rtext->addChild(rtspan, NULL); + Inkscape::GC::release(rtspan); + } + length = Inkscape::Util::Quantity::convert(length / doc_scale, display_unit.c_str(), unit.get_abbreviation()); + std::stringstream length_str; + length_str.precision(precision); + length_str.setf(std::ios::fixed, std::ios::floatfield); + if (local_locale) { + length_str.imbue(std::locale("")); + } else { + length_str.imbue(std::locale::classic()); + } + length_str << std::fixed << length; + Glib::ustring label_value = Glib::ustring(format.param_getSVGValue()); + size_t s = label_value.find((Glib::ustring)"{measure}",0); + if(s < label_value.length()) { + label_value.replace(s,s+9,length_str.str()); + } + s = label_value.find((Glib::ustring)"{unit}",0); + if(s < label_value.length()) { + label_value.replace(s,s+6,unit.get_abbreviation()); + } + Inkscape::XML::Node *rstring = NULL; + if (!elemref) { + rstring = xml_doc->createTextNode(label_value.c_str()); + rtspan->addChild(rstring, NULL); + Inkscape::GC::release(rstring); + } else { + rstring = rtspan->firstChild(); + rstring->setContent(label_value.c_str()); + } + if (!elemref) { + elemref = SP_OBJECT(desktop->currentLayer()->appendChildRepr(rtext)); + Inkscape::GC::release(rtext); + } + Inkscape::XML::Node *tmp_node = rtext->duplicate(xml_doc); + affine = Geom::Affine(Geom::Scale(1.4)); + tmp_node->setAttribute("transform", sp_svg_transform_write(affine)); + SPObject * tmp_obj = SP_OBJECT(desktop->currentLayer()->appendChildRepr(tmp_node)); + Inkscape::GC::release(tmp_node); + tmp_obj->updateRepr(); + Geom::OptRect bounds = SP_ITEM(tmp_obj)->bounds(SPItem::GEOMETRIC_BBOX); + if (bounds) { + anotation_width = bounds->width(); + } + tmp_obj->deleteObject(); + } +} + +void +LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, Glib::ustring id, bool main, bool overflow, bool remove, bool arrows) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *line = NULL; + if (!main) { + Geom::Ray ray(start, end); + Geom::Coord angle = ray.angle(); + start = start + Point::polar(angle, helpline_distance ); + end = end + Point::polar(angle, helpline_overlap ); + } + Geom::PathVector line_pathv; + if (main && std::abs(text_top_bottom) < fontsize/1.5 && hide_back && !overflow){ + Geom::Path line_path; + double k = 0; + if (flip_side) { + k = (Geom::distance(start,end)/2.0) + arrow_gap - (anotation_width/2.0); + } else { + k = (Geom::distance(start,end)/2.0) - arrow_gap - (anotation_width/2.0); + } + if (Geom::distance(start,end) < anotation_width){ + return; + } + Geom::Ray ray(end, start); + Geom::Coord angle = ray.angle(); + line_path.start(start); + line_path.appendNew<Geom::LineSegment>(start - Point::polar(angle, k)); + line_pathv.push_back(line_path); + line_path.clear(); + line_path.start(end + Point::polar(angle, k)); + line_path.appendNew<Geom::LineSegment>(end); + line_pathv.push_back(line_path); + } else { + Geom::Path line_path; + line_path.start(start); + line_path.appendNew<Geom::LineSegment>(end); + line_pathv.push_back(line_path); + } + + if (elemref = SVGElemRef->getObject()) { + if (remove) { + elemref->deleteObject(); + return; + } + line = elemref->getRepr(); + + gchar * line_str = sp_svg_write_path( line_pathv ); + line->setAttribute("d" , line_str); + } else { + if (remove) { + return; + } + line = xml_doc->createElement("svg:path"); + line->setAttribute("id", id.c_str()); + gchar * line_str = sp_svg_write_path( line_pathv ); + line->setAttribute("d" , line_str); + } + line->setAttribute("sodipodi:insensitive", "true"); + line_pathv.clear(); + + Glib::ustring style = (Glib::ustring)"stroke:#000000;fill:none;"; + if (overflow && !arrows) { + line->setAttribute("inkscape:label", "downline"); + } else if (main) { + line->setAttribute("inkscape:label", "dinline"); + if (arrows_outside) { + style = style + (Glib::ustring)"marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);"; + } else { + style = style + (Glib::ustring)"marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);"; + } + } else { + line->setAttribute("inkscape:label", "dinhelpline"); + } + std::stringstream stroke_w; + stroke_w.imbue(std::locale::classic()); + if (line_group_05) { + double stroke_width = Inkscape::Util::Quantity::convert(0.25 / doc_scale, "mm", display_unit.c_str()); + stroke_w << stroke_width; + style = style + (Glib::ustring)"stroke-width:" + (Glib::ustring)stroke_w.str(); + } else { + double stroke_width = Inkscape::Util::Quantity::convert(0.35 / doc_scale, "mm", display_unit.c_str()); + stroke_w << stroke_width; + style = style + (Glib::ustring)"stroke-width:" + (Glib::ustring)stroke_w.str(); + } + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, style.c_str()); + if (main) { + sp_repr_css_attr_add_from_string(css, dimline_format.param_getSVGValue()); + } else { + sp_repr_css_attr_add_from_string(css, helperlines_format.param_getSVGValue()); + } + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + line->setAttribute("style", css_str.c_str()); + if (!elemref) { + elemref = SP_OBJECT(desktop->currentLayer()->appendChildRepr(line)); + Inkscape::GC::release(line); + } + } +} + +void +LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) +{ + SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem); + SPPath *sp_path = dynamic_cast<SPPath *>(splpeitem); + if (sp_path) { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem)->parent, SP_OBJECT(doc->getRoot())); + double parents_scale = (affinetransform.inverse().expansionX() + affinetransform.inverse().expansionY()) / 2.0; + + Geom::PathVector pathvector = sp_path->get_original_curve()->get_pathvector(); + pathvector *= affinetransform; + if (arrows_outside) { + createArrowMarker((Glib::ustring)"ArrowDINout-start"); + createArrowMarker((Glib::ustring)"ArrowDINout-end"); + } else { + createArrowMarker((Glib::ustring)"ArrowDIN-start"); + createArrowMarker((Glib::ustring)"ArrowDIN-end"); + } + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + if (((Glib::ustring)format.param_getSVGValue()).empty()) { + format.param_setValue((Glib::ustring)"{measure}{unit}"); + this->upd_params = true; + } + size_t ncurves = pathvector.curveCount(); + curve_linked.param_set_range(0, ncurves); + Geom::Point start = pathvector.initialPoint(); + Geom::Point end = pathvector.finalPoint(); + if (curve_linked) { //!0 + start = pathvector.pointAt(curve_linked -1); + end = pathvector.pointAt(curve_linked); + } + Geom::Point hstart = start; + Geom::Point hend = end; + bool remove = false; + if (Geom::are_near(hstart, hend)) { + remove = true; + } + if (orientation == OM_VERTICAL) { + Coord xpos = std::max(hstart[Geom::X],hend[Geom::X]); + if (flip_side) { + xpos = std::min(hstart[Geom::X],hend[Geom::X]); + } + hstart[Geom::X] = xpos; + hend[Geom::X] = xpos; + if (hstart[Geom::Y] > hend[Geom::Y]) { + swap(hstart,hend); + swap(start,end); + } + if (Geom::are_near(hstart[Geom::Y], hend[Geom::Y])) { + remove = true; + } + } + if (orientation == OM_HORIZONTAL) { + Coord ypos = std::max(hstart[Geom::Y],hend[Geom::Y]); + if (flip_side) { + ypos = std::min(hstart[Geom::Y],hend[Geom::Y]); + } + hstart[Geom::Y] = ypos; + hend[Geom::Y] = ypos; + if (hstart[Geom::X] < hend[Geom::X]) { + swap(hstart,hend); + swap(start,end); + } + if (Geom::are_near(hstart[Geom::X], hend[Geom::X])) { + remove = true; + } + } + double length = Geom::distance(hstart,hend) * scale; + Geom::Point pos = Geom::middle_point(hstart,hend); + Geom::Ray ray(hstart,hend); + Geom::Coord angle = ray.angle(); + if (flip_side) { + angle = std::fmod(angle + rad_from_deg(180), 2*M_PI); + if (angle < 0) angle += 2*M_PI; + } + //We get the font size to offset the text to the middle + Pango::FontDescription fontdesc((Glib::ustring)fontbutton.param_getSVGValue()); + fontsize = fontdesc.get_size()/(double)Pango::SCALE; + fontsize *= desktop->doc()->getRoot()->c2p.inverse().expansionX(); + Geom::Coord angle_cross = std::fmod(angle + rad_from_deg(90), 2*M_PI); + if (angle_cross < 0) angle_cross += 2*M_PI; + angle = std::fmod(angle, 2*M_PI); + if (angle < 0) angle += 2*M_PI; + if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { + pos = pos - Point::polar(angle_cross, (position - text_top_bottom) + fontsize/2.5); + } else { + pos = pos - Point::polar(angle_cross, (position + text_top_bottom) - fontsize/2.5); + } + if (scale_insensitive) { + length *= parents_scale; + } + createTextLabel(pos, length, angle, remove); + bool overflow = false; + if ((anotation_width/2) + std::abs(text_right_left) > Geom::distance(start,end)/2.0) { + Geom::Point sstart = end - Point::polar(angle_cross, position); + Geom::Point send = end - Point::polar(angle_cross, position); + if (text_right_left < 0 && flip_side || text_right_left > 0 && !flip_side) { + sstart = start - Point::polar(angle_cross, position); + send = start - Point::polar(angle_cross, position); + } + Geom::Point prog_end = Geom::Point(); + if (std::abs(text_top_bottom) < fontsize/1.5 && hide_back) { + if (text_right_left > 0 ) { + prog_end = sstart - Point::polar(angle, std::abs(text_right_left) - (anotation_width/1.9) - (Geom::distance(start,end)/2.0)); + } else { + prog_end = sstart + Point::polar(angle, std::abs(text_right_left) - (anotation_width/1.9) - (Geom::distance(start,end)/2.0)); + } + } else { + if (text_right_left > 0 ) { + prog_end = sstart - Point::polar(angle,(anotation_width/2) + std::abs(text_right_left) - (Geom::distance(start,end)/2.0)); + } else { + prog_end = sstart + Point::polar(angle,(anotation_width/2) + std::abs(text_right_left) - (Geom::distance(start,end)/2.0)); + } + } + overflow = true; + createLine(sstart, prog_end, (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id"), true, overflow, false, false); + } else { + //erase it + createLine(Geom::Point(),Geom::Point(), (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id"), true, overflow, true, false); + } + //LINE + arrow_gap = 8 * Inkscape::Util::Quantity::convert(0.35 / doc_scale, "mm", display_unit.c_str()); + if (line_group_05) { + arrow_gap = 8 * Inkscape::Util::Quantity::convert(0.25 / doc_scale, "mm", display_unit.c_str()); + } + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string(css, dimline_format.param_getSVGValue()); + setlocale(LC_NUMERIC, std::locale::classic().name().c_str()); + double width_line = atof(sp_repr_css_property(css,"stroke-width","-1")); + setlocale(LC_NUMERIC, std::locale("").name().c_str()); + if (width_line > -0.0001) { + arrow_gap = 8 * Inkscape::Util::Quantity::convert(width_line/ doc_scale, "mm", display_unit.c_str()); + } + if (flip_side) { + arrow_gap *= -1; + } + hstart = hstart - Point::polar(angle_cross, position); + Glib::ustring id = (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id"); + createLine(start, hstart, id, false, false, remove); + hend = hend - Point::polar(angle_cross, position); + id = (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id"); + createLine(end, hend, id, false, false, remove); + if (!arrows_outside) { + hstart = hstart + Point::polar(angle, arrow_gap); + hend = hend - Point::polar(angle, arrow_gap ); + } + id = (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id"); + createLine(hstart, hend, id, true, overflow, remove, true); + } + } +} + +void LPEMeasureLine::doOnRemove (SPLPEItem const* lpeitem) +{ + if (!erase) return; + + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + Inkscape::URI SVGElem_uri2(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri2); + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + Inkscape::URI SVGElem_uri3(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri3); + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + Inkscape::URI SVGElem_uri4(((Glib::ustring)"#" + (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri4); + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + Inkscape::URI SVGElem_uri5(((Glib::ustring)"#" + (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri5); + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + } +} + +void LPEMeasureLine::toObjects() +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + if (elemref = SVGElemRef->getObject()) { + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + } + Inkscape::URI SVGElem_uri2(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri2); + if (elemref = SVGElemRef->getObject()) { + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + } + Inkscape::URI SVGElem_uri3(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri3); + if (elemref = SVGElemRef->getObject()) { + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + } + Inkscape::URI SVGElem_uri4(((Glib::ustring)"#" + (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri4); + if (elemref = SVGElemRef->getObject()) { + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + } + Inkscape::URI SVGElem_uri5(((Glib::ustring)"#" + (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + SVGElemRef->attach(SVGElem_uri5); + if (elemref = SVGElemRef->getObject()) { + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + } + erase = false; + sp_lpe_item->removeCurrentPathEffect(true); + //TODO: find better way to refresh effect list + if (SP_IS_OBJECT(sp_lpe_item)){ + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); + selection->remove(SP_OBJECT(sp_lpe_item)); + selection->add(SP_OBJECT(sp_lpe_item)); + } + } +} + +Gtk::Widget *LPEMeasureLine::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + + std::vector<Parameter *>::iterator it = param_vector.begin(); + Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button2 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vbox_expander->set_border_width(0); + vbox_expander->set_spacing(2); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget()); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + if (param->param_key != "dimline_format" && + param->param_key != "helperlines_format" && + param->param_key != "arrows_format" && + param->param_key != "anotation_format") { + vbox->pack_start(*widg, true, true, 2); + } else { + vbox_expander->pack_start(*widg, true, true, 2); + } + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + Gtk::Button *save_default = Gtk::manage(new Gtk::Button(Glib::ustring(_("Save '*' as default")))); + save_default->signal_clicked().connect(sigc::mem_fun(*this, &LPEMeasureLine::saveDefault)); + button1->pack_start(*save_default, true, true, 2); + Gtk::Button *remove = Gtk::manage(new Gtk::Button(Glib::ustring(_("Convert to objects")))); + remove->signal_clicked().connect(sigc::mem_fun(*this, &LPEMeasureLine::toObjects)); + button2->pack_start(*remove, true, true, 2); + expander = Gtk::manage(new Gtk::Expander(Glib::ustring(_("Show DIM CSS style override")))); + expander->add(*vbox_expander); + expander->set_expanded(expanded); + expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPEMeasureLine::onExpanderChanged) ); + vbox->pack_start(*expander, true, true, 2); + vbox->pack_start(*button1, true, true, 2); + vbox->pack_start(*button2, true, true, 2); + return dynamic_cast<Gtk::Widget *>(vbox); +} + +void +LPEMeasureLine::onExpanderChanged() +{ + expanded = expander->get_expanded(); + if(expanded) { + expander->set_label (Glib::ustring(_("Hide DIM CSS style override"))); + } else { + expander->set_label (Glib::ustring(_("Show DIM CSS style override"))); + } +} + +Geom::PathVector +LPEMeasureLine::doEffect_path(Geom::PathVector const &path_in) +{ + return path_in; +} + +void +LPEMeasureLine::saveDefault() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/live_effects/measure-line/fontbutton", (Glib::ustring)fontbutton.param_getSVGValue()); + prefs->setDouble("/live_effects/measure-line/scale", scale); + prefs->setInt("/live_effects/measure-line/precision", precision); + prefs->setDouble("/live_effects/measure-line/position", position); + prefs->setDouble("/live_effects/measure-line/text_top_bottom", text_top_bottom); + prefs->setDouble("/live_effects/measure-line/helpline_distance", helpline_distance); + prefs->setDouble("/live_effects/measure-line/helpline_overlap", helpline_overlap); + prefs->setString("/live_effects/measure-line/unit", (Glib::ustring)unit.get_abbreviation()); + prefs->setString("/live_effects/measure-line/format", (Glib::ustring)format.param_getSVGValue()); + prefs->setString("/live_effects/measure-line/dimline_format", (Glib::ustring)dimline_format.param_getSVGValue()); + prefs->setString("/live_effects/measure-line/helperlines_format", (Glib::ustring)helperlines_format.param_getSVGValue()); + prefs->setString("/live_effects/measure-line/anotation_format", (Glib::ustring)anotation_format.param_getSVGValue()); + prefs->setString("/live_effects/measure-line/arrows_format", (Glib::ustring)arrows_format.param_getSVGValue()); + prefs->setBool("/live_effects/measure-line/flip_side", flip_side); + prefs->setBool("/live_effects/measure-line/scale_insensitive", scale_insensitive); + prefs->setBool("/live_effects/measure-line/local_locale", local_locale); + prefs->setBool("/live_effects/measure-line/line_group_05", line_group_05); + prefs->setBool("/live_effects/measure-line/rotate_anotation", rotate_anotation); + prefs->setBool("/live_effects/measure-line/hide_back", hide_back); +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offset:((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 : diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h new file mode 100644 index 000000000..2fab9dbb9 --- /dev/null +++ b/src/live_effects/lpe-measure-line.h @@ -0,0 +1,103 @@ +#ifndef INKSCAPE_LPE_MEASURE_LINE_H +#define INKSCAPE_LPE_MEASURE_LINE_H + +/* + * Author(s): + * Jabiertxo Arraiza Cenoz <jabier.arraiza@marker.es> + * + * Copyright (C) 2014 Author(s) + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/enum.h" +#include "live_effects/parameter/fontbutton.h" +#include "live_effects/parameter/text.h" +#include "live_effects/parameter/unit.h" +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/originalpath.h" +#include <libnrtype/font-lister.h> +#include <2geom/angle.h> +#include <2geom/ray.h> +#include <2geom/point.h> + +namespace Inkscape { +namespace LivePathEffect { + +enum OrientationMethod { + OM_HORIZONTAL, + OM_VERTICAL, + OM_PARALLEL, + OM_END +}; + +class LPEMeasureLine : public Effect { +public: + LPEMeasureLine(LivePathEffectObject *lpeobject); + virtual ~LPEMeasureLine(); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doOnRemove (SPLPEItem const* lpeitem); + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); + virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in); + void createLine(Geom::Point start,Geom::Point end,Glib::ustring id, bool main, bool overflow, bool remove, bool arrows = false); + void createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove); + void onExpanderChanged(); + void toObjects(); + void createArrowMarker(Glib::ustring mode); + void saveDefault(); + virtual Gtk::Widget *newWidget(); +private: + UnitParam unit; + FontButtonParam fontbutton; + EnumParam<OrientationMethod> orientation; + ScalarParam curve_linked; + ScalarParam precision; + ScalarParam position; + ScalarParam text_top_bottom; + ScalarParam text_right_left; + ScalarParam helpline_distance; + ScalarParam helpline_overlap; + ScalarParam scale; + TextParam format; + BoolParam arrows_outside; + BoolParam flip_side; + BoolParam scale_insensitive; + BoolParam local_locale; + BoolParam line_group_05; + BoolParam rotate_anotation; + BoolParam hide_back; + TextParam dimline_format; + TextParam helperlines_format; + TextParam anotation_format; + TextParam arrows_format; + Glib::ustring display_unit; + bool expanded; + Gtk::Expander * expander; + double doc_scale; + double fontsize; + double anotation_width; + double arrow_gap; + bool erase; +/* Geom::Affine affine_over;*/ + LPEMeasureLine(const LPEMeasureLine &); + LPEMeasureLine &operator=(const LPEMeasureLine &); + +}; + +} //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 : diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 0de668847..329a00756 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -609,11 +609,12 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in) // find time values for which x lies outside path domain // and only take portion of x and y that lies within those time values std::vector< double > rtsmin = roots (x - pwd2_in.domain().min()); - std::vector< double > rtsmax = roots (x - pwd2_in.domain().max()); + std::vector< double > rtsmax = roots (x + pwd2_in.domain().max()); if ( !rtsmin.empty() && !rtsmax.empty() ) { x = portion(x, rtsmin.at(0), rtsmax.at(0)); y = portion(y, rtsmin.at(0), rtsmax.at(0)); } + LineJoinType jointype = static_cast<LineJoinType>(linejoin_type.get_value()); Piecewise<D2<SBasis> > pwd2_out = compose(pwd2_in,x) + y*compose(n,x); diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 2b03a4bb2..78db622f2 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -87,7 +87,6 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - point_a = Point(boundingbox_X.min(), boundingbox_Y.middle()); point_b = Point(boundingbox_X.max(), boundingbox_Y.middle()); SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem); diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h index 2e62707e3..087223947 100644 --- a/src/live_effects/lpeobject.h +++ b/src/live_effects/lpeobject.h @@ -38,8 +38,14 @@ public: /* Note that the returned pointer can be NULL in a valid LivePathEffectObject contained in a valid list of lpeobjects in an lpeitem! * So one should always check whether the returned value is NULL or not */ - Inkscape::LivePathEffect::Effect * get_lpe() { return lpe; }; - Inkscape::LivePathEffect::Effect const * get_lpe() const { return lpe; }; + Inkscape::LivePathEffect::Effect * get_lpe() { + if(this) return lpe; + else return NULL; + } + Inkscape::LivePathEffect::Effect const * get_lpe() const { + if(this) return lpe; + else return NULL; + }; Inkscape::LivePathEffect::Effect *lpe; // this can be NULL in a valid LivePathEffectObject diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 9ecadbdeb..af99ef362 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -36,6 +36,12 @@ BoolParam::param_set_default() param_setValue(defvalue); } +void +BoolParam::param_update_default(bool const default_value) +{ + defvalue = default_value; +} + bool BoolParam::param_readSVGValue(const gchar * strvalue) { diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index 403dd0b87..7ad8a9368 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -36,7 +36,7 @@ public: void param_setValue(bool newvalue); virtual void param_set_default(); - + void param_update_default(bool const default_value); bool get_value() const { return value; }; inline operator bool() const { return value; }; diff --git a/src/live_effects/parameter/enum.h b/src/live_effects/parameter/enum.h index 2340663c3..dbfc68623 100644 --- a/src/live_effects/parameter/enum.h +++ b/src/live_effects/parameter/enum.h @@ -27,12 +27,14 @@ public: const Util::EnumDataConverter<E>& c, Inkscape::UI::Widget::Registry* wr, Effect* effect, - E default_value) + E default_value, + bool sort = true) : Parameter(label, tip, key, wr, effect) { enumdataconv = &c; defvalue = default_value; value = defvalue; + sorted = sort; }; virtual ~EnumParam() { }; @@ -40,12 +42,11 @@ public: virtual Gtk::Widget * param_newWidget() { Inkscape::UI::Widget::RegisteredEnum<E> *regenum = Gtk::manage ( new Inkscape::UI::Widget::RegisteredEnum<E>( param_label, param_tooltip, - param_key, *enumdataconv, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); + param_key, *enumdataconv, *param_wr, param_effect->getRepr(), param_effect->getSPDoc(), sorted ) ); regenum->set_active_by_id(value); regenum->combobox()->setProgrammatically = false; regenum->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change enumeration parameter")); - return dynamic_cast<Gtk::Widget *> (regenum); }; @@ -86,6 +87,7 @@ private: E value; E defvalue; + bool sorted; const Util::EnumDataConverter<E> * enumdataconv; }; diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp new file mode 100644 index 000000000..ff8ab76a0 --- /dev/null +++ b/src/live_effects/parameter/fontbutton.cpp @@ -0,0 +1,92 @@ +/* + * Authors: + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/registered-widget.h" +#include "live_effects/parameter/fontbutton.h" +#include "live_effects/effect.h" +#include "ui/widget/font-button.h" +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "verbs.h" + +#include <glibmm/i18n.h> + +namespace Inkscape { + +namespace LivePathEffect { + +FontButtonParam::FontButtonParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect, const Glib::ustring default_value ) + : Parameter(label, tip, key, wr, effect), + value(default_value), + defvalue(default_value) +{ +} + +void +FontButtonParam::param_set_default() +{ + param_setValue(defvalue); +} +void +FontButtonParam::param_update_default(const Glib::ustring default_value){ + defvalue = default_value; +} + +bool +FontButtonParam::param_readSVGValue(const gchar * strvalue) +{ + Inkscape::SVGOStringStream os; + os << strvalue; + param_setValue((Glib::ustring)os.str()); + return true; +} + +gchar * +FontButtonParam::param_getSVGValue() const +{ + return g_strdup(value.c_str()); +} + +Gtk::Widget * +FontButtonParam::param_newWidget() +{ + Inkscape::UI::Widget::RegisteredFontButton * fontbuttonwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredFontButton( param_label, + param_tooltip, + param_key, + *param_wr, + param_effect->getRepr(), + param_effect->getSPDoc() ) ); + Glib::ustring fontspec = param_getSVGValue(); + fontbuttonwdg->setValue( fontspec); + fontbuttonwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change font button parameter")); + param_effect->upd_params = false; + return dynamic_cast<Gtk::Widget *> (fontbuttonwdg); +} + +void +FontButtonParam::param_setValue(const Glib::ustring newvalue) +{ + value = newvalue; +} + +} /* 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 : diff --git a/src/live_effects/parameter/fontbutton.h b/src/live_effects/parameter/fontbutton.h new file mode 100644 index 000000000..387ad130b --- /dev/null +++ b/src/live_effects/parameter/fontbutton.h @@ -0,0 +1,62 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_FONT_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_FONT_H + +/* + * Inkscape::LivePathEffectParameters + * + * Authors: + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include <glib.h> +#include <gtkmm.h> +#include "live_effects/parameter/parameter.h" + +namespace Inkscape { + +namespace LivePathEffect { + +class FontButtonParam : public Parameter { +public: + FontButtonParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + const Glib::ustring default_value = ""); + virtual ~FontButtonParam() {} + + virtual Gtk::Widget * param_newWidget(); + virtual bool param_readSVGValue(const gchar * strvalue); + void param_update_default(const Glib::ustring defvalue); + virtual gchar * param_getSVGValue() const; + + void param_setValue(const Glib::ustring newvalue); + + virtual void param_set_default(); + + const Glib::ustring get_value() const { return defvalue; }; + +private: + FontButtonParam(const FontButtonParam&); + FontButtonParam& operator=(const FontButtonParam&); + Glib::ustring value; + Glib::ustring defvalue; + +}; + +} //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 : diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index d4e213948..befac4df1 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -4,11 +4,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "ui/widget/registered-widget.h" -#include <glibmm/i18n.h> -#include "live_effects/parameter/parameter.h" #include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" #include "svg/svg.h" #include "xml/repr.h" @@ -16,6 +14,8 @@ #include "verbs.h" +#include <glibmm/i18n.h> + #define noLPEREALPARAM_DEBUG namespace Inkscape { @@ -101,9 +101,16 @@ ScalarParam::param_set_default() param_set_value(defvalue); } +void +ScalarParam::param_update_default(gdouble default_value) +{ + defvalue = default_value; +} + void ScalarParam::param_set_value(gdouble val) { + param_effect->upd_params = true; value = val; if (integer) value = round(value); @@ -121,7 +128,7 @@ ScalarParam::param_set_range(gdouble min, gdouble max) // Once again, in gtk2, this is not a problem. But in gtk3, // widgets get allocated the amount of size they ask for, // leading to excessively long widgets. - + param_effect->upd_params = true; if (min >= -SCALARPARAM_G_MAXDOUBLE) { this->min = min; } else { @@ -130,15 +137,15 @@ ScalarParam::param_set_range(gdouble min, gdouble max) if (max <= SCALARPARAM_G_MAXDOUBLE) { this->max = max; } else { - this->max = SCALARPARAM_G_MAXDOUBLE; + this->max = SCALARPARAM_G_MAXDOUBLE; } - param_set_value(value); // reset value to see whether it is in ranges } void ScalarParam::param_make_integer(bool yes) { + param_effect->upd_params = true; integer = yes; digits = 0; inc_step = 1; @@ -169,6 +176,7 @@ ScalarParam::param_newWidget() if(!overwrite_widget){ rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } + param_effect->upd_params = false; return dynamic_cast<Gtk::Widget *> (rsu); } else { return NULL; @@ -178,12 +186,14 @@ ScalarParam::param_newWidget() void ScalarParam::param_set_digits(unsigned digits) { + param_effect->upd_params = true; this->digits = digits; } void ScalarParam::param_set_increments(double step, double page) { + param_effect->upd_params = true; inc_step = step; inc_page = page; } diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index 0ef28650a..3658bded8 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -12,6 +12,7 @@ #include <glibmm/ustring.h> #include <2geom/forward.h> #include <2geom/pathvector.h> +#include "ui/widget/registered-widget.h" // In gtk2, this wasn't an issue; we could toss around // G_MAXDOUBLE and not worry about size allocations. But @@ -110,12 +111,12 @@ public: virtual gchar * param_getSVGValue() const; virtual void param_set_default(); + void param_update_default(gdouble default_value); void param_set_value(gdouble val); void param_make_integer(bool yes = true); void param_set_range(gdouble min, gdouble max); void param_set_digits(unsigned digits); void param_set_increments(double step, double page); - void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; }; void param_overwrite_widget(bool overwrite_widget); diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index ca3471b29..3442fd851 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -4,7 +4,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "ui/widget/registered-widget.h" #include "live_effects/parameter/point.h" #include "live_effects/effect.h" #include "svg/svg.h" @@ -30,7 +29,8 @@ PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip, : Parameter(label, tip, key, wr, effect), defvalue(default_value), liveupdate(live_update), - knoth(NULL) + knoth(NULL), + _pointwdg(NULL) { knot_shape = SP_KNOT_SHAPE_DIAMOND; knot_mode = SP_KNOT_MODE_XOR; @@ -62,9 +62,9 @@ PointParam::param_get_default() const{ } void -PointParam::param_update_default(Geom::Point newpoint) +PointParam::param_update_default(const Geom::Point default_point) { - defvalue = newpoint; + defvalue = default_point; } void @@ -81,6 +81,9 @@ PointParam::param_setValue(Geom::Point newpoint, bool write) if(knoth && liveupdate){ knoth->update_knots(); } + if (_pointwdg) { + _pointwdg->setValue( newpoint ); + } } bool @@ -116,7 +119,7 @@ PointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) Gtk::Widget * PointParam::param_newWidget() { - Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage( + _pointwdg = Gtk::manage( new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label, param_tooltip, param_key, @@ -126,15 +129,15 @@ PointParam::param_newWidget() // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) SPDesktop *desktop = SP_ACTIVE_DESKTOP; Geom::Affine transf = desktop->doc2dt(); - pointwdg->setTransform(transf); - pointwdg->setValue( *this ); - pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); + _pointwdg->setTransform(transf); + _pointwdg->setValue( *this ); + _pointwdg->clearProgrammatically(); + _pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); - static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true); + static_cast<Gtk::HBox*>(hbox)->pack_start(*_pointwdg, true, true); static_cast<Gtk::HBox*>(hbox)->show_all_children(); - + param_effect->upd_params = false; return dynamic_cast<Gtk::Widget *> (hbox); } @@ -191,13 +194,13 @@ void PointParamKnotHolderEntity::knot_click(guint state) { if (state & GDK_CONTROL_MASK) { - if (state & GDK_MOD1_MASK) { - this->pparam->param_set_default(); - SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item); - if(splpeitem){ - sp_lpe_item_update_patheffect(splpeitem, false, false); - } + if (state & GDK_MOD1_MASK) { + this->pparam->param_set_default(); + SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item); + if(splpeitem){ + sp_lpe_item_update_patheffect(splpeitem, false, false); } + } } } diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index 4329e0bcd..62c6fb83d 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -11,7 +11,7 @@ #include <glib.h> #include <2geom/point.h> - +#include "ui/widget/registered-widget.h" #include "live_effects/parameter/parameter.h" #include "knot-holder-entity.h" @@ -43,7 +43,7 @@ public: void param_set_default(); Geom::Point param_get_default() const; void param_set_liveupdate(bool live_update); - void param_update_default(Geom::Point newpoint); + void param_update_default(const Geom::Point default_point); virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/); void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); @@ -62,6 +62,7 @@ private: SPKnotModeType knot_mode; guint32 knot_color; gchar *handle_tip; + Inkscape::UI::Widget::RegisteredTransformedPoint * _pointwdg; }; diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 234a6174d..0650b7e66 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -31,12 +31,16 @@ TextParam::TextParam( const Glib::ustring& label, const Glib::ustring& tip, Effect* effect, const Glib::ustring default_value ) : Parameter(label, tip, key, wr, effect), value(default_value), - defvalue(default_value) + defvalue(default_value), + _hide_canvas_text(false) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; // FIXME: we shouldn't use this! - canvas_text = (SPCanvasText *) sp_canvastext_new(desktop->getTempGroup(), desktop, Geom::Point(0,0), ""); - sp_canvastext_set_text (canvas_text, default_value.c_str()); - sp_canvastext_set_coords (canvas_text, 0, 0); + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { // FIXME: we shouldn't use this! + canvas_text = (SPCanvasText *) sp_canvastext_new(desktop->getTempGroup(), desktop, Geom::Point(0,0), ""); + sp_canvastext_set_text (canvas_text, default_value.c_str()); + sp_canvastext_set_coords (canvas_text, 0, 0); + } else { + _hide_canvas_text = true; + } } void @@ -46,9 +50,26 @@ TextParam::param_set_default() } void +TextParam::param_update_default(Glib::ustring default_value) +{ + defvalue = default_value; +} + +void +TextParam::param_hide_canvas_text() +{ + if (!_hide_canvas_text) { + sp_canvastext_set_text(canvas_text, " "); + _hide_canvas_text = true; + } +} + +void TextParam::setPos(Geom::Point pos) { - sp_canvastext_set_coords (canvas_text, pos); + if (!_hide_canvas_text) { + sp_canvastext_set_coords (canvas_text, pos); + } } void @@ -63,9 +84,10 @@ TextParam::setPosAndAnchor(const Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2, Point dir = unit_vector(derivative(pwd2_reparam).valueAt(t_reparam)); Point n = -rot90(dir); double angle = Geom::angle_between(dir, Point(1,0)); - - sp_canvastext_set_coords(canvas_text, pos + n * length); - sp_canvastext_set_anchor_manually(canvas_text, std::sin(angle), -std::cos(angle)); + if (!_hide_canvas_text) { + sp_canvastext_set_coords(canvas_text, pos + n * length); + sp_canvastext_set_anchor_manually(canvas_text, std::sin(angle), -std::cos(angle)); + } } void @@ -73,7 +95,9 @@ TextParam::setAnchor(double x_value, double y_value) { anchor_x = x_value; anchor_y = y_value; - sp_canvastext_set_anchor_manually (canvas_text, anchor_x, anchor_y); + if (!_hide_canvas_text) { + sp_canvastext_set_anchor_manually (canvas_text, anchor_x, anchor_y); + } } bool @@ -94,8 +118,7 @@ TextParam::param_newWidget() { Inkscape::UI::Widget::RegisteredText *rsu = Gtk::manage(new Inkscape::UI::Widget::RegisteredText( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc())); - - rsu->setText(value.c_str()); + rsu->setText(value); rsu->setProgrammatically = false; rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change text parameter")); @@ -107,8 +130,9 @@ void TextParam::param_setValue(const Glib::ustring newvalue) { value = newvalue; - - sp_canvastext_set_text (canvas_text, newvalue.c_str()); + if (!_hide_canvas_text) { + sp_canvastext_set_text (canvas_text, newvalue.c_str()); + } } } /* namespace LivePathEffect */ diff --git a/src/live_effects/parameter/text.h b/src/live_effects/parameter/text.h index 62de70eec..553c84c0a 100644 --- a/src/live_effects/parameter/text.h +++ b/src/live_effects/parameter/text.h @@ -40,7 +40,9 @@ public: virtual gchar * param_getSVGValue() const; void param_setValue(const Glib::ustring newvalue); + void param_hide_canvas_text(); virtual void param_set_default(); + void param_update_default(Glib::ustring default_value); void setPos(Geom::Point pos); void setPosAndAnchor(const Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2, const double t, const double length, bool use_curvature = false); @@ -53,7 +55,7 @@ private: TextParam& operator=(const TextParam&); double anchor_x; double anchor_y; - + bool _hide_canvas_text; Glib::ustring value; Glib::ustring defvalue; diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index 023bebc03..b3f6442bb 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -12,6 +12,7 @@ #include "live_effects/effect.h" #include "svg/svg.h" #include "svg/stringstream.h" +#include "selection.h" #include "widgets/icon.h" #include "inkscape.h" #include "verbs.h" @@ -104,13 +105,14 @@ ToggleButtonParam::param_newWidget() }else{ gtk_box_pack_start (GTK_BOX(box_button), label_button, false, false, 1); } + checkwdg->add(*Gtk::manage(Glib::wrap(box_button))); checkwdg->setActive(value); checkwdg->setProgrammatically = false; checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change togglebutton parameter")); _toggled_connection = checkwdg->signal_toggled().connect(sigc::mem_fun(*this, &ToggleButtonParam::toggled)); - + param_effect->upd_params = false; return checkwdg; } @@ -157,6 +159,12 @@ ToggleButtonParam::param_setValue(bool newvalue) void ToggleButtonParam::toggled() { + //Force redraw for update widgets + param_effect->upd_params = true; + if (SP_ACTIVE_DESKTOP) { + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); + selection->emitModified(); + } _signal_toggled.emit(); } diff --git a/src/live_effects/parameter/unit.cpp b/src/live_effects/parameter/unit.cpp index 0ee553e2c..b6ea99bfe 100644 --- a/src/live_effects/parameter/unit.cpp +++ b/src/live_effects/parameter/unit.cpp @@ -54,6 +54,12 @@ UnitParam::param_set_default() param_set_value(*defunit); } +void +UnitParam::param_update_default(const Glib::ustring default_unit) +{ + defunit = unit_table.getUnit(default_unit); +} + void UnitParam::param_set_value(Inkscape::Util::Unit const &val) { diff --git a/src/live_effects/parameter/unit.h b/src/live_effects/parameter/unit.h index 59a483018..ae58cf956 100644 --- a/src/live_effects/parameter/unit.h +++ b/src/live_effects/parameter/unit.h @@ -33,6 +33,7 @@ public: virtual gchar * param_getSVGValue() const; virtual void param_set_default(); void param_set_value(Inkscape::Util::Unit const &val); + void param_update_default(const Glib::ustring default_unit); const gchar *get_abbreviation() const; virtual Gtk::Widget * param_newWidget(); |
