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/keyboard.h"
23 #include "widgets/auto_spin.h"
25 using namespace Gtkmm2ext;
26 using namespace ArdourWidgets;
29 #define upper adjustment.get_upper()
30 #define lower adjustment.get_lower()
31 #define step_increment adjustment.get_step_increment()
32 #define page_increment adjustment.get_page_increment()
34 const unsigned int AutoSpin::initial_timer_interval = 500; /* msecs */
35 const unsigned int AutoSpin::timer_interval = 20; /* msecs */
36 const unsigned int AutoSpin::climb_timer_calls = 5; /* between climbing */
38 AutoSpin::AutoSpin (Gtk::Adjustment &adjr, gfloat cr, bool round_to_steps_yn)
43 initial = adjustment.get_value ();
44 left_is_decrement = true;
49 round_to_steps = round_to_steps_yn;
53 AutoSpin::stop_timer ()
56 g_source_remove (timeout_tag);
62 AutoSpin::stop_spinning (GdkEventButton */*ev*/)
70 AutoSpin::button_press (GdkEventButton *ev)
74 bool with_decrement = false;
78 if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
82 if (ev->state & Keyboard::TertiaryModifier) {
88 if (ev->state & Keyboard::PrimaryModifier) {
89 /* go to upper/lower bound on button1/button2 */
94 /* XXX should figure out which button is left/right */
99 set_value (left_is_decrement ? lower : upper);
102 if (left_is_decrement) {
103 with_decrement = true;
105 with_decrement = false;
119 set_value (left_is_decrement ? upper : lower);
126 adjust_value (shifted ? page_increment : step_increment);
135 adjust_value (shifted ? -page_increment : -step_increment);
143 start_spinning (with_decrement, shifted);
148 AutoSpin::scroll_event (GdkEventScroll *ev)
152 gfloat increment = step_increment;
154 if (ev->state & Keyboard::TertiaryModifier) {
155 increment = page_increment;
158 switch (ev->direction) {
159 case GDK_SCROLL_DOWN:
160 case GDK_SCROLL_LEFT:
161 adjust_value (-increment);
163 case GDK_SCROLL_RIGHT:
165 adjust_value (increment);
172 AutoSpin::start_spinning (bool decrement, bool page)
174 timer_increment = page ? page_increment : step_increment;
177 timer_increment = -timer_increment;
180 adjust_value (timer_increment);
184 timeout_tag = g_timeout_add (initial_timer_interval,
190 AutoSpin::_timer (void *arg)
192 return ((AutoSpin *) arg)->timer ();
196 AutoSpin::set_value (gfloat value)
199 adjustment.set_value (floor((value / step_increment) + 0.5f) * step_increment);
201 adjustment.set_value (value);
205 AutoSpin::adjust_value (gfloat increment)
210 val = adjustment.get_value ();
221 } else if (val < lower) {
240 done = adjust_value (timer_increment);
244 /* we're in the initial call, which happened
245 after initial_timer_interval msecs. Now
246 request a much more frequent update.
249 timeout_tag = g_timeout_add (timer_interval,
255 /* cancel this initial timeout */
260 /* this is the regular "fast" call after each
261 timer_interval msecs.
264 if (timer_calls < climb_timer_calls) {
267 if (climb_rate > 0.0) {
268 if (timer_increment > 0) {
269 timer_increment += climb_rate;
271 timer_increment -= climb_rate;
286 AutoSpin::set_bounds (gfloat init, gfloat up, gfloat down, bool with_reset)
288 adjustment.set_upper (up);
289 adjustment.set_lower (down);
293 adjustment.changed ();
296 adjustment.set_value (init);