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.
21 #include "gtk2ardour-config.h"
24 #include <cairo/cairo.h>
26 #include <boost/algorithm/string.hpp>
28 #include <gtkmm/liststore.h>
29 #include <gtkmm/stock.h>
30 #include <gtkmm/scale.h>
32 #include <gtkmm2ext/utils.h>
33 #include <gtkmm2ext/slider_controller.h>
34 #include <gtkmm2ext/gtk_ui.h>
35 #include <gtkmm2ext/paths_dialog.h>
40 #include "ardour/audioengine.h"
41 #include "ardour/dB.h"
42 #include "ardour/rc_configuration.h"
43 #include "ardour/control_protocol_manager.h"
44 #include "ardour/plugin_manager.h"
45 #include "control_protocol/control_protocol.h"
47 #include "canvas/wave_view.h"
49 #include "ardour_ui.h"
50 #include "ardour_window.h"
51 #include "ardour_dialog.h"
52 #include "gui_thread.h"
53 #include "midi_tracer.h"
54 #include "rc_option_editor.h"
56 #include "midi_port_dialog.h"
59 #include "theme_manager.h"
60 #include "ui_config.h"
65 using namespace Gtkmm2ext;
67 using namespace ARDOUR;
68 using namespace ARDOUR_UI_UTILS;
70 class AutoReturnTargetOptions : public OptionEditorBox
73 AutoReturnTargetOptions (RCConfiguration* c, Gtk::Window* p)
75 , range_selection_button (_("Play Range Selection"))
76 , last_roll_button (_("Play from Last Roll"))
77 , loop_button (_("Play Loop"))
78 , region_selection_button (_("Play Region Selection"))
79 , toggle_button (_("Enable/Disable all options"))
81 _box->pack_start (range_selection_button, false, false);
82 range_selection_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::range_selection_toggled));
84 _box->pack_start (loop_button, false, false);
85 loop_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::loop_toggled));
87 _box->pack_start (region_selection_button, false, false);
88 region_selection_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::region_selection_toggled));
90 _box->pack_start (last_roll_button, false, false);
91 last_roll_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::last_roll_toggled));
93 HBox* hbox = manage (new HBox);
94 /* keep the toggle button small */
95 hbox->pack_start (toggle_button, false, false);
96 _box->pack_start (*hbox, false, false);
98 toggle_button.signal_clicked().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::toggle));
100 Gtkmm2ext::UI::instance()->set_tip (range_selection_button,
101 _("If enabled, playhead will always start from the beginning of the current range selection.\n\nIf disabled or no range selection, see the next choice in this list"));
102 Gtkmm2ext::UI::instance()->set_tip (loop_button,
103 _("If enabled, playhead will always start from the beginning of the loop range.\n\nIf disabled or no loop range, see the next choice in this list"));
104 Gtkmm2ext::UI::instance()->set_tip (region_selection_button,
105 _("If enabled, playhead will always start from the beginning of the first selected region.\n\nIf disabled or no region selection, see the next choice in this list"));
106 Gtkmm2ext::UI::instance()->set_tip (last_roll_button,
107 _("If enabled, playhead will always start from the last position where it was started.\n\nIf disabled it will start from wherever it is currently located"));
109 Gtkmm2ext::UI::instance()->set_tip (toggle_button,
110 _("Change status of all buttons above to all enabled or all disabled"));
113 void parameter_changed (string const & p)
115 if (p == "auto-return-target-list") {
116 AutoReturnTarget art = _rc_config->get_auto_return_target_list();
117 cerr << "ARTO, reset buttons with " << enum_2_string (art) << endl;
118 range_selection_button.set_active (art & RangeSelectionStart);
119 loop_button.set_active (art & Loop);
120 region_selection_button.set_active (art & RegionSelectionStart);
121 last_roll_button.set_active (art & LastLocate);
125 void set_state_from_config ()
127 parameter_changed ("auto-return-target-list");
132 void range_selection_toggled () {
133 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
134 if (range_selection_button.get_active ()) {
135 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | RangeSelectionStart));
137 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~RangeSelectionStart));
140 void last_roll_toggled () {
141 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
142 if (range_selection_button.get_active ()) {
143 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | LastLocate));
145 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~LastLocate));
148 void region_selection_toggled () {
149 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
150 if (range_selection_button.get_active ()) {
151 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | RegionSelectionStart));
153 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~RegionSelectionStart));
156 void loop_toggled () {
157 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
158 if (range_selection_button.get_active ()) {
159 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | Loop));
161 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~Loop));
166 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
168 _rc_config->set_auto_return_target_list (AutoReturnTarget (0));
170 _rc_config->set_auto_return_target_list (AutoReturnTarget (RangeSelectionStart|
171 RegionSelectionStart|
177 RCConfiguration* _rc_config;
179 Gtk::CheckButton range_selection_button;
180 Gtk::CheckButton last_roll_button;
181 Gtk::CheckButton loop_button;
182 Gtk::CheckButton region_selection_button;
183 Gtk::Button toggle_button;
186 class ClickOptions : public OptionEditorBox
189 ClickOptions (RCConfiguration* c, Gtk::Window* p)
192 Table* t = manage (new Table (2, 3));
195 Label* l = manage (left_aligned_label (_("Click audio file:")));
196 t->attach (*l, 0, 1, 0, 1, FILL);
197 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
198 Button* b = manage (new Button (_("Browse...")));
199 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
200 t->attach (*b, 2, 3, 0, 1, FILL);
202 l = manage (left_aligned_label (_("Click emphasis audio file:")));
203 t->attach (*l, 0, 1, 1, 2, FILL);
204 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
205 b = manage (new Button (_("Browse...")));
206 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
207 t->attach (*b, 2, 3, 1, 2, FILL);
209 _box->pack_start (*t, false, false);
211 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
212 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
215 void parameter_changed (string const & p)
217 if (p == "click-sound") {
218 _click_path_entry.set_text (_rc_config->get_click_sound());
219 } else if (p == "click-emphasis-sound") {
220 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
224 void set_state_from_config ()
226 parameter_changed ("click-sound");
227 parameter_changed ("click-emphasis-sound");
232 void click_browse_clicked ()
234 SoundFileChooser sfdb (_("Choose Click"));
239 if (sfdb.run () == RESPONSE_OK) {
240 click_chosen (sfdb.get_filename());
244 void click_chosen (string const & path)
246 _click_path_entry.set_text (path);
247 _rc_config->set_click_sound (path);
250 void click_changed ()
252 click_chosen (_click_path_entry.get_text ());
255 void click_emphasis_browse_clicked ()
257 SoundFileChooser sfdb (_("Choose Click Emphasis"));
262 if (sfdb.run () == RESPONSE_OK) {
263 click_emphasis_chosen (sfdb.get_filename());
267 void click_emphasis_chosen (string const & path)
269 _click_emphasis_path_entry.set_text (path);
270 _rc_config->set_click_emphasis_sound (path);
273 void click_emphasis_changed ()
275 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
278 RCConfiguration* _rc_config;
279 Entry _click_path_entry;
280 Entry _click_emphasis_path_entry;
283 class UndoOptions : public OptionEditorBox
286 UndoOptions (RCConfiguration* c) :
288 _limit_undo_button (_("Limit undo history to")),
289 _save_undo_button (_("Save undo history of"))
291 Table* t = new Table (2, 3);
294 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
295 _limit_undo_spin.set_range (0, 512);
296 _limit_undo_spin.set_increments (1, 10);
297 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
298 Label* l = manage (left_aligned_label (_("commands")));
299 t->attach (*l, 2, 3, 0, 1);
301 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
302 _save_undo_spin.set_range (0, 512);
303 _save_undo_spin.set_increments (1, 10);
304 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
305 l = manage (left_aligned_label (_("commands")));
306 t->attach (*l, 2, 3, 1, 2);
308 _box->pack_start (*t);
310 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
311 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
312 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
313 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
316 void parameter_changed (string const & p)
318 if (p == "history-depth") {
319 int32_t const d = _rc_config->get_history_depth();
320 _limit_undo_button.set_active (d != 0);
321 _limit_undo_spin.set_sensitive (d != 0);
322 _limit_undo_spin.set_value (d);
323 } else if (p == "save-history") {
324 bool const x = _rc_config->get_save_history ();
325 _save_undo_button.set_active (x);
326 _save_undo_spin.set_sensitive (x);
327 } else if (p == "save-history-depth") {
328 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
332 void set_state_from_config ()
334 parameter_changed ("save-history");
335 parameter_changed ("history-depth");
336 parameter_changed ("save-history-depth");
339 void limit_undo_toggled ()
341 bool const x = _limit_undo_button.get_active ();
342 _limit_undo_spin.set_sensitive (x);
343 int32_t const n = x ? 16 : 0;
344 _limit_undo_spin.set_value (n);
345 _rc_config->set_history_depth (n);
348 void limit_undo_changed ()
350 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
353 void save_undo_toggled ()
355 bool const x = _save_undo_button.get_active ();
356 _rc_config->set_save_history (x);
359 void save_undo_changed ()
361 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
365 RCConfiguration* _rc_config;
366 CheckButton _limit_undo_button;
367 SpinButton _limit_undo_spin;
368 CheckButton _save_undo_button;
369 SpinButton _save_undo_spin;
374 static const struct {
386 { "Key|Shift", GDK_SHIFT_MASK },
387 { "Command", GDK_META_MASK },
388 { "Control", GDK_CONTROL_MASK },
389 { "Option", GDK_MOD1_MASK },
390 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
391 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
392 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
393 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
394 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
397 { "Key|Shift", GDK_SHIFT_MASK },
398 { "Control", GDK_CONTROL_MASK },
399 { "Alt", GDK_MOD1_MASK },
400 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
401 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
402 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
403 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
404 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
405 { "Mod2", GDK_MOD2_MASK },
406 { "Mod3", GDK_MOD3_MASK },
407 { "Windows", GDK_MOD4_MASK },
408 { "Mod5", GDK_MOD5_MASK },
414 class KeyboardOptions : public OptionEditorBox
418 _delete_button_adjustment (3, 1, 12),
419 _delete_button_spin (_delete_button_adjustment),
420 _edit_button_adjustment (3, 1, 5),
421 _edit_button_spin (_edit_button_adjustment),
422 _insert_note_button_adjustment (3, 1, 5),
423 _insert_note_button_spin (_insert_note_button_adjustment)
425 /* internationalize and prepare for use with combos */
428 for (int i = 0; modifiers[i].name; ++i) {
429 dumb.push_back (S_(modifiers[i].name));
432 set_popdown_strings (_edit_modifier_combo, dumb);
433 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
435 for (int x = 0; modifiers[x].name; ++x) {
436 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
437 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
442 Table* t = manage (new Table (5, 11));
448 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
449 l->set_name ("OptionsLabel");
453 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
454 strs.push_back (bf->first);
457 set_popdown_strings (_keyboard_layout_selector, strs);
458 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
459 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
461 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
462 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (left_aligned_label (_("When Clicking:")));
468 l->set_name ("OptionEditorHeading");
469 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
474 l = manage (left_aligned_label (_("Edit using:")));
475 l->set_name ("OptionsLabel");
477 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
478 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
480 l = manage (new Label (_("+ button")));
481 l->set_name ("OptionsLabel");
483 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
484 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
486 _edit_button_spin.set_name ("OptionsEntry");
487 _edit_button_adjustment.set_value (Keyboard::edit_button());
488 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
493 set_popdown_strings (_delete_modifier_combo, dumb);
494 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
496 for (int x = 0; modifiers[x].name; ++x) {
497 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
498 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
503 l = manage (left_aligned_label (_("Delete using:")));
504 l->set_name ("OptionsLabel");
506 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
507 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
509 l = manage (new Label (_("+ button")));
510 l->set_name ("OptionsLabel");
512 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
513 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
515 _delete_button_spin.set_name ("OptionsEntry");
516 _delete_button_adjustment.set_value (Keyboard::delete_button());
517 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
522 set_popdown_strings (_insert_note_modifier_combo, dumb);
523 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
525 for (int x = 0; modifiers[x].name; ++x) {
526 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
527 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
532 l = manage (left_aligned_label (_("Insert note using:")));
533 l->set_name ("OptionsLabel");
535 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
536 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
538 l = manage (new Label (_("+ button")));
539 l->set_name ("OptionsLabel");
541 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
542 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
544 _insert_note_button_spin.set_name ("OptionsEntry");
545 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
546 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
550 l = manage (left_aligned_label (_("When Beginning a Drag:")));
551 l->set_name ("OptionEditorHeading");
552 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
558 set_popdown_strings (_copy_modifier_combo, dumb);
559 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
561 for (int x = 0; modifiers[x].name; ++x) {
562 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
563 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
568 l = manage (left_aligned_label (_("Copy items using:")));
569 l->set_name ("OptionsLabel");
571 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
572 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
577 /* constraint modifier */
578 set_popdown_strings (_constraint_modifier_combo, dumb);
579 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
581 for (int x = 0; modifiers[x].name; ++x) {
582 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
583 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
588 l = manage (left_aligned_label (_("Constrain drag using:")));
589 l->set_name ("OptionsLabel");
591 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
592 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
596 l = manage (left_aligned_label (_("When Beginning a Trim:")));
597 l->set_name ("OptionEditorHeading");
598 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
604 set_popdown_strings (_trim_contents_combo, dumb);
605 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
607 for (int x = 0; modifiers[x].name; ++x) {
608 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
609 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
614 l = manage (left_aligned_label (_("Trim contents using:")));
615 l->set_name ("OptionsLabel");
617 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
618 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
624 set_popdown_strings (_trim_anchored_combo, dumb);
625 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
627 for (int x = 0; modifiers[x].name; ++x) {
628 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
629 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
634 l = manage (left_aligned_label (_("Anchored trim using:")));
635 l->set_name ("OptionsLabel");
637 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
644 /* jump trim disabled for now
645 set_popdown_strings (_trim_jump_combo, dumb);
646 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
648 for (int x = 0; modifiers[x].name; ++x) {
649 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
650 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
655 l = manage (left_aligned_label (_("Jump after trim using:")));
656 l->set_name ("OptionsLabel");
658 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
660 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
666 /* note resize relative */
667 set_popdown_strings (_note_size_relative_combo, dumb);
668 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
670 for (int x = 0; modifiers[x].name; ++x) {
671 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
672 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
677 l = manage (left_aligned_label (_("Resize notes relatively using:")));
678 l->set_name ("OptionsLabel");
680 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
682 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
686 l = manage (left_aligned_label (_("While Dragging:")));
687 l->set_name ("OptionEditorHeading");
688 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
694 set_popdown_strings (_snap_modifier_combo, dumb);
695 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
697 for (int x = 0; modifiers[x].name; ++x) {
698 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
699 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
704 l = manage (left_aligned_label (_("Ignore snap using:")));
705 l->set_name ("OptionsLabel");
707 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
708 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
714 set_popdown_strings (_snap_delta_combo, dumb);
715 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
717 for (int x = 0; modifiers[x].name; ++x) {
718 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
719 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
724 l = manage (left_aligned_label (_("Snap relatively using:")));
725 l->set_name ("OptionsLabel");
727 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
728 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
732 l = manage (left_aligned_label (_("While Trimming:")));
733 l->set_name ("OptionEditorHeading");
734 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
740 set_popdown_strings (_trim_overlap_combo, dumb);
741 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
743 for (int x = 0; modifiers[x].name; ++x) {
744 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
745 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
750 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
751 l->set_name ("OptionsLabel");
753 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
754 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
758 l = manage (left_aligned_label (_("While Dragging Control Points:")));
759 l->set_name ("OptionEditorHeading");
760 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
766 set_popdown_strings (_fine_adjust_combo, dumb);
767 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
769 for (int x = 0; modifiers[x].name; ++x) {
770 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
771 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
776 l = manage (left_aligned_label (_("Fine adjust using:")));
777 l->set_name ("OptionsLabel");
779 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
780 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
786 set_popdown_strings (_push_points_combo, dumb);
787 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
789 for (int x = 0; modifiers[x].name; ++x) {
790 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
791 _push_points_combo.set_active_text (S_(modifiers[x].name));
796 l = manage (left_aligned_label (_("Push points using:")));
797 l->set_name ("OptionsLabel");
799 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
800 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
802 _box->pack_start (*t, false, false);
805 void parameter_changed (string const &)
807 /* XXX: these aren't really config options... */
810 void set_state_from_config ()
812 /* XXX: these aren't really config options... */
817 void bindings_changed ()
819 string const txt = _keyboard_layout_selector.get_active_text();
821 /* XXX: config...? for all this keyboard stuff */
823 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
824 if (txt == i->first) {
825 if (Keyboard::load_keybindings (i->second)) {
826 Keyboard::save_keybindings ();
832 void edit_modifier_chosen ()
834 string const txt = _edit_modifier_combo.get_active_text();
836 for (int i = 0; modifiers[i].name; ++i) {
837 if (txt == _(modifiers[i].name)) {
838 Keyboard::set_edit_modifier (modifiers[i].modifier);
844 void delete_modifier_chosen ()
846 string const txt = _delete_modifier_combo.get_active_text();
848 for (int i = 0; modifiers[i].name; ++i) {
849 if (txt == _(modifiers[i].name)) {
850 Keyboard::set_delete_modifier (modifiers[i].modifier);
856 void copy_modifier_chosen ()
858 string const txt = _copy_modifier_combo.get_active_text();
860 for (int i = 0; modifiers[i].name; ++i) {
861 if (txt == _(modifiers[i].name)) {
862 Keyboard::set_copy_modifier (modifiers[i].modifier);
868 void insert_note_modifier_chosen ()
870 string const txt = _insert_note_modifier_combo.get_active_text();
872 for (int i = 0; modifiers[i].name; ++i) {
873 if (txt == _(modifiers[i].name)) {
874 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
880 void snap_modifier_chosen ()
882 string const txt = _snap_modifier_combo.get_active_text();
884 for (int i = 0; modifiers[i].name; ++i) {
885 if (txt == _(modifiers[i].name)) {
886 Keyboard::set_snap_modifier (modifiers[i].modifier);
892 void snap_delta_modifier_chosen ()
894 string const txt = _snap_delta_combo.get_active_text();
896 for (int i = 0; modifiers[i].name; ++i) {
897 if (txt == _(modifiers[i].name)) {
898 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
904 void constraint_modifier_chosen ()
906 string const txt = _constraint_modifier_combo.get_active_text();
908 for (int i = 0; modifiers[i].name; ++i) {
909 if (txt == _(modifiers[i].name)) {
910 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
916 void trim_contents_modifier_chosen ()
918 string const txt = _trim_contents_combo.get_active_text();
920 for (int i = 0; modifiers[i].name; ++i) {
921 if (txt == _(modifiers[i].name)) {
922 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
928 void trim_overlap_modifier_chosen ()
930 string const txt = _trim_overlap_combo.get_active_text();
932 for (int i = 0; modifiers[i].name; ++i) {
933 if (txt == _(modifiers[i].name)) {
934 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
940 void trim_anchored_modifier_chosen ()
942 string const txt = _trim_anchored_combo.get_active_text();
944 for (int i = 0; modifiers[i].name; ++i) {
945 if (txt == _(modifiers[i].name)) {
946 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
952 void fine_adjust_modifier_chosen ()
954 string const txt = _fine_adjust_combo.get_active_text();
956 for (int i = 0; modifiers[i].name; ++i) {
957 if (txt == _(modifiers[i].name)) {
958 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
964 void push_points_modifier_chosen ()
966 string const txt = _push_points_combo.get_active_text();
968 for (int i = 0; modifiers[i].name; ++i) {
969 if (txt == _(modifiers[i].name)) {
970 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
976 void note_size_relative_modifier_chosen ()
978 string const txt = _note_size_relative_combo.get_active_text();
980 for (int i = 0; modifiers[i].name; ++i) {
981 if (txt == _(modifiers[i].name)) {
982 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
988 void delete_button_changed ()
990 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
993 void edit_button_changed ()
995 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
998 void insert_note_button_changed ()
1000 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1003 ComboBoxText _keyboard_layout_selector;
1004 ComboBoxText _edit_modifier_combo;
1005 ComboBoxText _delete_modifier_combo;
1006 ComboBoxText _copy_modifier_combo;
1007 ComboBoxText _insert_note_modifier_combo;
1008 ComboBoxText _snap_modifier_combo;
1009 ComboBoxText _snap_delta_combo;
1010 ComboBoxText _constraint_modifier_combo;
1011 ComboBoxText _trim_contents_combo;
1012 ComboBoxText _trim_overlap_combo;
1013 ComboBoxText _trim_anchored_combo;
1014 ComboBoxText _trim_jump_combo;
1015 ComboBoxText _fine_adjust_combo;
1016 ComboBoxText _push_points_combo;
1017 ComboBoxText _note_size_relative_combo;
1018 Adjustment _delete_button_adjustment;
1019 SpinButton _delete_button_spin;
1020 Adjustment _edit_button_adjustment;
1021 SpinButton _edit_button_spin;
1022 Adjustment _insert_note_button_adjustment;
1023 SpinButton _insert_note_button_spin;
1027 class FontScalingOptions : public OptionEditorBox
1030 FontScalingOptions (UIConfiguration* uic) :
1032 _dpi_adjustment (100, 50, 250, 1, 5),
1033 _dpi_slider (_dpi_adjustment)
1035 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
1037 Label* l = manage (new Label (_("GUI and Font scaling:")));
1038 l->set_name ("OptionsLabel");
1040 const Glib::ustring dflt = _("Default");
1041 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1043 _dpi_slider.set_name("FontScaleSlider");
1044 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1045 _dpi_slider.set_draw_value(false);
1046 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1050 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1052 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1053 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1054 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1055 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1056 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1057 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1059 HBox* h = manage (new HBox);
1061 h->pack_start (*l, false, false);
1062 h->pack_start (_dpi_slider, true, true);
1064 _box->pack_start (*h, false, false);
1066 set_note (_("Adjusting the scale require an application restart to re-layout."));
1068 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1071 void parameter_changed (string const & p)
1073 if (p == "font-scale") {
1074 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
1078 void set_state_from_config ()
1080 parameter_changed ("font-scale");
1087 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1088 /* XXX: should be triggered from the parameter changed signal */
1092 UIConfiguration* _ui_config;
1093 Adjustment _dpi_adjustment;
1097 class ClipLevelOptions : public OptionEditorBox
1100 ClipLevelOptions (UIConfiguration* c)
1102 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1103 , _clip_level_slider (_clip_level_adjustment)
1105 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
1107 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1108 l->set_name ("OptionsLabel");
1110 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1111 HBox* h = manage (new HBox);
1113 h->pack_start (*l, false, false);
1114 h->pack_start (_clip_level_slider, true, true);
1116 _box->pack_start (*h, false, false);
1118 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1121 void parameter_changed (string const & p)
1123 if (p == "waveform-clip-level") {
1124 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1128 void set_state_from_config ()
1130 parameter_changed ("waveform-clip-level");
1135 void clip_level_changed ()
1137 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1138 /* XXX: should be triggered from the parameter changed signal */
1139 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1142 UIConfiguration* _ui_config;
1143 Adjustment _clip_level_adjustment;
1144 HScale _clip_level_slider;
1147 class BufferingOptions : public OptionEditorBox
1150 BufferingOptions (RCConfiguration* c)
1152 , _playback_adjustment (5, 1, 60, 1, 4)
1153 , _capture_adjustment (5, 1, 60, 1, 4)
1154 , _playback_slider (_playback_adjustment)
1155 , _capture_slider (_capture_adjustment)
1157 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1159 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
1160 l->set_name ("OptionsLabel");
1162 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1163 HBox* h = manage (new HBox);
1165 h->pack_start (*l, false, false);
1166 h->pack_start (_playback_slider, true, true);
1168 _box->pack_start (*h, false, false);
1170 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1172 l = manage (new Label (_("Recording (seconds of buffering):")));
1173 l->set_name ("OptionsLabel");
1175 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1176 h = manage (new HBox);
1178 h->pack_start (*l, false, false);
1179 h->pack_start (_capture_slider, true, true);
1181 _box->pack_start (*h, false, false);
1183 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1184 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1187 void parameter_changed (string const & p)
1189 if (p == "playback-buffer-seconds") {
1190 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1191 } else if (p == "capture-buffer-seconds") {
1192 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1196 void set_state_from_config ()
1198 parameter_changed ("playback-buffer-seconds");
1199 parameter_changed ("capture-buffer-seconds");
1204 void playback_changed ()
1206 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1209 void capture_changed ()
1211 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1214 RCConfiguration* _rc_config;
1215 Adjustment _playback_adjustment;
1216 Adjustment _capture_adjustment;
1217 HScale _playback_slider;
1218 HScale _capture_slider;
1221 class ControlSurfacesOptions : public OptionEditorBox
1224 ControlSurfacesOptions (Gtk::Window& parent)
1226 , _ignore_view_change (0)
1228 _store = ListStore::create (_model);
1229 _view.set_model (_store);
1230 _view.append_column (_("Control Surface Protocol"), _model.name);
1231 _view.get_column(0)->set_resizable (true);
1232 _view.get_column(0)->set_expand (true);
1233 _view.append_column_editable (_("Enabled"), _model.enabled);
1234 _view.append_column_editable (_("Feedback"), _model.feedback);
1236 _box->pack_start (_view, false, false);
1238 Label* label = manage (new Label);
1239 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1241 _box->pack_start (*label, false, false);
1244 ControlProtocolManager& m = ControlProtocolManager::instance ();
1245 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1246 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1248 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1249 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1252 void parameter_changed (std::string const &)
1257 void set_state_from_config ()
1261 ControlProtocolManager& m = ControlProtocolManager::instance ();
1262 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1264 if (!(*i)->mandatory) {
1265 TreeModel::Row r = *_store->append ();
1266 r[_model.name] = (*i)->name;
1267 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1268 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1269 r[_model.protocol_info] = *i;
1276 void protocol_status_changed (ControlProtocolInfo* cpi) {
1278 TreeModel::Children rows = _store->children();
1280 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1281 string n = ((*x)[_model.name]);
1283 if ((*x)[_model.protocol_info] == cpi) {
1284 _ignore_view_change++;
1285 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1286 _ignore_view_change--;
1292 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1294 TreeModel::Row r = *i;
1296 if (_ignore_view_change) {
1300 ControlProtocolInfo* cpi = r[_model.protocol_info];
1305 bool const was_enabled = (cpi->protocol != 0);
1306 bool const is_enabled = r[_model.enabled];
1309 if (was_enabled != is_enabled) {
1312 ControlProtocolManager::instance().activate (*cpi);
1314 ControlProtocolManager::instance().deactivate (*cpi);
1318 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1319 bool const is_feedback = r[_model.feedback];
1321 if (was_feedback != is_feedback && cpi->protocol) {
1322 cpi->protocol->set_feedback (is_feedback);
1326 void edit_clicked (GdkEventButton* ev)
1328 if (ev->type != GDK_2BUTTON_PRESS) {
1333 ControlProtocolInfo* cpi;
1336 row = *(_view.get_selection()->get_selected());
1337 if (!row[_model.enabled]) {
1340 cpi = row[_model.protocol_info];
1341 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1344 Box* box = (Box*) cpi->protocol->get_gui ();
1348 if (box->get_parent()) {
1349 static_cast<ArdourWindow*>(box->get_parent())->present();
1352 string title = row[_model.name];
1353 /* once created, the window is managed by the surface itself (as ->get_parent())
1354 * Surface's tear_down_gui() is called on session close, when de-activating
1355 * or re-initializing a surface.
1356 * tear_down_gui() hides an deletes the Window if it exists.
1358 ArdourWindow* win = new ArdourWindow (_parent, title);
1359 win->set_title ("Control Protocol Options");
1365 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1369 ControlSurfacesModelColumns ()
1374 add (protocol_info);
1377 TreeModelColumn<string> name;
1378 TreeModelColumn<bool> enabled;
1379 TreeModelColumn<bool> feedback;
1380 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1383 Glib::RefPtr<ListStore> _store;
1384 ControlSurfacesModelColumns _model;
1386 Gtk::Window& _parent;
1387 PBD::ScopedConnection protocol_status_connection;
1388 uint32_t _ignore_view_change;
1391 class VideoTimelineOptions : public OptionEditorBox
1394 VideoTimelineOptions (RCConfiguration* c)
1396 , _show_video_export_info_button (_("Show Video Export Info before export"))
1397 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1398 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1400 Table* t = manage (new Table (2, 6));
1401 t->set_spacings (4);
1403 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1404 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1405 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1406 _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
1408 Label* l = manage (new Label (_("Video Server URL:")));
1409 l->set_alignment (0, 0.5);
1410 t->attach (*l, 0, 1, 1, 2, FILL);
1411 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1412 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1413 _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
1415 l = manage (new Label (_("Video Folder:")));
1416 l->set_alignment (0, 0.5);
1417 t->attach (*l, 0, 1, 2, 3, FILL);
1418 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1419 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1420 _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
1422 /* small vspace y=3..4 */
1424 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1425 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1426 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1427 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1429 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1430 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1431 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1432 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1434 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1435 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1436 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1437 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1439 _box->pack_start (*t,true,true);
1442 void server_url_changed ()
1444 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1447 void server_docroot_changed ()
1449 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1452 void show_video_export_info_toggled ()
1454 bool const x = _show_video_export_info_button.get_active ();
1455 _rc_config->set_show_video_export_info (x);
1458 void show_video_server_dialog_toggled ()
1460 bool const x = _show_video_server_dialog_button.get_active ();
1461 _rc_config->set_show_video_server_dialog (x);
1464 void video_advanced_setup_toggled ()
1466 bool const x = _video_advanced_setup_button.get_active ();
1467 _rc_config->set_video_advanced_setup(x);
1470 void parameter_changed (string const & p)
1472 if (p == "video-server-url") {
1473 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1474 } else if (p == "video-server-docroot") {
1475 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1476 } else if (p == "show-video-export-info") {
1477 bool const x = _rc_config->get_show_video_export_info();
1478 _show_video_export_info_button.set_active (x);
1479 } else if (p == "show-video-server-dialog") {
1480 bool const x = _rc_config->get_show_video_server_dialog();
1481 _show_video_server_dialog_button.set_active (x);
1482 } else if (p == "video-advanced-setup") {
1483 bool const x = _rc_config->get_video_advanced_setup();
1484 _video_advanced_setup_button.set_active(x);
1485 _video_server_docroot_entry.set_sensitive(x);
1486 _video_server_url_entry.set_sensitive(x);
1490 void set_state_from_config ()
1492 parameter_changed ("video-server-url");
1493 parameter_changed ("video-server-docroot");
1494 parameter_changed ("video-monitor-setup-dialog");
1495 parameter_changed ("show-video-export-info");
1496 parameter_changed ("show-video-server-dialog");
1497 parameter_changed ("video-advanced-setup");
1501 RCConfiguration* _rc_config;
1502 Entry _video_server_url_entry;
1503 Entry _video_server_docroot_entry;
1504 CheckButton _show_video_export_info_button;
1505 CheckButton _show_video_server_dialog_button;
1506 CheckButton _video_advanced_setup_button;
1509 class PluginOptions : public OptionEditorBox
1512 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1515 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1516 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1517 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1518 , _timeout_adjustment (0, 0, 3000, 50, 50)
1519 , _timeout_slider (_timeout_adjustment)
1522 std::stringstream ss;
1523 Table* t = manage (new Table (2, 6));
1524 t->set_spacings (4);
1528 ss << "<b>" << _("General") << "</b>";
1529 l = manage (left_aligned_label (ss.str()));
1530 l->set_use_markup (true);
1531 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1532 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1534 b = manage (new Button (_("Scan for Plugins")));
1535 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1536 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1538 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1539 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1540 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1541 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1543 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1544 _timeout_slider.set_digits (0);
1545 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1547 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1548 _("Specify the default timeout for plugin instantiation in 1/10 seconds. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1550 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1551 HBox* h = manage (new HBox);
1553 h->pack_start (*l, false, false);
1554 h->pack_start (_timeout_slider, true, true);
1555 t->attach (*h, 0, 2, n, n+1); ++n;
1558 ss << "<b>" << _("VST") << "</b>";
1559 l = manage (left_aligned_label (ss.str()));
1560 l->set_use_markup (true);
1561 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1562 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1564 b = manage (new Button (_("Clear VST Cache")));
1565 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1566 t->attach (*b, 0, 1, n, n+1, FILL);
1568 b = manage (new Button (_("Clear VST Blacklist")));
1569 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1570 t->attach (*b, 1, 2, n, n+1, FILL);
1573 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1574 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1575 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1576 _("<b>When enabled</b> new VST plugins are searched, tested and added to the cache index on application start. When disabled new plugins will only be available after triggering a 'Scan' manually"));
1578 #ifdef LXVST_SUPPORT
1579 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1580 b = manage (new Button (_("Edit")));
1581 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1582 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1585 #ifdef WINDOWS_VST_SUPPORT
1586 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1587 b = manage (new Button (_("Edit")));
1588 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1589 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1593 #ifdef AUDIOUNIT_SUPPORT
1595 ss << "<b>" << _("Audio Unit") << "</b>";
1596 l = manage (left_aligned_label (ss.str()));
1597 l->set_use_markup (true);
1598 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1599 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1601 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1602 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1603 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1604 _("<b>When enabled</b> Audio Unit Plugins are discovered on application start. When disabled AU plugins will only be available after triggering a 'Scan' manually. The first successful scan will enable AU auto-scan, Any crash during plugin discovery will disable it."));
1607 b = manage (new Button (_("Clear AU Cache")));
1608 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1609 t->attach (*b, 0, 1, n, n+1, FILL);
1611 b = manage (new Button (_("Clear AU Blacklist")));
1612 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1613 t->attach (*b, 1, 2, n, n+1, FILL);
1617 _box->pack_start (*t,true,true);
1620 void parameter_changed (string const & p) {
1621 if (p == "show-plugin-scan-window") {
1622 bool const x = _ui_config->get_show_plugin_scan_window();
1623 _display_plugin_scan_progress.set_active (x);
1625 else if (p == "discover-vst-on-start") {
1626 bool const x = _rc_config->get_discover_vst_on_start();
1627 _discover_vst_on_start.set_active (x);
1629 else if (p == "vst-scan-timeout") {
1630 int const x = _rc_config->get_vst_scan_timeout();
1631 _timeout_adjustment.set_value (x);
1633 else if (p == "discover-audio-units") {
1634 bool const x = _rc_config->get_discover_audio_units();
1635 _discover_au_on_start.set_active (x);
1639 void set_state_from_config () {
1640 parameter_changed ("show-plugin-scan-window");
1641 parameter_changed ("discover-vst-on-start");
1642 parameter_changed ("vst-scan-timeout");
1643 parameter_changed ("discover-audio-units");
1647 RCConfiguration* _rc_config;
1648 UIConfiguration* _ui_config;
1649 CheckButton _display_plugin_scan_progress;
1650 CheckButton _discover_vst_on_start;
1651 CheckButton _discover_au_on_start;
1652 Adjustment _timeout_adjustment;
1653 HScale _timeout_slider;
1655 void display_plugin_scan_progress_toggled () {
1656 bool const x = _display_plugin_scan_progress.get_active();
1657 _ui_config->set_show_plugin_scan_window(x);
1660 void discover_vst_on_start_toggled () {
1661 bool const x = _discover_vst_on_start.get_active();
1662 _rc_config->set_discover_vst_on_start(x);
1665 void discover_au_on_start_toggled () {
1666 bool const x = _discover_au_on_start.get_active();
1667 _rc_config->set_discover_audio_units(x);
1670 void timeout_changed () {
1671 int x = floor(_timeout_adjustment.get_value());
1672 _rc_config->set_vst_scan_timeout(x);
1675 void clear_vst_cache_clicked () {
1676 PluginManager::instance().clear_vst_cache();
1679 void clear_vst_blacklist_clicked () {
1680 PluginManager::instance().clear_vst_blacklist();
1683 void clear_au_cache_clicked () {
1684 PluginManager::instance().clear_au_cache();
1687 void clear_au_blacklist_clicked () {
1688 PluginManager::instance().clear_au_blacklist();
1692 void edit_vst_path_clicked () {
1693 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1694 _("Set Windows VST Search Path"),
1695 _rc_config->get_plugin_path_vst(),
1696 PluginManager::instance().get_default_windows_vst_path()
1698 ResponseType r = (ResponseType) pd->run ();
1700 if (r == RESPONSE_ACCEPT) {
1701 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1706 // todo consolidate with edit_vst_path_clicked..
1707 void edit_lxvst_path_clicked () {
1708 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1709 _("Set Linux VST Search Path"),
1710 _rc_config->get_plugin_path_lxvst(),
1711 PluginManager::instance().get_default_lxvst_path()
1713 ResponseType r = (ResponseType) pd->run ();
1715 if (r == RESPONSE_ACCEPT) {
1716 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1721 void refresh_clicked () {
1722 PluginManager::instance().refresh();
1727 /** A class which allows control of visibility of some editor components usign
1728 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1729 * which has the correct members, but with null widget pointers. This
1730 * class allows the user to set visibility of the members, the details
1731 * of which are stored in a configuration variable which can be watched
1732 * by parts of the editor that actually contain the widgets whose visibility
1733 * is being controlled.
1736 class VisibilityOption : public Option
1739 /** @param name User-visible name for this group.
1740 * @param g `Dummy' VisibilityGroup (as described above).
1741 * @param get Method to get the value of the appropriate configuration variable.
1742 * @param set Method to set the value of the appropriate configuration variable.
1744 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1745 : Option (g->get_state_name(), name)
1747 , _visibility_group (g)
1751 /* Watch for changes made by the user to our members */
1752 _visibility_group->VisibilityChanged.connect_same_thread (
1753 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1757 void set_state_from_config ()
1759 /* Set our state from the current configuration */
1760 _visibility_group->set_state (_get ());
1763 void add_to_page (OptionEditorPage* p)
1765 _heading.add_to_page (p);
1766 add_widget_to_page (p, _visibility_group->list_view ());
1769 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1774 /* The user has changed something, so reflect this change
1775 in the RCConfiguration.
1777 _set (_visibility_group->get_state_value ());
1780 OptionEditorHeading _heading;
1781 VisibilityGroup* _visibility_group;
1782 sigc::slot<std::string> _get;
1783 sigc::slot<bool, std::string> _set;
1784 PBD::ScopedConnection _visibility_group_connection;
1789 RCOptionEditor::RCOptionEditor ()
1790 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1791 , _rc_config (Config)
1792 , _ui_config (ARDOUR_UI::config())
1793 , _mixer_strip_visibility ("mixer-element-visibility")
1797 uint32_t hwcpus = hardware_concurrency ();
1799 BoolComboOption* bco;
1802 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1804 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1806 _("Signal processing uses"),
1807 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1808 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1811 procs->add (-1, _("all but one processor"));
1812 procs->add (0, _("all available processors"));
1814 for (uint32_t i = 1; i <= hwcpus; ++i) {
1815 procs->add (i, string_compose (_("%1 processors"), i));
1818 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1820 add_option (_("Misc"), procs);
1823 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1825 add_option (_("Misc"), new UndoOptions (_rc_config));
1827 add_option (_("Misc"),
1829 "verify-remove-last-capture",
1830 _("Verify removal of last capture"),
1831 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1832 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1835 add_option (_("Misc"),
1837 "periodic-safety-backups",
1838 _("Make periodic backups of the session file"),
1839 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1840 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1843 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1845 add_option (_("Misc"),
1847 "only-copy-imported-files",
1848 _("Always copy imported files"),
1849 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1850 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1853 add_option (_("Misc"), new DirectoryOption (
1854 X_("default-session-parent-dir"),
1855 _("Default folder for new sessions:"),
1856 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1857 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1860 add_option (_("Misc"),
1861 new SpinOption<uint32_t> (
1862 "max-recent-sessions",
1863 _("Maximum number of recent sessions"),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1869 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1871 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1873 add_option (_("Misc"),
1876 _("Click gain level"),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1878 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1881 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1883 add_option (_("Misc"),
1884 new SpinOption<double> (
1885 "automation-thinning-factor",
1886 _("Thinning factor (larger value => less data)"),
1887 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1888 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1892 add_option (_("Misc"),
1893 new SpinOption<double> (
1894 "automation-interval-msecs",
1895 _("Automation sampling interval (milliseconds)"),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1897 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1903 add_option (_("Transport"), new OptionEditorHeading (S_("Playhead Behaviour")));
1904 add_option (_("Transport"), new AutoReturnTargetOptions (_rc_config, this));
1905 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1909 tsf = new BoolOption (
1910 "latched-record-enable",
1911 _("Keep record-enable engaged on stop"),
1912 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1913 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1915 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1916 add_option (_("Transport"), tsf);
1918 tsf = new BoolOption (
1920 _("Play loop is a transport mode"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1924 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1925 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1926 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1927 add_option (_("Transport"), tsf);
1929 tsf = new BoolOption (
1930 "stop-recording-on-xrun",
1931 _("Stop recording when an xrun occurs"),
1932 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1933 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1935 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1936 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1938 add_option (_("Transport"), tsf);
1940 tsf = new BoolOption (
1941 "create-xrun-marker",
1942 _("Create markers where xruns occur"),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1946 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1947 add_option (_("Transport"), tsf);
1949 tsf = new BoolOption (
1950 "stop-at-session-end",
1951 _("Stop at the end of the session"),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1953 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1955 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1956 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1957 "when it reaches the current session end marker\n\n"
1958 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1960 add_option (_("Transport"), tsf);
1962 tsf = new BoolOption (
1964 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1965 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1968 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1969 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1970 "preventing any need to do a transport locate at the end of the loop\n\n"
1971 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1972 "which will often cause a small click or delay"), PROGRAM_NAME));
1973 add_option (_("Transport"), tsf);
1975 tsf = new BoolOption (
1976 "disable-disarm-during-roll",
1977 _("Disable per-track record disarm while rolling"),
1978 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1979 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1981 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
1982 add_option (_("Transport"), tsf);
1984 tsf = new BoolOption (
1986 _("12dB gain reduction during fast-forward and fast-rewind"),
1987 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1988 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1990 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1991 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1992 add_option (_("Transport"), tsf);
1994 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1996 _sync_source = new ComboOption<SyncSource> (
1998 _("External timecode source"),
1999 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2003 add_option (_("Transport"), _sync_source);
2005 _sync_framerate = new BoolOption (
2006 "timecode-sync-frame-rate",
2007 _("Match session video frame rate to external timecode"),
2008 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2011 Gtkmm2ext::UI::instance()->set_tip
2012 (_sync_framerate->tip_widget(),
2013 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2014 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2015 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2016 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2017 "timecode standard and the session standard."), PROGRAM_NAME));
2019 add_option (_("Transport"), _sync_framerate);
2021 _sync_genlock = new BoolOption (
2022 "timecode-source-is-synced",
2023 _("Sync-lock timecode to clock (disable drift compensation)"),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2025 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2027 Gtkmm2ext::UI::instance()->set_tip
2028 (_sync_genlock->tip_widget(),
2029 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2030 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2031 "(Black & Burst, Wordclock, etc) with the audio interface. "
2032 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2033 "Vari-speed LTC will be ignored and cause drift."
2035 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2036 "timecode sources shares clock sync."
2040 add_option (_("Transport"), _sync_genlock);
2042 _sync_source_2997 = new BoolOption (
2043 "timecode-source-2997",
2044 _("Lock to 29.9700 fps instead of 30000/1001"),
2045 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2046 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2048 Gtkmm2ext::UI::instance()->set_tip
2049 (_sync_source_2997->tip_widget(),
2050 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2051 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2052 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2053 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2054 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2055 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2058 add_option (_("Transport"), _sync_source_2997);
2060 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2062 _ltc_port = new ComboStringOption (
2064 _("LTC incoming port"),
2065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2069 vector<string> physical_inputs;
2070 physical_inputs.push_back (_("None"));
2071 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2072 _ltc_port->set_popdown_strings (physical_inputs);
2074 populate_sync_options ();
2076 add_option (_("Transport"), _ltc_port);
2078 // TODO; rather disable this button than not compile it..
2079 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2081 add_option (_("Transport"),
2084 _("Enable LTC generator"),
2085 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2086 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2089 _ltc_send_continuously = new BoolOption (
2090 "ltc-send-continuously",
2091 _("Send LTC while stopped"),
2092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2095 Gtkmm2ext::UI::instance()->set_tip
2096 (_ltc_send_continuously->tip_widget(),
2097 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2098 add_option (_("Transport"), _ltc_send_continuously);
2100 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2101 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2102 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2103 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2105 Gtkmm2ext::UI::instance()->set_tip
2106 (_ltc_volume_slider->tip_widget(),
2107 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2109 add_option (_("Transport"), _ltc_volume_slider);
2110 parameter_changed ("send-ltc");
2112 parameter_changed ("sync-source");
2116 add_option (S_("Editor"),
2118 "draggable-playhead",
2119 _("Allow dragging of playhead"),
2120 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2121 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2124 add_option (_("Editor"),
2126 "automation-follows-regions",
2127 _("Move relevant automation when audio regions are moved"),
2128 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2129 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2132 add_option (_("Editor"),
2134 "show-track-meters",
2135 _("Show meters on tracks in the editor"),
2136 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2137 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2140 add_option (_("Editor"),
2142 "show-editor-meter",
2143 _("Display master-meter in the toolbar"),
2144 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2145 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2148 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2149 "default-fade-shape",
2150 _("Default fade shape"),
2151 sigc::mem_fun (*_rc_config,
2152 &RCConfiguration::get_default_fade_shape),
2153 sigc::mem_fun (*_rc_config,
2154 &RCConfiguration::set_default_fade_shape)
2157 fadeshape->add (FadeLinear,
2158 _("Linear (for highly correlated material)"));
2159 fadeshape->add (FadeConstantPower, _("Constant power"));
2160 fadeshape->add (FadeSymmetric, _("Symmetric"));
2161 fadeshape->add (FadeSlow, _("Slow"));
2162 fadeshape->add (FadeFast, _("Fast"));
2164 add_option (_("Editor"), fadeshape);
2167 bco = new BoolComboOption (
2168 "use-overlap-equivalency",
2169 _("Regions in active edit groups are edited together"),
2170 _("whenever they overlap in time"),
2171 _("only if they have identical length, position and origin"),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2176 add_option (_("Editor"), bco);
2178 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2180 _("Layering model"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2185 lm->add (LaterHigher, _("later is higher"));
2186 lm->add (Manual, _("manual layering"));
2187 add_option (_("Editor"), lm);
2189 add_option (_("Editor"),
2191 "rubberbanding-snaps-to-grid",
2192 _("Make rubberband selection rectangle snap to the grid"),
2193 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2194 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2197 add_option (_("Editor"),
2200 _("Show waveforms in regions"),
2201 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2202 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2205 add_option (_("Editor"),
2206 new BoolComboOption (
2207 "show-region-gain-envelopes",
2208 _("Show gain envelopes in audio regions"),
2210 _("only in Draw and Internal Edit modes"),
2211 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2212 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2215 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2217 _("Waveform scale"),
2218 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2219 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2222 wfs->add (Linear, _("linear"));
2223 wfs->add (Logarithmic, _("logarithmic"));
2225 add_option (_("Editor"), wfs);
2227 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2229 _("Waveform shape"),
2230 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2231 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2234 wfsh->add (Traditional, _("traditional"));
2235 wfsh->add (Rectified, _("rectified"));
2237 add_option (_("Editor"), wfsh);
2239 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2241 add_option (_("Editor"),
2243 "show-waveforms-while-recording",
2244 _("Show waveforms for audio while it is being recorded"),
2245 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2246 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2249 add_option (_("Editor"),
2252 _("Show zoom toolbar"),
2253 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2254 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2257 add_option (_("Editor"),
2259 "update-editor-during-summary-drag",
2260 _("Update editor window during drags of the summary"),
2261 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2262 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2265 bo = new BoolOption (
2267 _("Name new markers"),
2268 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2269 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2272 add_option (_("Editor"), bo);
2273 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("If enabled, popup a dialog when a new marker is created to allow its name to be set as it is created."
2274 "\n\nYou can always rename markers by right-clicking on them"));
2276 add_option (_("Editor"),
2278 "autoscroll-editor",
2279 _("Auto-scroll editor window when dragging near its edges"),
2280 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2281 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2284 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2285 "region-selection-after-split",
2286 _("After splitting selected regions, select"),
2287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2290 // TODO: decide which of these modes are really useful
2291 rsas->add(None, _("no regions"));
2292 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2293 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2294 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2295 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2296 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2297 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2298 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2300 add_option (_("Editor"), rsas);
2305 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2307 add_option (_("Audio"), new BufferingOptions (_rc_config));
2309 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2311 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2313 _("Record monitoring handled by"),
2314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2318 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2319 mm->add (HardwareMonitoring, _("via Audio Driver"));
2322 string prog (PROGRAM_NAME);
2323 boost::algorithm::to_lower (prog);
2324 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2325 mm->add (ExternalMonitoring, _("audio hardware"));
2327 add_option (_("Audio"), mm);
2329 add_option (_("Audio"),
2331 "tape-machine-mode",
2332 _("Tape machine mode"),
2333 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2334 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2337 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2339 add_option (_("Audio"),
2341 "auto-connect-standard-busses",
2342 _("Auto-connect master/monitor busses"),
2343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2347 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2348 "input-auto-connect",
2349 _("Connect track inputs"),
2350 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2351 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2354 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2355 iac->add (ManualConnect, _("manually"));
2357 add_option (_("Audio"), iac);
2359 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2360 "output-auto-connect",
2361 _("Connect track and bus outputs"),
2362 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2363 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2366 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2367 oac->add (AutoConnectMaster, _("automatically to master bus"));
2368 oac->add (ManualConnect, _("manually"));
2370 add_option (_("Audio"), oac);
2372 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2374 add_option (_("Audio"),
2376 "denormal-protection",
2377 _("Use DC bias to protect against denormals"),
2378 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2379 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2382 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2384 _("Processor handling"),
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2386 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2390 dm->add (DenormalNone, _("no processor handling"));
2394 if (fpu.has_flush_to_zero()) {
2396 dm->add (DenormalFTZ, _("use FlushToZero"));
2397 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2398 _rc_config->set_denormal_model(DenormalNone);
2401 if (fpu.has_denormals_are_zero()) {
2403 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2404 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2405 _rc_config->set_denormal_model(DenormalNone);
2408 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
2410 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2411 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2412 _rc_config->set_denormal_model(DenormalNone);
2416 dm->set_sensitive(false);
2419 add_option (_("Audio"), dm);
2421 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2423 add_option (_("Audio"),
2425 "plugins-stop-with-transport",
2426 _("Silence plugins when the transport is stopped"),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2428 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2431 add_option (_("Audio"),
2433 "new-plugins-active",
2434 _("Make new plugins active"),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2436 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2439 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2441 add_option (_("Audio"),
2443 "auto-analyse-audio",
2444 _("Enable automatic analysis of audio"),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2449 add_option (_("Audio"),
2451 "replicate-missing-region-channels",
2452 _("Replicate missing region channels"),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2459 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2461 add_option (_("Solo / mute"),
2464 _("Solo-in-place mute cut (dB)"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2469 _solo_control_is_listen_control = new BoolOption (
2470 "solo-control-is-listen-control",
2471 _("Solo controls are Listen controls"),
2472 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2476 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2478 _listen_position = new ComboOption<ListenPosition> (
2480 _("Listen Position"),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2485 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2486 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2488 add_option (_("Solo / mute"), _listen_position);
2490 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2492 _("PFL signals come from"),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2497 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2498 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2500 add_option (_("Solo / mute"), pp);
2502 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2504 _("AFL signals come from"),
2505 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2506 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2509 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2510 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2512 add_option (_("Solo / mute"), pa);
2514 parameter_changed ("use-monitor-bus");
2516 add_option (_("Solo / mute"),
2519 _("Exclusive solo"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2524 add_option (_("Solo / mute"),
2527 _("Show solo muting"),
2528 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2529 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2532 add_option (_("Solo / mute"),
2534 "solo-mute-override",
2535 _("Soloing overrides muting"),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2540 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2542 add_option (_("Solo / mute"),
2544 "mute-affects-pre-fader",
2545 _("Mute affects pre-fader sends"),
2546 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2547 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2550 add_option (_("Solo / mute"),
2552 "mute-affects-post-fader",
2553 _("Mute affects post-fader sends"),
2554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2558 add_option (_("Solo / mute"),
2560 "mute-affects-control-outs",
2561 _("Mute affects control outputs"),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2566 add_option (_("Solo / mute"),
2568 "mute-affects-main-outs",
2569 _("Mute affects main outputs"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2574 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2576 add_option (_("Solo / mute"),
2578 "link-send-and-route-panner",
2579 _("Link panners of Aux and External Sends with main panner by default"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2584 add_option (_("MIDI"),
2585 new SpinOption<float> (
2587 _("MIDI read-ahead time (seconds)"),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2594 add_option (_("MIDI"),
2597 _("Send MIDI Clock"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2602 add_option (_("MIDI"),
2605 _("Send MIDI Time Code"),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2610 add_option (_("MIDI"),
2611 new SpinOption<int> (
2612 "mtc-qf-speed-tolerance",
2613 _("Percentage either side of normal transport speed to transmit MTC"),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2619 add_option (_("MIDI"),
2622 _("Obey MIDI Machine Control commands"),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2627 add_option (_("MIDI"),
2630 _("Send MIDI Machine Control commands"),
2631 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2632 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2635 add_option (_("MIDI"),
2638 _("Send MIDI control feedback"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2643 add_option (_("MIDI"),
2644 new SpinOption<uint8_t> (
2645 "mmc-receive-device-id",
2646 _("Inbound MMC device ID"),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2652 add_option (_("MIDI"),
2653 new SpinOption<uint8_t> (
2654 "mmc-send-device-id",
2655 _("Outbound MMC device ID"),
2656 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2661 add_option (_("MIDI"),
2662 new SpinOption<int32_t> (
2663 "initial-program-change",
2664 _("Initial program change"),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2670 add_option (_("MIDI"),
2672 "display-first-midi-bank-as-zero",
2673 _("Display first MIDI bank/program as 0"),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2678 add_option (_("MIDI"),
2680 "never-display-periodic-midi",
2681 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2682 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2683 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2686 add_option (_("MIDI"),
2689 _("Sound MIDI notes as they are selected"),
2690 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2691 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2694 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2696 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2697 "midi-audition-synth-uri",
2698 _("Midi Audition Synth (LV2)"),
2699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2703 audition_synth->add(X_(""), _("None"));
2704 PluginInfoList all_plugs;
2705 PluginManager& manager (PluginManager::instance());
2707 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2709 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2710 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2711 if (!(*i)->is_instrument()) continue;
2712 if ((*i)->type != ARDOUR::LV2) continue;
2713 audition_synth->add((*i)->unique_id, (*i)->name);
2717 add_option (_("MIDI"), audition_synth);
2719 /* USER INTERACTION */
2722 #ifdef PLATFORM_WINDOWS
2725 getenv ("ARDOUR_BUNDLED")
2729 add_option (_("User interaction"),
2731 "enable-translation",
2732 string_compose (_("Use translations of %1 messages\n"
2733 " <i>(requires a restart of %1 to take effect)</i>\n"
2734 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2735 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2736 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2739 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2741 add_option (_("User interaction"), new KeyboardOptions);
2743 /* Control Surfaces */
2745 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2747 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2749 _("Control surface remote ID"),
2750 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2754 rm->add (UserOrdered, _("assigned by user"));
2755 rm->add (MixerOrdered, _("follows order of mixer"));
2757 add_option (_("Control Surfaces"), rm);
2759 /* VIDEO Timeline */
2760 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2762 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2763 /* Plugin options (currrently VST only) */
2764 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2769 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2770 BoolOption* bgo = new BoolOption (
2772 _("Possibly improve slow graphical performance"),
2773 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2774 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2777 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("This requires restarting %1 before having an effect"), PROGRAM_NAME));
2778 add_option (S_("Preferences|GUI"), bgo);
2781 add_option (S_("Preferences|GUI"),
2784 _("Graphically indicate mouse pointer hovering over various widgets"),
2785 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2786 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2789 #ifdef TOOLTIPS_GOT_FIXED
2790 add_option (S_("Preferences|GUI"),
2793 _("Show tooltips if mouse hovers over a control"),
2794 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2795 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2799 add_option (S_("Preferences|GUI"),
2801 "show-name-highlight",
2802 _("Use name highlight bars in region displays (requires a restart)"),
2803 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2804 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2808 /* font scaling does nothing with GDK/Quartz */
2809 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2812 add_option (S_("GUI"),
2814 "super-rapid-clock-update",
2815 _("update transport clock display at FPS instead of every 100ms"),
2816 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2817 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2821 /* Image cache size */
2823 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2824 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2825 _("Waveform image cache size (megabytes)"),
2827 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2828 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2830 sics->scale().set_digits (0);
2831 Gtkmm2ext::UI::instance()->set_tip
2832 (sics->tip_widget(),
2833 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2834 add_option (S_("Preferences|GUI"), sics);
2836 /* Lock GUI timeout */
2838 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2839 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2840 _("Lock timeout (seconds)"),
2842 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2843 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2845 slts->scale().set_digits (0);
2846 Gtkmm2ext::UI::instance()->set_tip
2847 (slts->tip_widget(),
2848 _("Lock GUI after this many idle seconds (zero to never lock)"));
2849 add_option (S_("Preferences|GUI"), slts);
2851 /* The names of these controls must be the same as those given in MixerStrip
2852 for the actual widgets being controlled.
2854 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2855 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2856 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2857 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2858 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2859 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2862 S_("Preferences|GUI"),
2863 new VisibilityOption (
2865 &_mixer_strip_visibility,
2866 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2867 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2871 add_option (S_("Preferences|GUI"),
2873 "default-narrow_ms",
2874 _("Use narrow strips in the mixer by default"),
2875 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2876 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2879 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2881 ComboOption<float>* mht = new ComboOption<float> (
2883 _("Peak hold time"),
2884 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2885 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2888 mht->add (MeterHoldOff, _("off"));
2889 mht->add (MeterHoldShort, _("short"));
2890 mht->add (MeterHoldMedium, _("medium"));
2891 mht->add (MeterHoldLong, _("long"));
2893 add_option (S_("Preferences|Metering"), mht);
2895 ComboOption<float>* mfo = new ComboOption<float> (
2898 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2899 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2902 mfo->add (METER_FALLOFF_OFF, _("off"));
2903 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2904 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2905 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2906 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2907 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2908 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2909 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2910 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2912 add_option (S_("Preferences|Metering"), mfo);
2914 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2915 "meter-line-up-level",
2916 _("Meter line-up level; 0dBu"),
2917 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2918 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2921 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2922 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2923 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2924 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2926 Gtkmm2ext::UI::instance()->set_tip (mlu->tip_widget(), _("Configure meter-marks and color-knee point for dBFS scale DPM, set reference level for IEC1/Nordic, IEC2 PPM and VU meter."));
2928 add_option (S_("Preferences|Metering"), mlu);
2930 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2931 "meter-line-up-din",
2932 _("IEC1/DIN Meter line-up level; 0dBu"),
2933 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2934 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2937 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2938 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2939 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2940 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2942 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2944 add_option (S_("Preferences|Metering"), mld);
2946 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2947 "meter-vu-standard",
2948 _("VU Meter standard"),
2949 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2950 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2953 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2954 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2955 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2956 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2958 add_option (S_("Preferences|Metering"), mvu);
2960 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2961 HSliderOption *mpks = new HSliderOption("meter-peak",
2962 _("Peak threshold [dBFS]"),
2964 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2965 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2968 Gtkmm2ext::UI::instance()->set_tip
2969 (mpks->tip_widget(),
2970 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2972 add_option (S_("Preferences|Metering"), mpks);
2974 add_option (S_("Preferences|Metering"),
2977 _("LED meter style"),
2978 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2979 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2982 /* and now the theme manager */
2984 ThemeManager* tm = manage (new ThemeManager);
2985 add_page (_("Theme"), *tm);
2989 RCOptionEditor::parameter_changed (string const & p)
2991 OptionEditor::parameter_changed (p);
2993 if (p == "use-monitor-bus") {
2994 bool const s = Config->get_use_monitor_bus ();
2996 /* we can't use this if we don't have a monitor bus */
2997 Config->set_solo_control_is_listen_control (false);
2999 _solo_control_is_listen_control->set_sensitive (s);
3000 _listen_position->set_sensitive (s);
3001 } else if (p == "sync-source") {
3002 _sync_source->set_sensitive (true);
3004 _sync_source->set_sensitive (!_session->config.get_external_sync());
3006 switch(Config->get_sync_source()) {
3009 _sync_genlock->set_sensitive (true);
3010 _sync_framerate->set_sensitive (true);
3011 _sync_source_2997->set_sensitive (true);
3014 _sync_genlock->set_sensitive (false);
3015 _sync_framerate->set_sensitive (false);
3016 _sync_source_2997->set_sensitive (false);
3019 } else if (p == "send-ltc") {
3020 bool const s = Config->get_send_ltc ();
3021 _ltc_send_continuously->set_sensitive (s);
3022 _ltc_volume_slider->set_sensitive (s);
3026 void RCOptionEditor::ltc_generator_volume_changed () {
3027 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3031 RCOptionEditor::populate_sync_options ()
3033 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3035 _sync_source->clear ();
3037 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3038 _sync_source->add (*i, sync_source_to_string (*i));
3041 if (sync_opts.empty()) {
3042 _sync_source->set_sensitive(false);
3044 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3045 _rc_config->set_sync_source(sync_opts.front());