Correct formatting for if/else statements
[ardour.git] / libs / surfaces / launch_control_xl / controllers.cc
1 /*
2   Copyright (C) 2016 Paul 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
19 #include <algorithm>
20
21 #include "ardour/debug.h"
22 #include "ardour/mute_control.h"
23 #include "ardour/session.h"
24 #include "ardour/solo_control.h"
25
26 #include "launch_control_xl.h"
27
28 using namespace ArdourSurface;
29 using namespace ARDOUR;
30 using namespace PBD;
31 using std::cerr;
32
33 void
34 LaunchControlXL::build_maps ()
35 {
36         /* Knobs */
37
38         Knob* knob;
39
40         #define MAKE_KNOB(i,cc, index, color) \
41                 knob = new Knob ((i), (cc), (index), (color), (*this)); \
42                 cc_knob_map.insert (std::make_pair (knob->controller_number(), knob)); \
43                 id_knob_map.insert (std::make_pair (knob->id(), knob))
44
45                 for (uint8_t n = 0; n < 8; ++n) {
46                         MAKE_KNOB (static_cast<KnobID>(n), (n + 13), n, RedFull);
47                         MAKE_KNOB (static_cast<KnobID>(n + 8), (n + 29), (n + 8), GreenFull);
48                         MAKE_KNOB (static_cast<KnobID>(n + 16), (n + 49), (n + 16), Yellow);
49                 }
50
51         /* Faders */
52
53         Fader* fader;
54
55         #define MAKE_FADER(i,cc) \
56                 fader = new Fader ((i), (cc)); \
57                 cc_fader_map.insert (std::make_pair (fader->controller_number(), fader)); \
58                 id_fader_map.insert (std::make_pair (fader->id(), fader))
59
60                 for (uint8_t n = 0; n < 8; ++n) {
61                         MAKE_FADER (static_cast<FaderID>(n), (n + 77) );
62                 }
63
64         /* Buttons */
65
66         ControllerButton *controller_button;
67         NoteButton *note_button;
68
69
70         #define MAKE_TRACK_BUTTON_PRESS(i,nn,index,color,p) \
71                 note_button = new TrackButton ((i), (nn), (index), (color), (p), (*this)); \
72                 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
73                 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
74         #define MAKE_SELECT_BUTTON_PRESS(i,cc,index,p) \
75                 controller_button = new SelectButton ((i), (cc), (index), (p), (*this)); \
76                 cc_controller_button_map.insert (std::make_pair (controller_button->controller_number(), controller_button)); \
77                 id_controller_button_map.insert (std::make_pair (controller_button->id(), controller_button))
78         #define MAKE_TRACK_STATE_BUTTON_PRESS(i,nn,index,p) \
79                 note_button = new TrackStateButton ((i), (nn), (index), (p), (*this)); \
80                 nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
81                 id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
82                 #define MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(i,nn,index, p,r,l) \
83                         note_button = new TrackStateButton ((i), (nn), (index), (p), (r), (l), (*this)); \
84                         nn_note_button_map.insert (std::make_pair (note_button->note_number(), note_button)); \
85                         id_note_button_map.insert (std::make_pair (note_button->id(), note_button))
86
87
88         MAKE_TRACK_BUTTON_PRESS(Focus1, 41, 24, GreenFull, &LaunchControlXL::button_track_focus_1);
89         MAKE_TRACK_BUTTON_PRESS(Focus2, 42, 25, GreenFull, &LaunchControlXL::button_track_focus_2);
90         MAKE_TRACK_BUTTON_PRESS(Focus3, 43, 26, GreenFull, &LaunchControlXL::button_track_focus_3);
91         MAKE_TRACK_BUTTON_PRESS(Focus4, 44, 27, GreenFull, &LaunchControlXL::button_track_focus_4);
92         MAKE_TRACK_BUTTON_PRESS(Focus5, 57, 28, GreenFull, &LaunchControlXL::button_track_focus_5);
93         MAKE_TRACK_BUTTON_PRESS(Focus6, 58, 29, GreenFull, &LaunchControlXL::button_track_focus_6);
94         MAKE_TRACK_BUTTON_PRESS(Focus7, 59, 30, GreenFull, &LaunchControlXL::button_track_focus_7);
95         MAKE_TRACK_BUTTON_PRESS(Focus8, 60, 31, GreenFull, &LaunchControlXL::button_track_focus_8);
96         MAKE_TRACK_BUTTON_PRESS(Control1, 73, 32, Yellow, &LaunchControlXL::button_track_control_1);
97         MAKE_TRACK_BUTTON_PRESS(Control2, 74, 33, Yellow, &LaunchControlXL::button_track_control_2);
98         MAKE_TRACK_BUTTON_PRESS(Control3, 75, 34, Yellow, &LaunchControlXL::button_track_control_3);
99         MAKE_TRACK_BUTTON_PRESS(Control4, 76, 35, Yellow, &LaunchControlXL::button_track_control_4);
100         MAKE_TRACK_BUTTON_PRESS(Control5, 89, 36, Yellow, &LaunchControlXL::button_track_control_5);
101         MAKE_TRACK_BUTTON_PRESS(Control6, 90, 37, Yellow, &LaunchControlXL::button_track_control_6);
102         MAKE_TRACK_BUTTON_PRESS(Control7, 91, 38, Yellow, &LaunchControlXL::button_track_control_7);
103         MAKE_TRACK_BUTTON_PRESS(Control8, 92, 39, Yellow, &LaunchControlXL::button_track_control_8);
104
105         MAKE_SELECT_BUTTON_PRESS(SelectUp, 104, 44, &LaunchControlXL::button_select_up);
106         MAKE_SELECT_BUTTON_PRESS(SelectDown, 105, 45, &LaunchControlXL::button_select_down);
107         MAKE_SELECT_BUTTON_PRESS(SelectLeft, 106, 46, &LaunchControlXL::button_select_left);
108         MAKE_SELECT_BUTTON_PRESS(SelectRight, 107, 47, &LaunchControlXL::button_select_right);
109
110         MAKE_TRACK_STATE_BUTTON_PRESS_RELEASE_LONG(Device, 105, 40, &LaunchControlXL::relax, &LaunchControlXL::button_device, &LaunchControlXL::button_device_long_press);;
111         MAKE_TRACK_STATE_BUTTON_PRESS(Mute, 106, 41, &LaunchControlXL::button_mute);
112         MAKE_TRACK_STATE_BUTTON_PRESS(Solo, 107, 42, &LaunchControlXL::button_solo);
113         MAKE_TRACK_STATE_BUTTON_PRESS(Record, 108, 43, &LaunchControlXL::button_record);
114
115 }
116
117 std::string
118 LaunchControlXL::button_name_by_id (ButtonID id)
119 {
120         switch (id) {
121                 case Device:
122                         return "Device";
123                 case Mute:
124                         return "Mute";
125                 case Solo:
126                         return "Solo";
127                 case Record:
128                         return "Record";
129                 case SelectUp:
130                         return "Select Up";
131                 case SelectDown:
132                         return "Select Down";
133                 case SelectRight:
134                         return "Select Right";
135                 case SelectLeft:
136                         return "Select Left";
137                 case Focus1:
138                         return "Focus 1";
139                 case Focus2:
140                         return "Focus 2";
141                 case Focus3:
142                         return "Focus 3";
143                 case Focus4:
144                         return "Focus 4";
145                 case Focus5:
146                         return "Focus 5";
147                 case Focus6:
148                         return "Focus 6";
149                 case Focus7:
150                         return "Focus 7";
151                 case Focus8:
152                         return "Focus 8";
153                 case Control1:
154                         return "Control 1";
155                 case Control2:
156                         return "Control 2";
157                 case Control3:
158                         return "Control 3";
159                 case Control4:
160                         return "Control 4";
161                 case Control5:
162                         return "Control 5";
163                 case Control6:
164                         return "Control 6";
165                 case Control7:
166                         return "Control 7";
167                 case Control8:
168                         return "Control 8";
169         default:
170                 break;
171         }
172
173         return "???";
174 }
175
176 std::string
177 LaunchControlXL::knob_name_by_id (KnobID id)
178 {
179         switch (id) {
180                 case SendA1:
181                         return "SendA 1";
182                 case SendA2:
183                         return "SendA 2";
184                 case SendA3:
185                         return "SendA 3";
186                 case SendA4:
187                         return "SendA 4";
188                 case SendA5:
189                         return "SendA 5";
190                 case SendA6:
191                         return "SendA 6";
192                 case SendA7:
193                         return "SendA 7";
194                 case SendA8:
195                         return "SendA 8";
196                 case SendB1:
197                         return "SendB 1";
198                 case SendB2:
199                         return "SendB 2";
200                 case SendB3:
201                         return "SendB 3";
202                 case SendB4:
203                         return "SendB 4";
204                 case SendB5:
205                         return "SendB 5";
206                 case SendB6:
207                         return "SendB 6";
208                 case SendB7:
209                         return "SendB 7";
210                 case SendB8:
211                         return "SendB 8";
212                 case Pan1:
213                         return "Pan 1";
214                 case Pan2:
215                         return "Pan 2";
216                 case Pan3:
217                         return "Pan 3";
218                 case Pan4:
219                         return "Pan 4";
220                 case Pan5:
221                         return "Pan 5";
222                 case Pan6:
223                         return "Pan 6";
224                 case Pan7:
225                         return "Pan 7";
226                 case Pan8:
227                         return "Pan 8";
228         default:
229                 break;
230         }
231
232         return "???";
233 }
234
235 std::string
236 LaunchControlXL::fader_name_by_id (FaderID id)
237 {
238         switch (id) {
239                 case Fader1:
240                         return "Fader 1";
241                 case Fader2:
242                         return "Fader 2";
243                 case Fader3:
244                         return "Fader 3";
245                 case Fader4:
246                         return "Fader 4";
247                 case Fader5:
248                         return "Fader 5";
249                 case Fader6:
250                         return "Fader 6";
251                 case Fader7:
252                         return "Fader 7";
253                 case Fader8:
254                         return "Fader 8";
255         default:
256                 break;
257         }
258
259         return "???";
260 }
261
262 LaunchControlXL::TrackButton*
263 LaunchControlXL::track_button_by_number(uint8_t n, uint8_t first, uint8_t middle)
264 {
265         NNNoteButtonMap::iterator b;
266         if ( n < 4)     {
267                 b = nn_note_button_map.find (first + n);
268         } else {
269                 b = nn_note_button_map.find (middle + n - 4);
270         }
271
272         TrackButton* button = 0;
273
274         if (b != nn_note_button_map.end()) {
275                 button = static_cast<TrackButton*>(b->second);
276         }
277
278         return button;
279
280 }
281
282 void
283 LaunchControlXL::button_track_focus(uint8_t n)
284 {
285         if (!stripable[n]) {
286                 return;
287         }
288
289         TrackButton* b = focus_button_by_number(n);
290
291         if (b == 0) {
292                 return;
293         }
294
295         if ( stripable[n]->is_selected() ) {
296                 b->set_color(AmberFull);
297         } else {
298                 b->set_color(AmberLow);
299         }
300         write (b->state_msg());
301
302 }
303
304 boost::shared_ptr<AutomationControl>
305 LaunchControlXL::get_ac_by_state(uint8_t n) {
306                 boost::shared_ptr<AutomationControl> ac;
307
308                 switch(track_mode()) {
309                         case TrackMute:
310                                 ac = stripable[n]->mute_control();
311                                 break;
312
313                         case TrackSolo:
314                                 ac = stripable[n]->solo_control();
315                                 break;
316
317                         case TrackRecord:
318                                 ac = stripable[n]->rec_enable_control();
319                                 break;
320
321                         default:
322                         break;
323                 }
324                 return ac;
325 }
326
327
328 void
329 LaunchControlXL::update_track_control_led(uint8_t n)
330 {
331         TrackButton* b = control_button_by_number(n);
332
333         if (!stripable[n] || !b) {
334                 return;
335         }
336
337         boost::shared_ptr<AutomationControl> ac = get_ac_by_state(n);
338
339
340                 switch(track_mode()) {
341                         case TrackMute:
342                                 if (ac->get_value()) {
343                                         b->set_color(AmberFull);
344                                 } else {
345                                         b->set_color(AmberLow);
346                                 }
347                                 break;
348
349                         case TrackSolo:
350                                 if (ac && stripable[n] != master ) {
351                                         if (ac->get_value()) {
352                                                 b->set_color(GreenFull);
353                                         } else {
354                                                 b->set_color(GreenLow);
355                                         }
356                                 } else {
357                                         b->set_color(Off);
358                                 }
359                                 break;
360
361                         case TrackRecord:
362                                 if (ac) {
363                                         if (ac->get_value()) {
364                                                 b->set_color(RedFull);
365                                         } else {
366                                                 b->set_color(RedLow);
367                                         }
368                                 } else {
369
370                                 }
371                                 break;
372
373                         default:
374                         break;
375                 }
376                 if (ac) {
377                         write (b->state_msg());
378                 }
379 }
380
381 void
382 LaunchControlXL::solo_mute_rec_changed(uint32_t n) {
383         if (!stripable[n]) {
384                 return;
385         }
386         update_track_control_led(n);
387 }
388
389 void
390 LaunchControlXL::button_track_control(uint8_t n) {
391         if (!stripable[n]) {
392                 return;
393         }
394         boost::shared_ptr<AutomationControl> ac = get_ac_by_state(n);
395
396         if (ac) {
397                 session->set_control (ac, !ac->get_value(), PBD::Controllable::UseGroup);
398         }
399 }
400
401 void
402 LaunchControlXL::button_track_mode(TrackMode state)
403 {
404                 set_track_mode(state);
405                 for (uint8_t n = 0; n < 8; ++n) {
406                         update_track_control_led(n);
407                 }
408
409                 TrackStateButton* mute = static_cast<TrackStateButton*>(id_note_button_map[Mute]);
410                 TrackStateButton* solo = static_cast<TrackStateButton*>(id_note_button_map[Solo]);
411                 TrackStateButton* record = static_cast<TrackStateButton*>(id_note_button_map[Record]);
412
413                 write(mute->state_msg( (state == TrackMute) ));
414                 write(solo->state_msg( (state == TrackSolo) ));
415                 write(record->state_msg( (state == TrackRecord) ));
416 }
417
418 void
419 LaunchControlXL::button_select_left()
420 {
421         switch_bank (max (0, bank_start - 1));
422 }
423
424 void
425 LaunchControlXL::button_select_right()
426 {
427         switch_bank (max (0, bank_start + 1));
428 }
429
430 void
431 LaunchControlXL::button_select_up()
432 {
433
434 }
435
436 void
437 LaunchControlXL::button_select_down()
438 {
439
440 }
441
442 void
443 LaunchControlXL::button_device()
444 {
445
446 }
447
448 void
449 LaunchControlXL::button_device_long_press()
450 {
451
452 }
453
454 bool
455 LaunchControlXL::button_long_press_timeout (ButtonID id, Button* button)
456 {
457         if (buttons_down.find (id) != buttons_down.end()) {
458                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("long press timeout for %1, invoking method\n", id));
459                 (this->*button->long_press_method) ();
460         } else {
461                 DEBUG_TRACE (DEBUG::LaunchControlXL, string_compose ("long press timeout for %1, expired/cancelled\n", id));
462                 /* release happened and somehow we were not cancelled */
463         }
464
465         /* whichever button this was, we've used it ... don't invoke the
466            release action.
467         */
468         consumed.insert (id);
469
470         return false; /* don't get called again */
471 }
472
473
474 void
475 LaunchControlXL::start_press_timeout (Button* button, ButtonID id)
476 {
477         Glib::RefPtr<Glib::TimeoutSource> timeout = Glib::TimeoutSource::create (500); // milliseconds
478         button->timeout_connection = timeout->connect (sigc::bind (sigc::mem_fun (*this, &LaunchControlXL::button_long_press_timeout), id, button));
479         timeout->attach (main_loop()->get_context());
480 }