Code

29ec03a8ca6294ed7cd6278b6e5d98adda534e32
[inkscape.git] / src / ui / dialog / livepatheffect-editor.cpp
1 /**
2  * \brief LivePathEffect dialog
3  *
4  * Authors:
5  *   Johan Engelen <j.b.c.engelen@utwente.nl>
6  *
7  * Copyright (C) 2007 Author
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <glibmm/i18n.h>
17 #include "livepatheffect-editor.h"
18 #include "verbs.h"
19 #include "selection.h"
20 #include "sp-shape.h"
21 #include "sp-path.h"
22 #include "live_effects/effect.h"
23 #include "live_effects/lpeobject.h"
24 #include "gtkmm/widget.h"
25 #include <vector>
26 #include "inkscape.h"
27 #include "desktop-handles.h"
28 #include "desktop.h"
29 #include "document-private.h"
30 #include "xml/node.h"
31 #include "xml/document.h"
33 namespace Inkscape {
34 class Application;
36 namespace UI {
37 namespace Dialog {
40 /*####################
41  * Callback functions
42  */
43 static void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data)
44 {
45     LivePathEffectEditor *lpeeditor = static_cast<LivePathEffectEditor *>(data);
46     lpeeditor->onSelectionChanged(selection);
47 }
50 /*#######################
51  * LivePathEffectEditor
52  */
54 LivePathEffectEditor::LivePathEffectEditor() 
55     : UI::Widget::Panel("", "dialogs.livepatheffect", SP_VERB_DIALOG_LIVE_PATH_EFFECT),
56       combo_effecttype(Inkscape::LivePathEffect::LPETypeConverter),
57       button_apply(_("_Apply"), _("Apply chosen effect to selection")),
58       button_remove(_("_Remove"), _("Remove effect from selection")),
59       effectwidget(NULL),
60       explain_label("", Gtk::ALIGN_CENTER),
61       effectapplication_frame(_("Apply new effect")),
62       effectcontrol_frame(_("Current effect")),
63       current_desktop(NULL)
64 {
65     Gtk::Box *contents = _getContents();
66     contents->set_spacing(4);
68     effectapplication_hbox.set_spacing(4);
69     effectcontrol_vbox.set_spacing(4);
71     effectapplication_hbox.pack_start(combo_effecttype, true, true);
72     effectapplication_hbox.pack_start(button_apply, true, true);
73     effectapplication_frame.add(effectapplication_hbox);
75     effectcontrol_vbox.pack_start(explain_label, true, true);
76     effectcontrol_vbox.pack_end(button_remove, true, true);
77     effectcontrol_frame.add(effectcontrol_vbox);
79     contents->pack_start(effectapplication_frame, false, false);
80     contents->pack_start(effectcontrol_frame, false, false);
82     // connect callback functions to buttons
83     button_apply.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectEditor::onApply));
84     button_remove.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectEditor::onRemove));
86     show_all_children();
88     button_remove.hide();
89 }
91 LivePathEffectEditor::~LivePathEffectEditor() 
92 {
93     if (effectwidget) {
94         effectcontrol_vbox.remove(*effectwidget);
95         delete effectwidget;
96         effectwidget = NULL;
97     }
99     if (current_desktop) {
100         selection_changed_connection.disconnect();
101     }
104 void
105 LivePathEffectEditor::showParams(LivePathEffect::Effect* effect)
107     if (effectwidget) {
108         effectcontrol_vbox.remove(*effectwidget);
109         delete effectwidget;
110         effectwidget = NULL;
111     }
113     explain_label.set_markup("<b>" + effect->getName() + "</b>");
114     effectwidget = effect->newWidget(&tooltips);
115     if (effectwidget) {
116         effectcontrol_vbox.pack_start(*effectwidget, true, true);
117     }
118     button_remove.show();
120     effectcontrol_vbox.show_all_children();
121     // fixme: add resizing of dialog
124 void
125 LivePathEffectEditor::showText(Glib::ustring const &str)
127     if (effectwidget) {
128         effectcontrol_vbox.remove(*effectwidget);
129         delete effectwidget;
130         effectwidget = NULL;
131     }
133     explain_label.set_label(str);
134     button_remove.hide();
136     // fixme: do resizing of dialog ?
139 void
140 LivePathEffectEditor::set_sensitize_all(bool sensitive)
142     combo_effecttype.set_sensitive(sensitive);
143     button_apply.set_sensitive(sensitive);
144     button_remove.set_sensitive(sensitive);
147 void
148 LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
150     if ( sel && !sel->isEmpty() ) {
151         SPItem *item = sel->singleItem();
152         if ( item ) {
153             if ( SP_IS_SHAPE(item) ) {
154                 SPShape *shape = SP_SHAPE(item);
155                 LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
156                 set_sensitize_all(true);
157                 if (lpeobj) {
158                     if (lpeobj->lpe) {
159                         showParams(lpeobj->lpe);
160                     } else {
161                         showText(_("Unknown effect is applied"));
162                     }
163                 } else {
164                     showText(_("No effect applied"));
165                     button_remove.set_sensitive(false);
166                 }
167             } else {
168                 showText(_("Item is not a shape or path"));
169                 set_sensitize_all(false);
170             }
171         } else {
172             showText(_("Only one item can be selected"));
173             set_sensitize_all(false);
174         }
175     } else {
176         showText(_("Empty selection"));
177         set_sensitize_all(false);
178     }
181 void 
182 LivePathEffectEditor::setDesktop(SPDesktop *desktop)
184     Panel::setDesktop(desktop);
186     if ( desktop == current_desktop ) {
187         return;
188     }
190     if (current_desktop) {
191         selection_changed_connection.disconnect();
192     }
194     current_desktop = desktop;
195     if (desktop) {
196         Inkscape::Selection *selection = sp_desktop_selection(desktop);
197         selection_changed_connection = selection->connectChanged(
198             sigc::bind (sigc::ptr_fun(&lpeeditor_selection_changed), this ) );
200         onSelectionChanged(selection);
201     } else {
202         onSelectionChanged(NULL);
203     }
209 /*########################################################################
210 # BUTTON CLICK HANDLERS    (callbacks)
211 ########################################################################*/
213 // TODO:  factor out the effect applying code which can be called from anywhere. (selection-chemistry.cpp also needs it)
215 void
216 LivePathEffectEditor::onApply()
218     Inkscape::Selection *sel = _getSelection();
219     if ( sel && !sel->isEmpty() ) {
220         SPItem *item = sel->singleItem();
221         if ( item && SP_IS_SHAPE(item) ) {
222             SPDocument *doc = current_desktop->doc();
224             const Util::EnumData<LivePathEffect::EffectType>* data = combo_effecttype.get_active_data();
225             if (!data) return;
227             Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
228             Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect");
229             repr->setAttribute("effect", data->key.c_str() );
231             SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->addChild(repr, NULL); // adds to <defs> and assigns the 'id' attribute
232             const gchar * repr_id = repr->attribute("id");
233             Inkscape::GC::release(repr);
235             gchar *href = g_strdup_printf("#%s", repr_id);
236             sp_shape_set_path_effect(SP_SHAPE(item), href);
237             g_free(href);
239             // make sure there is an original-d for paths!!!
240             if ( SP_IS_PATH(item) ) {
241                 Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(item);
242                 if ( ! pathrepr->attribute("inkscape:original-d") ) {
243                     pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
244                 }
245             }
247             LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(item));
248             if (lpeobj && lpeobj->lpe) {
249                 lpeobj->lpe->resetDefaults(item);
250             }
252             sp_document_done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
253                              _("Create and apply path effect"));
255             onSelectionChanged(sel);
256         }
257     }
260 void
261 LivePathEffectEditor::onRemove()
263     Inkscape::Selection *sel = _getSelection();
264     if ( sel && !sel->isEmpty() ) {
265         SPItem *item = sel->singleItem();
266         if ( item && SP_IS_SHAPE(item) ) {
267             sp_shape_remove_path_effect(SP_SHAPE(item));
268             showText(_("No effect applied"));
269             button_remove.set_sensitive(false);
270             sp_document_done ( sp_desktop_document (current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
271                                _("Remove path effect") );
272         }
273     }
278 } // namespace Dialog
279 } // namespace UI
280 } // namespace Inkscape