enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / surfaces / tranzport / general.cc
1 /*
2  *   Copyright (C) 2006 Paul Davis
3  *   Copyright (C) 2007 Michael Taht
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  *   */
20
21 #include <tranzport_common.h>
22 #include <tranzport_control_protocol.h>
23
24 using namespace ARDOUR;
25 using namespace std;
26 using namespace sigc;
27 using namespace PBD;
28
29 #include "pbd/i18n.h"
30
31 #include <pbd/abstract_ui.cc>
32 // HA, I don't need this anymore
33 #include <slider_gain.h>
34
35 //   FIXME, flash recording light when recording and transport is moving
36 int TranzportControlProtocol::lights_show_recording()
37 {
38         return     lights_show_normal();
39 }
40
41 void TranzportControlProtocol::show_bling() {
42         lights_show_bling();
43         screen_show_bling();
44 }
45
46 void TranzportControlProtocol::notify(const char *msg) {
47         last_notify=100;
48         if(strlen(msg) < 21) {
49                 strcpy(last_notify_msg,msg);
50         } else {
51                 strncpy(last_notify_msg,msg,16);
52                 last_notify_msg[16] = '\n';
53         }
54 }
55
56 void TranzportControlProtocol::show_notify() {
57 // FIXME: Get width of the notify area somehow
58         if(last_notify==0) {
59                 print(1,0,"                ");
60                 last_notify=-1;
61         }
62         if(last_notify > 0) {
63                 print(1,0,last_notify_msg);
64                 --last_notify;
65         }
66 }
67
68 // Need more bling!
69
70 int TranzportControlProtocol::lights_show_bling()
71 {
72         switch (bling_mode) {
73         case BlingOff: break;
74         case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
75         case BlingRotating: break; // switch between lights
76         case BlingPairs: break; // Show pairs of lights
77         case BlingRows: break; // light each row in sequence
78         case BlingFlashAll: break; // Flash everything randomly
79         case BlingEnter: lights_on(); // Show intro
80         case BlingExit:
81                 lights_off();
82                 break;
83         }
84         return 0;
85 }
86
87 int TranzportControlProtocol::screen_show_bling()
88 {
89         switch (bling_mode) {
90         case BlingOff: break;
91         case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
92         case BlingRotating: break; // switch between lights
93         case BlingPairs: break; // Show pairs of lights
94         case BlingRows: break; // light each row in sequence
95         case BlingFlashAll: break; // Flash everything randomly
96         case BlingEnter: // Show intro
97                 print(0,0,"!!Welcome to Ardour!");
98                 print(1,0,"Peace through Music!");
99                 break;
100         case BlingExit:
101                 break;
102         }
103         return 0;
104 }
105
106 int TranzportControlProtocol::lights_show_normal()
107 {
108         /* Track only */
109
110         if (route_table[0]) {
111                 boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (route_table[0]);
112                 lights_pending[LightTrackrec]  = at && at->record_enabled();
113                 lights_pending[LightTrackmute] = route_get_muted(0);
114                 lights_pending[LightTracksolo] = route_get_soloed(0);
115         } else {
116                 lights_pending[LightTrackrec]  = false;
117                 lights_pending[LightTracksolo] = false;
118                 lights_pending[LightTrackmute] = false;
119         }
120
121         /* Global settings */
122
123         lights_pending[LightLoop]        = session->get_play_loop();
124         lights_pending[LightPunch]       = session->config.get_punch_in() || session->config.get_punch_out();
125         lights_pending[LightRecord]      = session->get_record_enabled();
126         lights_pending[LightAnysolo]     = session->soloing();
127
128         return 0;
129 }
130
131 int TranzportControlProtocol::lights_show_tempo()
132 {
133         // someday soon fiddle with the lights more sanely based on the tempo
134         return     lights_show_normal();
135 }
136
137 int
138 TranzportControlProtocol::update_state ()
139 {
140         /* do the text and light updates */
141
142         switch (display_mode) {
143         case DisplayBigMeter:
144                 lights_show_tempo();
145                 show_meter ();
146                 break;
147
148         case DisplayNormal:
149                 lights_show_normal();
150                 normal_update();
151                 break;
152
153         case DisplayConfig:
154                 break;
155
156         case DisplayRecording:
157                 lights_show_recording();
158                 normal_update();
159                 break;
160
161         case DisplayRecordingMeter:
162                 lights_show_recording();
163                 show_meter();
164                 break;
165
166         case DisplayBling:
167                 show_bling();
168                 break;
169
170         case DisplayBlingMeter:
171                 lights_show_bling();
172                 show_meter();
173                 break;
174         }
175         show_notify();
176
177         return 0;
178
179 }
180
181 void
182 TranzportControlProtocol::prev_marker ()
183 {
184         Location *location = session->locations()->first_location_before (session->transport_frame());
185
186         if (location) {
187                 session->request_locate (location->start(), session->transport_rolling());
188                 notify(location->name().c_str());
189         } else {
190                 session->goto_start ();
191                 notify("START");
192         }
193
194 }
195
196 void
197 TranzportControlProtocol::next_marker ()
198 {
199         Location *location = session->locations()->first_location_after (session->transport_frame());
200
201         if (location) {
202                 session->request_locate (location->start(), session->transport_rolling());
203                 notify(location->name().c_str());
204         } else {
205                 session->request_locate (session->current_end_frame());
206                 notify("END ");
207         }
208 }
209
210
211 void
212 TranzportControlProtocol::show_current_track ()
213 {
214         char pad[COLUMNS];
215         char *v;
216         int len;
217         if (route_table[0] == 0) {
218                 print (0, 0, "---------------");
219                 last_track_gain = FLT_MAX;
220         } else {
221                 strcpy(pad,"               ");
222                 v =  (char *)route_get_name (0).substr (0, 14).c_str();
223                 if((len = strlen(v)) > 0) {
224                         strncpy(pad,(char *)v,len);
225                 }
226                 print (0, 0, pad);
227         }
228 }
229
230
231 #if 0
232 void
233 TranzportControlProtocol::step_gain (float increment)
234 {
235 // FIXME: buttonstop is used elsewhere
236         if (buttonmask & ButtonStop) {
237                 gain_fraction += 0.001*increment;
238         } else {
239                 gain_fraction += 0.01*increment;
240         }
241
242         if (fabsf(gain_fraction) > 2.0) {
243                 gain_fraction = 2.0*sign(gain_fraction);
244         }
245
246         route_set_gain (0, slider_position_to_gain (gain_fraction));
247 }
248 #endif
249
250 void
251 TranzportControlProtocol::step_gain_up ()
252 {
253         if (buttonmask & ButtonStop) {
254                 gain_fraction += 0.001;
255         } else {
256                 gain_fraction += 0.01;
257         }
258
259         if (gain_fraction > 2.0) {
260                 gain_fraction = 2.0;
261         }
262
263         route_set_gain (0, slider_position_to_gain (gain_fraction));
264 }
265
266 void
267 TranzportControlProtocol::step_gain_down ()
268 {
269         if (buttonmask & ButtonStop) {
270                 gain_fraction -= 0.001;
271         } else {
272                 gain_fraction -= 0.01;
273         }
274
275         if (gain_fraction < 0.0) {
276                 gain_fraction = 0.0;
277         }
278
279         route_set_gain (0, slider_position_to_gain (gain_fraction));
280 }
281
282
283 void
284 TranzportControlProtocol::next_track ()
285 {
286         ControlProtocol::next_track (current_track_id);
287         gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
288 //      notify("NextTrak"); // not needed til we have more modes
289 }
290
291 void
292 TranzportControlProtocol::prev_track ()
293 {
294         ControlProtocol::prev_track (current_track_id);
295         gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
296 //      notify("PrevTrak");
297 }
298
299 // This should kind of switch to using notify
300
301 // Was going to keep state around saying to retry or not
302 // haven't got to it yet, still not sure it's a good idea
303
304 void
305 TranzportControlProtocol::print (int row, int col, const char *text) {
306         print_noretry(row,col,text);
307 }
308
309 // -1 on failure
310 // 0 on no damage
311 // count of bit set on damage?
312
313 void
314 TranzportControlProtocol::print_noretry (int row, int col, const char *text)
315 {
316         uint32_t length = strlen (text);
317         if (row*COLUMNS+col+length > (ROWS*COLUMNS)) {
318                 return;
319         }
320         // FIXME - be able to print the whole screen at a go.
321         uint32_t t,r,c;
322         std::bitset<ROWS*COLUMNS> mask(screen_invalid);
323         for(r = row, c = col, t = 0 ; t < length; c++,t++) {
324                 screen_pending[r][c] = text[t];
325                 mask[r*COLUMNS+c] = (screen_current[r][c] != screen_pending[r][c]);
326         }
327         screen_invalid = mask;
328 }
329
330 void TranzportControlProtocol::invalidate()
331 {
332         lcd_damage(); lights_invalidate(); screen_invalidate(); // one of these days lcds can be fine but screens not
333 }