ardour
auto_spin.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999 Paul Barton-Davis
3 
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.
8 
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.
13 
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.
17 
18  $Id$
19 */
20 
21 #include <cmath>
22 #include "gtkmm2ext/auto_spin.h"
23 #include "gtkmm2ext/keyboard.h"
24 
25 using namespace Gtkmm2ext;
26 using namespace std;
27 
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()
32 
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 */
36 
37 AutoSpin::AutoSpin (Gtk::Adjustment &adjr, gfloat cr, bool round_to_steps_yn)
38  : adjustment (adjr),
39  climb_rate (cr)
40 
41 {
42  initial = adjustment.get_value();
43  left_is_decrement = true;
44  wrap = false;
45  have_timer = false;
46  need_timer = false;
47  timer_calls = 0;
48  round_to_steps = round_to_steps_yn;
49 }
50 
51 void
53 {
54  if (have_timer) {
55  g_source_remove (timeout_tag);
56  have_timer = false;
57  }
58 }
59 
60 gint
61 AutoSpin::stop_spinning (GdkEventButton */*ev*/)
62 {
63  need_timer = false;
64  stop_timer ();
65  return FALSE;
66 }
67 
68 gint
69 AutoSpin::button_press (GdkEventButton *ev)
70 {
71  bool shifted = false;
72  bool control = false;
73  bool with_decrement = false;
74 
75  stop_spinning (0);
76 
77  if (ev->state & Keyboard::TertiaryModifier) {
78  /* use page shift */
79 
80  shifted = true;
81  }
82 
83  if (ev->state & Keyboard::PrimaryModifier) {
84  /* go to upper/lower bound on button1/button2 */
85 
86  control = true;
87  }
88 
89  /* XXX should figure out which button is left/right */
90 
91  switch (ev->button) {
92  case 1:
93  if (control) {
95  return TRUE;
96  } else {
97  if (left_is_decrement) {
98  with_decrement = true;
99  } else {
100  with_decrement = false;
101  }
102  }
103  break;
104 
105  case 2:
106  if (!control) {
107  set_value (initial);
108  }
109  return TRUE;
110  break;
111 
112  case 3:
113  if (control) {
115  return TRUE;
116  }
117  break;
118 
119  case 4:
120  if (!control) {
122  } else {
123  set_value (upper);
124  }
125  return TRUE;
126  break;
127 
128  case 5:
129  if (!control) {
131  } else {
132  set_value (lower);
133  }
134  return TRUE;
135  break;
136  }
137 
138  start_spinning (with_decrement, shifted);
139  return TRUE;
140 }
141 
142 void
143 AutoSpin::start_spinning (bool decrement, bool page)
144 {
146 
147  if (decrement) {
149  }
150 
152 
153  have_timer = true;
154  timer_calls = 0;
155  timeout_tag = g_timeout_add (initial_timer_interval,
157  this);
158 }
159 
160 gint
161 AutoSpin::_timer (void *arg)
162 {
163  return ((AutoSpin *) arg)->timer ();
164 }
165 
166 void
167 AutoSpin::set_value (gfloat value)
168 {
169  if (round_to_steps)
170  adjustment.set_value (floor((value / step_increment) + 0.5f) * step_increment);
171  else
172  adjustment.set_value (value);
173 }
174 
175 bool
176 AutoSpin::adjust_value (gfloat increment)
177 {
178  gfloat val;
179  bool done = false;
180 
181  val = adjustment.get_value();
182 
183  val += increment;
184 
185  if (val > upper) {
186  if (wrap) {
187  val = lower;
188  } else {
189  val = upper;
190  done = true;
191  }
192  } else if (val < lower) {
193  if (wrap) {
194  val = upper;
195  } else {
196  val = lower;
197  done = true;
198  }
199  }
200 
201  set_value(val);
202  return done;
203 }
204 
205 gint
207 {
208  bool done;
209  int retval = FALSE;
210 
211  done = adjust_value (timer_increment);
212 
213  if (need_timer) {
214 
215  /* we're in the initial call, which happened
216  after initial_timer_interval msecs. Now
217  request a much more frequent update.
218  */
219 
220  timeout_tag = g_timeout_add (timer_interval,
221  _timer,
222  this);
223  have_timer = true;
224  need_timer = false;
225 
226  /* cancel this initial timeout */
227 
228  retval = FALSE;
229 
230  } else {
231  /* this is the regular "fast" call after each
232  timer_interval msecs.
233  */
234 
236  timer_calls++;
237  } else {
238  if (climb_rate > 0.0) {
239  if (timer_increment > 0) {
241  } else {
243  }
244  }
245  timer_calls = 0;
246  }
247 
248  if (!done) {
249  retval = TRUE;
250  }
251  }
252 
253  return retval;
254 }
255 
256 void
257 AutoSpin::set_bounds (gfloat init, gfloat up, gfloat down, bool with_reset)
258 {
259  adjustment.set_upper(up);
260  adjustment.set_lower(down);
261 
262  initial = init;
263 
264  adjustment.changed ();
265 
266  if (with_reset) {
267  adjustment.set_value (init);
268  }
269 }
AutoSpin(Gtk::Adjustment &adj, gfloat cr=0, bool round_to_steps_yn=false)
Definition: auto_spin.cc:37
gfloat timer_increment
Definition: auto_spin.h:54
static const unsigned int timer_interval
Definition: auto_spin.h:65
void set_value(gfloat value)
Definition: auto_spin.cc:167
tuple f
Definition: signals.py:35
Definition: Beats.hpp:239
gint button_press(GdkEventButton *)
Definition: auto_spin.cc:69
static gint _timer(void *arg)
Definition: auto_spin.cc:161
static uint32_t TertiaryModifier
Definition: keyboard.h:57
static const unsigned int climb_timer_calls
Definition: auto_spin.h:66
void start_spinning(bool decrementing, bool use_page)
Definition: auto_spin.cc:143
unsigned int timer_calls
Definition: auto_spin.h:56
bool adjust_value(gfloat increment)
Definition: auto_spin.cc:176
static uint32_t PrimaryModifier
Definition: keyboard.h:55
Gtk::Adjustment & adjustment
Definition: auto_spin.h:52
#define page_increment
Definition: auto_spin.cc:31
#define upper
Definition: auto_spin.cc:28
LIBGTKMM2EXT_API void init(const char *)
Definition: utils.cc:42
gint stop_spinning(GdkEventButton *ignored_but_here_for_clicked)
Definition: auto_spin.cc:61
#define lower
Definition: auto_spin.cc:29
#define step_increment
Definition: auto_spin.cc:30
static const unsigned int initial_timer_interval
Definition: auto_spin.h:64
void set_bounds(gfloat initial, gfloat low, gfloat high, bool with_reset=true)
Definition: auto_spin.cc:257