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