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.
22 #include "gtkmm2ext/auto_spin.h"
23 #include "gtkmm2ext/keyboard.h"
25 using namespace Gtkmm2ext;
28 #define upper adjustment.get_upper()
29 #define lower adjustment.get_lower()
30 #define step_increment adjustment.get_step_increment()
31 #define page_increment adjustment.get_page_increment()
33 const unsigned int AutoSpin::initial_timer_interval = 500; /* msecs */
34 const unsigned int AutoSpin::timer_interval = 20; /* msecs */
35 const unsigned int AutoSpin::climb_timer_calls = 5; /* between climbing */
37 AutoSpin::AutoSpin (Gtk::Adjustment &adjr, gfloat cr, bool round_to_steps_yn)
42 initial = adjustment.get_value ();
43 left_is_decrement = true;
48 round_to_steps = round_to_steps_yn;
52 AutoSpin::stop_timer ()
55 g_source_remove (timeout_tag);
61 AutoSpin::stop_spinning (GdkEventButton */*ev*/)
69 AutoSpin::button_press (GdkEventButton *ev)
73 bool with_decrement = false;
77 if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
81 if (ev->state & Keyboard::TertiaryModifier) {
87 if (ev->state & Keyboard::PrimaryModifier) {
88 /* go to upper/lower bound on button1/button2 */
93 /* XXX should figure out which button is left/right */
98 set_value (left_is_decrement ? lower : upper);
101 if (left_is_decrement) {
102 with_decrement = true;
104 with_decrement = false;
118 set_value (left_is_decrement ? upper : lower);
125 adjust_value (shifted ? page_increment : step_increment);
134 adjust_value (shifted ? -page_increment : -step_increment);
142 start_spinning (with_decrement, shifted);
147 AutoSpin::scroll_event (GdkEventScroll *ev)
151 gfloat increment = step_increment;
153 if (ev->state & Keyboard::TertiaryModifier) {
154 increment = page_increment;
157 switch (ev->direction) {
158 case GDK_SCROLL_DOWN:
159 case GDK_SCROLL_LEFT:
160 adjust_value (-increment);
162 case GDK_SCROLL_RIGHT:
164 adjust_value (increment);
171 AutoSpin::start_spinning (bool decrement, bool page)
173 timer_increment = page ? page_increment : step_increment;
176 timer_increment = -timer_increment;
179 adjust_value (timer_increment);
183 timeout_tag = g_timeout_add (initial_timer_interval,
189 AutoSpin::_timer (void *arg)
191 return ((AutoSpin *) arg)->timer ();
195 AutoSpin::set_value (gfloat value)
198 adjustment.set_value (floor((value / step_increment) + 0.5f) * step_increment);
200 adjustment.set_value (value);
204 AutoSpin::adjust_value (gfloat increment)
209 val = adjustment.get_value ();
220 } else if (val < lower) {
239 done = adjust_value (timer_increment);
243 /* we're in the initial call, which happened
244 after initial_timer_interval msecs. Now
245 request a much more frequent update.
248 timeout_tag = g_timeout_add (timer_interval,
254 /* cancel this initial timeout */
259 /* this is the regular "fast" call after each
260 timer_interval msecs.
263 if (timer_calls < climb_timer_calls) {
266 if (climb_rate > 0.0) {
267 if (timer_increment > 0) {
268 timer_increment += climb_rate;
270 timer_increment -= climb_rate;
285 AutoSpin::set_bounds (gfloat init, gfloat up, gfloat down, bool with_reset)
287 adjustment.set_upper (up);
288 adjustment.set_lower (down);
292 adjustment.changed ();
295 adjustment.set_value (init);