Code

4db4363caf76ca7389de0fcfade9975ff0acdcb5
[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);
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));
107 void
108 RegisteredCheckButton::setActive (bool b)
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         }
117 void
118 RegisteredCheckButton::on_toggled()
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);
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     _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);
304 RegisteredColorPicker::RegisteredColorPicker()
305 : _label(0), _cp(0)
309 RegisteredColorPicker::~RegisteredColorPicker()
311     _changed_connection.disconnect();
312     if (_cp) delete _cp;
313     if (_label) delete _label;
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)
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));
330 void
331 RegisteredColorPicker::setRgba32 (guint32 rgba)
333     _cp->setRgba32 (rgba);
336 void
337 RegisteredColorPicker::closeWindow()
339     _cp->closeWindow();
342 void
343 RegisteredColorPicker::on_changed (guint32 rgba)
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);
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)
384 RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
386     _changed_connection.disconnect();
387     if (_label) delete _label;
388     if (_suffix) delete _suffix;
389     if (_sb) delete _sb;
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)
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));
409 void
410 RegisteredSuffixedInteger::setValue (int i)
412     _adj.set_value (i);
415 void
416 RegisteredSuffixedInteger::on_value_changed()
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);
432 RegisteredRadioButtonPair::RegisteredRadioButtonPair()
433 : _hbox(0)
437 RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
439     _changed_connection.disconnect();
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)
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));
463 void
464 RegisteredRadioButtonPair::setValue (bool second)
466     if (second) _rb2->set_active();
467     else        _rb1->set_active();
470 void
471 RegisteredRadioButtonPair::on_value_changed()
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);
484 /*#########################################
485  * Registered POINT
486  */
488 RegisteredPoint::RegisteredPoint()
490     _widget = NULL;
493 RegisteredPoint::~RegisteredPoint()
495     if (_widget) 
496         delete _widget;
498     _value_x_changed_connection.disconnect();
499     _value_y_changed_connection.disconnect();
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 )
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));
517 Point*
518 RegisteredPoint::getPoint()
520     return _widget;
523 void
524 RegisteredPoint::setValue (double xval, double yval)
526     _widget->setValue(xval, yval);
527     on_value_changed();
530 void
531 RegisteredPoint::on_value_changed()
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);
546 /*#########################################
547  * Registered RANDOM
548  */
550 RegisteredRandom::RegisteredRandom()
552     _widget = NULL;
555 RegisteredRandom::~RegisteredRandom()
557     if (_widget) 
558         delete _widget;
560     _value_changed_connection.disconnect();
561     _reseeded_connection.disconnect();
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 )
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));
579 Random*
580 RegisteredRandom::getR()
582     return _widget;
585 void
586 RegisteredRandom::setValue (double val, long startseed)
588     _widget->setValue (val);
589     _widget->setStartSeed(startseed);
590     on_value_changed();
593 void
594 RegisteredRandom::on_value_changed()
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);
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 :