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 = ≀
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 = sp_document_get_undo_sensitive (local_doc);
108 sp_document_set_undo_sensitive (local_doc, false);
109 if (!write_undo) local_repr->setAttribute(_key.c_str(), svgstr);
110 sp_document_set_undo_sensitive (local_doc, saved);
112 local_doc->setModifiedSinceSave();
114 if (write_undo) {
115 local_repr->setAttribute(_key.c_str(), svgstr);
116 sp_document_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 :