Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
registered-widget.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Authors:
4 * Ralf Stephan <ralf@ark.in-berlin.de>
5 * Johan Engelen <j.b.c.engelen@utwente.nl>
6 * Abhishek Sharma
7 *
8 * Copyright (C) 2005-2008 Authors
9 *
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 *
12 *
13 * Used by Live Path Effects (see src/live_effects/parameter/) and Document Properties dialog.
14 *
15 */
16
17#ifndef SEEN_INKSCAPE_UI_WIDGET_REGISTERED_WIDGET_H
18#define SEEN_INKSCAPE_UI_WIDGET_REGISTERED_WIDGET_H
19
20#include <gtkmm/switch.h>
21#include <utility>
22#include <vector>
23#include <glibmm/ustring.h>
24#include <gtkmm/box.h>
25#include <gtkmm/checkbutton.h>
26#include <gtkmm/togglebutton.h>
27#include <2geom/affine.h>
28
29#include "desktop.h"
30#include "document.h"
31#include "document-undo.h"
32#include "registry.h"
33
34#include <sigc++/scoped_connection.h>
35#include "object/sp-namedview.h"
38#include "ui/widget/point.h"
39#include "ui/widget/random.h"
41#include "ui/widget/scalar.h"
42#include "ui/widget/text.h"
43#include "ui/widget/unit-menu.h"
44#include "xml/node.h"
45
46class SPDocument;
47
48namespace Inkscape::UI::Widget {
49
50class Registry;
51
52template <class W>
53class RegisteredWidget : public W {
54public:
55 void set_undo_parameters(Glib::ustring _event_description, Glib::ustring _icon_name, std::string undo_id = "")
56 {
57 icon_name = std::move(_icon_name);
58 event_description = std::move(_event_description);
59 _undo_id = undo_id;
60 write_undo = true;
61 }
62
64 {
65 repr = xml_node;
66 doc = document;
67 }
68
69 bool is_updating() const { return _wr && _wr->isUpdating(); }
70
71protected:
72 template <typename ...Args>
73 RegisteredWidget(Args &&...args)
74 : W{std::forward<Args>(args)...}
75 {
76 }
77
78 void init_parent(Glib::ustring const &key, Registry &wr,
79 Inkscape::XML::Node * const repr_in, SPDocument * const doc_in)
80 {
81 _wr = &wr;
82 _key = key;
83 repr = repr_in;
84 doc = doc_in;
85 if (repr && !doc) // doc cannot be NULL when repr is not NULL
86 g_warning("Initialization of registered widget using defined repr but with doc==NULL");
87 }
88
89 void write_to_xml(const char * const svgstr)
90 {
91 // Use local repr here. When repr is specified, use that one, but
92 // if repr==NULL, get the repr of namedview of active desktop.
93 Inkscape::XML::Node *local_repr = repr;
94 SPDocument *local_doc = doc;
95 if (!local_repr) {
96 SPDesktop* dt = _wr->desktop();
97 if (!dt) {
98 return;
99 }
100 local_repr = reinterpret_cast<SPObject *>(dt->getNamedView())->getRepr();
101 local_doc = dt->getDocument();
102 }
103 const char * svgstr_old = local_repr->attribute(_key.c_str());
104 {
105 DocumentUndo::ScopedInsensitive _no_undo(local_doc);
106 if (!write_undo) {
107 local_repr->setAttribute(_key, svgstr);
108 }
109 }
110 if (svgstr_old && svgstr && strcmp(svgstr_old,svgstr)) {
111 local_doc->setModifiedSinceSave();
112 }
113
114 if (write_undo) {
115 local_repr->setAttribute(_key, svgstr);
116 if (_undo_id.empty())
118 else
120 }
121 }
122
123 Registry * _wr = nullptr;
124 Glib::ustring _key;
126 SPDocument * doc = nullptr;
127 Glib::ustring event_description;
128 Glib::ustring icon_name; // Used by History dialog.
129 bool write_undo = false;
130 std::string _undo_id;
131};
132
133//#######################################################
134
135class RegisteredCheckButton : public RegisteredWidget<Gtk::CheckButton> {
136public:
137 RegisteredCheckButton(Glib::ustring const &label, Glib::ustring const &tip,
138 Glib::ustring const &key, Registry &wr, bool right = false,
139 Inkscape::XML::Node *repr_in = nullptr, SPDocument *doc_in = nullptr,
140 char const *active_str = "true", char const *inactive_str = "false");
141
142 void setActive(bool);
143
144 // a subordinate button is only sensitive when the main button is active
145 // i.e. a subordinate button is greyed-out when the main button is not checked
146
147 void setSubordinateWidgets(std::vector<Gtk::Widget *> btns) {
148 _subordinate_widgets = std::move(btns);
149 }
150
151 bool setProgrammatically; // true if the value was set by setActive, not changed by the user;
152 // if a callback checks it, it must reset it back to false
153
154private:
155 char const *_active_str = nullptr, *_inactive_str = nullptr;
156 std::vector<Gtk::Widget *> _subordinate_widgets;
157
158 void on_toggled() final;
159};
160
161class RegisteredToggleButton : public RegisteredWidget<Gtk::ToggleButton> {
162public:
163 RegisteredToggleButton(Glib::ustring const &label, Glib::ustring const &tip,
164 Glib::ustring const &key, Registry &wr, bool right = true,
165 Inkscape::XML::Node *repr_in = nullptr, SPDocument *doc_in = nullptr,
166 char const *icon_active = "", char const *icon_inactive = "");
167
168 void setActive(bool);
169
170 // a subordinate button is only sensitive when the main button is active
171 // i.e. a subordinate button is greyed-out when the main button is not checked
172 void setSubordinateWidgets(std::vector<Gtk::Widget *> btns) {
173 _subordinate_widgets = std::move(btns);
174 }
175
176 bool setProgrammatically; // true if the value was set by setActive, not changed by the user;
177 // if a callback checks it, it must reset it back to false
178
179private:
180 std::vector<Gtk::Widget *> _subordinate_widgets;
181 Glib::ustring _on_icon, _off_icon;
182
183 void on_toggled() final;
184};
185
187public:
188 RegisteredSwitchButton(Glib::ustring const &label, Glib::ustring const &tip,
189 Glib::ustring const &key, Registry &wr, bool right = true,
190 Inkscape::XML::Node *repr_in = nullptr, SPDocument *doc_in = nullptr);
191
192 // a subordinate button is only sensitive when the main button is active
193 // i.e. a subordinate button is greyed-out when the main button is not checked
194 void setSubordinateWidgets(std::vector<Gtk::Widget *> btns) {
195 _subordinate_widgets = std::move(btns);
196 }
197
198 bool setProgrammatically = false; // true if the value was set by setActive, not changed by the user;
199 // if a callback checks it, it must reset it back to false
200
201private:
202 std::vector<Gtk::Widget *> _subordinate_widgets;
203};
204
205class RegisteredUnitMenu : public RegisteredWidget<Labelled> {
206public:
207 RegisteredUnitMenu(Glib::ustring const &label,
208 Glib::ustring const &key,
209 Registry &wr,
210 Inkscape::XML::Node *repr_in = nullptr,
211 SPDocument *doc_in = nullptr);
212
213 void setUnit(const Glib::ustring);
214 Unit const * getUnit () const { return getUnitMenu()->getUnit(); };
215 UnitMenu const * getUnitMenu() const { return static_cast<UnitMenu const *>(getWidget()); };
216 UnitMenu * getUnitMenu() { return static_cast<UnitMenu *>(getWidget()); };
217
218private:
219 sigc::scoped_connection _changed_connection;
220
221 void on_changed();
222};
223
224// Allow RegisteredScalarUnit to output lengths in 'user units' (which may have direction dependent
225// scale factors).
231
232class RegisteredScalarUnit : public RegisteredWidget<ScalarUnit> {
233public:
234 RegisteredScalarUnit(Glib::ustring const &label,
235 Glib::ustring const &tip,
236 Glib::ustring const &key,
238 Registry &wr,
239 Inkscape::XML::Node *repr_in = nullptr,
240 SPDocument *doc_in = nullptr,
241 RSU_UserUnits user_units = RSU_none);
242
243protected:
244 void on_value_changed();
245
246private:
247 sigc::scoped_connection _value_changed_connection;
248 UnitMenu const *_um;
250};
251
252class RegisteredScalar : public RegisteredWidget<Scalar> {
253public:
254 RegisteredScalar(Glib::ustring const &label,
255 Glib::ustring const &tip,
256 Glib::ustring const &key,
257 Registry &wr,
258 Inkscape::XML::Node *repr_in = nullptr,
259 SPDocument *doc_in = nullptr);
260
261protected:
262 void on_value_changed();
263
264private:
265 sigc::scoped_connection _value_changed_connection;
266};
267
268class RegisteredText : public RegisteredWidget<Text> {
269public:
270 RegisteredText(Glib::ustring const &label,
271 Glib::ustring const &tip,
272 Glib::ustring const &key,
273 Registry &wr,
274 Inkscape::XML::Node *repr_in = nullptr,
275 SPDocument *doc_in = nullptr);
276
277protected:
278 void on_activate();
279
280private:
281 sigc::scoped_connection _activate_connection;
282};
283
284class RegisteredColorPicker : public RegisteredWidget<LabelledColorPicker> {
285public:
286 RegisteredColorPicker(Glib::ustring const &label,
287 Glib::ustring const &title,
288 Glib::ustring const &tip,
289 Glib::ustring const &ckey,
290 Glib::ustring const &akey,
291 Registry &wr,
292 Inkscape::XML::Node *repr_in = nullptr,
293 SPDocument *doc_in = nullptr);
294
295 void setColor(Colors::Color const &);
296 void closeWindow();
297 void setCustomSetter(std::function<void (Inkscape::XML::Node*, Colors::Color)> setter) { _setter = std::move(setter); }
298
299private:
300 Glib::ustring _ckey, _akey;
301 sigc::scoped_connection _changed_connection;
303 void on_changed(Colors::Color const &);
304};
305
306class RegisteredInteger : public RegisteredWidget<Scalar> {
307public:
308 RegisteredInteger(Glib::ustring const &label,
309 Glib::ustring const &tip,
310 Glib::ustring const &key,
311 Registry &wr,
312 Inkscape::XML::Node *repr_in = nullptr,
313 SPDocument *doc_in = nullptr);
314
315 bool setProgrammatically; // true if the value was set by setValue, not changed by the user;
316 // if a callback checks it, it must reset it back to false
317
318protected:
319 void on_value_changed();
320
321private:
322 sigc::scoped_connection _changed_connection;
323};
324
325
327public:
328 RegisteredTransformedPoint(Glib::ustring const &label,
329 Glib::ustring const &tip,
330 Glib::ustring const &key,
331 Registry &wr,
332 Inkscape::XML::Node *repr_in = nullptr,
333 SPDocument *doc_in = nullptr);
334
335 // redefine setValue, because transform must be applied
336 void setValue(Geom::Point const & p);
337
338 void setTransform(Geom::Affine const & canvas_to_svg);
339
340protected:
341 void on_value_changed();
342
343private:
344 sigc::scoped_connection _value_x_changed_connection;
345 sigc::scoped_connection _value_y_changed_connection;
347};
348
349
350class RegisteredVector : public RegisteredWidget<Point> {
351public:
352 RegisteredVector(Glib::ustring const &label,
353 Glib::ustring const &tip,
354 Glib::ustring const &key,
355 Registry &wr,
356 Inkscape::XML::Node *repr_in = nullptr,
357 SPDocument *doc_in = nullptr);
358
359 // redefine setValue, because transform must be applied
360 void setValue(Geom::Point const & p);
361 void setValue(Geom::Point const & p, Geom::Point const & origin);
362
368 void setPolarCoords(bool polar_coords = true);
369
370protected:
371 void on_value_changed();
372
373private:
374 sigc::scoped_connection _value_x_changed_connection;
375 sigc::scoped_connection _value_y_changed_connection;
378};
379
380
381class RegisteredRandom : public RegisteredWidget<Random> {
382public:
383 RegisteredRandom(Glib::ustring const &label,
384 Glib::ustring const &tip,
385 Glib::ustring const &key,
386 Registry &wr,
387 Inkscape::XML::Node *repr_in = nullptr,
388 SPDocument *doc_in = nullptr);
389
390 void setValue(double val, long startseed);
391
392protected:
393 void on_value_changed();
394
395private:
396 sigc::scoped_connection _value_changed_connection;
397 sigc::scoped_connection _reseeded_connection;
398};
399
400class RegisteredFontButton : public RegisteredWidget<FontButton> {
401public:
402 RegisteredFontButton(Glib::ustring const &label,
403 Glib::ustring const &tip,
404 Glib::ustring const &key,
405 Registry &wr,
406 Inkscape::XML::Node *repr_in = nullptr,
407 SPDocument *doc_in = nullptr);
408
409 void setValue(Glib::ustring fontspec);
410
411protected:
412 void on_value_changed();
413
414private:
415 sigc::scoped_connection _signal_font_set;
416};
417
418} // namespace Inkscape::UI::Widget
419
420#endif // SEEN_INKSCAPE_UI_WIDGET_REGISTERED_WIDGET_H
421
422/*
423 Local Variables:
424 mode:c++
425 c-file-style:"stroustrup"
426 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
427 indent-tabs-mode:nil
428 fill-column:99
429 End:
430*/
431// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Point origin
Definition aa.cpp:227
3x3 affine transformation matrix.
3x3 matrix representing an affine transformation.
Definition affine.h:70
Two-dimensional point that doubles as a vector.
Definition point.h:66
RAII-style mechanism for creating a temporary undo-insensitive context.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
void setSubordinateWidgets(std::vector< Gtk::Widget * > btns)
std::vector< Gtk::Widget * > _subordinate_widgets
void setCustomSetter(std::function< void(Inkscape::XML::Node *, Colors::Color)> setter)
std::function< void(Inkscape::XML::Node *, Colors::Color)> _setter
sigc::scoped_connection _value_changed_connection
sigc::scoped_connection _value_changed_connection
std::vector< Gtk::Widget * > _subordinate_widgets
void setSubordinateWidgets(std::vector< Gtk::Widget * > btns)
sigc::scoped_connection _activate_connection
void setSubordinateWidgets(std::vector< Gtk::Widget * > btns)
std::vector< Gtk::Widget * > _subordinate_widgets
sigc::scoped_connection _value_x_changed_connection
sigc::scoped_connection _value_y_changed_connection
void set_xml_target(Inkscape::XML::Node *xml_node, SPDocument *document)
void write_to_xml(const char *const svgstr)
void init_parent(Glib::ustring const &key, Registry &wr, Inkscape::XML::Node *const repr_in, SPDocument *const doc_in)
void set_undo_parameters(Glib::ustring _event_description, Glib::ustring _icon_name, std::string undo_id="")
SPDesktop * desktop() const
Definition registry.h:27
A drop down menu for choosing unit types.
Definition unit-menu.h:31
Interface for refcounted XML nodes.
Definition node.h:80
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
Definition node.cpp:25
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
To do: update description of desktop.
Definition desktop.h:149
SPDocument * getDocument() const
Definition desktop.h:189
SPNamedView * getNamedView() const
Definition desktop.h:191
Typed SVG document implementation.
Definition document.h:101
void setModifiedSinceSave(bool const modified=true)
Indicate to the user if the document has been modified since the last save by displaying a "*" in fro...
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
Color picker button and window.
Editable view implementation.
TODO: insert short description here.
Glib::ustring label
Definition desktop.h:50
Custom widgets.
Definition desktop.h:126
STL namespace.
static cairo_user_data_key_t key
Interface for XML nodes.