Code

c99fcb5ffc2a3eedb46f99de7296b54e157696bf
[inkscape.git] / src / ui / widget / registered-widget.cpp
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);
71     if (!write_undo) local_repr->setAttribute(_key.c_str(), svgstr);
72     local_doc->rroot->setAttribute("sodipodi:modified", "true");
74     sp_document_set_undo_sensitive (local_doc, saved);
75     if (write_undo) {
76         local_repr->setAttribute(_key.c_str(), svgstr);
77         sp_document_done (local_doc, event_type, event_description);
78     }
79 }
82 //====================================================
84 RegisteredCheckButton::RegisteredCheckButton()
85 : _button(0)
86 {
87 }
89 RegisteredCheckButton::~RegisteredCheckButton()
90 {
91     _toggled_connection.disconnect();
92     if (_button) delete _button;
93 }
95 void
96 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)
97 {
98     init_parent(key, wr, repr_in, doc_in);
100     _button = new Gtk::CheckButton;
101     _tt.set_tip (*_button, tip);
102     Gtk::Label *l = new Gtk::Label (label);
103     l->set_use_underline (true);
104     _button->add (*manage (l));
105     _button->set_alignment (right? 1.0 : 0.0, 0.5);
106     _toggled_connection = _button->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredCheckButton::on_toggled));
109 void
110 RegisteredCheckButton::setActive (bool b)
112     _button->set_active (b);
113         //The slave button is greyed out if the master button is unchecked
114         for (std::list<Gtk::ToggleButton*>::const_iterator i = _slavebuttons.begin(); i != _slavebuttons.end(); i++) {
115                 (*i)->set_sensitive(b);
116         }
119 void
120 RegisteredCheckButton::on_toggled()
122     if (_wr->isUpdating())
123         return;
125     _wr->setUpdating (true);
127     write_to_xml(_button->get_active() ? "true" : "false");
128     //The slave button is greyed out if the master button is unchecked
129     for (std::list<Gtk::ToggleButton*>::const_iterator i = _slavebuttons.begin(); i != _slavebuttons.end(); i++) {
130         (*i)->set_sensitive(_button->get_active());
131     }
133     _wr->setUpdating (false);
136 RegisteredUnitMenu::RegisteredUnitMenu()
137 : _label(0), _sel(0)
141 RegisteredUnitMenu::~RegisteredUnitMenu()
143     _changed_connection.disconnect();
144     if (_label) delete _label;
145     if (_sel) delete _sel;
148 void
149 RegisteredUnitMenu::init (const Glib::ustring& label, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
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));
161 void
162 RegisteredUnitMenu::setUnit (const SPUnit* unit)
164     _sel->setUnit (sp_unit_get_abbreviation (unit));
167 void
168 RegisteredUnitMenu::on_changed()
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);
184 RegisteredScalarUnit::RegisteredScalarUnit()
185 : _widget(0), _um(0)
189 RegisteredScalarUnit::~RegisteredScalarUnit()
191     if (_widget) delete _widget;
192     _value_changed_connection.disconnect();
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)
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));
208 ScalarUnit*
209 RegisteredScalarUnit::getSU()
211     return _widget;
214 void
215 RegisteredScalarUnit::setValue (double val)
217     _widget->setValue (val);
218     on_value_changed();
221 void
222 RegisteredScalarUnit::on_value_changed()
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);
240 RegisteredScalar::RegisteredScalar()
242     _widget = NULL;
245 RegisteredScalar::~RegisteredScalar()
247     if (_widget) 
248         delete _widget;
250     _value_changed_connection.disconnect();
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 )
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));
267 Scalar*
268 RegisteredScalar::getS()
270     return _widget;
273 void
274 RegisteredScalar::setValue (double val)
276     _widget->setValue (val);
277     on_value_changed();
280 void
281 RegisteredScalar::on_value_changed()
283     if (_wr->isUpdating()) {
284         return;
285     }
286     _wr->setUpdating (true);
288     Inkscape::SVGOStringStream os;
289     os << _widget->getValue();
291     _widget->set_sensitive(false);
292     write_to_xml(os.str().c_str());
293     _widget->set_sensitive(true);
295     _wr->setUpdating (false);
299 RegisteredColorPicker::RegisteredColorPicker()
300 : _label(0), _cp(0)
304 RegisteredColorPicker::~RegisteredColorPicker()
306     _changed_connection.disconnect();
307     if (_cp) delete _cp;
308     if (_label) delete _label;
311 void
312 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)
314     init_parent("", wr, repr_in, doc_in);
316     _label = new Gtk::Label (label, 1.0, 0.5);
317     _label->set_use_underline (true);
318     _cp = new ColorPicker (title,tip,0,true);
319     _label->set_mnemonic_widget (*_cp);
320     _ckey = ckey;
321     _akey = akey;
322     _changed_connection = _cp->connectChanged (sigc::mem_fun (*this, &RegisteredColorPicker::on_changed));
325 void
326 RegisteredColorPicker::setRgba32 (guint32 rgba)
328     _cp->setRgba32 (rgba);
331 void
332 RegisteredColorPicker::closeWindow()
334     _cp->closeWindow();
337 void
338 RegisteredColorPicker::on_changed (guint32 rgba)
340     if (_wr->isUpdating())
341         return;
343     _wr->setUpdating (true);
345     // Use local repr here. When repr is specified, use that one, but
346     // if repr==NULL, get the repr of namedview of active desktop.
347     Inkscape::XML::Node *local_repr = repr;
348     SPDocument *local_doc = doc;
349     if (!local_repr) {
350         // no repr specified, use active desktop's namedview's repr
351         SPDesktop *dt = SP_ACTIVE_DESKTOP;
352         if (!dt)
353             return;
354         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
355         local_doc = sp_desktop_document(dt);
356     }
358     gchar c[32];
359     sp_svg_write_color(c, 32, rgba);
360     bool saved = sp_document_get_undo_sensitive (local_doc);
361     sp_document_set_undo_sensitive (local_doc, false);
362     local_repr->setAttribute(_ckey.c_str(), c);
363     sp_repr_set_css_double(local_repr, _akey.c_str(), (rgba & 0xff) / 255.0);
364     local_doc->rroot->setAttribute("sodipodi:modified", "true");
365     sp_document_set_undo_sensitive (local_doc, saved);
366     sp_document_done (local_doc, SP_VERB_NONE,
367                       /* TODO: annotate */ "registered-widget.cpp: RegisteredColorPicker::on_changed");
369     _wr->setUpdating (false);
372 RegisteredSuffixedInteger::RegisteredSuffixedInteger()
373 : _label(0), _sb(0),
374   _adj(0.0,0.0,100.0,1.0,1.0,1.0),
375   _suffix(0)
379 RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
381     _changed_connection.disconnect();
382     if (_label) delete _label;
383     if (_suffix) delete _suffix;
384     if (_sb) delete _sb;
387 void
388 RegisteredSuffixedInteger::init (const Glib::ustring& label, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
390     init_parent(key, wr, repr_in, doc_in);
392     _label = new Gtk::Label (label);
393     _label->set_alignment (1.0, 0.5);
394     _label->set_use_underline();
395     _sb = new Gtk::SpinButton (_adj, 1.0, 0);
396     _label->set_mnemonic_widget (*_sb);
397     _suffix = new Gtk::Label (suffix);
398     _hbox.pack_start (*_sb, true, true, 0);
399     _hbox.pack_start (*_suffix, false, false, 0);
401     _changed_connection = _adj.signal_value_changed().connect (sigc::mem_fun(*this, &RegisteredSuffixedInteger::on_value_changed));
404 void
405 RegisteredSuffixedInteger::setValue (int i)
407     _adj.set_value (i);
410 void
411 RegisteredSuffixedInteger::on_value_changed()
413     if (_wr->isUpdating())
414         return;
416     _wr->setUpdating (true);
418     Inkscape::SVGOStringStream os;
419     int value = int(_adj.get_value());
420     os << value;
422     write_to_xml(os.str().c_str());
424     _wr->setUpdating (false);
427 RegisteredRadioButtonPair::RegisteredRadioButtonPair()
428 : _hbox(0)
432 RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
434     _changed_connection.disconnect();
437 void
438 RegisteredRadioButtonPair::init (const Glib::ustring& label,
439 const Glib::ustring& label1, const Glib::ustring& label2,
440 const Glib::ustring& tip1, const Glib::ustring& tip2,
441 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
443     init_parent(key, wr, repr_in, doc_in);
445     _hbox = new Gtk::HBox;
446     _hbox->add (*manage (new Gtk::Label (label)));
447     _rb1 = manage (new Gtk::RadioButton (label1, true));
448     _hbox->add (*_rb1);
449     Gtk::RadioButtonGroup group = _rb1->get_group();
450     _rb2 = manage (new Gtk::RadioButton (group, label2, true));
451     _hbox->add (*_rb2);
452     _rb2->set_active();
453     _tt.set_tip (*_rb1, tip1);
454     _tt.set_tip (*_rb2, tip2);
455     _changed_connection = _rb1->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredRadioButtonPair::on_value_changed));
458 void
459 RegisteredRadioButtonPair::setValue (bool second)
461     if (second) _rb2->set_active();
462     else        _rb1->set_active();
465 void
466 RegisteredRadioButtonPair::on_value_changed()
468     if (_wr->isUpdating())
469         return;
471     _wr->setUpdating (true);
473     bool second = _rb2->get_active();
474     write_to_xml(second ? "true" : "false");
476     _wr->setUpdating (false);
479 /*#########################################
480  * Registered POINT
481  */
483 RegisteredPoint::RegisteredPoint()
485     _widget = NULL;
488 RegisteredPoint::~RegisteredPoint()
490     if (_widget) 
491         delete _widget;
493     _value_x_changed_connection.disconnect();
494     _value_y_changed_connection.disconnect();
497 void
498 RegisteredPoint::init ( const Glib::ustring& label, const Glib::ustring& tip, 
499                         const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, 
500                         SPDocument* doc_in )
502     init_parent(key, wr, repr_in, doc_in);
504     _widget = new Point (label, tip);
505     _widget->setRange (-1e6, 1e6);
506     _widget->setDigits (2);
507     _widget->setIncrements(0.1, 1.0);
508     _value_x_changed_connection = _widget->signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
509     _value_y_changed_connection = _widget->signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
512 Point*
513 RegisteredPoint::getPoint()
515     return _widget;
518 void
519 RegisteredPoint::setValue (double xval, double yval)
521     _widget->setValue(xval, yval);
522     on_value_changed();
525 void
526 RegisteredPoint::on_value_changed()
528     if (_wr->isUpdating())
529         return;
531     _wr->setUpdating (true);
533     Inkscape::SVGOStringStream os;
534     os << _widget->getXValue() << "," << _widget->getYValue();
536     write_to_xml(os.str().c_str());
538     _wr->setUpdating (false);
541 /*#########################################
542  * Registered RANDOM
543  */
545 RegisteredRandom::RegisteredRandom()
547     _widget = NULL;
550 RegisteredRandom::~RegisteredRandom()
552     if (_widget) 
553         delete _widget;
555     _value_changed_connection.disconnect();
556     _reseeded_connection.disconnect();
559 void
560 RegisteredRandom::init ( const Glib::ustring& label, const Glib::ustring& tip, 
561                          const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
562                          SPDocument * doc_in )
564     init_parent(key, wr, repr_in, doc_in);
566     _widget = new Random (label, tip);
567     _widget->setRange (-1e6, 1e6);
568     _widget->setDigits (2);
569     _widget->setIncrements(0.1, 1.0);
570     _value_changed_connection = _widget->signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredRandom::on_value_changed));
571     _reseeded_connection = _widget->signal_reseeded.connect(sigc::mem_fun(*this, &RegisteredRandom::on_value_changed));
574 Random*
575 RegisteredRandom::getR()
577     return _widget;
580 void
581 RegisteredRandom::setValue (double val, long startseed)
583     _widget->setValue (val);
584     _widget->setStartSeed(startseed);
585     on_value_changed();
588 void
589 RegisteredRandom::on_value_changed()
591     if (_wr->isUpdating())
592         return;
593     _wr->setUpdating (true);
595     // FIXME:  gtk bug?
596     // disable interruptibility: see http://inkscape.svn.sourceforge.net/viewvc/inkscape/inkscape/trunk/src/ui/widget/selected-style.cpp?r1=13149&r2=13257&sortby=date
597     SPDesktop* dt = SP_ACTIVE_DESKTOP;
598     sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(dt), 0);
600     Inkscape::SVGOStringStream os;
601     os << _widget->getValue() << ';' << _widget->getStartSeed();
603     write_to_xml(os.str().c_str());
605     // resume interruptibility
606     sp_canvas_end_forced_full_redraws(sp_desktop_canvas(dt));
608     _wr->setUpdating (false);
612 } // namespace Dialog
613 } // namespace UI
614 } // namespace Inkscape
616 /*
617   Local Variables:
618   mode:c++
619   c-file-style:"stroustrup"
620   c-file-offsets:((innamespace . 0)(inline-open . 0))
621   indent-tabs-mode:nil
622   fill-column:99
623   End:
624 */
625 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :