Add valgrind option for tests.
[ardour.git] / libs / surfaces / mackie / controls.h
1 /*
2         Copyright (C) 2006,2007 John Anderson
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 #ifndef mackie_controls_h
19 #define mackie_controls_h
20
21 #include <map>
22 #include <vector>
23 #include <string>
24
25 #include "pbd/signals.h"
26
27 #include "mackie_control_exception.h"
28
29 namespace Mackie
30 {
31
32 class Control;
33
34 /**
35         This is a loose group of controls, eg cursor buttons,
36         transport buttons, functions buttons etc.
37 */
38 class Group
39 {
40 public:
41         Group( const std::string & name )
42         : _name( name )
43         {
44         }
45         
46         virtual ~Group() {}
47         
48         virtual bool is_strip() const
49         {
50                 return false;
51         }
52         
53         virtual bool is_master() const
54         {
55                 return false;
56         }
57         
58         virtual void add( Control & control );
59         
60         const std::string & name() const
61         {
62                 return _name;
63         }
64         
65         // This is for Surface only
66         void name( const std::string & rhs ) { _name = rhs; }
67         
68         typedef std::vector<Control*> Controls;
69         const Controls & controls() const { return _controls; }
70         
71 protected:
72         Controls _controls;
73         
74 private:
75         std::string _name;
76 };
77
78 class Button;
79 class Pot;
80 class Fader;
81
82 /**
83         This is the set of controls that make up a strip.
84 */
85 class Strip : public Group
86 {
87 public:
88         /**
89                 \param is the index of the strip. 0-based.
90         */
91         Strip( const std::string & name, int index );
92         
93         virtual bool is_strip() const
94         {
95                 return true;
96         }
97         
98         virtual void add( Control & control );
99         
100         /// This is the index of the strip. zero-based.
101         int index() const { return _index; }
102         
103         /// This is for Surface only
104         /// index is zero-based
105         void index( int rhs ) { _index = rhs; }
106         
107         Button & solo();
108         Button & recenable();
109         Button & mute();
110         Button & select();
111         Button & vselect();
112         Button & fader_touch();
113         Pot & vpot();
114         Fader & gain();
115         
116         bool has_solo() const { return _solo != 0; }
117         bool has_recenable() const { return _recenable != 0; }
118         bool has_mute() const { return _mute != 0; }
119         bool has_select() const { return _select != 0; }
120         bool has_vselect() const { return _vselect != 0; }
121         bool has_fader_touch() const { return _fader_touch != 0; }
122         bool has_vpot() const { return _vpot != 0; }
123         bool has_gain() const { return _gain != 0; }
124         
125 private:
126         Button * _solo;
127         Button * _recenable;
128         Button * _mute;
129         Button * _select;
130         Button * _vselect;
131         Button * _fader_touch;
132         Pot * _vpot;
133         Fader * _gain;
134         int _index;
135 };
136
137 std::ostream & operator << ( std::ostream &, const Strip & );
138
139 class MasterStrip : public Strip
140 {
141 public:
142         MasterStrip( const std::string & name, int index )
143         : Strip( name, index )
144         {
145         }
146         
147         virtual bool is_master() const
148         {
149                 return true;
150         }
151 };
152
153 class Led;
154
155 /**
156         The base class for controls on the surface. They deliberately
157         don't know the midi protocol for updating them.
158 */
159 class Control
160 {
161 public:
162         enum type_t { type_led, type_led_ring, type_fader = 0xe0, type_button = 0x90, type_pot = 0xb0 };
163         
164         Control( int id, int ordinal, std::string name, Group & group );
165         virtual ~Control() {}
166         
167         virtual const Led & led() const
168         {
169                 throw MackieControlException( "no led available" );
170         }
171
172         /// type() << 8 + midi id of the control. This
173         /// provides a unique id for any control on the surface.
174         int id() const
175         {
176                 return ( type() << 8 ) + _id;
177         }
178         
179         /// the value of the second bytes of the message. It's
180         /// the id of the control, but only guaranteed to be
181         /// unique within the control type.
182         int raw_id() const { return _id; }
183         
184         /// The 1-based number of the control
185         int ordinal() const { return _ordinal; }
186         
187         const std::string & name() const
188         {
189                 return _name;
190         }
191         
192         const Group & group() const
193         {
194                 return _group;
195         }
196         
197         const Strip & strip() const
198         {
199                 return dynamic_cast<const Strip&>( _group );
200         }
201         
202         Strip & strip()
203         {
204                 return dynamic_cast<Strip&>( _group );
205         }
206         
207         virtual bool accepts_feedback() const
208         {
209                 return true;
210         }
211         
212         virtual type_t type() const = 0;
213         
214         /// Return true if this control is the one and only Jog Wheel
215         virtual bool is_jog() const { return false; }
216
217         bool in_use () const;
218         void set_in_use (bool);
219         
220         /// Keep track of the timeout so it can be updated with more incoming events
221         sigc::connection in_use_connection;
222
223         /** If we are doing an in_use timeout for a fader without touch, this
224          *  is its touch button control; otherwise 0.
225          */
226         Control* in_use_touch_control;
227         
228 private:
229         int _id;
230         int _ordinal;
231         std::string _name;
232         Group & _group;
233         bool _in_use;
234 };
235
236 std::ostream & operator << ( std::ostream & os, const Control & control );
237
238 class Fader : public Control
239 {
240 public:
241         Fader( int id, int ordinal, std::string name, Group & group )
242         : Control( id, ordinal, name, group )
243         {
244         }
245         
246         virtual type_t type() const { return type_fader; }
247 };
248
249 class Led : public Control
250 {
251 public:
252         Led( int id, int ordinal, std::string name, Group & group )
253         : Control( id, ordinal, name, group )
254         {
255         }
256         
257         virtual const Led & led() const { return *this; }
258
259         virtual type_t type() const { return type_led; }
260 };
261
262 class Button : public Control
263 {
264 public:
265         Button( int id, int ordinal, std::string name, Group & group )
266         : Control( id, ordinal, name, group )
267         , _led( id, ordinal, name + "_led", group )
268         {
269         }
270         
271         virtual const Led & led() const
272         {
273                 return _led;
274         }
275         
276         virtual type_t type() const { return type_button; };
277         
278 private:
279         Led _led;
280 };
281
282 class LedRing : public Led
283 {
284 public:
285         LedRing( int id, int ordinal, std::string name, Group & group )
286         : Led( id, ordinal, name, group )
287         {
288         }
289
290         virtual type_t type() const { return type_led_ring; }
291 };
292
293 class Pot : public Control
294 {
295 public:
296         Pot( int id, int ordinal, std::string name, Group & group )
297         : Control( id, ordinal, name, group )
298         , _led_ring( id, ordinal, name + "_ring", group )
299         {
300         }
301
302         virtual type_t type() const { return type_pot; }
303
304         virtual const LedRing & led_ring() const
305         {
306                 return _led_ring;
307         }
308
309 private:
310         LedRing _led_ring;
311 };
312
313 class Jog : public Pot
314 {
315 public:
316         Jog( int id, int ordinal, std::string name, Group & group )
317         : Pot( id, ordinal, name, group )
318         {
319         }
320
321         virtual bool is_jog() const { return true; }
322 };
323
324 }
325
326 #endif