1092c40453de6e7aba90264609cdf470aefc4a68
[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 "mackie_control_exception.h"
26
27 namespace Mackie
28 {
29
30 class Control;
31
32 /**
33         This is a loose group of controls, eg cursor buttons,
34         transport buttons, functions buttons etc.
35 */
36 class Group
37 {
38 public:
39         Group( const std::string & name )
40         : _name( name )
41         {
42         }
43         
44         virtual ~Group() {}
45         
46         virtual bool is_strip() const
47         {
48                 return false;
49         }
50         
51         virtual bool is_master() const
52         {
53                 return false;
54         }
55         
56         virtual void add( Control & control );
57         
58         const std::string & name() const
59         {
60                 return _name;
61         }
62         
63         // This is for Surface only
64         void name( const std::string & rhs ) { _name = rhs; }
65         
66         typedef std::vector<Control*> Controls;
67         const Controls & controls() const { return _controls; }
68         
69 protected:
70         Controls _controls;
71         
72 private:
73         std::string _name;
74 };
75
76 class Button;
77 class Pot;
78 class Fader;
79
80 /**
81         This is the set of controls that make up a strip.
82 */
83 class Strip : public Group
84 {
85 public:
86         Strip( const std::string & name, int index );
87         
88         virtual bool is_strip() const
89         {
90                 return true;
91         }
92         
93         virtual void add( Control & control );
94         
95         /// This is the index of the strip
96         int index() const { return _index; }
97         
98         /// This is for Surface only
99         void index( int rhs ) { _index = rhs; }
100         
101         Button & solo();
102         Button & recenable();
103         Button & mute();
104         Button & select();
105         Button & vselect();
106         Button & fader_touch();
107         Pot & vpot();
108         Fader & gain();
109         
110         bool has_solo() { return _solo != 0; }
111         bool has_recenable() { return _recenable != 0; }
112         bool has_mute() { return _mute != 0; }
113         bool has_select() { return _select != 0; }
114         bool has_vselect() { return _vselect != 0; }
115         bool has_fader_touch() { return _fader_touch != 0; }
116         bool has_vpot() { return _vpot != 0; }
117         bool has_gain() { return _gain != 0; }
118         
119 private:
120         Button * _solo;
121         Button * _recenable;
122         Button * _mute;
123         Button * _select;
124         Button * _vselect;
125         Button * _fader_touch;
126         Pot * _vpot;
127         Fader * _gain;
128         int _index;
129 };
130
131 class MasterStrip : public Strip
132 {
133 public:
134         MasterStrip( const std::string & name, int index )
135         : Strip( name, index )
136         {
137         }
138         
139         virtual bool is_master() const
140         {
141                 return true;
142         }
143 };
144
145 class Led;
146
147 /**
148         The base class for controls on the surface. They deliberately
149         don't know the midi protocol for updating them.
150 */
151 class Control
152 {
153 public:
154         enum type_t { type_fader, type_button, type_pot, type_led, type_led_ring };
155         
156         Control( int id, int ordinal, std::string name, Group & group )
157         : _id( id ), _ordinal( ordinal ), _name( name ), _group( group )
158         {
159         }
160         
161         virtual ~Control() {}
162         
163         virtual const Led & led() const
164         {
165                 throw MackieControlException( "no led available" );
166         }
167
168         /// The midi id of the control
169         int id() const
170         {
171                 return _id;
172         }
173         
174         /// The 1-based number of the control
175         int ordinal() const
176         {
177                 return _ordinal;
178         }
179         
180         const std::string & name() const
181         {
182                 return _name;
183         }
184         
185         const Group & group() const
186         {
187                 return _group;
188         }
189         
190         const Strip & strip() const
191         {
192                 return dynamic_cast<const Strip&>( _group );
193         }
194         
195         Strip & strip()
196         {
197                 return dynamic_cast<Strip&>( _group );
198         }
199         
200         virtual bool accepts_feedback() const
201         {
202                 return true;
203         }
204         
205         virtual type_t type() const = 0;
206         
207 private:
208         int _id;
209         int _ordinal;
210         std::string _name;
211         Group & _group;
212 };
213
214 std::ostream & operator << ( std::ostream & os, const Control & control );
215
216 class Fader : public Control
217 {
218 public:
219         Fader( int id, int ordinal, std::string name, Group & group )
220         : Control( id, ordinal, name, group )
221         , _touch( false )
222         {
223         }
224         
225         bool touch() const { return _touch; }
226         
227         void touch( bool yn ) { _touch = yn; }
228
229         virtual type_t type() const { return type_fader; }
230
231 private:
232         bool _touch;
233 };
234
235 class Led : public Control
236 {
237 public:
238         Led( int id, int ordinal, std::string name, Group & group )
239         : Control( id, ordinal, name, group )
240         {
241         }
242         
243         virtual const Led & led() const { return *this; }
244
245         virtual type_t type() const { return type_led; }
246 };
247
248 class Button : public Control
249 {
250 public:
251         Button( int id, int ordinal, std::string name, Group & group )
252         : Control( id, ordinal, name, group )
253         , _led( id, ordinal, name + "_led", group )
254         {
255         }
256         
257         virtual const Led & led() const
258         {
259                 return _led;
260         }
261         
262         virtual type_t type() const { return type_button; };
263
264 private:
265         Led _led;
266 };
267
268 class LedRing : public Led
269 {
270 public:
271         LedRing( int id, int ordinal, std::string name, Group & group )
272         : Led( id, ordinal, name, group )
273         {
274         }
275
276         virtual type_t type() const { return type_led_ring; }
277 };
278
279 class Pot : public Control
280 {
281 public:
282         Pot( int id, int ordinal, std::string name, Group & group )
283         : Control( id, ordinal, name, group )
284         , _led_ring( id, ordinal, name + "_ring", group )
285         {
286         }
287
288         virtual type_t type() const { return type_pot; }
289
290         virtual const LedRing & led_ring() const
291         {
292                 return _led_ring;
293         }
294
295 private:
296         LedRing _led_ring;
297 };
298
299 }
300
301 #endif