send control now has working metering, and switches back and forth between busses...
[ardour.git] / gtk2_ardour / ardour_ui_options.cc
1 /*
2     Copyright (C) 2005 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
20 #include "pbd/convert.h"
21 #include "pbd/stacktrace.h"
22
23 #include <gtkmm2ext/utils.h>
24
25 #include "ardour/configuration.h"
26 #include "ardour/session.h"
27 #include "ardour/audioengine.h"
28
29 #ifdef HAVE_LIBLO
30 #include "ardour/osc.h"
31 #endif
32
33 #include "ardour_ui.h"
34 #include "actions.h"
35 #include "gui_thread.h"
36 #include "public_editor.h"
37
38 #include "i18n.h"
39
40 using namespace Gtk;
41 using namespace Gtkmm2ext;
42 using namespace ARDOUR;
43 using namespace PBD;
44 using namespace sigc;
45
46 void
47 ARDOUR_UI::toggle_time_master ()
48 {
49         ActionManager::toggle_config_state_foo ("Transport", "ToggleTimeMaster", mem_fun (session->config, &SessionConfiguration::set_jack_time_master), mem_fun (session->config, &SessionConfiguration::get_jack_time_master));
50 }
51
52 void
53 ARDOUR_UI::toggle_send_mtc ()
54 {
55         ActionManager::toggle_config_state ("options", "SendMTC", &RCConfiguration::set_send_mtc, &RCConfiguration::get_send_mtc);
56 }
57
58 void
59 ARDOUR_UI::toggle_send_mmc ()
60 {
61         ActionManager::toggle_config_state ("options", "SendMMC", &RCConfiguration::set_send_mmc, &RCConfiguration::get_send_mmc);
62 }
63
64 void
65 ARDOUR_UI::toggle_send_midi_clock ()
66 {
67         ActionManager::toggle_config_state ("options", "SendMidiClock", &RCConfiguration::set_send_midi_clock, &RCConfiguration::get_send_midi_clock);
68 }
69
70 void
71 ARDOUR_UI::toggle_use_mmc ()
72 {
73         ActionManager::toggle_config_state ("options", "UseMMC", &RCConfiguration::set_mmc_control, &RCConfiguration::get_mmc_control);
74 }
75
76 void
77 ARDOUR_UI::toggle_send_midi_feedback ()
78 {
79         ActionManager::toggle_config_state ("options", "SendMIDIfeedback", &RCConfiguration::set_midi_feedback, &RCConfiguration::get_midi_feedback);
80 }
81
82 void
83 ARDOUR_UI::toggle_auto_input ()
84 {
85         ActionManager::toggle_config_state_foo ("Transport", "ToggleAutoInput", mem_fun (session->config, &SessionConfiguration::set_auto_input), mem_fun (session->config, &SessionConfiguration::get_auto_input));
86 }
87
88 void
89 ARDOUR_UI::toggle_auto_play ()
90 {
91         ActionManager::toggle_config_state_foo ("Transport", "ToggleAutoPlay", mem_fun (session->config, &SessionConfiguration::set_auto_play), mem_fun (session->config, &SessionConfiguration::get_auto_play));
92 }
93
94 void
95 ARDOUR_UI::toggle_auto_return ()
96 {
97         ActionManager::toggle_config_state_foo ("Transport", "ToggleAutoReturn", mem_fun (session->config, &SessionConfiguration::set_auto_return), mem_fun (session->config, &SessionConfiguration::get_auto_return));
98 }
99
100 void
101 ARDOUR_UI::toggle_click ()
102 {
103         ActionManager::toggle_config_state ("Transport", "ToggleClick", &RCConfiguration::set_clicking, &RCConfiguration::get_clicking);
104 }
105
106 void
107 ARDOUR_UI::toggle_session_auto_loop ()
108 {
109         if (session) {
110                 if (session->get_play_loop()) {
111                         if (session->transport_rolling()) {
112                                 transport_roll();
113                         } else {
114                                 session->request_play_loop (false);
115                         }
116                 } else {
117                         session->request_play_loop (true);
118                 }
119         }
120 }
121
122 void
123 ARDOUR_UI::unset_dual_punch ()
124 {
125         Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch");
126
127         if (action) {
128                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(action);
129                 if (tact) {
130                         ignore_dual_punch = true;
131                         tact->set_active (false);
132                         ignore_dual_punch = false;
133                 }
134         }
135 }
136
137 void
138 ARDOUR_UI::toggle_punch ()
139 {
140         if (ignore_dual_punch) {
141                 return;
142         }
143
144         Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch");
145
146         if (action) {
147
148                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(action);
149
150                 if (!tact) {
151                         return;
152                 }
153
154                 /* drive the other two actions from this one */
155
156                 Glib::RefPtr<Action> in_action = ActionManager::get_action ("Transport", "TogglePunchIn");
157                 Glib::RefPtr<Action> out_action = ActionManager::get_action ("Transport", "TogglePunchOut");
158
159                 if (in_action && out_action) {
160                         Glib::RefPtr<ToggleAction> tiact = Glib::RefPtr<ToggleAction>::cast_dynamic(in_action);
161                         Glib::RefPtr<ToggleAction> toact = Glib::RefPtr<ToggleAction>::cast_dynamic(out_action);
162                         tiact->set_active (tact->get_active());
163                         toact->set_active (tact->get_active());
164                 }
165         }
166 }
167
168 void
169 ARDOUR_UI::toggle_punch_in ()
170 {
171         ActionManager::toggle_config_state_foo ("Transport", "TogglePunchIn", mem_fun (session->config, &SessionConfiguration::set_punch_in), mem_fun (session->config, &SessionConfiguration::get_punch_in));
172 }
173
174 void
175 ARDOUR_UI::toggle_punch_out ()
176 {
177         ActionManager::toggle_config_state_foo ("Transport", "TogglePunchOut", mem_fun (session->config, &SessionConfiguration::set_punch_out), mem_fun (session->config, &SessionConfiguration::get_punch_out));
178 }
179
180 void
181 ARDOUR_UI::toggle_video_sync()
182 {
183         Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", "ToggleVideoSync");
184         if (act) {
185                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
186                 session->config.set_use_video_sync (tact->get_active());
187         }
188 }
189
190 void
191 ARDOUR_UI::toggle_editing_space()
192 {
193         Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalEditor");
194         if (act) {
195                 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
196                 if (tact->get_active()) {
197                         maximise_editing_space ();
198                 } else {
199                         restore_editing_space ();
200                 }
201         }
202 }
203
204 void
205 ARDOUR_UI::mtc_port_changed ()
206 {
207         bool have_mtc;
208         bool have_midi_clock;
209
210         if (session) {
211                 if (session->mtc_port()) {
212                         have_mtc = true;
213                 } else {
214                         have_mtc = false;
215                 }
216                 if (session->midi_clock_port()) {
217                         have_midi_clock = true;
218                 } else {
219                         have_midi_clock = false;
220                 }
221         } else {
222                 have_mtc = false;
223                 have_midi_clock = false;
224         }
225
226         positional_sync_strings.clear ();
227         positional_sync_strings.push_back (slave_source_to_string (None));
228         if (have_mtc) {
229                 positional_sync_strings.push_back (slave_source_to_string (MTC));
230         }
231         if (have_midi_clock) {
232                 positional_sync_strings.push_back (slave_source_to_string (MIDIClock));
233         }
234         positional_sync_strings.push_back (slave_source_to_string (JACK));
235
236         set_popdown_strings (sync_option_combo, positional_sync_strings);
237 }
238
239 void
240 ARDOUR_UI::setup_session_options ()
241 {
242         mtc_port_changed ();
243
244         Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
245 }
246
247 void
248 ARDOUR_UI::parameter_changed (std::string p)
249 {
250         ENSURE_GUI_THREAD (bind (mem_fun (*this, &ARDOUR_UI::parameter_changed), p));
251
252         if (p == "slave-source") {
253
254                 sync_option_combo.set_active_text (slave_source_to_string (Config->get_slave_source()));
255
256                 switch (Config->get_slave_source()) {
257                 case None:
258                         ActionManager::get_action ("Transport", "ToggleAutoPlay")->set_sensitive (true);
259                         ActionManager::get_action ("Transport", "ToggleAutoReturn")->set_sensitive (true);
260                         break;
261
262                 default:
263                         /* XXX need to make auto-play is off as well as insensitive */
264                         ActionManager::get_action ("Transport", "ToggleAutoPlay")->set_sensitive (false);
265                         ActionManager::get_action ("Transport", "ToggleAutoReturn")->set_sensitive (false);
266                         break;
267                 }
268
269         } else if (p == "send-mtc") {
270
271                 ActionManager::map_some_state ("options", "SendMTC", &RCConfiguration::get_send_mtc);
272
273         } else if (p == "send-mmc") {
274
275                 ActionManager::map_some_state ("options", "SendMMC", &RCConfiguration::get_send_mmc);
276
277         } else if (p == "use-osc") {
278
279 #ifdef HAVE_LIBLO
280                 if (Config->get_use_osc()) {
281                         osc->start ();
282                 } else {
283                         osc->stop ();
284                 }
285 #endif
286
287         } else if (p == "mmc-control") {
288                 ActionManager::map_some_state ("options", "UseMMC", &RCConfiguration::get_mmc_control);
289         } else if (p == "midi-feedback") {
290                 ActionManager::map_some_state ("options", "SendMIDIfeedback", &RCConfiguration::get_midi_feedback);
291         } else if (p == "auto-play") {
292                 ActionManager::map_some_state ("Transport", "ToggleAutoPlay", mem_fun (session->config, &SessionConfiguration::get_auto_play));
293         } else if (p == "auto-return") {
294                 ActionManager::map_some_state ("Transport", "ToggleAutoReturn", mem_fun (session->config, &SessionConfiguration::get_auto_return));
295         } else if (p == "auto-input") {
296                 ActionManager::map_some_state ("Transport", "ToggleAutoInput", mem_fun (session->config, &SessionConfiguration::get_auto_input));
297         } else if (p == "punch-out") {
298                 ActionManager::map_some_state ("Transport", "TogglePunchOut", mem_fun (session->config, &SessionConfiguration::get_punch_out));
299                 if (!session->config.get_punch_out()) {
300                         unset_dual_punch ();
301                 }
302         } else if (p == "punch-in") {
303                 ActionManager::map_some_state ("Transport", "TogglePunchIn", mem_fun (session->config, &SessionConfiguration::get_punch_in));
304                 if (!session->config.get_punch_in()) {
305                         unset_dual_punch ();
306                 }
307         } else if (p == "clicking") {
308                 ActionManager::map_some_state ("Transport", "ToggleClick", &RCConfiguration::get_clicking);
309         } else if (p == "jack-time-master") {
310                 ActionManager::map_some_state ("Transport",  "ToggleTimeMaster", mem_fun (session->config, &SessionConfiguration::get_jack_time_master));
311         } else if (p == "use-video-sync") {
312                 ActionManager::map_some_state ("Transport",  "ToggleVideoSync", mem_fun (session->config, &SessionConfiguration::get_use_video_sync));
313         } else if (p == "shuttle-behaviour") {
314
315                 switch (Config->get_shuttle_behaviour ()) {
316                 case Sprung:
317                         shuttle_style_button.set_active_text (_("sprung"));
318                         shuttle_fract = 0.0;
319                         shuttle_box.queue_draw ();
320                         if (session) {
321                                 if (session->transport_rolling()) {
322                                         shuttle_fract = SHUTTLE_FRACT_SPEED1;
323                                         session->request_transport_speed (1.0);
324                                 }
325                         }
326                         break;
327                 case Wheel:
328                         shuttle_style_button.set_active_text (_("wheel"));
329                         break;
330                 }
331
332         } else if (p == "shuttle-units") {
333
334                 switch (Config->get_shuttle_units()) {
335                 case Percentage:
336                         shuttle_units_button.set_label("% ");
337                         break;
338                 case Semitones:
339                         shuttle_units_button.set_label(_("ST"));
340                         break;
341                 }
342         } else if (p == "video-pullup" || p == "smpte-format") {
343                 if (session) {
344                         primary_clock.set (session->audible_frame(), true);
345                         secondary_clock.set (session->audible_frame(), true);
346                 } else {
347                         primary_clock.set (0, true);
348                         secondary_clock.set (0, true);
349                 }
350         } else if (p == "show-track-meters") {
351                 editor->toggle_meter_updating();
352         }
353 }