change the use of "SMPTE" to "Timecode" to reflect the global economy and the end...
[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 using ARDOUR::nframes_t;
32
33 sigc::signal<void,std::string,std::string> BasicUI::AccessAction;
34
35 BasicUI::BasicUI (Session& s)
36         : session (&s)
37 {
38 }
39
40 BasicUI::BasicUI ()
41         : session (0)
42 {
43 }
44
45 BasicUI::~BasicUI ()
46 {
47         
48 }
49
50 void
51 BasicUI::register_thread (std::string name)
52 {
53         PBD::notify_gui_about_thread_creation (pthread_self(), name);
54 }
55
56 void
57 BasicUI::access_action ( std::string action_path ) 
58 {
59         int split_at = action_path.find( "/" );
60         std::string group = action_path.substr( 0, split_at );
61         std::string item = action_path.substr( split_at + 1 );
62
63         AccessAction( group, item );
64 }
65
66 void
67 BasicUI::loop_toggle () 
68 {
69         if (session->get_play_loop()) {
70                 session->request_play_loop (false);
71         } else {
72                 session->request_play_loop (true);
73                 if (!session->transport_rolling()) {
74                         session->request_transport_speed (1.0);
75                 }
76         }
77 }
78
79 void
80 BasicUI::goto_start ()
81 {
82         session->goto_start ();
83 }
84
85 void
86 BasicUI::goto_end ()
87 {
88         session->goto_end ();
89 }
90
91 void       
92 BasicUI::add_marker ()
93 {
94         nframes_t when = session->audible_frame();
95         session->locations()->add (new Location (when, when, _("unnamed"), Location::IsMark));
96 }
97
98 void
99 BasicUI::rewind ()
100 {
101         session->request_transport_speed (-2.0f);
102 }
103
104 void
105 BasicUI::ffwd ()
106 {
107         session->request_transport_speed (2.0f);
108 }
109
110 void
111 BasicUI::transport_stop ()
112 {
113         session->request_transport_speed (0.0);
114 }
115
116 void
117 BasicUI::transport_play (bool from_last_start)
118 {
119         bool rolling = session->transport_rolling ();
120
121         if (session->get_play_loop()) {
122                 session->request_play_loop (false);
123         } 
124
125         if (session->get_play_range ()) {
126                 session->request_play_range (false);
127         }
128         
129         if (from_last_start && rolling) {
130                 session->request_locate (session->last_transport_start(), true);
131
132         }
133
134         session->request_transport_speed (1.0f);
135 }
136
137 void
138 BasicUI::rec_enable_toggle ()
139 {
140         switch (session->record_status()) {
141         case Session::Disabled:
142                 if (session->ntracks() == 0) {
143                         // string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
144                         // MessageDialog msg (*editor, txt);
145                         // msg.run ();
146                         return;
147                 }
148                 session->maybe_enable_record ();
149                 break;
150         case Session::Recording:
151         case Session::Enabled:
152                 session->disable_record (true);
153         }
154 }
155
156 void
157 BasicUI::save_state ()
158 {
159         session->save_state ("");
160 }
161
162 void
163 BasicUI::prev_marker ()
164 {
165         Location *location = session->locations()->first_location_before (session->transport_frame());
166         
167         if (location) {
168                 session->request_locate (location->start(), session->transport_rolling());
169         } else {
170                 session->goto_start ();
171         }
172 }
173
174 void
175 BasicUI::next_marker ()
176 {
177         Location *location = session->locations()->first_location_after (session->transport_frame());
178
179         if (location) {
180                 session->request_locate (location->start(), session->transport_rolling());
181         } else {
182                 session->request_locate (session->current_end_frame());
183         }
184 }
185
186 void
187 BasicUI::set_transport_speed (double speed)
188 {
189         session->request_transport_speed (speed);
190 }
191
192 double
193 BasicUI::get_transport_speed ()
194 {
195         return session->transport_speed ();
196 }
197
198 void
199 BasicUI::undo ()
200 {
201         session->undo (1);
202 }
203
204 void
205 BasicUI::redo ()
206 {
207         session->redo (1);
208 }
209
210 void
211 BasicUI::toggle_all_rec_enables ()
212 {
213         if (session->get_record_enabled()) {
214                 session->record_disenable_all ();
215         } else {
216                 session->record_enable_all ();
217         }
218 }
219
220 void
221 BasicUI::toggle_punch_in ()
222 {
223         session->config.set_punch_in (!session->config.get_punch_in());
224 }
225
226 void
227 BasicUI::toggle_punch_out ()
228 {
229         session->config.set_punch_out (!session->config.get_punch_out());
230 }
231
232 bool
233 BasicUI::get_record_enabled ()
234 {
235         return session->get_record_enabled();
236 }
237
238 void
239 BasicUI::set_record_enable (bool yn)
240 {
241         if (yn) {
242                 session->maybe_enable_record ();
243         } else {
244                 session->disable_record (false, true);
245         }
246 }
247
248 nframes_t
249 BasicUI::transport_frame ()
250 {
251         return session->transport_frame();
252 }
253
254 void
255 BasicUI::locate (nframes_t where, bool roll_after_locate)
256 {
257         session->request_locate (where, roll_after_locate);
258 }
259
260 bool
261 BasicUI::locating ()
262 {
263         return session->locate_pending();
264 }
265
266 bool
267 BasicUI::locked ()
268 {
269         return session->transport_locked ();
270 }
271
272 nframes_t
273 BasicUI::timecode_frames_per_hour ()
274 {
275         return session->timecode_frames_per_hour ();
276 }
277
278 void
279 BasicUI::timecode_time (nframes_t where, Timecode::Time& timecode)
280 {
281         session->timecode_time (where, *((Timecode::Time *) &timecode));
282 }
283
284 void 
285 BasicUI::timecode_to_sample (Timecode::Time& timecode, nframes_t& sample, bool use_offset, bool use_subframes) const
286 {
287         session->timecode_to_sample (*((Timecode::Time*)&timecode), sample, use_offset, use_subframes);
288 }
289
290 void 
291 BasicUI::sample_to_timecode (nframes_t sample, Timecode::Time& timecode, bool use_offset, bool use_subframes) const
292 {
293         session->sample_to_timecode (sample, *((Timecode::Time*)&timecode), use_offset, use_subframes);
294 }