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/random.h"
28 #include "ui/widget/unit-menu.h"
29 #include "ui/widget/color-picker.h"
30 #include "inkscape.h"
32 #include "document.h"
33 #include "desktop-handles.h"
34 #include "sp-namedview.h"
36 class SPUnit;
37 class SPDocument;
39 namespace Gtk {
40 class HScale;
41 class RadioButton;
42 class SpinButton;
43 }
45 namespace Inkscape {
46 namespace UI {
47 namespace Widget {
49 class Registry;
51 template <class W>
52 class RegisteredWidget : public W {
53 public:
54 void set_undo_parameters(const unsigned int _event_type, Glib::ustring _event_description)
55 {
56 event_type = _event_type;
57 event_description = _event_description;
58 write_undo = true;
59 }
61 bool is_updating() {if (_wr) return _wr->isUpdating(); else return false;}
63 // provide automatic 'upcast' for ease of use. (do it 'dynamic_cast' instead of 'static' because who knows what W is)
64 operator const Gtk::Widget () { return dynamic_cast<Gtk::Widget*>(this); }
66 protected:
67 RegisteredWidget() : W() { construct(); }
68 template< typename A >
69 explicit RegisteredWidget( A& a ): W( a ) { construct(); }
70 template< typename A, typename B >
71 RegisteredWidget( A& a, B& b ): W( a, b ) { construct(); }
72 template< typename A, typename B, typename C >
73 RegisteredWidget( A& a, B& b, C* c ): W( a, b, c ) { 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, typename D >
77 RegisteredWidget( A& a, B& b, C c, D d ): W( a, b, c, d ) { construct(); }
78 template< typename A, typename B, typename C, typename D, typename E , typename F>
79 RegisteredWidget( A& a, B& b, C c, D& d, E& e, F* f): W( a, b, c, d, e, f) { construct(); }
81 virtual ~RegisteredWidget() {};
83 void init_parent(const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
84 {
85 _wr = ≀
86 _key = key;
87 repr = repr_in;
88 doc = doc_in;
89 if (repr && !doc) // doc cannot be NULL when repr is not NULL
90 g_warning("Initialization of registered widget using defined repr but with doc==NULL");
91 }
93 void write_to_xml(const char * svgstr)
94 {
95 // Use local repr here. When repr is specified, use that one, but
96 // if repr==NULL, get the repr of namedview of active desktop.
97 Inkscape::XML::Node *local_repr = repr;
98 SPDocument *local_doc = doc;
99 if (!local_repr) {
100 // no repr specified, use active desktop's namedview's repr
101 SPDesktop* dt = SP_ACTIVE_DESKTOP;
102 local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
103 local_doc = sp_desktop_document(dt);
104 }
106 bool saved = sp_document_get_undo_sensitive (local_doc);
107 sp_document_set_undo_sensitive (local_doc, false);
108 if (!write_undo) local_repr->setAttribute(_key.c_str(), svgstr);
109 sp_document_set_undo_sensitive (local_doc, saved);
111 local_doc->setModifiedSinceSave();
113 if (write_undo) {
114 local_repr->setAttribute(_key.c_str(), svgstr);
115 sp_document_done (local_doc, event_type, event_description);
116 }
117 }
119 Registry * _wr;
120 Glib::ustring _key;
121 Inkscape::XML::Node * repr;
122 SPDocument * doc;
123 unsigned int event_type;
124 Glib::ustring event_description;
125 bool write_undo;
127 private:
128 void construct() {
129 _wr = NULL;
130 repr = NULL;
131 doc = NULL;
132 write_undo = false;
133 }
134 };
136 //#######################################################
138 class RegisteredCheckButton : public RegisteredWidget<Gtk::CheckButton> {
139 public:
140 virtual ~RegisteredCheckButton();
141 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);
143 void setActive (bool);
145 std::list<Gtk::Widget*> _slavewidgets;
147 // a slave button is only sensitive when the master button is active
148 // i.e. a slave button is greyed-out when the master button is not checked
150 void setSlaveWidgets(std::list<Gtk::Widget*> btns) {
151 _slavewidgets = btns;
152 }
154 bool setProgrammatically; // true if the value was set by setActive, not changed by the user;
155 // if a callback checks it, it must reset it back to false
157 protected:
158 Gtk::Tooltips _tt;
159 sigc::connection _toggled_connection;
160 void on_toggled();
161 };
163 class RegisteredUnitMenu : public RegisteredWidget<Labelled> {
164 public:
165 ~RegisteredUnitMenu();
166 RegisteredUnitMenu ( const Glib::ustring& label,
167 const Glib::ustring& key,
168 Registry& wr,
169 Inkscape::XML::Node* repr_in = NULL,
170 SPDocument *doc_in = NULL );
172 void setUnit (const SPUnit*);
173 Unit getUnit() const { return static_cast<UnitMenu*>(_widget)->getUnit(); };
174 UnitMenu* getUnitMenu() const { return static_cast<UnitMenu*>(_widget); };
175 sigc::connection _changed_connection;
177 protected:
178 void on_changed();
179 };
181 class RegisteredScalarUnit : public RegisteredWidget<ScalarUnit> {
182 public:
183 ~RegisteredScalarUnit();
184 RegisteredScalarUnit ( const Glib::ustring& label,
185 const Glib::ustring& tip,
186 const Glib::ustring& key,
187 const RegisteredUnitMenu &rum,
188 Registry& wr,
189 Inkscape::XML::Node* repr_in = NULL,
190 SPDocument *doc_in = NULL );
192 protected:
193 sigc::connection _value_changed_connection;
194 UnitMenu *_um;
195 void on_value_changed();
196 };
198 class RegisteredScalar : public RegisteredWidget<Scalar> {
199 public:
200 virtual ~RegisteredScalar();
201 RegisteredScalar (const Glib::ustring& label,
202 const Glib::ustring& tip,
203 const Glib::ustring& key,
204 Registry& wr,
205 Inkscape::XML::Node* repr_in = NULL,
206 SPDocument *doc_in = NULL );
208 protected:
209 sigc::connection _value_changed_connection;
210 void on_value_changed();
211 };
213 class RegisteredColorPicker : public RegisteredWidget<ColorPicker> {
214 public:
215 virtual ~RegisteredColorPicker();
217 RegisteredColorPicker (const Glib::ustring& label,
218 const Glib::ustring& title,
219 const Glib::ustring& tip,
220 const Glib::ustring& ckey,
221 const Glib::ustring& akey,
222 Registry& wr,
223 Inkscape::XML::Node* repr_in = NULL,
224 SPDocument *doc_in = NULL);
226 void setRgba32 (guint32);
227 void closeWindow();
229 Gtk::Label *_label;
231 protected:
232 Glib::ustring _ckey, _akey;
233 void on_changed (guint32);
234 sigc::connection _changed_connection;
235 };
237 class RegisteredSuffixedInteger : public RegisteredWidget<Scalar> {
238 public:
239 virtual ~RegisteredSuffixedInteger();
240 RegisteredSuffixedInteger ( const Glib::ustring& label,
241 const Glib::ustring& tip,
242 const Glib::ustring& suffix,
243 const Glib::ustring& key,
244 Registry& wr,
245 Inkscape::XML::Node* repr_in = NULL,
246 SPDocument *doc_in = NULL );
248 bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
249 // if a callback checks it, it must reset it back to false
251 protected:
252 sigc::connection _changed_connection;
253 void on_value_changed();
254 };
256 class RegisteredRadioButtonPair : public RegisteredWidget<Gtk::HBox> {
257 public:
258 virtual ~RegisteredRadioButtonPair();
259 RegisteredRadioButtonPair ( const Glib::ustring& label,
260 const Glib::ustring& label1,
261 const Glib::ustring& label2,
262 const Glib::ustring& tip1,
263 const Glib::ustring& tip2,
264 const Glib::ustring& key,
265 Registry& wr,
266 Inkscape::XML::Node* repr_in = NULL,
267 SPDocument *doc_in = NULL );
269 void setValue (bool second);
271 bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
272 // if a callback checks it, it must reset it back to false
273 protected:
274 Gtk::RadioButton *_rb1, *_rb2;
275 Gtk::Tooltips _tt;
276 sigc::connection _changed_connection;
277 void on_value_changed();
278 };
280 class RegisteredPoint : public RegisteredWidget<Point> {
281 public:
282 virtual ~RegisteredPoint();
283 RegisteredPoint ( const Glib::ustring& label,
284 const Glib::ustring& tip,
285 const Glib::ustring& key,
286 Registry& wr,
287 Inkscape::XML::Node* repr_in = NULL,
288 SPDocument *doc_in = NULL );
290 protected:
291 sigc::connection _value_x_changed_connection;
292 sigc::connection _value_y_changed_connection;
293 void on_value_changed();
294 };
297 class RegisteredTransformedPoint : public RegisteredWidget<Point> {
298 public:
299 virtual ~RegisteredTransformedPoint();
300 RegisteredTransformedPoint ( const Glib::ustring& label,
301 const Glib::ustring& tip,
302 const Glib::ustring& key,
303 Registry& wr,
304 Inkscape::XML::Node* repr_in = NULL,
305 SPDocument *doc_in = NULL );
307 // redefine setValue, because transform must be applied
308 void setValue(Geom::Point const & p);
310 void setTransform(Geom::Matrix const & canvas_to_svg);
312 protected:
313 sigc::connection _value_x_changed_connection;
314 sigc::connection _value_y_changed_connection;
315 void on_value_changed();
317 Geom::Matrix to_svg;
318 };
321 class RegisteredRandom : public RegisteredWidget<Random> {
322 public:
323 virtual ~RegisteredRandom();
324 RegisteredRandom ( const Glib::ustring& label,
325 const Glib::ustring& tip,
326 const Glib::ustring& key,
327 Registry& wr,
328 Inkscape::XML::Node* repr_in = NULL,
329 SPDocument *doc_in = NULL);
331 void setValue (double val, long startseed);
333 protected:
334 sigc::connection _value_changed_connection;
335 sigc::connection _reseeded_connection;
336 void on_value_changed();
337 };
339 } // namespace Widget
340 } // namespace UI
341 } // namespace Inkscape
343 #endif // INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
345 /*
346 Local Variables:
347 mode:c++
348 c-file-style:"stroustrup"
349 c-file-offsets:((innamespace . 0)(inline-open . 0))
350 indent-tabs-mode:nil
351 fill-column:99
352 End:
353 */
354 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :