Indent python files with spaces as per style guide.
[ardour.git] / libs / surfaces / control_protocol / basic_ui.cc
1 /*
2     Copyright (C) 2006 Paul Davis 
3
4     This program is free software; you can redistribute it
5     and/or modify it under the terms of the GNU Lesser
6     General Public License as published by the Free Software
7     Foundation; either version 2 of the License, or (at your
8     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 "pbd/pthread_utils.h"
22
23 #include "ardour/session.h"
24 #include "ardour/location.h"
25
26 #include "control_protocol/basic_ui.h"
27
28 #include "i18n.h"
29
30 using namespace ARDOUR;
31
32 PBD::Signal2<void,std::string,std::string> BasicUI::AccessAction;
33
34 BasicUI::BasicUI (Session& s)
35         : session (&s)
36 {
37 }
38
39 BasicUI::BasicUI ()
40         : session (0)
41 {
42 }
43
44 BasicUI::~BasicUI ()
45 {
46         
47 }
48
49 void
50 BasicUI::register_thread (std::string name)
51 {
52         std::string pool_name = name;
53         pool_name += " events";
54
55         SessionEvent::create_per_thread_pool (pool_name, 64);
56 }
57
58 void
59 BasicUI::access_action ( std::string action_path ) 
60 {
61         int split_at = action_path.find( "/" );
62         std::string group = action_path.substr( 0, split_at );
63         std::string item = action_path.substr( split_at + 1 );
64
65         AccessAction( group, item );
66 }
67
68 void
69 BasicUI::loop_toggle () 
70 {
71         if (session->get_play_loop()) {
72                 session->request_play_loop (false);
73         } else {
74                 session->request_play_loop (true);
75                 if (!session->transport_rolling()) {
76                         session->request_transport_speed (1.0);
77                 }
78         }
79 }
80
81 void
82 BasicUI::goto_start ()
83 {
84         session->goto_start ();
85 }
86
87 void
88 BasicUI::goto_end ()
89 {
90         session->goto_end ();
91 }
92
93 void       
94 BasicUI::add_marker ()
95 {
96         framepos_t when = session->audible_frame();
97         session->locations()->add (new Location (*session, when, when, _("unnamed"), Location::IsMark));
98 }
99
100 void
101 BasicUI::rewind ()
102 {
103         session->request_transport_speed (-2.0f);
104 }
105
106 void
107 BasicUI::ffwd ()
108 {
109         session->request_transport_speed (2.0f);
110 }
111
112 void
113 BasicUI::transport_stop ()
114 {
115         session->request_transport_speed (0.0);
116 }
117
118 void
119 BasicUI::transport_play (bool from_last_start)
120 {
121         bool rolling = session->transport_rolling ();
122
123         if (session->get_play_loop()) {
124                 session->request_play_loop (false);
125         } 
126
127         if (session->get_play_range ()) {
128                 session->request_play_range (0);
129         }
130         
131         if (from_last_start && rolling) {
132                 session->request_locate (session->last_transport_start(), true);
133
134         }
135
136         session->request_transport_speed (1.0f);
137 }
138
139 void
140 BasicUI::rec_enable_toggle ()
141 {
142         switch (session->record_status()) {
143         case Session::Disabled:
144                 if (session->ntracks() == 0) {
145                         // string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
146                         // MessageDialog msg (*editor, txt);
147                         // msg.run ();
148                         return;
149                 }
150                 session->maybe_enable_record ();
151                 break;
152         case Session::Recording:
153         case Session::Enabled:
154                 session->disable_record (true);
155         }
156 }
157
158 void
159 BasicUI::save_state ()
160 {
161         session->save_state ("");
162 }
163
164 void
165 BasicUI::prev_marker ()
166 {
167         Location *location = session->locations()->first_location_before (session->transport_frame());
168         
169         if (location) {
170                 session->request_locate (location->start(), session->transport_rolling());
171         } else {
172                 session->goto_start ();
173         }
174 }
175
176 void
177 BasicUI::next_marker ()
178 {
179         Location *location = session->locations()->first_location_after (session->transport_frame());
180
181         if (location) {
182                 session->request_locate (location->start(), session->transport_rolling());
183         } else {
184                 session->request_locate (session->current_end_frame());
185         }
186 }
187
188 void
189 BasicUI::set_transport_speed (double speed)
190 {
191         session->request_transport_speed (speed);
192 }
193
194 double
195 BasicUI::get_transport_speed ()
196 {
197         return session->transport_speed ();
198 }
199
200 void
201 BasicUI::undo ()
202 {
203         session->undo (1);
204 }
205
206 void
207 BasicUI::redo ()
208 {
209         session->redo (1);
210 }
211
212 void
213 BasicUI::toggle_all_rec_enables ()
214 {
215         if (session->get_record_enabled()) {
216                 // session->record_disenable_all ();
217         } else {
218                 // session->record_enable_all ();
219         }
220 }
221
222 void
223 BasicUI::toggle_punch_in ()
224 {
225         session->config.set_punch_in (!session->config.get_punch_in());
226 }
227
228 void
229 BasicUI::toggle_punch_out ()
230 {
231         session->config.set_punch_out (!session->config.get_punch_out());
232 }
233
234 bool
235 BasicUI::get_record_enabled ()
236 {
237         return session->get_record_enabled();
238 }
239
240 void
241 BasicUI::set_record_enable (bool yn)
242 {
243         if (yn) {
244                 session->maybe_enable_record ();
245         } else {
246                 session->disable_record (false, true);
247         }
248 }
249
250 framepos_t
251 BasicUI::transport_frame ()
252 {
253         return session->transport_frame();
254 }
255
256 void
257 BasicUI::locate (framepos_t where, bool roll_after_locate)
258 {
259         session->request_locate (where, roll_after_locate);
260 }
261
262 bool
263 BasicUI::locating ()
264 {
265         return session->locate_pending();
266 }
267
268 bool
269 BasicUI::locked ()
270 {
271         return session->transport_locked ();
272 }
273
274 ARDOUR::framecnt_t
275 BasicUI::timecode_frames_per_hour ()
276 {
277         return session->timecode_frames_per_hour ();
278 }
279
280 void
281 BasicUI::timecode_time (framepos_t where, Timecode::Time& timecode)
282 {
283         session->timecode_time (where, *((Timecode::Time *) &timecode));
284 }
285
286 void 
287 BasicUI::timecode_to_sample (Timecode::Time& timecode, framepos_t & sample, bool use_offset, bool use_subframes) const
288 {
289         session->timecode_to_sample (*((Timecode::Time*)&timecode), sample, use_offset, use_subframes);
290 }
291
292 void 
293 BasicUI::sample_to_timecode (framepos_t sample, Timecode::Time& timecode, bool use_offset, bool use_subframes) const
294 {
295         session->sample_to_timecode (sample, *((Timecode::Time*)&timecode), use_offset, use_subframes);
296 }
297
298 #if 0
299 this stuff is waiting to go in so that all UIs can offer complex solo/mute functionality
300
301 void
302 BasicUI::solo_release (boost::shared_ptr<Route> r)
303 {
304 }
305
306 void
307 BasicUI::solo_press (boost::shared_ptr<Route> r, bool momentary, bool global, bool exclusive, bool isolate, bool solo_group)
308 {
309         if (momentary) {
310                 _solo_release = new SoloMuteRelease (_route->soloed());
311         }
312         
313         if (global) {
314                 
315                 if (_solo_release) {
316                         _solo_release->routes = _session->get_routes ();
317                 }
318                 
319                 if (Config->get_solo_control_is_listen_control()) {
320                         _session->set_listen (_session->get_routes(), !_route->listening(),  Session::rt_cleanup, true);
321                 } else {
322                         _session->set_solo (_session->get_routes(), !_route->soloed(),  Session::rt_cleanup, true);
323                 }
324                 
325         } else if (exclusive) {
326                 
327                 if (_solo_release) {
328                         _solo_release->exclusive = true;
329                         
330                         boost::shared_ptr<RouteList> routes = _session->get_routes();
331                         
332                         for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
333                                 if ((*i)->soloed ()) {
334                                         _solo_release->routes_on->push_back (*i);
335                                 } else {
336                                         _solo_release->routes_off->push_back (*i);
337                                 }
338                         }
339                 }
340                 
341                 if (Config->get_solo_control_is_listen_control()) {
342                         /* ??? we need a just_one_listen() method */
343                 } else {
344                         _session->set_just_one_solo (_route, true);
345                 }
346                 
347         } else if (isolate) {
348                 
349                 // shift-click: toggle solo isolated status
350                 
351                 _route->set_solo_isolated (!_route->solo_isolated(), this);
352                 delete _solo_release;
353                 _solo_release = 0;
354                 
355         } else if (solo_group) {
356                 
357                 /* Primary-button1: solo mix group.
358                    NOTE: Primary-button2 is MIDI learn.
359                 */
360                 
361                 if (_route->route_group()) {
362                         
363                         if (_solo_release) {
364                                 _solo_release->routes = _route->route_group()->route_list();
365                         }
366                         
367                         if (Config->get_solo_control_is_listen_control()) {
368                                 _session->set_listen (_route->route_group()->route_list(), !_route->listening(),  Session::rt_cleanup, true);
369                         } else {
370                                 _session->set_solo (_route->route_group()->route_list(), !_route->soloed(),  Session::rt_cleanup, true);
371                         }
372                 }
373                 
374         } else {
375                 
376                 /* click: solo this route */
377                 
378                 boost::shared_ptr<RouteList> rl (new RouteList);
379                 rl->push_back (route());
380                 
381                 if (_solo_release) {
382                         _solo_release->routes = rl;
383                 }
384                 
385                 if (Config->get_solo_control_is_listen_control()) {
386                         _session->set_listen (rl, !_route->listening());
387                 } else {
388                         _session->set_solo (rl, !_route->soloed());
389                 }
390         }
391 }
392 #endif