various fixes to MidiRegionView selection handling, key handling, drawing of ghost...
[ardour2.git] / gtk2_ardour / rc_option_editor.cc
blob597bdb50fc3f8f43f765177ec956117a04648e28
1 /*
2 Copyright (C) 2001-2011 Paul Davis
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.
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.
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.
20 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #endif
24 #include <gtkmm/liststore.h>
25 #include <gtkmm/stock.h>
26 #include <gtkmm/scale.h>
27 #include <gtkmm2ext/utils.h>
28 #include <gtkmm2ext/slider_controller.h>
30 #include "pbd/fpu.h"
31 #include "pbd/cpus.h"
33 #include "midi++/manager.h"
35 #include "ardour/audioengine.h"
36 #include "ardour/dB.h"
37 #include "ardour/rc_configuration.h"
38 #include "ardour/control_protocol_manager.h"
39 #include "control_protocol/control_protocol.h"
41 #include "gui_thread.h"
42 #include "midi_tracer.h"
43 #include "rc_option_editor.h"
44 #include "utils.h"
45 #include "midi_port_dialog.h"
46 #include "sfdb_ui.h"
47 #include "keyboard.h"
48 #include "i18n.h"
50 using namespace std;
51 using namespace Gtk;
52 using namespace Gtkmm2ext;
53 using namespace PBD;
54 using namespace ARDOUR;
56 class ClickOptions : public OptionEditorBox
58 public:
59 ClickOptions (RCConfiguration* c, ArdourDialog* p)
60 : _rc_config (c),
61 _parent (p)
63 Table* t = manage (new Table (2, 3));
64 t->set_spacings (4);
66 Label* l = manage (new Label (_("Click audio file:")));
67 l->set_alignment (0, 0.5);
68 t->attach (*l, 0, 1, 0, 1, FILL);
69 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
70 Button* b = manage (new Button (_("Browse...")));
71 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
72 t->attach (*b, 2, 3, 0, 1, FILL);
74 l = manage (new Label (_("Click emphasis audio file:")));
75 l->set_alignment (0, 0.5);
76 t->attach (*l, 0, 1, 1, 2, FILL);
77 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
78 b = manage (new Button (_("Browse...")));
79 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
80 t->attach (*b, 2, 3, 1, 2, FILL);
82 _box->pack_start (*t, false, false);
85 void parameter_changed (string const & p)
87 if (p == "click-sound") {
88 _click_path_entry.set_text (_rc_config->get_click_sound());
89 } else if (p == "click-emphasis-sound") {
90 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
94 void set_state_from_config ()
96 parameter_changed ("click-sound");
97 parameter_changed ("click-emphasis-sound");
100 private:
102 void click_browse_clicked ()
104 SoundFileChooser sfdb (*_parent, _("Choose Click"));
106 sfdb.show_all ();
107 sfdb.present ();
109 if (sfdb.run () == RESPONSE_OK) {
110 click_chosen (sfdb.get_filename());
114 void click_chosen (string const & path)
116 _click_path_entry.set_text (path);
117 _rc_config->set_click_sound (path);
120 void click_emphasis_browse_clicked ()
122 SoundFileChooser sfdb (*_parent, _("Choose Click Emphasis"));
124 sfdb.show_all ();
125 sfdb.present ();
127 if (sfdb.run () == RESPONSE_OK) {
128 click_emphasis_chosen (sfdb.get_filename());
132 void click_emphasis_chosen (string const & path)
134 _click_emphasis_path_entry.set_text (path);
135 _rc_config->set_click_emphasis_sound (path);
138 RCConfiguration* _rc_config;
139 ArdourDialog* _parent;
140 Entry _click_path_entry;
141 Entry _click_emphasis_path_entry;
144 class UndoOptions : public OptionEditorBox
146 public:
147 UndoOptions (RCConfiguration* c) :
148 _rc_config (c),
149 _limit_undo_button (_("Limit undo history to")),
150 _save_undo_button (_("Save undo history of"))
152 Table* t = new Table (2, 3);
153 t->set_spacings (4);
155 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
156 _limit_undo_spin.set_range (0, 512);
157 _limit_undo_spin.set_increments (1, 10);
158 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
159 Label* l = manage (new Label (_("commands")));
160 l->set_alignment (0, 0.5);
161 t->attach (*l, 2, 3, 0, 1);
163 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
164 _save_undo_spin.set_range (0, 512);
165 _save_undo_spin.set_increments (1, 10);
166 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
167 l = manage (new Label (_("commands")));
168 l->set_alignment (0, 0.5);
169 t->attach (*l, 2, 3, 1, 2);
171 _box->pack_start (*t);
173 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
174 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
175 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
176 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
179 void parameter_changed (string const & p)
181 if (p == "history-depth") {
182 int32_t const d = _rc_config->get_history_depth();
183 _limit_undo_button.set_active (d != 0);
184 _limit_undo_spin.set_sensitive (d != 0);
185 _limit_undo_spin.set_value (d);
186 } else if (p == "save-history") {
187 bool const x = _rc_config->get_save_history ();
188 _save_undo_button.set_active (x);
189 _save_undo_spin.set_sensitive (x);
190 } else if (p == "save-history-depth") {
191 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
195 void set_state_from_config ()
197 parameter_changed ("save-history");
198 parameter_changed ("history-depth");
199 parameter_changed ("save-history-depth");
202 void limit_undo_toggled ()
204 bool const x = _limit_undo_button.get_active ();
205 _limit_undo_spin.set_sensitive (x);
206 int32_t const n = x ? 16 : 0;
207 _limit_undo_spin.set_value (n);
208 _rc_config->set_history_depth (n);
211 void limit_undo_changed ()
213 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
216 void save_undo_toggled ()
218 bool const x = _save_undo_button.get_active ();
219 _rc_config->set_save_history (x);
222 void save_undo_changed ()
224 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
227 private:
228 RCConfiguration* _rc_config;
229 CheckButton _limit_undo_button;
230 SpinButton _limit_undo_spin;
231 CheckButton _save_undo_button;
232 SpinButton _save_undo_spin;
237 static const struct {
238 const char *name;
239 guint modifier;
240 } modifiers[] = {
242 { "Unmodified", 0 },
244 #ifdef GTKOSX
246 /* Command = Meta
247 Option/Alt = Mod1
249 { "Shift", GDK_SHIFT_MASK },
250 { "Command", GDK_META_MASK },
251 { "Control", GDK_CONTROL_MASK },
252 { "Option", GDK_MOD1_MASK },
253 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
254 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
255 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
256 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
258 #else
259 { "Shift", GDK_SHIFT_MASK },
260 { "Control", GDK_CONTROL_MASK },
261 { "Alt (Mod1)", GDK_MOD1_MASK },
262 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
263 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
264 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
265 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
266 { "Mod2", GDK_MOD2_MASK },
267 { "Mod3", GDK_MOD3_MASK },
268 { "Mod4", GDK_MOD4_MASK },
269 { "Mod5", GDK_MOD5_MASK },
270 #endif
271 { 0, 0 }
275 class KeyboardOptions : public OptionEditorBox
277 public:
278 KeyboardOptions () :
279 _delete_button_adjustment (3, 1, 12),
280 _delete_button_spin (_delete_button_adjustment),
281 _edit_button_adjustment (3, 1, 5),
282 _edit_button_spin (_edit_button_adjustment),
283 _insert_note_button_adjustment (3, 1, 5),
284 _insert_note_button_spin (_insert_note_button_adjustment)
286 /* internationalize and prepare for use with combos */
288 vector<string> dumb;
289 for (int i = 0; modifiers[i].name; ++i) {
290 dumb.push_back (_(modifiers[i].name));
293 set_popdown_strings (_edit_modifier_combo, dumb);
294 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
296 for (int x = 0; modifiers[x].name; ++x) {
297 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
298 _edit_modifier_combo.set_active_text (_(modifiers[x].name));
299 break;
303 Table* t = manage (new Table (4, 4));
304 t->set_spacings (4);
306 Label* l = manage (new Label (_("Edit using:")));
307 l->set_name ("OptionsLabel");
308 l->set_alignment (0, 0.5);
310 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
311 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
313 l = manage (new Label (_("+ button")));
314 l->set_name ("OptionsLabel");
316 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
317 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
319 _edit_button_spin.set_name ("OptionsEntry");
320 _edit_button_adjustment.set_value (Keyboard::edit_button());
321 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
323 set_popdown_strings (_delete_modifier_combo, dumb);
324 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
326 for (int x = 0; modifiers[x].name; ++x) {
327 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
328 _delete_modifier_combo.set_active_text (_(modifiers[x].name));
329 break;
333 l = manage (new Label (_("Delete using:")));
334 l->set_name ("OptionsLabel");
335 l->set_alignment (0, 0.5);
337 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
338 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
340 l = manage (new Label (_("+ button")));
341 l->set_name ("OptionsLabel");
343 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
344 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
346 _delete_button_spin.set_name ("OptionsEntry");
347 _delete_button_adjustment.set_value (Keyboard::delete_button());
348 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
351 set_popdown_strings (_insert_note_modifier_combo, dumb);
352 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
354 for (int x = 0; modifiers[x].name; ++x) {
355 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
356 _insert_note_modifier_combo.set_active_text (_(modifiers[x].name));
357 break;
361 l = manage (new Label (_("Insert note using:")));
362 l->set_name ("OptionsLabel");
363 l->set_alignment (0, 0.5);
365 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
366 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
368 l = manage (new Label (_("+ button")));
369 l->set_name ("OptionsLabel");
371 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
372 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
374 _insert_note_button_spin.set_name ("OptionsEntry");
375 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
376 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
379 set_popdown_strings (_snap_modifier_combo, dumb);
380 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
382 for (int x = 0; modifiers[x].name; ++x) {
383 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
384 _snap_modifier_combo.set_active_text (_(modifiers[x].name));
385 break;
389 l = manage (new Label (_("Toggle snap using:")));
390 l->set_name ("OptionsLabel");
391 l->set_alignment (0, 0.5);
393 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
394 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
396 vector<string> strs;
398 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
399 strs.push_back (bf->first);
402 set_popdown_strings (_keyboard_layout_selector, strs);
403 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
404 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
406 l = manage (new Label (_("Keyboard layout:")));
407 l->set_name ("OptionsLabel");
408 l->set_alignment (0, 0.5);
410 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
411 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
413 _box->pack_start (*t, false, false);
416 void parameter_changed (string const &)
418 /* XXX: these aren't really config options... */
421 void set_state_from_config ()
423 /* XXX: these aren't really config options... */
426 private:
428 void bindings_changed ()
430 string const txt = _keyboard_layout_selector.get_active_text();
432 /* XXX: config...? for all this keyboard stuff */
434 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
435 if (txt == i->first) {
436 if (Keyboard::load_keybindings (i->second)) {
437 Keyboard::save_keybindings ();
443 void edit_modifier_chosen ()
445 string const txt = _edit_modifier_combo.get_active_text();
447 for (int i = 0; modifiers[i].name; ++i) {
448 if (txt == _(modifiers[i].name)) {
449 Keyboard::set_edit_modifier (modifiers[i].modifier);
450 break;
455 void delete_modifier_chosen ()
457 string const txt = _delete_modifier_combo.get_active_text();
459 for (int i = 0; modifiers[i].name; ++i) {
460 if (txt == _(modifiers[i].name)) {
461 Keyboard::set_delete_modifier (modifiers[i].modifier);
462 break;
467 void insert_note_modifier_chosen ()
469 string const txt = _insert_note_modifier_combo.get_active_text();
471 for (int i = 0; modifiers[i].name; ++i) {
472 if (txt == _(modifiers[i].name)) {
473 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
474 break;
479 void snap_modifier_chosen ()
481 string const txt = _snap_modifier_combo.get_active_text();
483 for (int i = 0; modifiers[i].name; ++i) {
484 if (txt == _(modifiers[i].name)) {
485 Keyboard::set_snap_modifier (modifiers[i].modifier);
486 break;
491 void delete_button_changed ()
493 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
496 void edit_button_changed ()
498 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
501 void insert_note_button_changed ()
503 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
506 ComboBoxText _keyboard_layout_selector;
507 ComboBoxText _edit_modifier_combo;
508 ComboBoxText _delete_modifier_combo;
509 ComboBoxText _insert_note_modifier_combo;
510 ComboBoxText _snap_modifier_combo;
511 Adjustment _delete_button_adjustment;
512 SpinButton _delete_button_spin;
513 Adjustment _edit_button_adjustment;
514 SpinButton _edit_button_spin;
515 Adjustment _insert_note_button_adjustment;
516 SpinButton _insert_note_button_spin;
520 class FontScalingOptions : public OptionEditorBox
522 public:
523 FontScalingOptions (RCConfiguration* c) :
524 _rc_config (c),
525 _dpi_adjustment (50, 50, 250, 1, 10),
526 _dpi_slider (_dpi_adjustment)
528 _dpi_adjustment.set_value (_rc_config->get_font_scale () / 1024);
530 Label* l = manage (new Label (_("Font scaling:")));
531 l->set_name ("OptionsLabel");
533 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
534 HBox* h = manage (new HBox);
535 h->set_spacing (4);
536 h->pack_start (*l, false, false);
537 h->pack_start (_dpi_slider, true, true);
539 _box->pack_start (*h, false, false);
541 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
544 void parameter_changed (string const & p)
546 if (p == "font-scale") {
547 _dpi_adjustment.set_value (_rc_config->get_font_scale() / 1024);
551 void set_state_from_config ()
553 parameter_changed ("font-scale");
556 private:
558 void dpi_changed ()
560 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
561 /* XXX: should be triggered from the parameter changed signal */
562 reset_dpi ();
565 RCConfiguration* _rc_config;
566 Adjustment _dpi_adjustment;
567 HScale _dpi_slider;
570 class BufferingOptions : public OptionEditorBox
572 public:
573 BufferingOptions (RCConfiguration* c)
574 : _rc_config (c)
575 , _playback_adjustment (5, 1, 60, 1, 4)
576 , _capture_adjustment (5, 1, 60, 1, 4)
577 , _playback_slider (_playback_adjustment)
578 , _capture_slider (_capture_adjustment)
580 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
582 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
583 l->set_name ("OptionsLabel");
585 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
586 HBox* h = manage (new HBox);
587 h->set_spacing (4);
588 h->pack_start (*l, false, false);
589 h->pack_start (_playback_slider, true, true);
591 _box->pack_start (*h, false, false);
593 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
595 l = manage (new Label (_("Recording (seconds of buffering):")));
596 l->set_name ("OptionsLabel");
598 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
599 h = manage (new HBox);
600 h->set_spacing (4);
601 h->pack_start (*l, false, false);
602 h->pack_start (_capture_slider, true, true);
604 _box->pack_start (*h, false, false);
606 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
607 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
610 void parameter_changed (string const & p)
612 if (p == "playback-buffer-seconds") {
613 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
614 } else if (p == "capture-buffer-seconds") {
615 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
619 void set_state_from_config ()
621 parameter_changed ("playback-buffer-seconds");
622 parameter_changed ("capture-buffer-seconds");
625 private:
627 void playback_changed ()
629 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
632 void capture_changed ()
634 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
637 RCConfiguration* _rc_config;
638 Adjustment _playback_adjustment;
639 Adjustment _capture_adjustment;
640 HScale _playback_slider;
641 HScale _capture_slider;
644 class ControlSurfacesOptions : public OptionEditorBox
646 public:
647 ControlSurfacesOptions (ArdourDialog& parent)
648 : _parent (parent)
650 _store = ListStore::create (_model);
651 _view.set_model (_store);
652 _view.append_column (_("Name"), _model.name);
653 _view.get_column(0)->set_resizable (true);
654 _view.get_column(0)->set_expand (true);
655 _view.append_column_editable (_("Enabled"), _model.enabled);
656 _view.append_column_editable (_("Feedback"), _model.feedback);
658 _box->pack_start (_view, false, false);
660 Label* label = manage (new Label);
661 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
663 _box->pack_start (*label, false, false);
664 label->show ();
666 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::model_changed));
667 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
670 void parameter_changed (std::string const &)
675 void set_state_from_config ()
677 _store->clear ();
679 ControlProtocolManager& m = ControlProtocolManager::instance ();
680 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
682 if (!(*i)->mandatory) {
683 TreeModel::Row r = *_store->append ();
684 r[_model.name] = (*i)->name;
685 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
686 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
687 r[_model.protocol_info] = *i;
692 private:
694 void model_changed (TreeModel::Path const &, TreeModel::iterator const & i)
696 TreeModel::Row r = *i;
698 ControlProtocolInfo* cpi = r[_model.protocol_info];
699 if (!cpi) {
700 return;
703 bool const was_enabled = (cpi->protocol != 0);
704 bool const is_enabled = r[_model.enabled];
706 if (was_enabled != is_enabled) {
707 if (!was_enabled) {
708 ControlProtocolManager::instance().instantiate (*cpi);
709 } else {
710 ControlProtocolManager::instance().teardown (*cpi);
714 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
715 bool const is_feedback = r[_model.feedback];
717 if (was_feedback != is_feedback && cpi->protocol) {
718 cpi->protocol->set_feedback (is_feedback);
722 void edit_clicked (GdkEventButton* ev)
724 if (ev->type != GDK_2BUTTON_PRESS) {
725 return;
728 std::string name;
729 ControlProtocolInfo* cpi;
730 TreeModel::Row row;
732 row = *(_view.get_selection()->get_selected());
734 Window* win = row[_model.editor];
735 if (win && !win->is_visible()) {
736 win->present ();
737 } else {
738 cpi = row[_model.protocol_info];
740 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
741 Box* box = (Box*) cpi->protocol->get_gui ();
742 if (box) {
743 string title = row[_model.name];
744 ArdourDialog* win = new ArdourDialog (_parent, title);
745 win->get_vbox()->pack_start (*box, false, false);
746 box->show ();
747 win->present ();
748 row[_model.editor] = win;
754 class ControlSurfacesModelColumns : public TreeModelColumnRecord
756 public:
758 ControlSurfacesModelColumns ()
760 add (name);
761 add (enabled);
762 add (feedback);
763 add (protocol_info);
764 add (editor);
767 TreeModelColumn<string> name;
768 TreeModelColumn<bool> enabled;
769 TreeModelColumn<bool> feedback;
770 TreeModelColumn<ControlProtocolInfo*> protocol_info;
771 TreeModelColumn<Gtk::Window*> editor;
774 Glib::RefPtr<ListStore> _store;
775 ControlSurfacesModelColumns _model;
776 TreeView _view;
777 Gtk::Window& _parent;
781 RCOptionEditor::RCOptionEditor ()
782 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
783 , _rc_config (Config)
785 /* MISC */
787 uint32_t hwcpus = hardware_concurrency ();
789 if (hwcpus > 1) {
790 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
792 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
793 "processor-usage",
794 _("Signal processing uses"),
795 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
796 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
799 procs->add (-1, _("all but one processor"));
800 procs->add (0, _("all available processors"));
802 for (uint32_t i = 1; i <= hwcpus; ++i) {
803 procs->add (i, string_compose (_("%1 processors"), i));
806 add_option (_("Misc"), procs);
809 add_option (_("Misc"), new OptionEditorHeading (_("Metering")));
811 ComboOption<float>* mht = new ComboOption<float> (
812 "meter-hold",
813 _("Meter hold time"),
814 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
815 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
818 mht->add (MeterHoldOff, _("off"));
819 mht->add (MeterHoldShort, _("short"));
820 mht->add (MeterHoldMedium, _("medium"));
821 mht->add (MeterHoldLong, _("long"));
823 add_option (_("Misc"), mht);
825 ComboOption<float>* mfo = new ComboOption<float> (
826 "meter-falloff",
827 _("Meter fall-off"),
828 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
829 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
832 mfo->add (METER_FALLOFF_OFF, _("off"));
833 mfo->add (METER_FALLOFF_SLOWEST, _("slowest"));
834 mfo->add (METER_FALLOFF_SLOW, _("slow"));
835 mfo->add (METER_FALLOFF_MEDIUM, _("medium"));
836 mfo->add (METER_FALLOFF_FAST, _("fast"));
837 mfo->add (METER_FALLOFF_FASTER, _("faster"));
838 mfo->add (METER_FALLOFF_FASTEST, _("fastest"));
840 add_option (_("Misc"), mfo);
842 add_option (_("Misc"), new OptionEditorHeading (_("Undo")));
844 add_option (_("Misc"), new UndoOptions (_rc_config));
846 add_option (_("Misc"), new OptionEditorHeading (_("Misc")));
848 #ifndef GTKOSX
849 /* font scaling does nothing with GDK/Quartz */
850 add_option (_("Misc"), new FontScalingOptions (_rc_config));
851 #endif
853 add_option (_("Misc"),
854 new BoolOption (
855 "verify-remove-last-capture",
856 _("Verify removal of last capture"),
857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
861 add_option (_("Misc"),
862 new BoolOption (
863 "periodic-safety-backups",
864 _("Make periodic backups of the session file"),
865 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
866 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
869 add_option (_("Misc"),
870 new BoolOption (
871 "sync-all-route-ordering",
872 _("Synchronise editor and mixer track order"),
873 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_all_route_ordering),
874 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_all_route_ordering)
877 add_option (_("Misc"),
878 new BoolOption (
879 "only-copy-imported-files",
880 _("Always copy imported files"),
881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
885 add_option (_("Misc"),
886 new BoolOption (
887 "default-narrow_ms",
888 _("Use narrow mixer strips"),
889 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
890 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
893 add_option (_("Misc"),
894 new BoolOption (
895 "name-new-markers",
896 _("Name new markers"),
897 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
898 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
901 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
903 add_option (_("Misc"), new ClickOptions (_rc_config, this));
905 /* TRANSPORT */
907 add_option (_("Transport"),
908 new BoolOption (
909 "latched-record-enable",
910 _("Keep record-enable engaged on stop"),
911 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
912 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
915 add_option (_("Transport"),
916 new BoolOption (
917 "stop-recording-on-xrun",
918 _("Stop recording when an xrun occurs"),
919 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
920 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
923 add_option (_("Transport"),
924 new BoolOption (
925 "create-xrun-marker",
926 _("Create markers where xruns occur"),
927 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
928 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
931 add_option (_("Transport"),
932 new BoolOption (
933 "stop-at-session-end",
934 _("Stop at the end of the session"),
935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
939 add_option (_("Transport"),
940 new BoolOption (
941 "seamless-loop",
942 _("Do seamless looping (not possible when slaved to MTC, JACK etc)"),
943 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
944 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
947 add_option (_("Transport"),
948 new BoolOption (
949 "primary-clock-delta-edit-cursor",
950 _("Primary clock delta to edit cursor"),
951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_primary_clock_delta_edit_cursor),
952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_primary_clock_delta_edit_cursor)
955 add_option (_("Transport"),
956 new BoolOption (
957 "secondary-clock-delta-edit-cursor",
958 _("Secondary clock delta to edit cursor"),
959 sigc::mem_fun (*_rc_config, &RCConfiguration::get_secondary_clock_delta_edit_cursor),
960 sigc::mem_fun (*_rc_config, &RCConfiguration::set_secondary_clock_delta_edit_cursor)
963 add_option (_("Transport"),
964 new BoolOption (
965 "disable-disarm-during-roll",
966 _("Disable per-track record disarm while rolling"),
967 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
968 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
971 add_option (_("Transport"),
972 new BoolOption (
973 "quieten_at_speed",
974 _("12dB gain reduction during fast-forward and fast-rewind"),
975 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
976 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
979 /* EDITOR */
981 add_option (_("Editor"),
982 new BoolOption (
983 "link-region-and-track-selection",
984 _("Link selection of regions and tracks"),
985 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
986 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
989 add_option (_("Editor"),
990 new BoolOption (
991 "automation-follows-regions",
992 _("Move relevant automation when audio regions are moved"),
993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
997 add_option (_("Editor"),
998 new BoolOption (
999 "show-track-meters",
1000 _("Show meters on tracks in the editor"),
1001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1005 add_option (_("Editor"),
1006 new BoolOption (
1007 "use-overlap-equivalency",
1008 _("Use overlap equivalency for regions"),
1009 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1010 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1013 add_option (_("Editor"),
1014 new BoolOption (
1015 "rubberbanding-snaps-to-grid",
1016 _("Make rubberband selection rectangle snap to the grid"),
1017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1021 add_option (_("Editor"),
1022 new BoolOption (
1023 "show-waveforms",
1024 _("Show waveforms in regions"),
1025 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1026 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1029 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1030 "waveform-scale",
1031 _("Waveform scale"),
1032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1036 wfs->add (Linear, _("linear"));
1037 wfs->add (Logarithmic, _("logarithmic"));
1039 add_option (_("Editor"), wfs);
1041 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1042 "waveform-shape",
1043 _("Waveform shape"),
1044 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1045 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1048 wfsh->add (Traditional, _("traditional"));
1049 wfsh->add (Rectified, _("rectified"));
1051 add_option (_("Editor"), wfsh);
1053 add_option (_("Editor"),
1054 new BoolOption (
1055 "show-waveforms-while-recording",
1056 _("Show waveforms for audio while it is being recorded"),
1057 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1058 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1061 add_option (_("Editor"),
1062 new BoolOption (
1063 "show-zoom-tools",
1064 _("Show zoom toolbar"),
1065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1069 add_option (_("Editor"),
1070 new BoolOption (
1071 "color-regions-using-track-color",
1072 _("Color regions using their track's color"),
1073 sigc::mem_fun (*_rc_config, &RCConfiguration::get_color_regions_using_track_color),
1074 sigc::mem_fun (*_rc_config, &RCConfiguration::set_color_regions_using_track_color)
1077 /* AUDIO */
1079 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1081 add_option (_("Audio"), new BufferingOptions (_rc_config));
1083 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1085 add_option (_("Audio"),
1086 new BoolOption (
1087 "use-monitor-bus",
1088 _("Use a monitor bus (allows AFL/PFL and more control)"),
1089 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_monitor_bus),
1090 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_monitor_bus)
1093 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1094 "monitoring-model",
1095 _("Record monitoring handled by"),
1096 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1097 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1100 #ifndef __APPLE__
1101 /* no JACK monitoring on CoreAudio */
1102 if (AudioEngine::instance()->can_request_hardware_monitoring()) {
1103 mm->add (HardwareMonitoring, _("JACK"));
1105 #endif
1106 mm->add (SoftwareMonitoring, _("ardour"));
1107 mm->add (ExternalMonitoring, _("audio hardware"));
1109 add_option (_("Audio"), mm);
1111 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1112 "pfl-position",
1113 _("PFL signals come from"),
1114 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1115 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1118 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1119 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1121 add_option (_("Audio"), pp);
1123 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1124 "afl-position",
1125 _("AFL signals come from"),
1126 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1127 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1130 pa->add (AFLFromBeforeProcessors, _("post-fader but before post-fader processors"));
1131 pa->add (AFLFromAfterProcessors, _("after post-fader processors"));
1133 add_option (_("Audio"), pa);
1135 add_option (_("Audio"),
1136 new BoolOption (
1137 "tape-machine-mode",
1138 _("Tape machine mode"),
1139 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1140 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1143 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1145 add_option (_("Audio"),
1146 new BoolOption (
1147 "auto-connect-standard-busses",
1148 _("Auto-connect master/monitor busses"),
1149 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1150 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1153 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1154 "input-auto-connect",
1155 _("Connect track inputs"),
1156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1160 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1161 iac->add (ManualConnect, _("manually"));
1163 add_option (_("Audio"), iac);
1165 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1166 "output-auto-connect",
1167 _("Connect track and bus outputs"),
1168 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1169 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1172 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1173 oac->add (AutoConnectMaster, _("automatically to master bus"));
1174 oac->add (ManualConnect, _("manually"));
1176 add_option (_("Audio"), oac);
1178 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1180 add_option (_("Audio"),
1181 new BoolOption (
1182 "denormal-protection",
1183 _("Use DC bias to protect against denormals"),
1184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1188 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1189 "denormal-model",
1190 _("Processor handling"),
1191 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1192 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1195 dm->add (DenormalNone, _("no processor handling"));
1197 FPU fpu;
1199 if (fpu.has_flush_to_zero()) {
1200 dm->add (DenormalFTZ, _("use FlushToZero"));
1203 if (fpu.has_denormals_are_zero()) {
1204 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1207 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1208 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZerO"));
1211 add_option (_("Audio"), dm);
1213 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1215 add_option (_("Audio"),
1216 new BoolOption (
1217 "plugins-stop-with-transport",
1218 _("Stop plugins when the transport is stopped"),
1219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1223 add_option (_("Audio"),
1224 new BoolOption (
1225 "do-not-record-plugins",
1226 _("Disable plugins during recording"),
1227 sigc::mem_fun (*_rc_config, &RCConfiguration::get_do_not_record_plugins),
1228 sigc::mem_fun (*_rc_config, &RCConfiguration::set_do_not_record_plugins)
1231 add_option (_("Audio"),
1232 new BoolOption (
1233 "new-plugins-active",
1234 _("Make new plugins active"),
1235 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1236 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1239 add_option (_("Audio"),
1240 new BoolOption (
1241 "auto-analyse-audio",
1242 _("Enable automatic analysis of audio"),
1243 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1244 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1247 add_option (_("Audio"),
1248 new BoolOption (
1249 "replicate-missing-region-channels",
1250 _("Replicate missing region channels"),
1251 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1252 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1255 /* SOLO AND MUTE */
1257 add_option (_("Solo / mute"),
1258 new FaderOption (
1259 "solo-mute-gain",
1260 _("Solo-in-place mute cut (dB)"),
1261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1265 _solo_control_is_listen_control = new BoolOption (
1266 "solo-control-is-listen-control",
1267 _("Solo controls are Listen controls"),
1268 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1269 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1272 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1274 _listen_position = new ComboOption<ListenPosition> (
1275 "listen-position",
1276 _("Listen Position"),
1277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1281 _listen_position->add (AfterFaderListen, _("after-fader listen"));
1282 _listen_position->add (PreFaderListen, _("pre-fader listen"));
1284 add_option (_("Solo / mute"), _listen_position);
1286 parameter_changed ("use-monitor-bus");
1288 add_option (_("Solo / mute"),
1289 new BoolOption (
1290 "exclusive-solo",
1291 _("Exclusive solo"),
1292 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1293 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1296 add_option (_("Solo / mute"),
1297 new BoolOption (
1298 "show-solo-mutes",
1299 _("Show solo muting"),
1300 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1301 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1304 add_option (_("Solo / mute"),
1305 new BoolOption (
1306 "solo-mute-override",
1307 _("Soloing overrides muting"),
1308 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1309 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1312 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1314 add_option (_("Solo / mute"),
1315 new BoolOption (
1316 "mute-affects-pre-fader",
1317 _("Mute affects pre-fader sends"),
1318 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1319 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1322 add_option (_("Solo / mute"),
1323 new BoolOption (
1324 "mute-affects-post-fader",
1325 _("Mute affects post-fader sends"),
1326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1330 add_option (_("Solo / mute"),
1331 new BoolOption (
1332 "mute-affects-control-outs",
1333 _("Mute affects control outputs"),
1334 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1335 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1338 add_option (_("Solo / mute"),
1339 new BoolOption (
1340 "mute-affects-main-outs",
1341 _("Mute affects main outputs"),
1342 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1343 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1346 add_option (_("MIDI"),
1347 new BoolOption (
1348 "send-midi-clock",
1349 _("Send MIDI Clock"),
1350 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1351 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1354 add_option (_("MIDI"),
1355 new BoolOption (
1356 "send-mtc",
1357 _("Send MIDI Time Code"),
1358 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1359 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1362 add_option (_("MIDI"),
1363 new SpinOption<int> (
1364 "mtc-qf-speed-tolerance",
1365 _("Percentage either side of normal transport speed to transmit MTC"),
1366 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1367 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1368 0, 20, 1, 5
1371 add_option (_("MIDI"),
1372 new BoolOption (
1373 "mmc-control",
1374 _("Obey MIDI Machine Control commands"),
1375 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1376 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1379 add_option (_("MIDI"),
1380 new BoolOption (
1381 "send-mmc",
1382 _("Send MIDI Machine Control commands"),
1383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1384 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1387 add_option (_("MIDI"),
1388 new BoolOption (
1389 "midi-feedback",
1390 _("Send MIDI control feedback"),
1391 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1392 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1395 add_option (_("MIDI"),
1396 new SpinOption<uint8_t> (
1397 "mmc-receive-device-id",
1398 _("Inbound MMC device ID"),
1399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1401 0, 128, 1, 10
1404 add_option (_("MIDI"),
1405 new SpinOption<uint8_t> (
1406 "mmc-send-device-id",
1407 _("Outbound MMC device ID"),
1408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1410 0, 128, 1, 10
1413 add_option (_("MIDI"),
1414 new SpinOption<int32_t> (
1415 "initial-program-change",
1416 _("Initial program change"),
1417 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1418 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1419 -1, 65536, 1, 10
1422 add_option (_("MIDI"),
1423 new BoolOption (
1424 "diplay-first-midi-bank-as-zero",
1425 _("Display first MIDI bank/program as 0"),
1426 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
1427 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
1430 /* CONTROL SURFACES */
1432 add_option (_("Control surfaces"), new ControlSurfacesOptions (*this));
1434 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
1435 "remote-model",
1436 _("Control surface remote ID"),
1437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
1438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
1441 rm->add (UserOrdered, _("assigned by user"));
1442 rm->add (MixerOrdered, _("follows order of mixer"));
1443 rm->add (EditorOrdered, _("follows order of editor"));
1445 add_option (_("Control surfaces"), rm);
1447 /* KEYBOARD */
1449 add_option (_("Keyboard"), new KeyboardOptions);
1452 void
1453 RCOptionEditor::parameter_changed (string const & p)
1455 OptionEditor::parameter_changed (p);
1457 if (p == "use-monitor-bus") {
1458 bool const s = Config->get_use_monitor_bus ();
1459 if (!s) {
1460 /* we can't use this if we don't have a monitor bus */
1461 Config->set_solo_control_is_listen_control (false);
1463 _solo_control_is_listen_control->set_sensitive (s);
1464 _listen_position->set_sensitive (s);