1 /** \file
2 *
3 Implementation of tolerance slider widget.
4 *
5 * Authors:
6 * Ralf Stephan <ralf@ark.in-berlin.de>
7 *
8 * Copyright (C) 2006 Authors
9 *
10 * Released under GNU GPL. Read the file 'COPYING' for more information
11 */
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
17 #include <gtkmm/adjustment.h>
18 #include <gtkmm/box.h>
19 #include <gtkmm/label.h>
20 #include <gtkmm/scale.h>
22 #include "xml/repr.h"
23 #include "svg/stringstream.h"
25 #include "inkscape.h"
26 #include "document.h"
27 #include "desktop-handles.h"
28 #include "sp-namedview.h"
30 #include "registry.h"
31 #include "tolerance-slider.h"
33 namespace Inkscape {
34 namespace UI {
35 namespace Widget {
37 //===================================================
39 //---------------------------------------------------
43 //====================================================
45 ToleranceSlider::ToleranceSlider()
46 : _vbox(0)
47 {
48 }
50 ToleranceSlider::~ToleranceSlider()
51 {
52 if (_vbox) delete _vbox;
53 _scale_changed_connection.disconnect();
54 }
56 void
57 ToleranceSlider::init (const Glib::ustring& label1, const Glib::ustring& label2, const Glib::ustring& label3, const Glib::ustring& tip1, const Glib::ustring& tip2, const Glib::ustring& tip3, const Glib::ustring& key, Registry& wr)
58 {
59 // hbox = label + slider
60 //
61 // e.g.
62 //
63 // snap distance |-------X---| 37
65 // vbox = checkbutton
66 // +
67 // hbox
69 _vbox = new Gtk::VBox;
70 _hbox = manage (new Gtk::HBox);
72 Gtk::Label *theLabel1 = manage (new Gtk::Label (label1));
73 theLabel1->set_use_underline();
74 theLabel1->set_alignment(0, 0.5);
75 // align the label with the checkbox text above by indenting 22 px.
76 _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22);
77 _hscale = manage (new Gtk::HScale (1.0, 51, 1.0));
78 theLabel1->set_mnemonic_widget (*_hscale);
79 _hscale->set_draw_value (true);
80 _hscale->set_value_pos (Gtk::POS_RIGHT);
81 _hscale->set_size_request (100, -1);
82 _old_val = 10;
83 _hscale->set_value (_old_val);
84 _tt.set_tip (*_hscale, tip1);
85 _hbox->add (*_hscale);
88 Gtk::Label *theLabel2 = manage (new Gtk::Label (label2));
89 theLabel2->set_use_underline();
90 Gtk::Label *theLabel3 = manage (new Gtk::Label (label3));
91 theLabel3->set_use_underline();
92 _button1 = manage (new Gtk::RadioButton);
93 _radio_button_group = _button1->get_group();
94 _button2 = manage (new Gtk::RadioButton);
95 _button2->set_group(_radio_button_group);
96 _tt.set_tip (*_button1, tip2);
97 _tt.set_tip (*_button2, tip3);
98 _button1->add (*theLabel3);
99 _button1->set_alignment (0.0, 0.5);
100 _button2->add (*theLabel2);
101 _button2->set_alignment (0.0, 0.5);
103 _vbox->add (*_button1);
104 _vbox->add (*_button2);
105 // Here we need some extra pixels to get the vertical spacing right. Why?
106 _vbox->pack_end(*_hbox, true, true, 3); // add 3 px.
107 _key = key;
108 _scale_changed_connection = _hscale->signal_value_changed().connect (sigc::mem_fun (*this, &ToleranceSlider::on_scale_changed));
109 _btn_toggled_connection = _button2->signal_toggled().connect (sigc::mem_fun (*this, &ToleranceSlider::on_toggled));
110 _wr = ≀
111 _vbox->show_all_children();
112 }
114 void
115 ToleranceSlider::setValue (double val)
116 {
117 Gtk::Adjustment *adj = _hscale->get_adjustment();
119 adj->set_lower (1.0);
120 adj->set_upper (51.0);
121 adj->set_step_increment (1.0);
123 if (val > 9999.9) // magic value 10000.0
124 {
125 _button1->set_active (true);
126 _button2->set_active (false);
127 _hbox->set_sensitive (false);
128 val = 50.0;
129 }
130 else
131 {
132 _button1->set_active (false);
133 _button2->set_active (true);
134 _hbox->set_sensitive (true);
135 }
136 _hscale->set_value (val);
137 _hbox->show_all();
138 }
140 void
141 ToleranceSlider::setLimits (double theMin, double theMax)
142 {
143 _hscale->set_range (theMin, theMax);
144 _hscale->get_adjustment()->set_step_increment (1);
145 }
147 void
148 ToleranceSlider::on_scale_changed()
149 {
150 update (_hscale->get_value());
151 }
153 void
154 ToleranceSlider::on_toggled()
155 {
156 if (!_button2->get_active())
157 {
158 _old_val = _hscale->get_value();
159 _hbox->set_sensitive (false);
160 _hbox->show_all();
161 setValue (10000.0);
162 update (10000.0);
163 }
164 else
165 {
166 _hbox->set_sensitive (true);
167 _hbox->show_all();
168 setValue (_old_val);
169 update (_old_val);
170 }
171 }
173 void
174 ToleranceSlider::update (double val)
175 {
176 if (_wr->isUpdating())
177 return;
179 SPDesktop *dt = SP_ACTIVE_DESKTOP;
180 if (!dt)
181 return;
183 Inkscape::SVGOStringStream os;
184 os << val;
186 _wr->setUpdating (true);
188 SPDocument *doc = sp_desktop_document(dt);
189 bool saved = sp_document_get_undo_sensitive (doc);
190 sp_document_set_undo_sensitive (doc, false);
191 Inkscape::XML::Node *repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
192 repr->setAttribute(_key.c_str(), os.str().c_str());
193 sp_document_set_undo_sensitive (doc, saved);
195 doc->setModifiedSinceSave();
197 _wr->setUpdating (false);
198 }
201 } // namespace Dialog
202 } // namespace UI
203 } // namespace Inkscape
205 /*
206 Local Variables:
207 mode:c++
208 c-file-style:"stroustrup"
209 c-file-offsets:((innamespace . 0)(inline-open . 0))
210 indent-tabs-mode:nil
211 fill-column:99
212 End:
213 */
214 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :