2 Copyright (C) 1999 Paul Barton-Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <gtkmm2ext/auto_spin.h>
24 using namespace Gtkmm2ext;
27 #define upper adjustment.get_upper()
28 #define lower adjustment.get_lower()
29 #define step_increment adjustment.get_step_increment()
30 #define page_increment adjustment.get_page_increment()
32 const unsigned int AutoSpin::initial_timer_interval = 500; /* msecs */
33 const unsigned int AutoSpin::timer_interval = 20; /* msecs */
34 const unsigned int AutoSpin::climb_timer_calls = 5; /* between climbing */
36 AutoSpin::AutoSpin (Gtk::Adjustment &adjr, gfloat cr, bool round_to_steps_yn)
41 initial = adjustment.get_value();
42 left_is_decrement = true;
47 round_to_steps = round_to_steps_yn;
51 AutoSpin::stop_timer ()
54 g_source_remove (timeout_tag);
60 AutoSpin::stop_spinning (GdkEventButton *ev)
68 AutoSpin::button_press (GdkEventButton *ev)
72 bool with_decrement = false;
76 if (ev->state & GDK_SHIFT_MASK) {
82 if (ev->state & GDK_CONTROL_MASK) {
83 /* go to upper/lower bound on button1/button2 */
88 /* XXX should figure out which button is left/right */
93 set_value (left_is_decrement ? lower : upper);
96 if (left_is_decrement) {
97 with_decrement = true;
99 with_decrement = false;
113 set_value (left_is_decrement ? upper : lower);
120 adjust_value (shifted ? page_increment : step_increment);
129 adjust_value (shifted ? -page_increment : -step_increment);
137 start_spinning (with_decrement, shifted);
142 AutoSpin::start_spinning (bool decrement, bool page)
144 timer_increment = page ? page_increment : step_increment;
147 timer_increment = -timer_increment;
150 adjust_value (timer_increment);
154 timeout_tag = g_timeout_add (initial_timer_interval,
160 AutoSpin::_timer (void *arg)
162 return ((AutoSpin *) arg)->timer ();
166 AutoSpin::set_value (gfloat value)
169 adjustment.set_value (floor((value / step_increment) + 0.5f) * step_increment);
171 adjustment.set_value (value);
175 AutoSpin::adjust_value (gfloat increment)
180 val = adjustment.get_value();
191 } else if (val < lower) {
210 done = adjust_value (timer_increment);
214 /* we're in the initial call, which happened
215 after initial_timer_interval msecs. Now
216 request a much more frequent update.
219 timeout_tag = g_timeout_add (timer_interval,
225 /* cancel this initial timeout */
230 /* this is the regular "fast" call after each
231 timer_interval msecs.
234 if (timer_calls < climb_timer_calls) {
237 if (climb_rate > 0.0) {
238 if (timer_increment > 0) {
239 timer_increment += climb_rate;
241 timer_increment -= climb_rate;
256 AutoSpin::set_bounds (gfloat init, gfloat up, gfloat down, bool with_reset)
258 adjustment.set_upper(up);
259 adjustment.set_lower(down);
263 adjustment.changed ();
266 adjustment.set_value (init);