diff options
| -rw-r--r-- | po/POTFILES.skip | 1 | ||||
| -rw-r--r-- | src/live_effects/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/live_effects/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/live_effects/effect-enum.h | 1 | ||||
| -rw-r--r-- | src/live_effects/effect.cpp | 14 | ||||
| -rw-r--r-- | src/live_effects/parameter/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/ui/tools/node-tool.cpp | 48 | ||||
| -rw-r--r-- | src/ui/tools/node-tool.h | 2 | ||||
| -rw-r--r-- | src/ui/widget/registered-widget.cpp | 53 | ||||
| -rw-r--r-- | src/ui/widget/registered-widget.h | 25 |
10 files changed, 146 insertions, 6 deletions
diff --git a/po/POTFILES.skip b/po/POTFILES.skip index c67c7a672..f7e083480 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -25,6 +25,7 @@ src/live_effects/lpe-skeleton.cpp src/live_effects/lpe-tangent_to_curve.cpp src/live_effects/lpe-test-doEffect-stack.cpp src/live_effects/lpe-text_label.cpp +src/live_effects/lpe-simplify.cpp src/lpe-tool-context.cpp src/ui/dialog/session-player.cpp src/ui/dialog/whiteboard-connect.cpp diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 7aeb911b0..5979cd028 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -29,6 +29,7 @@ set(live_effects_SRC lpe-recursiveskeleton.cpp lpe-rough-hatches.cpp lpe-ruler.cpp + lpe-simplify.cpp # lpe-skeleton.cpp lpe-sketch.cpp lpe-spiro.cpp @@ -53,6 +54,7 @@ set(live_effects_SRC parameter/powerstrokepointarray.cpp parameter/random.cpp parameter/text.cpp + parameter/togglebutton.cpp parameter/unit.cpp parameter/vector.cpp @@ -90,6 +92,7 @@ set(live_effects_SRC lpe-recursiveskeleton.h lpe-rough-hatches.h lpe-ruler.h + lpe-simplify.h lpe-skeleton.h lpe-sketch.h lpe-spiro.h @@ -115,6 +118,7 @@ set(live_effects_SRC parameter/powerstrokepointarray.h parameter/random.h parameter/text.h + parameter/togglebutton.h parameter/unit.h parameter/vector.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 248030e8c..a9da81d5b 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -42,6 +42,8 @@ ink_common_sources += \ live_effects/lpe-bspline.h \ live_effects/lpe-lattice.cpp \ live_effects/lpe-lattice.h \ + live_effects/lpe-simplify.cpp \ + live_effects/lpe-simplify.h \ live_effects/lpe-envelope.cpp \ live_effects/lpe-envelope.h \ live_effects/lpe-spiro.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 342a2c849..cacb1190f 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -28,6 +28,7 @@ enum EffectType { PERSPECTIVE_PATH, SPIRO, LATTICE, + SIMPLIFY, ENVELOPE, CONSTRUCT_GRID, PERP_BISECTOR, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 9006e5359..66bce9c1d 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -26,6 +26,7 @@ #include "live_effects/lpe-perspective_path.h" #include "live_effects/lpe-spiro.h" #include "live_effects/lpe-lattice.h" +#include "live_effects/lpe-simplify.h" #include "live_effects/lpe-envelope.h" #include "live_effects/lpe-constructgrid.h" #include "live_effects/lpe-perp_bisector.h" @@ -122,6 +123,7 @@ const Util::EnumData<EffectType> LPETypeData[] = { {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, {BSPLINE, N_("BSpline"), "bspline"}, + {SIMPLIFY, N_("Simplify"), "simplify"}, }; const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -248,6 +250,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case CLONE_ORIGINAL: neweffect = static_cast<Effect*> ( new LPECloneOriginal(lpeobj) ); break; + case SIMPLIFY: + neweffect = static_cast<Effect*> ( new LPESimplify(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; @@ -499,9 +504,12 @@ Effect::getCanvasIndicators(SPLPEItem const* lpeitem) { std::vector<Geom::PathVector> hp_vec; - if (!SP_IS_SHAPE(lpeitem)) { -// g_print ("How to handle helperpaths for non-shapes?\n"); // non-shapes are for example SPGroups. - return hp_vec; + // TODO: we can probably optimize this by using a lot more references + // rather than copying PathVectors all over the place + if (SP_IS_SHAPE(lpeitem) && show_orig_path) { + // add original path to helperpaths + SPCurve* curve = SP_SHAPE(lpeitem)->getCurve (); + hp_vec.push_back(curve->get_pathvector()); } // add indicators provided by the effect itself diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index efdda686a..30f1f510b 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -22,6 +22,8 @@ ink_common_sources += \ live_effects/parameter/powerstrokepointarray.h \ live_effects/parameter/text.cpp \ live_effects/parameter/text.h \ + live_effects/parameter/togglebutton.cpp \ + live_effects/parameter/togglebutton.h \ live_effects/parameter/unit.cpp \ live_effects/parameter/unit.h \ live_effects/parameter/vector.cpp \ diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..ce487831d 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -23,6 +23,8 @@ #include "message-context.h" #include "selection.h" #include "shape-editor.h" // temporary! +#include "live_effects/effect.h" +#include "display/curve.h" #include "sp-clippath.h" #include "sp-item-group.h" #include "sp-mask.h" @@ -167,6 +169,10 @@ NodeTool::~NodeTool() { this->desktop->remove_temporary_canvasitem(this->flash_tempitem); } + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + } + this->_selection_changed_connection.disconnect(); //this->_selection_modified_connection.disconnect(); this->_mouseover_changed_connection.disconnect(); @@ -252,6 +258,7 @@ void NodeTool::setup() { this->flash_tempitem = NULL; this->flashed_item = NULL; this->_last_over = NULL; + this->helperpath_tmpitem = NULL; // read prefs before adding items to selection to prevent momentarily showing the outline sp_event_context_read(this, "show_handles"); @@ -278,6 +285,41 @@ void NodeTool::setup() { } this->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive + this->update_helperpath(); +} + +void NodeTool::update_helperpath(){ + Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + this->helperpath_tmpitem = NULL; + } + if (SP_IS_LPE_ITEM(selection->singleItem())) { + Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); + if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + if (lpe) { + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector<Geom::PathVector> cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector<Geom::PathVector>::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + c->transform(selection->singleItem()->i2dt_affine()); + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), + 0x0000ff9A, 1.0, + SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); + } + c->unref(); + cc->unref(); + } + } + } } void NodeTool::set(const Inkscape::Preferences::Entry& value) { @@ -392,7 +434,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { for (std::set<ShapeRecord>::iterator i = shapes.begin(); i != shapes.end(); ++i) { ShapeRecord const &r = *i; - if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) && + if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item) || SP_IS_GROUP(r.item) || SP_IS_OBJECTGROUP(r.item)) && this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); @@ -416,7 +458,7 @@ bool NodeTool::root_handler(GdkEvent* event) { Inkscape::Selection *selection = desktop->selection; static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - + if (this->_multipath->event(this, event)) { return true; } @@ -433,6 +475,7 @@ bool NodeTool::root_handler(GdkEvent* event) { { case GDK_MOTION_NOTIFY: { combine_motion_events(desktop->canvas, event->motion, 0); + this->update_helperpath(); SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button), FALSE, TRUE); @@ -441,7 +484,6 @@ bool NodeTool::root_handler(GdkEvent* event) { //ink_node_tool_update_tip(nt, event); this->update_tip(event); } - // create pathflash outline if (prefs->getBool("/tools/nodes/pathflash_enabled")) { if (over_item == this->flashed_item) { diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 42f89cd1c..9f0c40aa8 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -54,6 +54,7 @@ public: static const std::string prefsPath; virtual void setup(); + virtual void update_helperpath(); virtual void set(const Inkscape::Preferences::Entry& val); virtual bool root_handler(GdkEvent* event); @@ -66,6 +67,7 @@ private: SPItem *flashed_item; Inkscape::Display::TemporaryItem *flash_tempitem; + Inkscape::Display::TemporaryItem *helperpath_tmpitem; Inkscape::UI::Selector* _selector; Inkscape::UI::PathSharedData* _path_data; SPCanvasGroup *_transform_handle_group; diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 92cb3f03d..83da1a6d6 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -99,6 +99,59 @@ RegisteredCheckButton::on_toggled() _wr->setUpdating (false); } +/*######################################### + * Registered TOGGLEBUTTON + */ + +RegisteredToggleButton::~RegisteredToggleButton() +{ + _toggled_connection.disconnect(); +} + +RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) + : RegisteredWidget<Gtk::ToggleButton>(label) + , _active_str(active_str) + , _inactive_str(inactive_str) +{ + init_parent(key, wr, repr_in, doc_in); + setProgrammatically = false; + set_tooltip_text (tip); + set_alignment (right? 1.0 : 0.0, 0.5); + _toggled_connection = signal_toggled().connect (sigc::mem_fun (*this, &RegisteredToggleButton::on_toggled)); +} + +void +RegisteredToggleButton::setActive (bool b) +{ + setProgrammatically = true; + set_active (b); + //The slave button is greyed out if the master button is untoggled + for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { + (*i)->set_sensitive(b); + } + setProgrammatically = false; +} + +void +RegisteredToggleButton::on_toggled() +{ + if (setProgrammatically) { + setProgrammatically = false; + return; + } + + if (_wr->isUpdating()) + return; + _wr->setUpdating (true); + + write_to_xml(get_active() ? _active_str : _inactive_str); + //The slave button is greyed out if the master button is untoggled + for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { + (*i)->set_sensitive(get_active()); + } + + _wr->setUpdating (false); +} /*######################################### * Registered UNITMENU diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index d64c09c16..d8c0e6602 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -163,6 +163,31 @@ protected: void on_toggled(); }; +class RegisteredToggleButton : public RegisteredWidget<Gtk::ToggleButton> { +public: + virtual ~RegisteredToggleButton(); + RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL, char const *active_str = "true", char const *inactive_str = "false"); + + void setActive (bool); + + std::list<Gtk::Widget*> _slavewidgets; + + // a slave button is only sensitive when the master button is active + // i.e. a slave button is greyed-out when the master button is not checked + + void setSlaveWidgets(std::list<Gtk::Widget*> btns) { + _slavewidgets = btns; + } + + bool setProgrammatically; // true if the value was set by setActive, not changed by the user; + // if a callback checks it, it must reset it back to false + +protected: + char const *_active_str, *_inactive_str; + sigc::connection _toggled_connection; + void on_toggled(); +}; + class RegisteredUnitMenu : public RegisteredWidget<Labelled> { public: ~RegisteredUnitMenu(); |
