Code

A simple layout document as to what, why and how is cppification.
[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  *
8  * Copyright (C) 2005-2008 Authors
9  *
10  * Released under GNU GPL.  Read the file 'COPYING' for more information.
11  */
13 #ifndef INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
14 #define INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
16 #include <gtkmm/box.h>
17 #include <gtkmm/adjustment.h>
18 #include <gtkmm/tooltips.h>
19 #include <gtkmm/togglebutton.h>
20 #include <2geom/matrix.h>
21 #include "xml/node.h"
22 #include "registry.h"
24 #include "ui/widget/scalar.h"
25 #include "ui/widget/scalar-unit.h"
26 #include "ui/widget/point.h"
27 #include "ui/widget/text.h"
28 #include "ui/widget/random.h"
29 #include "ui/widget/unit-menu.h"
30 #include "ui/widget/color-picker.h"
31 #include "inkscape.h"
33 #include "document.h"
34 #include "desktop-handles.h"
35 #include "sp-namedview.h"
37 class SPUnit;
38 class SPDocument;
40 namespace Gtk {
41     class HScale;
42     class RadioButton;
43     class SpinButton;
44 }
46 namespace Inkscape {
47 namespace UI {
48 namespace Widget {
50 class Registry;
52 template <class W>
53 class RegisteredWidget : public W {
54 public:
55     void set_undo_parameters(const unsigned int _event_type, Glib::ustring _event_description)
56     {
57         event_type = _event_type;
58         event_description = _event_description;
59         write_undo = true;
60     }
62     bool is_updating() {if (_wr) return _wr->isUpdating(); else return false;}
64     // provide automatic 'upcast' for ease of use. (do it 'dynamic_cast' instead of 'static' because who knows what W is)
65     operator const Gtk::Widget () { return dynamic_cast<Gtk::Widget*>(this); }
67 protected:
68     RegisteredWidget() : W() { construct(); }
69     template< typename A >
70     explicit RegisteredWidget( A& a ): W( a ) { construct(); }
71     template< typename A, typename B >
72     RegisteredWidget( A& a, B& b ): W( a, b ) { construct(); }
73     template< typename A, typename B, typename C >
74     RegisteredWidget( A& a, B& b, C* c ): W( a, b, c ) { construct(); }
75     template< typename A, typename B, typename C >
76     RegisteredWidget( A& a, B& b, C& c ): W( a, b, c ) { construct(); }
77     template< typename A, typename B, typename C, typename D >
78     RegisteredWidget( A& a, B& b, C c, D d ): W( a, b, c, d ) { construct(); }
79     template< typename A, typename B, typename C, typename D, typename E , typename F>
80     RegisteredWidget( A& a, B& b, C c, D& d, E& e, F* f): W( a, b, c, d, e, f) { construct(); }
82     virtual ~RegisteredWidget() {};
84     void init_parent(const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
85     {
86         _wr = &wr;
87         _key = key;
88         repr = repr_in;
89         doc = doc_in;
90         if (repr && !doc)  // doc cannot be NULL when repr is not NULL
91             g_warning("Initialization of registered widget using defined repr but with doc==NULL");
92     }
94     void write_to_xml(const char * svgstr)
95     {
96         // Use local repr here. When repr is specified, use that one, but
97         // if repr==NULL, get the repr of namedview of active desktop.
98         Inkscape::XML::Node *local_repr = repr;
99         SPDocument *local_doc = doc;
100         if (!local_repr) {
101             // no repr specified, use active desktop's namedview's repr
102             SPDesktop* dt = SP_ACTIVE_DESKTOP;
103             local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
104             local_doc = sp_desktop_document(dt);
105         }
107         bool saved = SPDocumentUndo::get_undo_sensitive (local_doc);
108                 SPDocumentUndo::set_undo_sensitive (local_doc, false);
109         if (!write_undo) local_repr->setAttribute(_key.c_str(), svgstr);
110                 SPDocumentUndo::set_undo_sensitive (local_doc, saved);
112         local_doc->setModifiedSinceSave();
114         if (write_undo) {
115             local_repr->setAttribute(_key.c_str(), svgstr);
116                         SPDocumentUndo::done (local_doc, event_type, event_description);
117         }
118     }
120     Registry * _wr;
121     Glib::ustring _key;
122     Inkscape::XML::Node * repr;
123     SPDocument * doc;
124     unsigned int event_type;
125     Glib::ustring event_description;
126     bool write_undo;
128 private:
129     void construct() {
130         _wr = NULL;
131         repr = NULL;
132         doc = NULL;
133         write_undo = false;
134     }
135 };
137 //#######################################################
139 class RegisteredCheckButton : public RegisteredWidget<Gtk::CheckButton> {
140 public:
141     virtual ~RegisteredCheckButton();
142     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);
144     void setActive (bool);
146     std::list<Gtk::Widget*> _slavewidgets;
148     // a slave button is only sensitive when the master button is active
149     // i.e. a slave button is greyed-out when the master button is not checked
151     void setSlaveWidgets(std::list<Gtk::Widget*> btns) {
152         _slavewidgets = btns;
153     }
155     bool setProgrammatically; // true if the value was set by setActive, not changed by the user;
156                                 // if a callback checks it, it must reset it back to false
158 protected:
159     Gtk::Tooltips     _tt;
160     sigc::connection  _toggled_connection;
161     void on_toggled();
162 };
164 class RegisteredUnitMenu : public RegisteredWidget<Labelled> {
165 public:
166     ~RegisteredUnitMenu();
167     RegisteredUnitMenu ( const Glib::ustring& label,
168                          const Glib::ustring& key,
169                          Registry& wr,
170                          Inkscape::XML::Node* repr_in = NULL,
171                          SPDocument *doc_in = NULL );
173     void setUnit (const SPUnit*);
174     Unit getUnit() const { return static_cast<UnitMenu*>(_widget)->getUnit(); };
175     UnitMenu* getUnitMenu() const { return static_cast<UnitMenu*>(_widget); };
176     sigc::connection _changed_connection;
178 protected:
179     void on_changed();
180 };
182 class RegisteredScalarUnit : public RegisteredWidget<ScalarUnit> {
183 public:
184     ~RegisteredScalarUnit();
185     RegisteredScalarUnit ( const Glib::ustring& label,
186                            const Glib::ustring& tip,
187                            const Glib::ustring& key,
188                            const RegisteredUnitMenu &rum,
189                            Registry& wr,
190                            Inkscape::XML::Node* repr_in = NULL,
191                            SPDocument *doc_in = NULL );
193 protected:
194     sigc::connection  _value_changed_connection;
195     UnitMenu         *_um;
196     void on_value_changed();
197 };
199 class RegisteredScalar : public RegisteredWidget<Scalar> {
200 public:
201     virtual ~RegisteredScalar();
202     RegisteredScalar (const Glib::ustring& label,
203             const Glib::ustring& tip,
204             const Glib::ustring& key,
205             Registry& wr,
206             Inkscape::XML::Node* repr_in = NULL,
207             SPDocument *doc_in = NULL );
209 protected:
210     sigc::connection  _value_changed_connection;
211     void on_value_changed();
212 };
214 class RegisteredText : public RegisteredWidget<Text> {
215 public:
216     virtual ~RegisteredText();
217     RegisteredText (const Glib::ustring& label,
218             const Glib::ustring& tip,
219             const Glib::ustring& key,
220             Registry& wr,
221             Inkscape::XML::Node* repr_in = NULL,
222             SPDocument *doc_in = NULL );
224 protected:
225     sigc::connection  _activate_connection;
226     void on_activate();
227 };
229 class RegisteredColorPicker : public RegisteredWidget<ColorPicker> {
230 public:
231     virtual ~RegisteredColorPicker();
233     RegisteredColorPicker (const Glib::ustring& label,
234                            const Glib::ustring& title,
235                            const Glib::ustring& tip,
236                            const Glib::ustring& ckey,
237                            const Glib::ustring& akey,
238                            Registry& wr,
239                            Inkscape::XML::Node* repr_in = NULL,
240                            SPDocument *doc_in = NULL);
242     void setRgba32 (guint32);
243     void closeWindow();
245     Gtk::Label *_label;
247 protected:
248     Glib::ustring _ckey, _akey;
249     void on_changed (guint32);
250     sigc::connection _changed_connection;
251 };
253 class RegisteredSuffixedInteger : public RegisteredWidget<Scalar> {
254 public:
255     virtual ~RegisteredSuffixedInteger();
256     RegisteredSuffixedInteger ( const Glib::ustring& label,
257                                 const Glib::ustring& tip, 
258                                 const Glib::ustring& suffix,
259                                 const Glib::ustring& key,
260                                 Registry& wr,
261                                 Inkscape::XML::Node* repr_in = NULL,
262                                 SPDocument *doc_in = NULL );
264     bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
265                                 // if a callback checks it, it must reset it back to false
267 protected:
268     sigc::connection _changed_connection;
269     void on_value_changed();
270 };
272 class RegisteredRadioButtonPair : public RegisteredWidget<Gtk::HBox> {
273 public:
274     virtual ~RegisteredRadioButtonPair();
275     RegisteredRadioButtonPair ( const Glib::ustring& label,
276                                 const Glib::ustring& label1,
277                                 const Glib::ustring& label2,
278                                 const Glib::ustring& tip1,
279                                 const Glib::ustring& tip2,
280                                 const Glib::ustring& key,
281                                 Registry& wr,
282                                 Inkscape::XML::Node* repr_in = NULL,
283                                 SPDocument *doc_in = NULL );
285     void setValue (bool second);
287     bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
288                                     // if a callback checks it, it must reset it back to false
289 protected:
290     Gtk::RadioButton *_rb1, *_rb2;
291     Gtk::Tooltips     _tt;
292     sigc::connection _changed_connection;
293     void on_value_changed();
294 };
296 class RegisteredPoint : public RegisteredWidget<Point> {
297 public:
298     virtual ~RegisteredPoint();
299     RegisteredPoint ( const Glib::ustring& label,
300                       const Glib::ustring& tip,
301                       const Glib::ustring& key,
302                       Registry& wr,
303                       Inkscape::XML::Node* repr_in = NULL,
304                       SPDocument *doc_in = NULL );
306 protected:
307     sigc::connection  _value_x_changed_connection;
308     sigc::connection  _value_y_changed_connection;
309     void on_value_changed();
310 };
313 class RegisteredTransformedPoint : public RegisteredWidget<Point> {
314 public:
315     virtual ~RegisteredTransformedPoint();
316     RegisteredTransformedPoint (  const Glib::ustring& label,
317                                   const Glib::ustring& tip,
318                                   const Glib::ustring& key,
319                                   Registry& wr,
320                                   Inkscape::XML::Node* repr_in = NULL,
321                                   SPDocument *doc_in = NULL );
323     // redefine setValue, because transform must be applied
324     void setValue(Geom::Point const & p);
326     void setTransform(Geom::Matrix const & canvas_to_svg);
328 protected:
329     sigc::connection  _value_x_changed_connection;
330     sigc::connection  _value_y_changed_connection;
331     void on_value_changed();
333     Geom::Matrix to_svg;
334 };
337 class RegisteredVector : public RegisteredWidget<Point> {
338 public:
339     virtual ~RegisteredVector();
340     RegisteredVector (const Glib::ustring& label,
341                       const Glib::ustring& tip,
342                       const Glib::ustring& key,
343                       Registry& wr,
344                       Inkscape::XML::Node* repr_in = NULL,
345                       SPDocument *doc_in = NULL );
347     // redefine setValue, because transform must be applied
348     void setValue(Geom::Point const & p);
349     void setValue(Geom::Point const & p, Geom::Point const & origin);
350     void setPolarCoords(bool polar_coords = true);
352 protected:
353     sigc::connection  _value_x_changed_connection;
354     sigc::connection  _value_y_changed_connection;
355     void on_value_changed();
357     Geom::Point _origin;
358     bool _polar_coords;
359 };
362 class RegisteredRandom : public RegisteredWidget<Random> {
363 public:
364     virtual ~RegisteredRandom();
365     RegisteredRandom ( const Glib::ustring& label,
366                        const Glib::ustring& tip,
367                        const Glib::ustring& key,
368                        Registry& wr,
369                        Inkscape::XML::Node* repr_in = NULL,
370                        SPDocument *doc_in = NULL);
372     void setValue (double val, long startseed);
374 protected:
375     sigc::connection  _value_changed_connection;
376     sigc::connection  _reseeded_connection;
377     void on_value_changed();
378 };
380 } // namespace Widget
381 } // namespace UI
382 } // namespace Inkscape
384 #endif // INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
386 /*
387   Local Variables:
388   mode:c++
389   c-file-style:"stroustrup"
390   c-file-offsets:((innamespace . 0)(inline-open . 0))
391   indent-tabs-mode:nil
392   fill-column:99
393   End:
394 */
395 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :