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 = ≀
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 :