1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Authors:
4 * Johan Engelen <j.b.c.engelen@utwente.nl>
5 * bulia byak <buliabyak@users.sf.net>
6 * Bryce W. Harrington <bryce@bryceharrington.org>
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * Jon Phillips <jon@rejon.org>
9 * Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
10 * Abhishek Sharma
11 *
12 * Copyright (C) 2000 - 2007 Authors
13 *
14 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
15 */
16
17 #include "registered-widget.h"
18
19 #include <gtkmm/radiobutton.h>
20
21 #include "verbs.h"
22
23 #include "object/sp-root.h"
24
25 #include "svg/svg-color.h"
26 #include "svg/stringstream.h"
27
28 #include <glibmm/i18n.h>
29
30 namespace Inkscape {
31 namespace UI {
32 namespace Widget {
33
34 /*#########################################
35 * Registered CHECKBUTTON
36 */
37
~RegisteredCheckButton()38 RegisteredCheckButton::~RegisteredCheckButton()
39 {
40 _toggled_connection.disconnect();
41 }
42
RegisteredCheckButton(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,bool right,Inkscape::XML::Node * repr_in,SPDocument * doc_in,char const * active_str,char const * inactive_str)43 RegisteredCheckButton::RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str)
44 : RegisteredWidget<Gtk::CheckButton>()
45 , _active_str(active_str)
46 , _inactive_str(inactive_str)
47 {
48 init_parent(key, wr, repr_in, doc_in);
49
50 setProgrammatically = false;
51
52 set_tooltip_text (tip);
53 Gtk::Label *l = new Gtk::Label();
54 l->set_markup(label);
55 l->set_use_underline (true);
56 add (*manage (l));
57
58 if(right) set_halign(Gtk::ALIGN_END);
59 else set_halign(Gtk::ALIGN_START);
60
61 set_valign(Gtk::ALIGN_CENTER);
62 _toggled_connection = signal_toggled().connect (sigc::mem_fun (*this, &RegisteredCheckButton::on_toggled));
63 }
64
65 void
setActive(bool b)66 RegisteredCheckButton::setActive (bool b)
67 {
68 setProgrammatically = true;
69 set_active (b);
70 //The slave button is greyed out if the master button is unchecked
71 for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) {
72 (*i)->set_sensitive(b);
73 }
74 setProgrammatically = false;
75 }
76
77 void
on_toggled()78 RegisteredCheckButton::on_toggled()
79 {
80 if (setProgrammatically) {
81 setProgrammatically = false;
82 return;
83 }
84
85 if (_wr->isUpdating())
86 return;
87 _wr->setUpdating (true);
88
89 write_to_xml(get_active() ? _active_str : _inactive_str);
90 //The slave button is greyed out if the master button is unchecked
91 for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) {
92 (*i)->set_sensitive(get_active());
93 }
94
95 _wr->setUpdating (false);
96 }
97
98 /*#########################################
99 * Registered TOGGLEBUTTON
100 */
101
~RegisteredToggleButton()102 RegisteredToggleButton::~RegisteredToggleButton()
103 {
104 _toggled_connection.disconnect();
105 }
106
RegisteredToggleButton(const Glib::ustring &,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,bool right,Inkscape::XML::Node * repr_in,SPDocument * doc_in,char const * icon_active,char const * icon_inactive)107 RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& /*label*/, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *icon_active, char const *icon_inactive)
108 : RegisteredWidget<Gtk::ToggleButton>()
109 {
110 init_parent(key, wr, repr_in, doc_in);
111 setProgrammatically = false;
112 set_tooltip_text (tip);
113
114 if(right) set_halign(Gtk::ALIGN_END);
115 else set_halign(Gtk::ALIGN_START);
116
117 set_valign(Gtk::ALIGN_CENTER);
118 _toggled_connection = signal_toggled().connect (sigc::mem_fun (*this, &RegisteredToggleButton::on_toggled));
119 }
120
121 void
setActive(bool b)122 RegisteredToggleButton::setActive (bool b)
123 {
124 setProgrammatically = true;
125 set_active (b);
126 //The slave button is greyed out if the master button is untoggled
127 for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) {
128 (*i)->set_sensitive(b);
129 }
130 setProgrammatically = false;
131 }
132
133 void
on_toggled()134 RegisteredToggleButton::on_toggled()
135 {
136 if (setProgrammatically) {
137 setProgrammatically = false;
138 return;
139 }
140
141 if (_wr->isUpdating())
142 return;
143 _wr->setUpdating (true);
144
145 write_to_xml(get_active() ? "true" : "false");
146 //The slave button is greyed out if the master button is untoggled
147 for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) {
148 (*i)->set_sensitive(get_active());
149 }
150
151 _wr->setUpdating (false);
152 }
153
154 /*#########################################
155 * Registered UNITMENU
156 */
157
~RegisteredUnitMenu()158 RegisteredUnitMenu::~RegisteredUnitMenu()
159 {
160 _changed_connection.disconnect();
161 }
162
RegisteredUnitMenu(const Glib::ustring & label,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)163 RegisteredUnitMenu::RegisteredUnitMenu (const Glib::ustring& label, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
164 : RegisteredWidget<Labelled> (label, "" /*tooltip*/, new UnitMenu())
165 {
166 init_parent(key, wr, repr_in, doc_in);
167
168 getUnitMenu()->setUnitType (UNIT_TYPE_LINEAR);
169 _changed_connection = getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &RegisteredUnitMenu::on_changed));
170 }
171
172 void
setUnit(Glib::ustring unit)173 RegisteredUnitMenu::setUnit (Glib::ustring unit)
174 {
175 getUnitMenu()->setUnit(unit);
176 }
177
178 void
on_changed()179 RegisteredUnitMenu::on_changed()
180 {
181 if (_wr->isUpdating())
182 return;
183
184 Inkscape::SVGOStringStream os;
185 os << getUnitMenu()->getUnitAbbr();
186
187 _wr->setUpdating (true);
188
189 write_to_xml(os.str().c_str());
190
191 _wr->setUpdating (false);
192 }
193
194
195 /*#########################################
196 * Registered SCALARUNIT
197 */
198
~RegisteredScalarUnit()199 RegisteredScalarUnit::~RegisteredScalarUnit()
200 {
201 _value_changed_connection.disconnect();
202 }
203
RegisteredScalarUnit(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,const RegisteredUnitMenu & rum,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in,RSU_UserUnits user_units)204 RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in, RSU_UserUnits user_units)
205 : RegisteredWidget<ScalarUnit>(label, tip, UNIT_TYPE_LINEAR, "", "", rum.getUnitMenu()),
206 _um(nullptr)
207 {
208 init_parent(key, wr, repr_in, doc_in);
209
210 setProgrammatically = false;
211
212 initScalar (-1e6, 1e6);
213 setUnit (rum.getUnitMenu()->getUnitAbbr());
214 setDigits (2);
215 _um = rum.getUnitMenu();
216 _user_units = user_units;
217 _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed));
218 }
219
220
221 void
on_value_changed()222 RegisteredScalarUnit::on_value_changed()
223 {
224 if (setProgrammatically) {
225 setProgrammatically = false;
226 return;
227 }
228
229 if (_wr->isUpdating())
230 return;
231
232 _wr->setUpdating (true);
233
234 Inkscape::SVGOStringStream os;
235 if (_user_units != RSU_none) {
236 // Output length in 'user units', taking into account scale in 'x' or 'y'.
237 double scale = 1.0;
238 if (doc) {
239 SPRoot *root = doc->getRoot();
240 if (root->viewBox_set) {
241 // check to see if scaling is uniform
242 if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) {
243 scale = (root->viewBox.width() / root->width.computed + root->viewBox.height() / root->height.computed)/2.0;
244 } else if (_user_units == RSU_x) {
245 scale = root->viewBox.width() / root->width.computed;
246 } else {
247 scale = root->viewBox.height() / root->height.computed;
248 }
249 }
250 }
251 os << getValue("px") * scale;
252 } else {
253 // Output using unit identifiers.
254 os << getValue("");
255 if (_um)
256 os << _um->getUnitAbbr();
257 }
258
259 write_to_xml(os.str().c_str());
260 _wr->setUpdating (false);
261 }
262
263
264 /*#########################################
265 * Registered SCALAR
266 */
267
~RegisteredScalar()268 RegisteredScalar::~RegisteredScalar()
269 {
270 _value_changed_connection.disconnect();
271 }
272
RegisteredScalar(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)273 RegisteredScalar::RegisteredScalar ( const Glib::ustring& label, const Glib::ustring& tip,
274 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
275 SPDocument * doc_in )
276 : RegisteredWidget<Scalar>(label, tip)
277 {
278 init_parent(key, wr, repr_in, doc_in);
279
280 setProgrammatically = false;
281 setRange (-1e6, 1e6);
282 setDigits (2);
283 setIncrements(0.1, 1.0);
284 _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalar::on_value_changed));
285 }
286
287 void
on_value_changed()288 RegisteredScalar::on_value_changed()
289 {
290 if (setProgrammatically) {
291 setProgrammatically = false;
292 return;
293 }
294 if (_wr->isUpdating()) {
295 return;
296 }
297 _wr->setUpdating (true);
298
299 Inkscape::SVGOStringStream os;
300 //Force exact 0 if decimals over to 6
301 double val = getValue() < 1e-6 && getValue() > -1e-6?0.0:getValue();
302 os << val;
303 //TODO: Test is ok remove this sensitives
304 //also removed in registered text and in registered random
305 //set_sensitive(false);
306 write_to_xml(os.str().c_str());
307 //set_sensitive(true);
308 _wr->setUpdating (false);
309 }
310
311
312 /*#########################################
313 * Registered TEXT
314 */
315
~RegisteredText()316 RegisteredText::~RegisteredText()
317 {
318 _activate_connection.disconnect();
319 }
320
RegisteredText(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)321 RegisteredText::RegisteredText ( const Glib::ustring& label, const Glib::ustring& tip,
322 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
323 SPDocument * doc_in )
324 : RegisteredWidget<Text>(label, tip)
325 {
326 init_parent(key, wr, repr_in, doc_in);
327
328 setProgrammatically = false;
329 _activate_connection = signal_activate().connect (sigc::mem_fun (*this, &RegisteredText::on_activate));
330 }
331
332 void
on_activate()333 RegisteredText::on_activate()
334 {
335 if (setProgrammatically) {
336 setProgrammatically = false;
337 return;
338 }
339
340 if (_wr->isUpdating()) {
341 return;
342 }
343 _wr->setUpdating (true);
344 Glib::ustring str(getText());
345 Inkscape::SVGOStringStream os;
346 os << str;
347 write_to_xml(os.str().c_str());
348 _wr->setUpdating (false);
349 }
350
351
352 /*#########################################
353 * Registered COLORPICKER
354 */
355
RegisteredColorPicker(const Glib::ustring & label,const Glib::ustring & title,const Glib::ustring & tip,const Glib::ustring & ckey,const Glib::ustring & akey,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)356 RegisteredColorPicker::RegisteredColorPicker(const Glib::ustring& label,
357 const Glib::ustring& title,
358 const Glib::ustring& tip,
359 const Glib::ustring& ckey,
360 const Glib::ustring& akey,
361 Registry& wr,
362 Inkscape::XML::Node* repr_in,
363 SPDocument *doc_in)
364 : RegisteredWidget<LabelledColorPicker> (label, title, tip, 0, true)
365 {
366 init_parent("", wr, repr_in, doc_in);
367
368 _ckey = ckey;
369 _akey = akey;
370 _changed_connection = connectChanged (sigc::mem_fun (*this, &RegisteredColorPicker::on_changed));
371 }
372
~RegisteredColorPicker()373 RegisteredColorPicker::~RegisteredColorPicker()
374 {
375 _changed_connection.disconnect();
376 }
377
378 void
setRgba32(guint32 rgba)379 RegisteredColorPicker::setRgba32 (guint32 rgba)
380 {
381 LabelledColorPicker::setRgba32 (rgba);
382 }
383
384 void
closeWindow()385 RegisteredColorPicker::closeWindow()
386 {
387 LabelledColorPicker::closeWindow();
388 }
389
390 void
on_changed(guint32 rgba)391 RegisteredColorPicker::on_changed (guint32 rgba)
392 {
393 if (_wr->isUpdating())
394 return;
395
396 _wr->setUpdating (true);
397
398 // Use local repr here. When repr is specified, use that one, but
399 // if repr==NULL, get the repr of namedview of active desktop.
400 Inkscape::XML::Node *local_repr = repr;
401 SPDocument *local_doc = doc;
402 if (!local_repr) {
403 SPDesktop *dt = _wr->desktop();
404 if (!dt) {
405 _wr->setUpdating(false);
406 return;
407 }
408 local_repr = dt->getNamedView()->getRepr();
409 local_doc = dt->getDocument();
410 }
411 gchar c[32];
412 if (_akey == _ckey + "_opacity_LPE") { //For LPE parameter we want stored with alpha
413 sprintf(c, "#%08x", rgba);
414 } else {
415 sp_svg_write_color(c, sizeof(c), rgba);
416 }
417 bool saved = DocumentUndo::getUndoSensitive(local_doc);
418 DocumentUndo::setUndoSensitive(local_doc, false);
419 local_repr->setAttribute(_ckey, c);
420 sp_repr_set_css_double(local_repr, _akey.c_str(), (rgba & 0xff) / 255.0);
421 DocumentUndo::setUndoSensitive(local_doc, saved);
422
423 local_doc->setModifiedSinceSave();
424 DocumentUndo::done(local_doc, SP_VERB_NONE,
425 /* TODO: annotate */ "registered-widget.cpp: RegisteredColorPicker::on_changed");
426
427 _wr->setUpdating (false);
428 }
429
430
431 /*#########################################
432 * Registered SUFFIXEDINTEGER
433 */
434
~RegisteredSuffixedInteger()435 RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
436 {
437 _changed_connection.disconnect();
438 }
439
RegisteredSuffixedInteger(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & suffix,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)440 RegisteredSuffixedInteger::RegisteredSuffixedInteger (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
441 : RegisteredWidget<Scalar>(label, tip, 0, suffix),
442 setProgrammatically(false)
443 {
444 init_parent(key, wr, repr_in, doc_in);
445
446 setRange (0, 1e6);
447 setDigits (0);
448 setIncrements(1, 10);
449
450 _changed_connection = signal_value_changed().connect (sigc::mem_fun(*this, &RegisteredSuffixedInteger::on_value_changed));
451 }
452
453 void
on_value_changed()454 RegisteredSuffixedInteger::on_value_changed()
455 {
456 if (setProgrammatically) {
457 setProgrammatically = false;
458 return;
459 }
460
461 if (_wr->isUpdating())
462 return;
463
464 _wr->setUpdating (true);
465
466 Inkscape::SVGOStringStream os;
467 os << getValue();
468
469 write_to_xml(os.str().c_str());
470
471 _wr->setUpdating (false);
472 }
473
474
475 /*#########################################
476 * Registered RADIOBUTTONPAIR
477 */
478
~RegisteredRadioButtonPair()479 RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
480 {
481 _changed_connection.disconnect();
482 }
483
RegisteredRadioButtonPair(const Glib::ustring & label,const Glib::ustring & label1,const Glib::ustring & label2,const Glib::ustring & tip1,const Glib::ustring & tip2,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)484 RegisteredRadioButtonPair::RegisteredRadioButtonPair (const Glib::ustring& label,
485 const Glib::ustring& label1, const Glib::ustring& label2,
486 const Glib::ustring& tip1, const Glib::ustring& tip2,
487 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
488 : RegisteredWidget<Gtk::Box>(),
489 _rb1(nullptr),
490 _rb2(nullptr)
491 {
492 init_parent(key, wr, repr_in, doc_in);
493
494 setProgrammatically = false;
495
496 set_orientation(Gtk::ORIENTATION_HORIZONTAL);
497 add(*Gtk::manage(new Gtk::Label(label)));
498 _rb1 = Gtk::manage(new Gtk::RadioButton(label1, true));
499 add (*_rb1);
500 Gtk::RadioButtonGroup group = _rb1->get_group();
501 _rb2 = Gtk::manage(new Gtk::RadioButton(group, label2, true));
502 add (*_rb2);
503 _rb2->set_active();
504 _rb1->set_tooltip_text(tip1);
505 _rb2->set_tooltip_text(tip2);
506 _changed_connection = _rb1->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredRadioButtonPair::on_value_changed));
507 }
508
509 void
setValue(bool second)510 RegisteredRadioButtonPair::setValue (bool second)
511 {
512 if (!_rb1 || !_rb2)
513 return;
514
515 setProgrammatically = true;
516 if (second) {
517 _rb2->set_active();
518 } else {
519 _rb1->set_active();
520 }
521 }
522
523 void
on_value_changed()524 RegisteredRadioButtonPair::on_value_changed()
525 {
526 if (setProgrammatically) {
527 setProgrammatically = false;
528 return;
529 }
530
531 if (_wr->isUpdating())
532 return;
533
534 _wr->setUpdating (true);
535
536 bool second = _rb2->get_active();
537 write_to_xml(second ? "true" : "false");
538
539 _wr->setUpdating (false);
540 }
541
542
543 /*#########################################
544 * Registered POINT
545 */
546
~RegisteredPoint()547 RegisteredPoint::~RegisteredPoint()
548 {
549 _value_x_changed_connection.disconnect();
550 _value_y_changed_connection.disconnect();
551 }
552
RegisteredPoint(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)553 RegisteredPoint::RegisteredPoint ( const Glib::ustring& label, const Glib::ustring& tip,
554 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
555 SPDocument* doc_in )
556 : RegisteredWidget<Point> (label, tip)
557 {
558 init_parent(key, wr, repr_in, doc_in);
559
560 setRange (-1e6, 1e6);
561 setDigits (2);
562 setIncrements(0.1, 1.0);
563 _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
564 _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
565 }
566
567 void
on_value_changed()568 RegisteredPoint::on_value_changed()
569 {
570 if (setProgrammatically()) {
571 clearProgrammatically();
572 return;
573 }
574
575 if (_wr->isUpdating())
576 return;
577
578 _wr->setUpdating (true);
579
580 Inkscape::SVGOStringStream os;
581 os << getXValue() << "," << getYValue();
582
583 write_to_xml(os.str().c_str());
584
585 _wr->setUpdating (false);
586 }
587
588 /*#########################################
589 * Registered TRANSFORMEDPOINT
590 */
591
~RegisteredTransformedPoint()592 RegisteredTransformedPoint::~RegisteredTransformedPoint()
593 {
594 _value_x_changed_connection.disconnect();
595 _value_y_changed_connection.disconnect();
596 }
597
RegisteredTransformedPoint(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)598 RegisteredTransformedPoint::RegisteredTransformedPoint ( const Glib::ustring& label, const Glib::ustring& tip,
599 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
600 SPDocument* doc_in )
601 : RegisteredWidget<Point> (label, tip),
602 to_svg(Geom::identity())
603 {
604 init_parent(key, wr, repr_in, doc_in);
605
606 setRange (-1e6, 1e6);
607 setDigits (2);
608 setIncrements(0.1, 1.0);
609 _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredTransformedPoint::on_value_changed));
610 _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredTransformedPoint::on_value_changed));
611 }
612
613 void
setValue(Geom::Point const & p)614 RegisteredTransformedPoint::setValue(Geom::Point const & p)
615 {
616 Geom::Point new_p = p * to_svg.inverse();
617 Point::setValue(new_p); // the Point widget should display things in canvas coordinates
618 }
619
620 void
setTransform(Geom::Affine const & canvas_to_svg)621 RegisteredTransformedPoint::setTransform(Geom::Affine const & canvas_to_svg)
622 {
623 // check if matrix is singular / has inverse
624 if ( ! canvas_to_svg.isSingular() ) {
625 to_svg = canvas_to_svg;
626 } else {
627 // set back to default
628 to_svg = Geom::identity();
629 }
630 }
631
632 void
on_value_changed()633 RegisteredTransformedPoint::on_value_changed()
634 {
635 if (setProgrammatically()) {
636 clearProgrammatically();
637 return;
638 }
639
640 if (_wr->isUpdating())
641 return;
642
643 _wr->setUpdating (true);
644
645 Geom::Point pos = getValue() * to_svg;
646
647 Inkscape::SVGOStringStream os;
648 os << pos;
649
650 write_to_xml(os.str().c_str());
651
652 _wr->setUpdating (false);
653 }
654
655 /*#########################################
656 * Registered TRANSFORMEDPOINT
657 */
658
~RegisteredVector()659 RegisteredVector::~RegisteredVector()
660 {
661 _value_x_changed_connection.disconnect();
662 _value_y_changed_connection.disconnect();
663 }
664
RegisteredVector(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)665 RegisteredVector::RegisteredVector ( const Glib::ustring& label, const Glib::ustring& tip,
666 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
667 SPDocument* doc_in )
668 : RegisteredWidget<Point> (label, tip),
669 _polar_coords(false)
670 {
671 init_parent(key, wr, repr_in, doc_in);
672
673 setRange (-1e6, 1e6);
674 setDigits (2);
675 setIncrements(0.1, 1.0);
676 _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredVector::on_value_changed));
677 _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredVector::on_value_changed));
678 }
679
680 void
setValue(Geom::Point const & p)681 RegisteredVector::setValue(Geom::Point const & p)
682 {
683 if (!_polar_coords) {
684 Point::setValue(p);
685 } else {
686 Geom::Point polar;
687 polar[Geom::X] = atan2(p) *180/M_PI;
688 polar[Geom::Y] = p.length();
689 Point::setValue(polar);
690 }
691 }
692
693 void
setValue(Geom::Point const & p,Geom::Point const & origin)694 RegisteredVector::setValue(Geom::Point const & p, Geom::Point const & origin)
695 {
696 RegisteredVector::setValue(p);
697 _origin = origin;
698 }
699
setPolarCoords(bool polar_coords)700 void RegisteredVector::setPolarCoords(bool polar_coords)
701 {
702 _polar_coords = polar_coords;
703 if (polar_coords) {
704 xwidget.setLabelText(_("Angle:"));
705 ywidget.setLabelText(_("Distance:"));
706 } else {
707 xwidget.setLabelText(_("X:"));
708 ywidget.setLabelText(_("Y:"));
709 }
710 }
711
712 void
on_value_changed()713 RegisteredVector::on_value_changed()
714 {
715 if (setProgrammatically()) {
716 clearProgrammatically();
717 return;
718 }
719
720 if (_wr->isUpdating())
721 return;
722
723 _wr->setUpdating (true);
724
725 Geom::Point origin = _origin;
726 Geom::Point vector = getValue();
727 if (_polar_coords) {
728 vector = Geom::Point::polar(vector[Geom::X]*M_PI/180, vector[Geom::Y]);
729 }
730
731 Inkscape::SVGOStringStream os;
732 os << origin << " , " << vector;
733
734 write_to_xml(os.str().c_str());
735
736 _wr->setUpdating (false);
737 }
738
739 /*#########################################
740 * Registered RANDOM
741 */
742
~RegisteredRandom()743 RegisteredRandom::~RegisteredRandom()
744 {
745 _value_changed_connection.disconnect();
746 _reseeded_connection.disconnect();
747 }
748
RegisteredRandom(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)749 RegisteredRandom::RegisteredRandom ( const Glib::ustring& label, const Glib::ustring& tip,
750 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
751 SPDocument * doc_in )
752 : RegisteredWidget<Random> (label, tip)
753 {
754 init_parent(key, wr, repr_in, doc_in);
755
756 setProgrammatically = false;
757 setRange (-1e6, 1e6);
758 setDigits (2);
759 setIncrements(0.1, 1.0);
760 _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredRandom::on_value_changed));
761 _reseeded_connection = signal_reseeded.connect(sigc::mem_fun(*this, &RegisteredRandom::on_value_changed));
762 }
763
764 void
setValue(double val,long startseed)765 RegisteredRandom::setValue (double val, long startseed)
766 {
767 Scalar::setValue (val);
768 setStartSeed(startseed);
769 }
770
771 void
on_value_changed()772 RegisteredRandom::on_value_changed()
773 {
774 if (setProgrammatically) {
775 setProgrammatically = false;
776 return;
777 }
778
779 if (_wr->isUpdating()) {
780 return;
781 }
782 _wr->setUpdating (true);
783
784 Inkscape::SVGOStringStream os;
785 //Force exact 0 if decimals over to 6
786 double val = getValue() < 1e-6 && getValue() > -1e-6?0.0:getValue();
787 os << val << ';' << getStartSeed();
788 write_to_xml(os.str().c_str());
789 _wr->setUpdating (false);
790 }
791
792 /*#########################################
793 * Registered FONT-BUTTON
794 */
795
~RegisteredFontButton()796 RegisteredFontButton::~RegisteredFontButton()
797 {
798 _signal_font_set.disconnect();
799 }
800
RegisteredFontButton(const Glib::ustring & label,const Glib::ustring & tip,const Glib::ustring & key,Registry & wr,Inkscape::XML::Node * repr_in,SPDocument * doc_in)801 RegisteredFontButton::RegisteredFontButton ( const Glib::ustring& label, const Glib::ustring& tip,
802 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
803 SPDocument* doc_in )
804 : RegisteredWidget<FontButton>(label, tip)
805 {
806 init_parent(key, wr, repr_in, doc_in);
807 _signal_font_set = signal_font_value_changed().connect (sigc::mem_fun (*this, &RegisteredFontButton::on_value_changed));
808 }
809
810 void
setValue(Glib::ustring fontspec)811 RegisteredFontButton::setValue (Glib::ustring fontspec)
812 {
813 FontButton::setValue(fontspec);
814 }
815
816 void
on_value_changed()817 RegisteredFontButton::on_value_changed()
818 {
819
820 if (_wr->isUpdating())
821 return;
822
823 _wr->setUpdating (true);
824
825 Inkscape::SVGOStringStream os;
826 os << getValue();
827
828 write_to_xml(os.str().c_str());
829
830 _wr->setUpdating (false);
831 }
832
833 } // namespace Dialog
834 } // namespace UI
835 } // namespace Inkscape
836
837 /*
838 Local Variables:
839 mode:c++
840 c-file-style:"stroustrup"
841 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
842 indent-tabs-mode:nil
843 fill-column:99
844 End:
845 */
846 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
847