4db4363caf76ca7389de0fcfade9975ff0acdcb5
1 /** \file
2 *
3 *
4 * Authors:
5 * Johan Engelen <j.b.c.engelen@utwente.nl>
6 * bulia byak <buliabyak@users.sf.net>
7 * Bryce W. Harrington <bryce@bryceharrington.org>
8 * Lauris Kaplinski <lauris@kaplinski.com>
9 * Jon Phillips <jon@rejon.org>
10 * Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
11 *
12 * Copyright (C) 2000 - 2007 Authors
13 *
14 * Released under GNU GPL. Read the file 'COPYING' for more information
15 */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
22 #include "ui/widget/color-picker.h"
23 #include "ui/widget/registry.h"
24 #include "ui/widget/scalar-unit.h"
25 #include "ui/widget/point.h"
26 #include "ui/widget/random.h"
27 #include "widgets/spinbutton-events.h"
29 #include "helper/units.h"
30 #include "xml/repr.h"
31 #include "svg/svg-color.h"
32 #include "svg/stringstream.h"
34 #include "inkscape.h"
35 #include "document.h"
36 #include "desktop-handles.h"
37 #include "sp-namedview.h"
39 #include "registered-widget.h"
40 #include "verbs.h"
42 // for interruptability bug:
43 #include "display/sp-canvas.h"
45 namespace Inkscape {
46 namespace UI {
47 namespace Widget {
49 //===================================================
51 //---------------------------------------------------
54 void
55 RegisteredWidget::write_to_xml(const char * svgstr)
56 {
57 // Use local repr here. When repr is specified, use that one, but
58 // if repr==NULL, get the repr of namedview of active desktop.
59 Inkscape::XML::Node *local_repr = repr;
60 SPDocument *local_doc = doc;
61 if (!local_repr) {
62 // no repr specified, use active desktop's namedview's repr
63 SPDesktop* dt = SP_ACTIVE_DESKTOP;
64 local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
65 local_doc = sp_desktop_document(dt);
66 }
68 bool saved = sp_document_get_undo_sensitive (local_doc);
69 sp_document_set_undo_sensitive (local_doc, false);
70 if (!write_undo) local_repr->setAttribute(_key.c_str(), svgstr);
71 local_doc->rroot->setAttribute("sodipodi:modified", "true");
72 sp_document_set_undo_sensitive (local_doc, saved);
73 if (write_undo) {
74 local_repr->setAttribute(_key.c_str(), svgstr);
75 sp_document_done (local_doc, event_type, event_description);
76 }
77 }
80 //====================================================
82 RegisteredCheckButton::RegisteredCheckButton()
83 : _button(0)
84 {
85 }
87 RegisteredCheckButton::~RegisteredCheckButton()
88 {
89 _toggled_connection.disconnect();
90 if (_button) delete _button;
91 }
93 void
94 RegisteredCheckButton::init (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
95 {
96 init_parent(key, wr, repr_in, doc_in);
98 _button = new Gtk::CheckButton;
99 _tt.set_tip (*_button, tip);
100 Gtk::Label *l = new Gtk::Label (label);
101 l->set_use_underline (true);
102 _button->add (*manage (l));
103 _button->set_alignment (right? 1.0 : 0.0, 0.5);
104 _toggled_connection = _button->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredCheckButton::on_toggled));
105 }
107 void
108 RegisteredCheckButton::setActive (bool b)
109 {
110 _button->set_active (b);
111 //The slave button is greyed out if the master button is unchecked
112 for (std::list<Gtk::ToggleButton*>::const_iterator i = _slavebuttons.begin(); i != _slavebuttons.end(); i++) {
113 (*i)->set_sensitive(b);
114 }
115 }
117 void
118 RegisteredCheckButton::on_toggled()
119 {
120 if (_wr->isUpdating())
121 return;
123 _wr->setUpdating (true);
125 write_to_xml(_button->get_active() ? "true" : "false");
126 //The slave button is greyed out if the master button is unchecked
127 for (std::list<Gtk::ToggleButton*>::const_iterator i = _slavebuttons.begin(); i != _slavebuttons.end(); i++) {
128 (*i)->set_sensitive(_button->get_active());
129 }
131 write_to_xml(_button->get_active() ? "true" : "false");
133 _wr->setUpdating (false);
134 }
136 RegisteredUnitMenu::RegisteredUnitMenu()
137 : _label(0), _sel(0)
138 {
139 }
141 RegisteredUnitMenu::~RegisteredUnitMenu()
142 {
143 _changed_connection.disconnect();
144 if (_label) delete _label;
145 if (_sel) delete _sel;
146 }
148 void
149 RegisteredUnitMenu::init (const Glib::ustring& label, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
150 {
151 init_parent(key, wr, repr_in, doc_in);
153 _label = new Gtk::Label (label, 1.0, 0.5);
154 _label->set_use_underline (true);
155 _sel = new UnitMenu ();
156 _label->set_mnemonic_widget (*_sel);
157 _sel->setUnitType (UNIT_TYPE_LINEAR);
158 _changed_connection = _sel->signal_changed().connect (sigc::mem_fun (*this, &RegisteredUnitMenu::on_changed));
159 }
161 void
162 RegisteredUnitMenu::setUnit (const SPUnit* unit)
163 {
164 _sel->setUnit (sp_unit_get_abbreviation (unit));
165 }
167 void
168 RegisteredUnitMenu::on_changed()
169 {
170 if (_wr->isUpdating())
171 return;
173 Inkscape::SVGOStringStream os;
174 os << _sel->getUnitAbbr();
176 _wr->setUpdating (true);
178 write_to_xml(os.str().c_str());
180 _wr->setUpdating (false);
181 }
184 RegisteredScalarUnit::RegisteredScalarUnit()
185 : _widget(0), _um(0)
186 {
187 }
189 RegisteredScalarUnit::~RegisteredScalarUnit()
190 {
191 if (_widget) delete _widget;
192 _value_changed_connection.disconnect();
193 }
195 void
196 RegisteredScalarUnit::init (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)
197 {
198 init_parent(key, wr, repr_in, doc_in);
200 _widget = new ScalarUnit (label, tip, UNIT_TYPE_LINEAR, "", "", rum._sel);
201 _widget->initScalar (-1e6, 1e6);
202 _widget->setUnit (rum._sel->getUnitAbbr());
203 _widget->setDigits (2);
204 _um = rum._sel;
205 _value_changed_connection = _widget->signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed));
206 }
208 ScalarUnit*
209 RegisteredScalarUnit::getSU()
210 {
211 return _widget;
212 }
214 void
215 RegisteredScalarUnit::setValue (double val)
216 {
217 _widget->setValue (val);
218 on_value_changed();
219 }
221 void
222 RegisteredScalarUnit::on_value_changed()
223 {
224 if (_wr->isUpdating())
225 return;
227 _wr->setUpdating (true);
229 Inkscape::SVGOStringStream os;
230 os << _widget->getValue("");
231 if (_um)
232 os << _um->getUnitAbbr();
234 write_to_xml(os.str().c_str());
236 _wr->setUpdating (false);
237 }
240 RegisteredScalar::RegisteredScalar()
241 {
242 _widget = NULL;
243 }
245 RegisteredScalar::~RegisteredScalar()
246 {
247 if (_widget)
248 delete _widget;
250 _value_changed_connection.disconnect();
251 }
253 void
254 RegisteredScalar::init ( const Glib::ustring& label, const Glib::ustring& tip,
255 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
256 SPDocument * doc_in )
257 {
258 init_parent(key, wr, repr_in, doc_in);
260 _widget = new Scalar (label, tip);
261 _widget->setRange (-1e6, 1e6);
262 _widget->setDigits (2);
263 _widget->setIncrements(0.1, 1.0);
264 _value_changed_connection = _widget->signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalar::on_value_changed));
265 }
267 Scalar*
268 RegisteredScalar::getS()
269 {
270 return _widget;
271 }
273 void
274 RegisteredScalar::setValue (double val)
275 {
276 _widget->setValue (val);
277 on_value_changed();
278 }
280 void
281 RegisteredScalar::on_value_changed()
282 {
283 if (_wr->isUpdating())
284 return;
285 _wr->setUpdating (true);
287 // FIXME: gtk bug?
288 // disable interruptibility: see http://inkscape.svn.sourceforge.net/viewvc/inkscape/inkscape/trunk/src/ui/widget/selected-style.cpp?r1=13149&r2=13257&sortby=date
289 SPDesktop* dt = SP_ACTIVE_DESKTOP;
290 sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(dt), 0);
292 Inkscape::SVGOStringStream os;
293 os << _widget->getValue();
295 write_to_xml(os.str().c_str());
297 // resume interruptibility
298 sp_canvas_end_forced_full_redraws(sp_desktop_canvas(dt));
300 _wr->setUpdating (false);
301 }
304 RegisteredColorPicker::RegisteredColorPicker()
305 : _label(0), _cp(0)
306 {
307 }
309 RegisteredColorPicker::~RegisteredColorPicker()
310 {
311 _changed_connection.disconnect();
312 if (_cp) delete _cp;
313 if (_label) delete _label;
314 }
316 void
317 RegisteredColorPicker::init (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)
318 {
319 init_parent("", wr, repr_in, doc_in);
321 _label = new Gtk::Label (label, 1.0, 0.5);
322 _label->set_use_underline (true);
323 _cp = new ColorPicker (title,tip,0,true);
324 _label->set_mnemonic_widget (*_cp);
325 _ckey = ckey;
326 _akey = akey;
327 _changed_connection = _cp->connectChanged (sigc::mem_fun (*this, &RegisteredColorPicker::on_changed));
328 }
330 void
331 RegisteredColorPicker::setRgba32 (guint32 rgba)
332 {
333 _cp->setRgba32 (rgba);
334 }
336 void
337 RegisteredColorPicker::closeWindow()
338 {
339 _cp->closeWindow();
340 }
342 void
343 RegisteredColorPicker::on_changed (guint32 rgba)
344 {
345 if (_wr->isUpdating())
346 return;
348 _wr->setUpdating (true);
350 // Use local repr here. When repr is specified, use that one, but
351 // if repr==NULL, get the repr of namedview of active desktop.
352 Inkscape::XML::Node *local_repr = repr;
353 SPDocument *local_doc = doc;
354 if (!local_repr) {
355 // no repr specified, use active desktop's namedview's repr
356 SPDesktop *dt = SP_ACTIVE_DESKTOP;
357 if (!dt)
358 return;
359 local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
360 local_doc = sp_desktop_document(dt);
361 }
363 gchar c[32];
364 sp_svg_write_color(c, 32, rgba);
365 bool saved = sp_document_get_undo_sensitive (local_doc);
366 sp_document_set_undo_sensitive (local_doc, false);
367 local_repr->setAttribute(_ckey.c_str(), c);
368 sp_repr_set_css_double(local_repr, _akey.c_str(), (rgba & 0xff) / 255.0);
369 local_doc->rroot->setAttribute("sodipodi:modified", "true");
370 sp_document_set_undo_sensitive (local_doc, saved);
371 sp_document_done (local_doc, SP_VERB_NONE,
372 /* TODO: annotate */ "registered-widget.cpp: RegisteredColorPicker::on_changed");
374 _wr->setUpdating (false);
375 }
377 RegisteredSuffixedInteger::RegisteredSuffixedInteger()
378 : _label(0), _sb(0),
379 _adj(0.0,0.0,100.0,1.0,1.0,1.0),
380 _suffix(0)
381 {
382 }
384 RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
385 {
386 _changed_connection.disconnect();
387 if (_label) delete _label;
388 if (_suffix) delete _suffix;
389 if (_sb) delete _sb;
390 }
392 void
393 RegisteredSuffixedInteger::init (const Glib::ustring& label, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
394 {
395 init_parent(key, wr, repr_in, doc_in);
397 _label = new Gtk::Label (label);
398 _label->set_alignment (1.0, 0.5);
399 _label->set_use_underline();
400 _sb = new Gtk::SpinButton (_adj, 1.0, 0);
401 _label->set_mnemonic_widget (*_sb);
402 _suffix = new Gtk::Label (suffix);
403 _hbox.pack_start (*_sb, true, true, 0);
404 _hbox.pack_start (*_suffix, false, false, 0);
406 _changed_connection = _adj.signal_value_changed().connect (sigc::mem_fun(*this, &RegisteredSuffixedInteger::on_value_changed));
407 }
409 void
410 RegisteredSuffixedInteger::setValue (int i)
411 {
412 _adj.set_value (i);
413 }
415 void
416 RegisteredSuffixedInteger::on_value_changed()
417 {
418 if (_wr->isUpdating())
419 return;
421 _wr->setUpdating (true);
423 Inkscape::SVGOStringStream os;
424 int value = int(_adj.get_value());
425 os << value;
427 write_to_xml(os.str().c_str());
429 _wr->setUpdating (false);
430 }
432 RegisteredRadioButtonPair::RegisteredRadioButtonPair()
433 : _hbox(0)
434 {
435 }
437 RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
438 {
439 _changed_connection.disconnect();
440 }
442 void
443 RegisteredRadioButtonPair::init (const Glib::ustring& label,
444 const Glib::ustring& label1, const Glib::ustring& label2,
445 const Glib::ustring& tip1, const Glib::ustring& tip2,
446 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
447 {
448 init_parent(key, wr, repr_in, doc_in);
450 _hbox = new Gtk::HBox;
451 _hbox->add (*manage (new Gtk::Label (label)));
452 _rb1 = manage (new Gtk::RadioButton (label1, true));
453 _hbox->add (*_rb1);
454 Gtk::RadioButtonGroup group = _rb1->get_group();
455 _rb2 = manage (new Gtk::RadioButton (group, label2, true));
456 _hbox->add (*_rb2);
457 _rb2->set_active();
458 _tt.set_tip (*_rb1, tip1);
459 _tt.set_tip (*_rb2, tip2);
460 _changed_connection = _rb1->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredRadioButtonPair::on_value_changed));
461 }
463 void
464 RegisteredRadioButtonPair::setValue (bool second)
465 {
466 if (second) _rb2->set_active();
467 else _rb1->set_active();
468 }
470 void
471 RegisteredRadioButtonPair::on_value_changed()
472 {
473 if (_wr->isUpdating())
474 return;
476 _wr->setUpdating (true);
478 bool second = _rb2->get_active();
479 write_to_xml(second ? "true" : "false");
481 _wr->setUpdating (false);
482 }
484 /*#########################################
485 * Registered POINT
486 */
488 RegisteredPoint::RegisteredPoint()
489 {
490 _widget = NULL;
491 }
493 RegisteredPoint::~RegisteredPoint()
494 {
495 if (_widget)
496 delete _widget;
498 _value_x_changed_connection.disconnect();
499 _value_y_changed_connection.disconnect();
500 }
502 void
503 RegisteredPoint::init ( const Glib::ustring& label, const Glib::ustring& tip,
504 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
505 SPDocument* doc_in )
506 {
507 init_parent(key, wr, repr_in, doc_in);
509 _widget = new Point (label, tip);
510 _widget->setRange (-1e6, 1e6);
511 _widget->setDigits (2);
512 _widget->setIncrements(0.1, 1.0);
513 _value_x_changed_connection = _widget->signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
514 _value_y_changed_connection = _widget->signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
515 }
517 Point*
518 RegisteredPoint::getPoint()
519 {
520 return _widget;
521 }
523 void
524 RegisteredPoint::setValue (double xval, double yval)
525 {
526 _widget->setValue(xval, yval);
527 on_value_changed();
528 }
530 void
531 RegisteredPoint::on_value_changed()
532 {
533 if (_wr->isUpdating())
534 return;
536 _wr->setUpdating (true);
538 Inkscape::SVGOStringStream os;
539 os << _widget->getXValue() << "," << _widget->getYValue();
541 write_to_xml(os.str().c_str());
543 _wr->setUpdating (false);
544 }
546 /*#########################################
547 * Registered RANDOM
548 */
550 RegisteredRandom::RegisteredRandom()
551 {
552 _widget = NULL;
553 }
555 RegisteredRandom::~RegisteredRandom()
556 {
557 if (_widget)
558 delete _widget;
560 _value_changed_connection.disconnect();
561 _reseeded_connection.disconnect();
562 }
564 void
565 RegisteredRandom::init ( const Glib::ustring& label, const Glib::ustring& tip,
566 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
567 SPDocument * doc_in )
568 {
569 init_parent(key, wr, repr_in, doc_in);
571 _widget = new Random (label, tip);
572 _widget->setRange (-1e6, 1e6);
573 _widget->setDigits (2);
574 _widget->setIncrements(0.1, 1.0);
575 _value_changed_connection = _widget->signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredRandom::on_value_changed));
576 _reseeded_connection = _widget->signal_reseeded.connect(sigc::mem_fun(*this, &RegisteredRandom::on_value_changed));
577 }
579 Random*
580 RegisteredRandom::getR()
581 {
582 return _widget;
583 }
585 void
586 RegisteredRandom::setValue (double val, long startseed)
587 {
588 _widget->setValue (val);
589 _widget->setStartSeed(startseed);
590 on_value_changed();
591 }
593 void
594 RegisteredRandom::on_value_changed()
595 {
596 if (_wr->isUpdating())
597 return;
598 _wr->setUpdating (true);
600 // FIXME: gtk bug?
601 // disable interruptibility: see http://inkscape.svn.sourceforge.net/viewvc/inkscape/inkscape/trunk/src/ui/widget/selected-style.cpp?r1=13149&r2=13257&sortby=date
602 SPDesktop* dt = SP_ACTIVE_DESKTOP;
603 sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(dt), 0);
605 Inkscape::SVGOStringStream os;
606 os << _widget->getValue() << ';' << _widget->getStartSeed();
608 write_to_xml(os.str().c_str());
610 // resume interruptibility
611 sp_canvas_end_forced_full_redraws(sp_desktop_canvas(dt));
613 _wr->setUpdating (false);
614 }
617 } // namespace Dialog
618 } // namespace UI
619 } // namespace Inkscape
621 /*
622 Local Variables:
623 mode:c++
624 c-file-style:"stroustrup"
625 c-file-offsets:((innamespace . 0)(inline-open . 0))
626 indent-tabs-mode:nil
627 fill-column:99
628 End:
629 */
630 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :