2 Copyright (C) 2004 Paul Davis
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <pbd/controllable.h>
26 #include <pbd/locale_guard.h>
28 #include "gtkmm2ext/gtk_ui.h"
29 #include "gtkmm2ext/utils.h"
30 #include "gtkmm2ext/keyboard.h"
31 #include "gtkmm2ext/barcontroller.h"
32 #include "gtkmm2ext/cairo_widget.h"
38 using namespace Gtkmm2ext;
40 BarController::BarController (Gtk::Adjustment& adj,
41 boost::shared_ptr<PBD::Controllable> mc)
42 : _slider (&adj, 60, 16)
43 , _logarithmic (false)
45 , _switch_on_release (false)
48 add_events (Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
49 set (.5, .5, 1.0, 1.0);
51 _slider.set_controllable (mc);
52 _slider.show_unity_line (false);
54 _slider.StartGesture.connect (sigc::mem_fun(*this, &BarController::passtrhu_gesture_start));
55 _slider.StopGesture.connect (sigc::mem_fun(*this, &BarController::passtrhu_gesture_stop));
56 _slider.OnExpose.connect (sigc::mem_fun(*this, &BarController::before_expose));
58 Gtk::SpinButton& spinner = _slider.get_spin_button();
59 spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
60 spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
61 spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input));
62 spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output));
63 spinner.set_digits (9);
64 spinner.set_numeric (true);
65 spinner.set_name ("BarControlSpinner");
70 BarController::~BarController ()
75 BarController::on_button_press_event (GdkEventButton* ev)
77 if (get_child() != &_slider) {
80 if (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
81 _switch_on_release = true;
84 _switch_on_release = false;
90 BarController::on_button_release_event (GdkEventButton* ev)
92 if (get_child() != &_slider) {
95 if (ev->button == 1 && _switch_on_release) {
96 Glib::signal_idle().connect (mem_fun (*this, &BarController::switch_to_spinner));
103 BarController::switch_to_bar ()
105 if (_switching || get_child() == &_slider) {
112 _slider.queue_draw ();
114 SpinnerActive (false); /* EMIT SIGNAL */
119 BarController::switch_to_spinner ()
121 if (_switching || get_child() != &_slider) {
126 Gtk::SpinButton& spinner = _slider.get_spin_button();
127 if (spinner.get_parent()) {
128 spinner.get_parent()->remove(spinner);
133 spinner.select_region (0, spinner.get_text_length());
134 spinner.grab_focus ();
136 SpinnerActive (true); /* EMIT SIGNAL */
141 BarController::entry_activated ()
147 BarController::entry_focus_out (GdkEventFocus* /*ev*/)
154 BarController::before_expose ()
157 _slider.set_text (get_label (xpos), false, false);
161 BarController::set_sensitive (bool yn)
163 Alignment::set_sensitive (yn);
164 _slider.set_sensitive (yn);
168 This is called when we need to update the adjustment with the value
169 from the spinner's text entry.
171 We need to use Gtk::Entry::get_text to avoid recursive nastiness :)
173 If we're not in logarithmic mode we can return false to use the
176 In theory we should check for conversion errors but set numeric
177 mode to true on the spinner prevents invalid input.
180 BarController::entry_input (double* new_value)
186 // extract a double from the string and take its log
187 Gtk::SpinButton& spinner = _slider.get_spin_button();
188 Entry *entry = dynamic_cast<Entry *>(&spinner);
192 // Switch to user's preferred locale so that
193 // if they use different LC_NUMERIC conventions,
194 // we will honor them.
196 PBD::LocaleGuard lg ("");
197 sscanf (entry->get_text().c_str(), "%lf", &value);
200 *new_value = log(value);
206 This is called when we need to update the spinner's text entry
207 with the value of the adjustment.
209 We need to use Gtk::Entry::set_text to avoid recursive nastiness :)
211 If we're not in logarithmic mode we can return false to use the
215 BarController::entry_output ()
222 Gtk::SpinButton& spinner = _slider.get_spin_button();
224 // generate the exponential and turn it into a string
225 // convert to correct locale.
231 // Switch to user's preferred locale so that
232 // if they use different LC_NUMERIC conventions,
233 // we will honor them.
235 PBD::LocaleGuard lg ("");
236 snprintf (buf, sizeof (buf), "%g", exp (spinner.get_adjustment()->get_value()));
239 Entry *entry = dynamic_cast<Entry *>(&spinner);
240 entry->set_text(buf);