Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / ui / widget / registered-widget.h
1 /** \file
2  * \brief
3  *
4  * Authors:
5  *   Ralf Stephan <ralf@ark.in-berlin.de>
6  *   Johan Engelen <j.b.c.engelen@utwente.nl>
7  *   Abhishek Sharma
8  *
9  * Copyright (C) 2005-2008 Authors
10  *
11  * Released under GNU GPL.  Read the file 'COPYING' for more information.
12  */
14 #ifndef INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
15 #define INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
17 #include <gtkmm/box.h>
18 #include <gtkmm/adjustment.h>
19 #include <gtkmm/tooltips.h>
20 #include <gtkmm/togglebutton.h>
21 #include <2geom/matrix.h>
22 #include "xml/node.h"
23 #include "registry.h"
25 #include "ui/widget/scalar.h"
26 #include "ui/widget/scalar-unit.h"
27 #include "ui/widget/point.h"
28 #include "ui/widget/text.h"
29 #include "ui/widget/random.h"
30 #include "ui/widget/unit-menu.h"
31 #include "ui/widget/color-picker.h"
32 #include "inkscape.h"
34 #include "document.h"
35 #include "desktop-handles.h"
36 #include "sp-namedview.h"
38 class SPUnit;
39 class SPDocument;
41 namespace Gtk {
42     class HScale;
43     class RadioButton;
44     class SpinButton;
45 }
47 namespace Inkscape {
48 namespace UI {
49 namespace Widget {
51 class Registry;
53 template <class W>
54 class RegisteredWidget : public W {
55 public:
56     void set_undo_parameters(const unsigned int _event_type, Glib::ustring _event_description)
57     {
58         event_type = _event_type;
59         event_description = _event_description;
60         write_undo = true;
61     }
63     bool is_updating() {if (_wr) return _wr->isUpdating(); else return false;}
65     // provide automatic 'upcast' for ease of use. (do it 'dynamic_cast' instead of 'static' because who knows what W is)
66     operator const Gtk::Widget () { return dynamic_cast<Gtk::Widget*>(this); }
68 protected:
69     RegisteredWidget() : W() { construct(); }
70     template< typename A >
71     explicit RegisteredWidget( A& a ): W( a ) { construct(); }
72     template< typename A, typename B >
73     RegisteredWidget( A& a, B& b ): W( a, b ) { construct(); }
74     template< typename A, typename B, typename C >
75     RegisteredWidget( A& a, B& b, C* c ): W( a, b, c ) { construct(); }
76     template< typename A, typename B, typename C >
77     RegisteredWidget( A& a, B& b, C& c ): W( a, b, c ) { construct(); }
78     template< typename A, typename B, typename C, typename D >
79     RegisteredWidget( A& a, B& b, C c, D d ): W( a, b, c, d ) { construct(); }
80     template< typename A, typename B, typename C, typename D, typename E , typename F>
81     RegisteredWidget( A& a, B& b, C c, D& d, E& e, F* f): W( a, b, c, d, e, f) { construct(); }
83     virtual ~RegisteredWidget() {};
85     void init_parent(const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
86     {
87         _wr = &wr;
88         _key = key;
89         repr = repr_in;
90         doc = doc_in;
91         if (repr && !doc)  // doc cannot be NULL when repr is not NULL
92             g_warning("Initialization of registered widget using defined repr but with doc==NULL");
93     }
95     void write_to_xml(const char * svgstr)
96     {
97         // Use local repr here. When repr is specified, use that one, but
98         // if repr==NULL, get the repr of namedview of active desktop.
99         Inkscape::XML::Node *local_repr = repr;
100         SPDocument *local_doc = doc;
101         if (!local_repr) {
102             // no repr specified, use active desktop's namedview's repr
103             SPDesktop* dt = SP_ACTIVE_DESKTOP;
104             local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
105             local_doc = sp_desktop_document(dt);
106         }
108         bool saved = DocumentUndo::getUndoSensitive(local_doc);
109         DocumentUndo::setUndoSensitive(local_doc, false);
110         if (!write_undo) {
111             local_repr->setAttribute(_key.c_str(), svgstr);
112         }
113         DocumentUndo::setUndoSensitive(local_doc, saved);
115         local_doc->setModifiedSinceSave();
117         if (write_undo) {
118             local_repr->setAttribute(_key.c_str(), svgstr);
119             DocumentUndo::done(local_doc, event_type, event_description);
120         }
121     }
123     Registry * _wr;
124     Glib::ustring _key;
125     Inkscape::XML::Node * repr;
126     SPDocument * doc;
127     unsigned int event_type;
128     Glib::ustring event_description;
129     bool write_undo;
131 private:
132     void construct() {
133         _wr = NULL;
134         repr = NULL;
135         doc = NULL;
136         write_undo = false;
137     }
138 };
140 //#######################################################
142 class RegisteredCheckButton : public RegisteredWidget<Gtk::CheckButton> {
143 public:
144     virtual ~RegisteredCheckButton();
145     RegisteredCheckButton (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);
147     void setActive (bool);
149     std::list<Gtk::Widget*> _slavewidgets;
151     // a slave button is only sensitive when the master button is active
152     // i.e. a slave button is greyed-out when the master button is not checked
154     void setSlaveWidgets(std::list<Gtk::Widget*> btns) {
155         _slavewidgets = btns;
156     }
158     bool setProgrammatically; // true if the value was set by setActive, not changed by the user;
159                                 // if a callback checks it, it must reset it back to false
161 protected:
162     Gtk::Tooltips     _tt;
163     sigc::connection  _toggled_connection;
164     void on_toggled();
165 };
167 class RegisteredUnitMenu : public RegisteredWidget<Labelled> {
168 public:
169     ~RegisteredUnitMenu();
170     RegisteredUnitMenu ( const Glib::ustring& label,
171                          const Glib::ustring& key,
172                          Registry& wr,
173                          Inkscape::XML::Node* repr_in = NULL,
174                          SPDocument *doc_in = NULL );
176     void setUnit (const SPUnit*);
177     Unit getUnit() const { return static_cast<UnitMenu*>(_widget)->getUnit(); };
178     UnitMenu* getUnitMenu() const { return static_cast<UnitMenu*>(_widget); };
179     sigc::connection _changed_connection;
181 protected:
182     void on_changed();
183 };
185 class RegisteredScalarUnit : public RegisteredWidget<ScalarUnit> {
186 public:
187     ~RegisteredScalarUnit();
188     RegisteredScalarUnit ( const Glib::ustring& label,
189                            const Glib::ustring& tip,
190                            const Glib::ustring& key,
191                            const RegisteredUnitMenu &rum,
192                            Registry& wr,
193                            Inkscape::XML::Node* repr_in = NULL,
194                            SPDocument *doc_in = NULL );
196 protected:
197     sigc::connection  _value_changed_connection;
198     UnitMenu         *_um;
199     void on_value_changed();
200 };
202 class RegisteredScalar : public RegisteredWidget<Scalar> {
203 public:
204     virtual ~RegisteredScalar();
205     RegisteredScalar (const Glib::ustring& label,
206             const Glib::ustring& tip,
207             const Glib::ustring& key,
208             Registry& wr,
209             Inkscape::XML::Node* repr_in = NULL,
210             SPDocument *doc_in = NULL );
212 protected:
213     sigc::connection  _value_changed_connection;
214     void on_value_changed();
215 };
217 class RegisteredText : public RegisteredWidget<Text> {
218 public:
219     virtual ~RegisteredText();
220     RegisteredText (const Glib::ustring& label,
221             const Glib::ustring& tip,
222             const Glib::ustring& key,
223             Registry& wr,
224             Inkscape::XML::Node* repr_in = NULL,
225             SPDocument *doc_in = NULL );
227 protected:
228     sigc::connection  _activate_connection;
229     void on_activate();
230 };
232 class RegisteredColorPicker : public RegisteredWidget<ColorPicker> {
233 public:
234     virtual ~RegisteredColorPicker();
236     RegisteredColorPicker (const Glib::ustring& label,
237                            const Glib::ustring& title,
238                            const Glib::ustring& tip,
239                            const Glib::ustring& ckey,
240                            const Glib::ustring& akey,
241                            Registry& wr,
242                            Inkscape::XML::Node* repr_in = NULL,
243                            SPDocument *doc_in = NULL);
245     void setRgba32 (guint32);
246     void closeWindow();
248     Gtk::Label *_label;
250 protected:
251     Glib::ustring _ckey, _akey;
252     void on_changed (guint32);
253     sigc::connection _changed_connection;
254 };
256 class RegisteredSuffixedInteger : public RegisteredWidget<Scalar> {
257 public:
258     virtual ~RegisteredSuffixedInteger();
259     RegisteredSuffixedInteger ( const Glib::ustring& label,
260                                 const Glib::ustring& tip, 
261                                 const Glib::ustring& suffix,
262                                 const Glib::ustring& key,
263                                 Registry& wr,
264                                 Inkscape::XML::Node* repr_in = NULL,
265                                 SPDocument *doc_in = NULL );
267     bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
268                                 // if a callback checks it, it must reset it back to false
270 protected:
271     sigc::connection _changed_connection;
272     void on_value_changed();
273 };
275 class RegisteredRadioButtonPair : public RegisteredWidget<Gtk::HBox> {
276 public:
277     virtual ~RegisteredRadioButtonPair();
278     RegisteredRadioButtonPair ( const Glib::ustring& label,
279                                 const Glib::ustring& label1,
280                                 const Glib::ustring& label2,
281                                 const Glib::ustring& tip1,
282                                 const Glib::ustring& tip2,
283                                 const Glib::ustring& key,
284                                 Registry& wr,
285                                 Inkscape::XML::Node* repr_in = NULL,
286                                 SPDocument *doc_in = NULL );
288     void setValue (bool second);
290     bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
291                                     // if a callback checks it, it must reset it back to false
292 protected:
293     Gtk::RadioButton *_rb1, *_rb2;
294     Gtk::Tooltips     _tt;
295     sigc::connection _changed_connection;
296     void on_value_changed();
297 };
299 class RegisteredPoint : public RegisteredWidget<Point> {
300 public:
301     virtual ~RegisteredPoint();
302     RegisteredPoint ( const Glib::ustring& label,
303                       const Glib::ustring& tip,
304                       const Glib::ustring& key,
305                       Registry& wr,
306                       Inkscape::XML::Node* repr_in = NULL,
307                       SPDocument *doc_in = NULL );
309 protected:
310     sigc::connection  _value_x_changed_connection;
311     sigc::connection  _value_y_changed_connection;
312     void on_value_changed();
313 };
316 class RegisteredTransformedPoint : public RegisteredWidget<Point> {
317 public:
318     virtual ~RegisteredTransformedPoint();
319     RegisteredTransformedPoint (  const Glib::ustring& label,
320                                   const Glib::ustring& tip,
321                                   const Glib::ustring& key,
322                                   Registry& wr,
323                                   Inkscape::XML::Node* repr_in = NULL,
324                                   SPDocument *doc_in = NULL );
326     // redefine setValue, because transform must be applied
327     void setValue(Geom::Point const & p);
329     void setTransform(Geom::Matrix const & canvas_to_svg);
331 protected:
332     sigc::connection  _value_x_changed_connection;
333     sigc::connection  _value_y_changed_connection;
334     void on_value_changed();
336     Geom::Matrix to_svg;
337 };
340 class RegisteredVector : public RegisteredWidget<Point> {
341 public:
342     virtual ~RegisteredVector();
343     RegisteredVector (const Glib::ustring& label,
344                       const Glib::ustring& tip,
345                       const Glib::ustring& key,
346                       Registry& wr,
347                       Inkscape::XML::Node* repr_in = NULL,
348                       SPDocument *doc_in = NULL );
350     // redefine setValue, because transform must be applied
351     void setValue(Geom::Point const & p);
352     void setValue(Geom::Point const & p, Geom::Point const & origin);
353     void setPolarCoords(bool polar_coords = true);
355 protected:
356     sigc::connection  _value_x_changed_connection;
357     sigc::connection  _value_y_changed_connection;
358     void on_value_changed();
360     Geom::Point _origin;
361     bool _polar_coords;
362 };
365 class RegisteredRandom : public RegisteredWidget<Random> {
366 public:
367     virtual ~RegisteredRandom();
368     RegisteredRandom ( const Glib::ustring& label,
369                        const Glib::ustring& tip,
370                        const Glib::ustring& key,
371                        Registry& wr,
372                        Inkscape::XML::Node* repr_in = NULL,
373                        SPDocument *doc_in = NULL);
375     void setValue (double val, long startseed);
377 protected:
378     sigc::connection  _value_changed_connection;
379     sigc::connection  _reseeded_connection;
380     void on_value_changed();
381 };
383 } // namespace Widget
384 } // namespace UI
385 } // namespace Inkscape
387 #endif // INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
389 /*
390   Local Variables:
391   mode:c++
392   c-file-style:"stroustrup"
393   c-file-offsets:((innamespace . 0)(inline-open . 0))
394   indent-tabs-mode:nil
395   fill-column:99
396   End:
397 */
398 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :