ardour
route_ui.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2006 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <gtkmm2ext/gtk_ui.h>
21 #include <gtkmm2ext/choice.h>
22 #include <gtkmm2ext/doi.h>
25 #include <gtkmm2ext/gtk_ui.h>
26 #include <gtkmm2ext/utils.h>
27 
28 #include "ardour/route_group.h"
29 #include "ardour/dB.h"
30 #include "pbd/memento_command.h"
31 #include "pbd/stacktrace.h"
32 #include "pbd/controllable.h"
33 #include "pbd/enumwriter.h"
34 
35 #include "ardour_ui.h"
36 #include "editor.h"
37 #include "route_ui.h"
38 #include "ardour_button.h"
39 #include "keyboard.h"
40 #include "utils.h"
41 #include "prompter.h"
42 #include "gui_thread.h"
43 #include "ardour_dialog.h"
44 #include "latency_gui.h"
45 #include "mixer_strip.h"
46 #include "automation_time_axis.h"
47 #include "route_time_axis.h"
48 #include "group_tabs.h"
49 #include "timers.h"
50 
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
54 #include "ardour/midi_track.h"
55 #include "ardour/internal_send.h"
56 #include "ardour/send.h"
57 #include "ardour/route.h"
58 #include "ardour/session.h"
59 #include "ardour/template_utils.h"
60 
61 #include "i18n.h"
62 using namespace Gtk;
63 using namespace Gtkmm2ext;
64 using namespace ARDOUR;
65 using namespace ARDOUR_UI_UTILS;
66 using namespace PBD;
67 using namespace std;
68 
69 uint32_t RouteUI::_max_invert_buttons = 3;
70 PBD::Signal1<void, boost::shared_ptr<Route> > RouteUI::BusSendDisplayChanged;
72 
74  : AxisView(sess)
75  , mute_menu(0)
76  , solo_menu(0)
77  , sends_menu(0)
78  , record_menu(0)
79  , comment_window(0)
80  , comment_area(0)
81  , input_selector (0)
82  , output_selector (0)
83  , _invert_menu(0)
84 {
85  if (sess) init ();
86 }
87 
89 {
90  if (_route) {
92  }
93 
94  _route.reset (); /* drop reference to route, so that it can be cleaned up */
96 
97  delete solo_menu;
98  delete mute_menu;
99  delete sends_menu;
100  delete record_menu;
101  delete comment_window;
102  delete input_selector;
103  delete output_selector;
104  delete _invert_menu;
105 
106  send_blink_connection.disconnect ();
107  rec_blink_connection.disconnect ();
108 }
109 
110 void
112 {
113  self_destruct = true;
114  mute_menu = 0;
115  solo_menu = 0;
116  sends_menu = 0;
117  record_menu = 0;
118  _invert_menu = 0;
121  listen_mute_check = 0;
122  main_mute_check = 0;
123  solo_safe_check = 0;
125  solo_isolated_led = 0;
126  solo_safe_led = 0;
127  _solo_release = 0;
128  _mute_release = 0;
129  denormal_menu_item = 0;
130  step_edit_item = 0;
131  multiple_mute_change = false;
132  multiple_solo_change = false;
133  _i_am_the_modifier = 0;
134 
135  input_selector = 0;
136  output_selector = 0;
137 
139 
140  mute_button = manage (new ArdourButton);
141  mute_button->set_name ("mute button");
142  UI::instance()->set_tip (mute_button, _("Mute this track"), "");
143 
144  solo_button = manage (new ArdourButton);
145  solo_button->set_name ("solo button");
146  UI::instance()->set_tip (solo_button, _("Mute other (non-soloed) tracks"), "");
147  solo_button->set_no_show_all (true);
148 
149  rec_enable_button = manage (new ArdourButton);
150  rec_enable_button->set_name ("record enable button");
153  UI::instance()->set_tip (rec_enable_button, _("Enable recording on this track"), "");
154 
155  if (ARDOUR_UI::config()->get_blink_rec_arm()) {
157  }
158 
159  show_sends_button = manage (new ArdourButton);
160  show_sends_button->set_name ("send alert button");
161  UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
162 
164  monitor_input_button->set_name ("monitor button");
166  UI::instance()->set_tip (monitor_input_button, _("Monitor input"), "");
167  monitor_input_button->set_no_show_all (true);
168 
170  monitor_disk_button->set_name ("monitor button");
171  monitor_disk_button->set_text (_("Disk"));
172  UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), "");
173  monitor_disk_button->set_no_show_all (true);
174 
178 
179  _session->config.ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
180  Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
181 
182  rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false);
183  rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false);
184 
185  show_sends_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_press), false);
186  show_sends_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_release), false);
187 
188  solo_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::solo_press), false);
189  solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
190  mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
191  mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
192 
195 
196  monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press), false);
197  monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release), false);
198 
199  monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press), false);
200  monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release), false);
201 
202  BusSendDisplayChanged.connect_same_thread (*this, boost::bind(&RouteUI::bus_send_display_changed, this, _1));
203 }
204 
205 void
207 {
209 
210  delete solo_menu;
211  solo_menu = 0;
212 
213  delete mute_menu;
214  mute_menu = 0;
215 
216  denormal_menu_item = 0;
217 }
218 
219 void
221 {
222  delete this;
223 }
224 
225 void
227 {
228  reset ();
229 
230  _route = rp;
231 
232  if (set_color_from_route()) {
234  }
235 
236  if (self_destruct) {
237  rp->DropReferences.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::self_delete, this), gui_context());
238  }
239 
240  delete input_selector;
241  input_selector = 0;
242 
243  delete output_selector;
244  output_selector = 0;
245 
248 
250  _route->mute_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_mute_display, this), gui_context());
251 
252  _route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::comment_changed, this, _1), gui_context());
253 
254  _route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
256  _route->listen_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
258  if (is_track()) {
259  track()->TrackModeChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::track_mode_changed, this), gui_context());
261  }
262 
264  _route->PropertyChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::property_changed, this, _1), gui_context());
265 
266  _route->io_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::setup_invert_buttons, this), gui_context ());
267  _route->gui_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_gui_changed, this, _1), gui_context ());
268 
269  if (_session->writable() && is_track()) {
271 
273 
274  rec_enable_button->show();
276 
277  if (is_midi_track()) {
279  boost::bind (&RouteUI::step_edit_changed, this, _1), gui_context());
280  }
281 
282  }
283 
284  /* this will work for busses and tracks, and needs to be called to
285  set up the name entry/name label display.
286  */
287 
288  if (is_track()) {
290  t->MonitoringChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::monitoring_changed, this), gui_context());
291 
293  }
294 
295  mute_button->unset_flags (Gtk::CAN_FOCUS);
296  solo_button->unset_flags (Gtk::CAN_FOCUS);
297 
298  mute_button->show();
299 
300  if (_route->is_monitor() || _route->is_master()) {
301  solo_button->hide ();
302  } else {
303  solo_button->show();
304  }
305 
306  map_frozen ();
307 
310 
313 
316 
317  if (!ARDOUR_UI::config()->get_blink_rec_arm()) {
318  blink_rec_display(true); // set initial rec-en button state
319  }
320 
322 }
323 
324 void
326 {
327  if (!_route) {
328  return;
329  }
330 
332 }
333 
334 bool
335 RouteUI::mute_press (GdkEventButton* ev)
336 {
337  if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
338  return true;
339  }
340 
341  //if this is a binding action, let the ArdourButton handle it
343  return false;
344 
345  multiple_mute_change = false;
346 
347  if (Keyboard::is_context_menu_event (ev)) {
348 
349  if (mute_menu == 0){
350  build_mute_menu();
351  }
352 
353  mute_menu->popup(0,ev->time);
354 
355  return true;
356 
357  } else {
358 
359  if (Keyboard::is_button2_event (ev)) {
360  // button2-click is "momentary"
361 
363  }
364 
365  if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
366 
367  if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
368 
369  /* toggle mute on everything (but
370  * exclude the master and monitor)
371  *
372  * because we are going to erase
373  * elements of the list we need to work
374  * on a copy.
375  */
376 
378 
379  *copy = *_session->get_routes ();
380 
381  for (RouteList::iterator i = copy->begin(); i != copy->end(); ) {
382  if ((*i)->is_master() || (*i)->is_monitor()) {
383  i = copy->erase (i);
384  } else {
385  ++i;
386  }
387  }
388 
389  if (_mute_release) {
390  _mute_release->routes = copy;
391  }
392 
393  DisplaySuspender ds;
394  _session->set_mute (copy, !_route->muted());
395 
396  } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
397 
398  /* Primary-button1 applies change to the mix group even if it is not active
399  NOTE: Primary-button2 is MIDI learn.
400  */
401 
403 
404  if (ev->button == 1) {
405 
406  if (_route->route_group()) {
407 
408  rl = _route->route_group()->route_list();
409 
410  if (_mute_release) {
411  _mute_release->routes = rl;
412  }
413  } else {
414  rl.reset (new RouteList);
415  rl->push_back (_route);
416  }
417 
418  DisplaySuspender ds;
419  _session->set_mute (rl, !_route->muted(), Session::rt_cleanup, true);
420  }
421 
422  } else {
423 
424  /* plain click applies change to this route */
425 
427  rl->push_back (_route);
428 
429  if (_mute_release) {
430  _mute_release->routes = rl;
431  }
432 
433  _session->set_mute (rl, !_route->muted());
434 
435  }
436  }
437  }
438 
439  return false;
440 }
441 
442 bool
443 RouteUI::mute_release (GdkEventButton* /*ev*/)
444 {
445  if (_mute_release){
446  DisplaySuspender ds;
447  _session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, true);
448  delete _mute_release;
449  _mute_release = 0;
450  }
451 
452  return false;
453 }
454 
455 void
457 {
458  if (output_selector == 0) {
459 
461  boost::shared_ptr<IO> output;
462 
463  if ((send = boost::dynamic_pointer_cast<Send>(_current_delivery)) != 0) {
464  if (!boost::dynamic_pointer_cast<InternalSend>(send)) {
465  output = send->output();
466  } else {
467  output = _route->output ();
468  }
469  } else {
470  output = _route->output ();
471  }
472 
473  output_selector = new IOSelectorWindow (_session, output);
474  }
475 
476  if (output_selector->is_visible()) {
477  output_selector->get_toplevel()->get_window()->raise();
478  } else {
479  output_selector->present ();
480  }
481 
482  //output_selector->set_keep_above (true);
483 }
484 
485 void
487 {
488  if (input_selector == 0) {
490  }
491 
492  if (input_selector->is_visible()) {
493  input_selector->get_toplevel()->get_window()->raise();
494  } else {
495  input_selector->present ();
496  }
497 
498  //input_selector->set_keep_above (true);
499 }
500 
501 bool
502 RouteUI::solo_press(GdkEventButton* ev)
503 {
504  /* ignore double/triple clicks */
505 
506  if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
507  return true;
508  }
509 
510  //if this is a binding action, let the ArdourButton handle it
512  return false;
513 
514  multiple_solo_change = false;
515 
516  if (Keyboard::is_context_menu_event (ev)) {
517 
518  if (! (solo_isolated_led && solo_isolated_led->is_visible()) ||
519  ! (solo_safe_led && solo_safe_led->is_visible())) {
520 
521  if (solo_menu == 0) {
522  build_solo_menu ();
523  }
524 
525  solo_menu->popup (1, ev->time);
526  }
527 
528  } else {
529 
530  if (Keyboard::is_button2_event (ev)) {
531 
532  // button2-click is "momentary"
534  }
535 
536  if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
537 
538  if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
539 
540  /* Primary-Tertiary-click applies change to all routes */
541 
542  if (_solo_release) {
544  }
545 
546  DisplaySuspender ds;
547  if (Config->get_solo_control_is_listen_control()) {
548  _session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, true);
549  } else {
550  _session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, true);
551  }
552 
553  } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
554 
555  // Primary-Secondary-click: exclusively solo this track
556 
557  if (_solo_release) {
558  _solo_release->exclusive = true;
559 
561 
562  for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
563  if ((*i)->soloed ()) {
564  _solo_release->routes_on->push_back (*i);
565  } else {
566  _solo_release->routes_off->push_back (*i);
567  }
568  }
569  }
570 
571  if (Config->get_solo_control_is_listen_control()) {
572  /* ??? we need a just_one_listen() method */
573  } else {
574  DisplaySuspender ds;
576  }
577 
578  } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
579 
580  // shift-click: toggle solo isolated status
581 
583  delete _solo_release;
584  _solo_release = 0;
585 
586  } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
587 
588  /* Primary-button1: solo mix group.
589  NOTE: Primary-button2 is MIDI learn.
590  */
591 
592  /* Primary-button1 applies change to the mix group even if it is not active
593  NOTE: Primary-button2 is MIDI learn.
594  */
595 
597 
598  if (ev->button == 1) {
599 
600  if (_route->route_group()) {
601 
602  rl = _route->route_group()->route_list();
603 
604  if (_solo_release) {
605  _solo_release->routes = rl;
606  }
607  } else {
608  rl.reset (new RouteList);
609  rl->push_back (_route);
610  }
611 
612  DisplaySuspender ds;
613  if (Config->get_solo_control_is_listen_control()) {
614  _session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, true);
615  } else {
616  _session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, true);
617  }
618  }
619 
620  } else {
621 
622  /* click: solo this route */
623 
625  rl->push_back (route());
626 
627  if (_solo_release) {
628  _solo_release->routes = rl;
629  }
630 
631  DisplaySuspender ds;
632  if (Config->get_solo_control_is_listen_control()) {
634  } else {
635  _session->set_solo (rl, !_route->self_soloed());
636  }
637  }
638  }
639  }
640 
641  return false;
642 }
643 
644 bool
645 RouteUI::solo_release (GdkEventButton* /*ev*/)
646 {
647  if (_solo_release) {
648 
649  if (_solo_release->exclusive) {
650 
651  } else {
652  DisplaySuspender ds;
653  if (Config->get_solo_control_is_listen_control()) {
654  _session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, true);
655  } else {
656  _session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, true);
657  }
658  }
659 
660  delete _solo_release;
661  _solo_release = 0;
662  }
663 
664  return false;
665 }
666 
667 bool
668 RouteUI::rec_enable_press(GdkEventButton* ev)
669 {
670  if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
671  return true;
672  }
673 
674  //if this is a binding action, let the ArdourButton handle it
676  return false;
677 
678  if (!_session->engine().connected()) {
679  MessageDialog msg (_("Not connected to AudioEngine - cannot engage record"));
680  msg.run ();
681  return false;
682  }
683 
684  if (is_midi_track()) {
685 
686  /* rec-enable button exits from step editing */
687 
688  if (midi_track()->step_editing()) {
689  midi_track()->set_step_editing (false);
690  return false;
691  }
692  }
693 
694  if (is_track() && rec_enable_button) {
695 
696  if (Keyboard::is_button2_event (ev)) {
697 
698  //rec arm does not have a momentary mode
699  return false;
700 
701  } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
702 
703  DisplaySuspender ds;
705 
706  } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
707 
708  /* Primary-button1 applies change to the route group (even if it is not active)
709  NOTE: Primary-button2 is MIDI learn.
710  */
711 
712  if (ev->button == 1) {
713 
715 
716  if (_route->route_group()) {
717 
718  rl = _route->route_group()->route_list();
719 
720  } else {
721  rl.reset (new RouteList);
722  rl->push_back (_route);
723  }
724 
725  DisplaySuspender ds;
726  _session->set_record_enabled (rl, !_route->record_enabled(), Session::rt_cleanup, true);
727  }
728 
729  } else if (Keyboard::is_context_menu_event (ev)) {
730 
731  /* do this on release */
732 
733  } else {
734 
736  rl->push_back (route());
737  DisplaySuspender ds;
739  }
740  }
741 
742  return false;
743 }
744 
745 void
747 {
749 }
750 
751 void
753 {
754  if (!_route) {
755  return;
756  }
757 
759 
760  if (!t) {
761  return;
762  }
763 
764  MonitorState ms = t->monitoring_state();
765 
766  if (t->monitoring_choice() & MonitorInput) {
768  } else {
769  if (ms & MonitoringInput) {
771  } else {
773  }
774  }
775 
776  if (t->monitoring_choice() & MonitorDisk) {
778  } else {
779  if (ms & MonitoringDisk) {
781  } else {
783  }
784  }
785 }
786 
787 bool
789 {
790  return false;
791 }
792 
793 bool
795 {
796  return monitor_release (ev, MonitorInput);
797 }
798 
799 bool
801 {
802  return false;
803 }
804 
805 bool
806 RouteUI::monitor_disk_release (GdkEventButton* ev)
807 {
808  return monitor_release (ev, MonitorDisk);
809 }
810 
811 bool
812 RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
813 {
814  if (ev->button != 1) {
815  return false;
816  }
817 
819 
820  if (!t) {
821  return true;
822  }
823 
824  MonitorChoice mc;
826 
827  /* XXX for now, monitoring choices are orthogonal. cue monitoring
828  will follow in 3.X but requires mixing the input and playback (disk)
829  signal together, which requires yet more buffers.
830  */
831 
832  if (t->monitoring_choice() & monitor_choice) {
833  mc = MonitorChoice (t->monitoring_choice() & ~monitor_choice);
834  } else {
835  /* this line will change when the options are non-orthogonal */
836  // mc = MonitorChoice (t->monitoring_choice() | monitor_choice);
837  mc = monitor_choice;
838  }
839 
840  if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
841  rl = _session->get_routes ();
842 
843  } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
845  rl = _route->route_group()->route_list();
846  } else {
847  rl.reset (new RouteList);
848  rl->push_back (route());
849  }
850  } else {
851  rl.reset (new RouteList);
852  rl->push_back (route());
853  }
854 
855  DisplaySuspender ds;
856  _session->set_monitoring (rl, mc, Session::rt_cleanup, true);
857 
858  return false;
859 }
860 
861 void
863 {
864  if (record_menu) {
865  return;
866  }
867 
868  /* no rec-button context menu for non-MIDI tracks
869  */
870 
871  if (is_midi_track()) {
872  record_menu = new Menu;
873  record_menu->set_name ("ArdourContextMenu");
874 
875  using namespace Menu_Helpers;
876  MenuList& items = record_menu->items();
877 
878  items.push_back (CheckMenuElem (_("Step Entry"), sigc::mem_fun (*this, &RouteUI::toggle_step_edit)));
879  step_edit_item = dynamic_cast<Gtk::CheckMenuItem*> (&items.back());
880 
881  if (_route->record_enabled()) {
882  step_edit_item->set_sensitive (false);
883  }
884 
885  step_edit_item->set_active (midi_track()->step_editing());
886  }
887 }
888 
889 void
891 {
892  if (!is_midi_track() || _route->record_enabled()) {
893  return;
894  }
895 
896  midi_track()->set_step_editing (step_edit_item->get_active());
897 }
898 
899 void
901 {
902  if (yn) {
903  if (rec_enable_button) {
905  }
906 
908 
909  if (step_edit_item) {
910  step_edit_item->set_active (true);
911  }
912 
913  } else {
914 
915  if (rec_enable_button) {
917  }
918 
920 
921  if (step_edit_item) {
922  step_edit_item->set_active (false);
923  }
924  }
925 }
926 
927 bool
928 RouteUI::rec_enable_release (GdkEventButton* ev)
929 {
930  if (Keyboard::is_context_menu_event (ev)) {
932  if (record_menu) {
933  record_menu->popup (1, ev->time);
934  }
935  return false;
936  }
937 
938  return false;
939 }
940 
941 void
943 {
944  using namespace Menu_Helpers;
945 
946  sends_menu = new Menu;
947  sends_menu->set_name ("ArdourContextMenu");
948  MenuList& items = sends_menu->items();
949 
950  items.push_back (
951  MenuElem(_("Assign all tracks (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PreFader, false))
952  );
953 
954  items.push_back (
955  MenuElem(_("Assign all tracks and buses (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PreFader, true))
956  );
957 
958  items.push_back (
959  MenuElem(_("Assign all tracks (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PostFader, false))
960  );
961 
962  items.push_back (
963  MenuElem(_("Assign all tracks and buses (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PostFader, true))
964  );
965 
966  items.push_back (
967  MenuElem(_("Assign selected tracks (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PreFader, false))
968  );
969 
970  items.push_back (
971  MenuElem(_("Assign selected tracks and buses (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PreFader, true)));
972 
973  items.push_back (
974  MenuElem(_("Assign selected tracks (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PostFader, false))
975  );
976 
977  items.push_back (
978  MenuElem(_("Assign selected tracks and buses (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PostFader, true))
979  );
980 
981  items.push_back (MenuElem(_("Copy track/bus gains to sends"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_from_track)));
982  items.push_back (MenuElem(_("Set sends gain to -inf"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_to_zero)));
983  items.push_back (MenuElem(_("Set sends gain to 0dB"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_to_unity)));
984 
985 }
986 
987 void
988 RouteUI::create_sends (Placement p, bool include_buses)
989 {
990  _session->globally_add_internal_sends (_route, p, include_buses);
991 }
992 
993 void
995 {
997  TrackSelection& selected_tracks (ARDOUR_UI::instance()->the_editor().get_selection().tracks);
998 
999  for (TrackSelection::iterator i = selected_tracks.begin(); i != selected_tracks.end(); ++i) {
1000  RouteTimeAxisView* rtv;
1001  RouteUI* rui;
1002  if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
1003  if ((rui = dynamic_cast<RouteUI*>(rtv)) != 0) {
1004  if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(rui->route())) {
1005  rlist->push_back (rui->route());
1006  }
1007  }
1008  }
1009  }
1010 
1011  _session->add_internal_sends (_route, p, rlist);
1012 }
1013 
1014 void
1016 {
1018 }
1019 
1020 void
1022 {
1024 }
1025 
1026 void
1028 {
1030 }
1031 
1032 bool
1033 RouteUI::show_sends_press(GdkEventButton* ev)
1034 {
1035  if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
1036  return true;
1037  }
1038 
1039  if (!is_track() && show_sends_button) {
1040 
1041  if (Keyboard::is_button2_event (ev) && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
1042 
1043  // do nothing on midi sigc::bind event
1044  return false;
1045 
1046  } else if (Keyboard::is_context_menu_event (ev)) {
1047 
1048  if (sends_menu == 0) {
1049  build_sends_menu ();
1050  }
1051 
1052  sends_menu->popup (0, ev->time);
1053 
1054  } else {
1055 
1057 
1058  if (s == _route) {
1060  } else {
1062  }
1063  }
1064  }
1065 
1066  return true;
1067 }
1068 
1069 bool
1071 {
1072  return true;
1073 }
1074 
1075 void
1077 {
1078  if (!show_sends_button) {
1079  return;
1080  }
1081 
1082  if (onoff) {
1084  } else {
1086  }
1087 }
1088 
1089 Gtkmm2ext::ActiveState
1091 {
1092  if (r->is_master() || r->is_monitor()) {
1093  return Gtkmm2ext::Off;
1094  }
1095 
1096  if (Config->get_solo_control_is_listen_control()) {
1097 
1098  if (r->listening_via_monitor()) {
1100  } else {
1101  return Gtkmm2ext::Off;
1102  }
1103 
1104  }
1105 
1106  if (r->soloed()) {
1107  if (!r->self_soloed()) {
1109  } else {
1111  }
1112  } else {
1113  return Gtkmm2ext::Off;
1114  }
1115 }
1116 
1117 Gtkmm2ext::ActiveState
1119 {
1120  if (r->is_master() || r->is_monitor()) {
1121  return Gtkmm2ext::Off;
1122  }
1123 
1124  if (r->solo_isolated()) {
1126  } else {
1127  return Gtkmm2ext::Off;
1128  }
1129 }
1130 
1131 Gtkmm2ext::ActiveState
1133 {
1134  if (r->is_master() || r->is_monitor()) {
1135  return Gtkmm2ext::Off;
1136  }
1137 
1138  if (r->solo_safe()) {
1140  } else {
1141  return Gtkmm2ext::Off;
1142  }
1143 }
1144 
1145 void
1147 {
1148  bool yn = _route->solo_safe ();
1149 
1150  if (solo_safe_check && solo_safe_check->get_active() != yn) {
1151  solo_safe_check->set_active (yn);
1152  }
1153 
1154  yn = _route->solo_isolated ();
1155 
1156  if (solo_isolated_check && solo_isolated_check->get_active() != yn) {
1157  solo_isolated_check->set_active (yn);
1158  }
1159 
1160  set_button_names ();
1161 
1162  if (solo_isolated_led) {
1163  if (_route->solo_isolated()) {
1165  } else {
1167  }
1168  }
1169 
1170  if (solo_safe_led) {
1171  if (_route->solo_safe()) {
1173  } else {
1175  }
1176  }
1177 
1179 
1180  /* some changes to solo status can affect mute display, so catch up
1181  */
1182 
1184 }
1185 
1186 void
1188 {
1190 }
1191 
1192 ActiveState
1194 {
1195  if (r->is_monitor()) {
1196  return ActiveState(0);
1197  }
1198 
1199 
1200  if (Config->get_show_solo_mutes() && !Config->get_solo_control_is_listen_control ()) {
1201 
1202  if (r->muted ()) {
1203  /* full mute */
1205  } else if (!r->is_master() && s->soloing() && !r->soloed() && !r->solo_isolated()) {
1206  /* master is NEVER muted by others */
1208  } else {
1209  /* no mute at all */
1210  return Gtkmm2ext::Off;
1211  }
1212 
1213  } else {
1214 
1215  if (r->muted()) {
1216  /* full mute */
1218  } else {
1219  /* no mute at all */
1220  return Gtkmm2ext::Off;
1221  }
1222  }
1223 
1224  return ActiveState(0);
1225 }
1226 
1227 void
1229 {
1230  if (!_route) {
1231  return;
1232  }
1233 
1235 }
1236 
1237 void
1239 {
1240  blink_rec_display(true); //this lets the button change "immediately" rather than wait for the next blink
1242 }
1243 
1244 void
1246 {
1247  blink_rec_display(true); //this lets the button change "immediately" rather than wait for the next blink
1249 }
1250 
1251 void
1253 {
1254  if (!rec_enable_button || !_route) {
1255  return;
1256  }
1257  if (boost::dynamic_pointer_cast<Send>(_current_delivery)) {
1258  return;
1259  }
1260 
1261  if (_route->record_enabled()) {
1262  switch (_session->record_status ()) {
1263  case Session::Recording:
1265  break;
1266 
1267  case Session::Disabled:
1268  case Session::Enabled:
1269  if ( ARDOUR_UI::config()->get_blink_rec_arm() )
1271  else
1273  break;
1274 
1275  }
1276 
1277  if (step_edit_item) {
1278  step_edit_item->set_sensitive (false);
1279  }
1280 
1281  } else {
1283 
1284  if (step_edit_item) {
1285  step_edit_item->set_sensitive (true);
1286  }
1287  }
1288 
1289 
1291 }
1292 
1293 void
1295 {
1296  using namespace Menu_Helpers;
1297 
1298  solo_menu = new Menu;
1299  solo_menu->set_name ("ArdourContextMenu");
1300  MenuList& items = solo_menu->items();
1301  Gtk::CheckMenuItem* check;
1302 
1303  check = new Gtk::CheckMenuItem(_("Solo Isolate"));
1304  check->set_active (_route->solo_isolated());
1305  check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_isolated), check));
1306  items.push_back (CheckMenuElem(*check));
1307  solo_isolated_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
1308  check->show_all();
1309 
1310  check = new Gtk::CheckMenuItem(_("Solo Safe"));
1311  check->set_active (_route->solo_safe());
1312  check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_safe), check));
1313  items.push_back (CheckMenuElem(*check));
1314  solo_safe_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
1315  check->show_all();
1316 
1317  //items.push_back (SeparatorElem());
1318  // items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
1319 
1320 }
1321 
1322 void
1324 {
1325  using namespace Menu_Helpers;
1326 
1327  mute_menu = new Menu;
1328  mute_menu->set_name ("ArdourContextMenu");
1329 
1330  MenuList& items = mute_menu->items();
1331 
1332  pre_fader_mute_check = manage (new Gtk::CheckMenuItem(_("Pre Fader Sends")));
1334  pre_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PreFader, pre_fader_mute_check));
1335  items.push_back (CheckMenuElem(*pre_fader_mute_check));
1336  pre_fader_mute_check->show_all();
1337 
1338  post_fader_mute_check = manage (new Gtk::CheckMenuItem(_("Post Fader Sends")));
1340  post_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PostFader, post_fader_mute_check));
1341  items.push_back (CheckMenuElem(*post_fader_mute_check));
1342  post_fader_mute_check->show_all();
1343 
1344  listen_mute_check = manage (new Gtk::CheckMenuItem(_("Control Outs")));
1345  init_mute_menu(MuteMaster::Listen, listen_mute_check);
1346  listen_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Listen, listen_mute_check));
1347  items.push_back (CheckMenuElem(*listen_mute_check));
1348  listen_mute_check->show_all();
1349 
1350  main_mute_check = manage (new Gtk::CheckMenuItem(_("Main Outs")));
1351  init_mute_menu(MuteMaster::Main, main_mute_check);
1352  main_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Main, main_mute_check));
1353  items.push_back (CheckMenuElem(*main_mute_check));
1354  main_mute_check->show_all();
1355 
1356  //items.push_back (SeparatorElem());
1357  // items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
1358 
1359  _route->mute_points_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::muting_change, this), gui_context());
1360 }
1361 
1362 void
1363 RouteUI::init_mute_menu(MuteMaster::MutePoint mp, Gtk::CheckMenuItem* check)
1364 {
1365  check->set_active (_route->mute_points() & mp);
1366 }
1367 
1368 void
1369 RouteUI::toggle_mute_menu(MuteMaster::MutePoint mp, Gtk::CheckMenuItem* check)
1370 {
1371  if (check->get_active()) {
1373  } else {
1375  }
1376 }
1377 
1378 void
1380 {
1382 
1383  bool yn;
1385 
1386  yn = (current & MuteMaster::PreFader);
1387 
1388  if (pre_fader_mute_check->get_active() != yn) {
1389  pre_fader_mute_check->set_active (yn);
1390  }
1391 
1392  yn = (current & MuteMaster::PostFader);
1393 
1394  if (post_fader_mute_check->get_active() != yn) {
1395  post_fader_mute_check->set_active (yn);
1396  }
1397 
1398  yn = (current & MuteMaster::Listen);
1399 
1400  if (listen_mute_check->get_active() != yn) {
1401  listen_mute_check->set_active (yn);
1402  }
1403 
1404  yn = (current & MuteMaster::Main);
1405 
1406  if (main_mute_check->get_active() != yn) {
1407  main_mute_check->set_active (yn);
1408  }
1409 }
1410 
1411 bool
1413 {
1414  if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS) {
1415  return true;
1416  }
1417 
1418  bool view = solo_isolated_led->active_state();
1419  bool model = _route->solo_isolated();
1420 
1421  /* called BEFORE the view has changed */
1422 
1423  if (ev->button == 1) {
1424  if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
1425 
1426  if (model) {
1427  /* disable isolate for all routes */
1428  DisplaySuspender ds;
1429  _session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, true);
1430  }
1431 
1432  } else {
1433  if (model == view) {
1434 
1435  /* flip just this route */
1436 
1438  rl->push_back (_route);
1439  DisplaySuspender ds;
1440  _session->set_solo_isolated (rl, !view, Session::rt_cleanup, true);
1441  }
1442  }
1443  }
1444 
1445  return false;
1446 }
1447 
1448 bool
1450 {
1451  if (ev->button == 1) {
1453  }
1454  return false;
1455 }
1456 
1457 void
1458 RouteUI::toggle_solo_isolated (Gtk::CheckMenuItem* check)
1459 {
1460  bool view = check->get_active();
1461  bool model = _route->solo_isolated();
1462 
1463  /* called AFTER the view has changed */
1464 
1465  if (model != view) {
1466  _route->set_solo_isolated (view, this);
1467  }
1468 }
1469 
1470 void
1471 RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
1472 {
1473  _route->set_solo_safe (check->get_active(), this);
1474 }
1475 
1478 void
1480 {
1481  bool picked;
1482  Gdk::Color const color = Gtkmm2ext::UI::instance()->get_color (_("Color Selection"), picked, &_color);
1483 
1484  if (picked) {
1485  set_color(color);
1486  }
1487 }
1488 
1492 void
1493 RouteUI::set_color (const Gdk::Color & c)
1494 {
1495  /* leave _color alone in the group case so that tracks can retain their
1496  * own pre-group colors.
1497  */
1498 
1499  char buf[64];
1500  _color = c;
1501  snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
1502 
1503  /* note: we use the route state ID here so that color is the same for both
1504  the time axis view and the mixer strip
1505  */
1506 
1507  gui_object_state().set_property<string> (route_state_id(), X_("color"), buf);
1508  _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
1509 }
1510 
1512 string
1514 {
1515  return string_compose (X_("route %1"), _route->id().to_s());
1516 }
1517 
1518 int
1520 {
1521  const string str = gui_object_state().get_string (route_state_id(), X_("color"));
1522 
1523  if (str.empty()) {
1524  return 1;
1525  }
1526 
1527  int r, g, b;
1528 
1529  sscanf (str.c_str(), "%d:%d:%d", &r, &g, &b);
1530 
1531  _color.set_red (r);
1532  _color.set_green (g);
1533  _color.set_blue (b);
1534 
1535  return 0;
1536 }
1537 
1539 bool
1541 {
1542  if (name.find (':') == string::npos) {
1543  return true;
1544  }
1545 
1546  MessageDialog colon_msg (
1547  _("The use of colons (':') is discouraged in track and bus names.\nDo you want to use this new name?"),
1548  false, MESSAGE_QUESTION, BUTTONS_NONE
1549  );
1550 
1551  colon_msg.add_button (_("Use the new name"), Gtk::RESPONSE_ACCEPT);
1552  colon_msg.add_button (_("Re-edit the name"), Gtk::RESPONSE_CANCEL);
1553 
1554  return (colon_msg.run () == Gtk::RESPONSE_ACCEPT);
1555 }
1556 
1557 void
1559 {
1560  ArdourPrompter name_prompter (true);
1561  string result;
1562  bool done = false;
1563 
1564  if (is_track()) {
1565  name_prompter.set_title (_("Rename Track"));
1566  } else {
1567  name_prompter.set_title (_("Rename Bus"));
1568  }
1569  name_prompter.set_prompt (_("New name:"));
1570  name_prompter.set_initial_text (_route->name());
1571  name_prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
1572  name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1573  name_prompter.show_all ();
1574 
1575  while (!done) {
1576  switch (name_prompter.run ()) {
1577  case Gtk::RESPONSE_ACCEPT:
1578  name_prompter.get_result (result);
1579  name_prompter.hide ();
1580  if (result.length()) {
1581  if (verify_new_route_name (result)) {
1582  _route->set_name (result);
1583  done = true;
1584  } else {
1585  /* back to name prompter */
1586  }
1587 
1588  } else {
1589  /* nothing entered, just get out of here */
1590  done = true;
1591  }
1592  break;
1593  default:
1594  done = true;
1595  break;
1596  }
1597  }
1598 
1599  return;
1600 
1601 }
1602 
1603 void
1605 {
1606  if (what_changed.contains (ARDOUR::Properties::name)) {
1607  name_label.set_text (_route->name());
1608  }
1609 }
1610 
1611 void
1613 {
1614 // if (ignore_toggle) {
1615 // return;
1616 // }
1617 
1618  if (comment_window && comment_window->is_visible ()) {
1619  comment_window->hide ();
1620  } else {
1622  }
1623 }
1624 
1625 
1626 void
1628 {
1629  if (comment_window == 0) {
1631  }
1632 
1633  string title;
1634  title = _route->name();
1635  title += _(": comment editor");
1636 
1637  comment_window->set_title (title);
1638  comment_window->present();
1639 }
1640 
1641 void
1643 {
1644  comment_window = new ArdourWindow (""); // title will be reset to show route
1645  comment_window->set_skip_taskbar_hint (true);
1646  comment_window->signal_hide().connect (sigc::mem_fun(*this, &MixerStrip::comment_editor_done_editing));
1647  comment_window->set_default_size (400, 200);
1648 
1649  comment_area = manage (new TextView());
1650  comment_area->set_name ("MixerTrackCommentArea");
1651  comment_area->set_wrap_mode (WRAP_WORD);
1652  comment_area->set_editable (true);
1653  comment_area->get_buffer()->set_text (_route->comment());
1654  comment_area->show ();
1655 
1656  comment_window->add (*comment_area);
1657 }
1658 
1659 void
1661 {
1663 
1664  if (src != this) {
1665  ignore_comment_edit = true;
1666  if (comment_area) {
1667  comment_area->get_buffer()->set_text (_route->comment());
1668  }
1669  ignore_comment_edit = false;
1670  }
1671 }
1672 
1673 void
1675 {
1677 
1678  string const str = comment_area->get_buffer()->get_text();
1679  if (str == _route->comment ()) {
1680  return;
1681  }
1682 
1683  _route->set_comment (str, this);
1684 }
1685 
1686 void
1687 RouteUI::set_route_active (bool a, bool apply_to_selection)
1688 {
1689  if (apply_to_selection) {
1691  } else {
1692  _route->set_active (a, this);
1693  }
1694 }
1695 
1696 void
1698 {
1699  if (denormal_menu_item) {
1700 
1701  bool x;
1702 
1704 
1705  if ((x = denormal_menu_item->get_active()) != _route->denormal_protection()) {
1707  }
1708  }
1709 }
1710 
1711 void
1713 {
1714  if (denormal_menu_item) {
1716  }
1717 }
1718 
1719 void
1721 {
1722  _route->input()->disconnect (this);
1723 }
1724 
1725 void
1727 {
1728  _route->output()->disconnect (this);
1729 }
1730 
1731 bool
1733 {
1735 }
1736 
1739 {
1741 }
1742 
1743 bool
1745 {
1747 }
1748 
1751 {
1753 }
1754 
1755 bool
1757 {
1759 }
1760 
1763 {
1765 }
1766 
1767 bool
1769 {
1770  return (_route->n_outputs().n_audio() > 0);
1771 }
1772 
1773 string
1775 {
1776  return _route->name();
1777 }
1778 
1779 void
1781 {
1783 
1784  AudioTrack* at = dynamic_cast<AudioTrack*>(_route.get());
1785 
1786  if (at) {
1787  switch (at->freeze_state()) {
1788  case AudioTrack::Frozen:
1789  rec_enable_button->set_sensitive (false);
1790  break;
1791  default:
1792  rec_enable_button->set_sensitive (true);
1793  break;
1794  }
1795  }
1796 }
1797 
1798 void
1800 {
1801  LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), AudioEngine::instance()->samples_per_cycle());
1802 }
1803 
1804 void
1806 {
1807  std::string path;
1808  std::string safe_name;
1809  string name;
1810 
1812 
1813  if (g_mkdir_with_parents (path.c_str(), 0755)) {
1814  error << string_compose (_("Cannot create route template directory %1"), path) << endmsg;
1815  return;
1816  }
1817 
1818  Prompter p (true); // modal
1819 
1820  p.set_title (_("Save As Template"));
1821  p.set_prompt (_("Template name:"));
1822  p.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1823  switch (p.run()) {
1824  case RESPONSE_ACCEPT:
1825  break;
1826  default:
1827  return;
1828  }
1829 
1830  p.hide ();
1831  p.get_result (name, true);
1832 
1833  safe_name = legalize_for_path (name);
1834  safe_name += template_suffix;
1835 
1836  path = Glib::build_filename (path, safe_name);
1837 
1838  _route->save_as_template (path, name);
1839 }
1840 
1841 void
1843 {
1844  if (_session->transport_rolling() && rec_enable_button->active_state() && Config->get_disable_disarm_during_roll()) {
1845  rec_enable_button->set_sensitive (false);
1846  } else {
1847  rec_enable_button->set_sensitive (true);
1848  }
1849 
1851 }
1852 
1853 void
1854 RouteUI::parameter_changed (string const & p)
1855 {
1856  /* this handles RC and per-session parameter changes */
1857 
1858  if (p == "disable-disarm-during-roll") {
1860  } else if (p == "use-monitor-bus" || p == "solo-control-is-listen-control" || p == "listen-position") {
1861  set_button_names ();
1862  } else if (p == "auto-input") {
1864  } else if (p == "blink-rec-arm") {
1865  if (ARDOUR_UI::config()->get_blink_rec_arm()) {
1866  rec_blink_connection.disconnect ();
1868  } else {
1869  rec_blink_connection.disconnect ();
1871  }
1872  }
1873 }
1874 
1875 void
1877 {
1879 }
1880 
1881 void
1883 {
1885 }
1886 
1887 void
1889 {
1891 }
1892 
1893 void
1895 {
1897 }
1898 
1899 void
1901 {
1902  ArdourDialog dialog (_("Remote Control ID"));
1903  SpinButton* spin = 0;
1904 
1905  dialog.get_vbox()->set_border_width (18);
1906 
1907  if (Config->get_remote_model() == UserOrdered) {
1908  uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
1909 
1910  HBox* hbox = manage (new HBox);
1911  hbox->set_spacing (6);
1912  hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
1913  spin = manage (new SpinButton);
1914  spin->set_digits (0);
1915  spin->set_increments (1, 10);
1916  spin->set_range (0, limit);
1917  spin->set_value (_route->remote_control_id());
1918  hbox->pack_start (*spin);
1919  dialog.get_vbox()->pack_start (*hbox);
1920 
1921  dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
1922  dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
1923  } else {
1924  Label* l = manage (new Label());
1925  if (_route->is_master() || _route->is_monitor()) {
1926  l->set_markup (string_compose (_("The remote control ID of %1 is: %2\n\n\n"
1927  "The remote control ID of %3 cannot be changed."),
1928  Glib::Markup::escape_text (_route->name()),
1930  (_route->is_master() ? _("the master bus") : _("the monitor bus"))));
1931  } else {
1932  l->set_markup (string_compose (_("The remote control ID of %5 is: %2\n\n\n"
1933  "Remote Control IDs are currently determined by track/bus ordering in %6.\n\n"
1934  "%3Use the User Interaction tab of the Preferences window if you want to change this%4"),
1935  (is_track() ? _("track") : _("bus")),
1937  "<span size=\"small\" style=\"italic\">",
1938  "</span>",
1939  Glib::Markup::escape_text (_route->name()),
1940  PROGRAM_NAME));
1941  }
1942  dialog.get_vbox()->pack_start (*l);
1943  dialog.add_button (Stock::OK, RESPONSE_CANCEL);
1944  }
1945 
1946  dialog.show_all ();
1947  int const r = dialog.run ();
1948 
1949  if (r == RESPONSE_ACCEPT && spin) {
1950  _route->set_remote_control_id (spin->get_value_as_int ());
1951  }
1952 }
1953 
1954 void
1956 {
1957  /* remove old invert buttons */
1958  for (vector<ArdourButton*>::iterator i = _invert_buttons.begin(); i != _invert_buttons.end(); ++i) {
1959  _invert_button_box.remove (**i);
1960  }
1961 
1962  _invert_buttons.clear ();
1963 
1964  if (!_route || !_route->input()) {
1965  return;
1966  }
1967 
1968  uint32_t const N = _route->input()->n_ports().n_audio ();
1969 
1970  uint32_t const to_add = (N <= _max_invert_buttons) ? N : 1;
1971 
1972  for (uint32_t i = 0; i < to_add; ++i) {
1973  ArdourButton* b = manage (new ArdourButton);
1974  b->signal_button_press_event().connect (sigc::mem_fun (*this, &RouteUI::invert_press), false);
1975  b->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_release), i), false);
1976 
1977  b->set_name (X_("invert button"));
1978  if (to_add == 1) {
1979  if (N > 1) {
1980  b->set_text (string_compose (X_("Ø (%1)"), N));
1981  } else {
1982  b->set_text (X_("Ø"));
1983  }
1984  } else {
1985  b->set_text (string_compose (X_("Ø%1"), i + 1));
1986  }
1987 
1988  if (N <= _max_invert_buttons) {
1989  UI::instance()->set_tip (*b, string_compose (_("Left-click to invert (phase reverse) channel %1 of this track. Right-click to show menu."), i + 1));
1990  } else {
1991  UI::instance()->set_tip (*b, _("Click to show a menu of channels for inversion (phase reverse)"));
1992  }
1993 
1994  _invert_buttons.push_back (b);
1995  _invert_button_box.pack_start (*b);
1996  }
1997 
1998  _invert_button_box.set_spacing (1);
1999  _invert_button_box.show_all ();
2000 }
2001 
2002 void
2004 {
2005  uint32_t const N = _route->input()->n_ports().n_audio();
2006  if (N > _max_invert_buttons) {
2007 
2008  /* One button for many channels; explicit active if all channels are inverted,
2009  implicit active if some are, off if none are.
2010  */
2011 
2012  ArdourButton* b = _invert_buttons.front ();
2013 
2014  if (_route->phase_invert().count() == _route->phase_invert().size()) {
2016  } else if (_route->phase_invert().any()) {
2018  } else {
2020  }
2021 
2022  } else {
2023 
2024  /* One button per channel; just set active */
2025 
2026  int j = 0;
2027  for (vector<ArdourButton*>::iterator i = _invert_buttons.begin(); i != _invert_buttons.end(); ++i, ++j) {
2028  (*i)->set_active (_route->phase_invert (j));
2029  }
2030 
2031  }
2032 }
2033 
2034 bool
2035 RouteUI::invert_release (GdkEventButton* ev, uint32_t i)
2036 {
2037  if (ev->button == 1 && i < _invert_buttons.size()) {
2038  uint32_t const N = _route->input()->n_ports().n_audio ();
2039  if (N <= _max_invert_buttons) {
2040  /* left-click inverts phase so long as we have a button per channel */
2041  _route->set_phase_invert (i, !_invert_buttons[i]->get_active());
2042  return false;
2043  }
2044  }
2045  return false;
2046 }
2047 
2048 
2049 bool
2050 RouteUI::invert_press (GdkEventButton* ev)
2051 {
2052  using namespace Menu_Helpers;
2053 
2054  uint32_t const N = _route->input()->n_ports().n_audio();
2055  if (N <= _max_invert_buttons && ev->button != 3) {
2056  /* If we have an invert button per channel, we only pop
2057  up a menu on right-click; left click is handled
2058  on release.
2059  */
2060  return false;
2061  }
2062 
2063  delete _invert_menu;
2064  _invert_menu = new Menu;
2065  _invert_menu->set_name ("ArdourContextMenu");
2066  MenuList& items = _invert_menu->items ();
2067 
2068  for (uint32_t i = 0; i < N; ++i) {
2069  items.push_back (CheckMenuElem (string_compose (X_("Ø%1"), i + 1), sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_menu_toggled), i)));
2070  Gtk::CheckMenuItem* e = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
2072  e->set_active (_route->phase_invert (i));
2074  }
2075 
2076  _invert_menu->popup (0, ev->time);
2077 
2078  return true;
2079 }
2080 
2081 void
2083 {
2084  if (_i_am_the_modifier) {
2085  return;
2086  }
2087 
2089 }
2090 
2091 void
2093 {
2094  for (vector<ArdourButton*>::iterator b = _invert_buttons.begin(); b != _invert_buttons.end(); ++b) {
2095  (*b)->set_sensitive (yn);
2096  }
2097 }
2098 
2099 void
2101 {
2102  if (_route) {
2103  _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
2104  }
2105 }
2106 
2108 void
2109 RouteUI::route_gui_changed (string what_changed)
2110 {
2111  if (what_changed == "color") {
2112  if (set_color_from_route () == 0) {
2114  }
2115  }
2116 }
2117 
2118 void
2120 {
2121  assert(is_track());
2122  switch (track()->mode()) {
2123  case ARDOUR::NonLayered:
2124  case ARDOUR::Normal:
2126  break;
2127  case ARDOUR::Destructive:
2129  break;
2130  }
2131  rec_enable_button->queue_draw();
2132 }
2133 
2137 Gdk::Color
2139 {
2140  RouteGroup* g = _route->route_group ();
2141 
2142  if (g && g->is_color()) {
2143  Gdk::Color c;
2145  return c;
2146  }
2147 
2148  return _color;
2149 }
2150 
2151 void
2153 {
2154  _showing_sends_to = send_to;
2155  BusSendDisplayChanged (send_to); /* EMIT SIGNAL */
2156 }
2157 
2158 void
2160 {
2161  if (_route == send_to) {
2162  show_sends_button->set_active (true);
2164  } else {
2165  show_sends_button->set_active (false);
2166  send_blink_connection.disconnect ();
2167  }
2168 }
2169 
2170 RouteGroup*
2172 {
2173  return _route->route_group();
2174 }
void set_route_active(bool, bool)
Definition: route_ui.cc:1687
bool transport_rolling() const
Definition: session.h:592
Gdk::Color color() const
Definition: route_ui.cc:2138
void open_comment_editor()
Definition: route_ui.cc:1627
bool rec_enable_press(GdkEventButton *)
Definition: route_ui.cc:668
void track_mode_changed()
Definition: route_ui.cc:2119
Gtk::CheckMenuItem * pre_fader_mute_check
Definition: route_ui.h:176
virtual void denormal_protection_changed()
Definition: route_ui.cc:1712
virtual void start_step_editing()
Definition: route_ui.h:260
static uint32_t _max_invert_buttons
Definition: route_ui.h:308
int _i_am_the_modifier
Definition: route_ui.h:301
void build_record_menu()
Definition: route_ui.cc:862
void set_listen(boost::shared_ptr< RouteList >, bool, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
bool soloing() const
Definition: session.h:691
void update_mute_display()
Definition: route_ui.cc:1228
boost::shared_ptr< ARDOUR::MidiTrack > midi_track() const
Definition: route_ui.cc:1762
virtual void route_color_changed()
Definition: route_ui.h:267
void open_remote_control_id_dialog()
Definition: route_ui.cc:1900
PBD::Signal0< void > TransportStateChange
Definition: session.h:308
std::string get_string(const std::string &id, const std::string &prop_name, bool *empty=0)
Definition: gui_object.cc:92
PBD::Signal0< void > DropReferences
Definition: destructible.h:34
ArdourButton * show_sends_button
Definition: route_ui.h:103
PBD::Signal0< void > TrackModeChanged
Definition: track.h:52
void add_internal_sends(boost::shared_ptr< Route > dest, Placement p, boost::shared_ptr< RouteList > senders)
Definition: session.cc:2840
void set_solo(boost::shared_ptr< RouteList >, bool, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
void toggle_mute_menu(ARDOUR::MuteMaster::MutePoint, Gtk::CheckMenuItem *)
Definition: route_ui.cc:1369
PBD::Signal1< void, const PropertyChange & > PropertyChanged
Definition: stateful.h:87
void build_sends_menu()
Definition: route_ui.cc:942
void set_mute_points(MuteMaster::MutePoint)
Definition: route.cc:999
bool is_midi_track() const
Definition: route_ui.cc:1756
sigc::connection rec_blink_connection
Definition: route_ui.h:118
void set_sends_gain_from_track()
Definition: route_ui.cc:1015
bool writable() const
Definition: session.h:173
Gtk::HBox _invert_button_box
Definition: route_ui.h:99
void globally_set_send_gains_to_unity(boost::shared_ptr< Route > dest)
Definition: session.cc:2797
boost::shared_ptr< ARDOUR::RouteList > routes
Definition: route_ui.h:284
void choose_color()
Definition: route_ui.cc:1479
bool is_audio_track() const
Definition: route_ui.cc:1744
void monitoring_changed()
Definition: route_ui.cc:746
void build_mute_menu(void)
Definition: route_ui.cc:1323
LIBARDOUR_API std::string legalize_for_path(const std::string &str)
bool has_audio_outputs() const
Definition: route_ui.cc:1768
void set_distinct_led_click(bool yn)
void edit_input_configuration()
Definition: route_ui.cc:486
Definition: ardour_ui.h:130
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
Gtkmm2ext::ActiveState active_state() const
Definition: cairo_widget.h:40
static ARDOUR_UI * instance()
Definition: ardour_ui.h:187
void route_rename()
Definition: route_ui.cc:1558
void set_gain(gain_t val, void *src)
Definition: route.cc:371
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
void update_monitoring_display()
Definition: route_ui.cc:752
Gtk::Menu * _invert_menu
Definition: route_ui.h:303
PBD::Signal0< void > SoloChanged
Definition: session.h:708
bool solo_safe() const
Definition: route.cc:804
void setup_comment_editor()
Definition: route_ui.cc:1642
Gtk::CheckMenuItem * solo_safe_check
Definition: route_ui.h:180
PBD::Signal1< void, void * > comment_changed
Definition: route.h:292
void globally_set_send_gains_from_track(boost::shared_ptr< Route > dest)
Definition: session.cc:2810
Gtk::Menu * mute_menu
Definition: route_ui.h:120
static Gdk::Color unique_random_color()
Definition: axis_view.cc:61
boost::shared_ptr< AutomationControl > gain_control() const
Definition: route.cc:4042
uint32_t nbusses() const
Definition: session.cc:4885
boost::shared_ptr< ARDOUR::RouteList > routes_on
Definition: route_ui.h:285
PBD::Signal0< void > io_changed
Definition: route.h:320
static int N
Definition: signals_test.cc:27
void set_record_enabled(boost::shared_ptr< RouteList >, bool, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
void build_solo_menu()
Definition: route_ui.cc:1294
uint32_t n_audio() const
Definition: chan_count.h:63
virtual void set_route(boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:226
bool monitor_disk_press(GdkEventButton *)
Definition: route_ui.cc:800
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
void set_solo_isolated(bool yn, void *src)
Definition: route.cc:939
IOSelectorWindow * input_selector
Definition: route_ui.h:250
bool set_name(const std::string &str)
Definition: route.cc:3870
void set_solo_safe(bool yn, void *src)
Definition: route.cc:795
void page_gain_down()
Definition: route_ui.cc:1894
PublicEditor & the_editor()
Definition: ardour_ui.h:191
int save_as_template(const std::string &path, const std::string &name)
Definition: route.cc:3857
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
MonitorChoice
Definition: types.h:386
SessionConfiguration config
Definition: session.h:866
RecordState record_status() const
Definition: session.h:276
void set_sends_gain_to_unity()
Definition: route_ui.cc:1027
bool self_destruct
Definition: route_ui.h:254
Gtk::CheckMenuItem * step_edit_item
Definition: route_ui.h:201
PBD::Signal1< void, void * > solo_isolated_changed
Definition: route.h:291
boost::shared_ptr< AutomationControl > rec_enable_control()
Definition: track.h:107
framecnt_t frame_rate() const
Definition: session.h:365
void set_invert_sensitive(bool)
Definition: route_ui.cc:2092
void muting_change()
Definition: route_ui.cc:1379
void unset_active_state()
Definition: cairo_widget.h:50
#define ENSURE_GUI_THREAD(obj, method,...)
Definition: gui_thread.h:34
void adjust_latency()
Definition: route_ui.cc:1799
#define invalidator(x)
Definition: gui_thread.h:40
void set_elements(Element)
Gtk::CheckMenuItem * post_fader_mute_check
Definition: route_ui.h:177
static void set_showing_sends_to(boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:2152
void set_initial_text(std::string txt)
Definition: prompter.h:50
void disconnect_output()
Definition: route_ui.cc:1726
static float accurate_coefficient_to_dB(float coeff)
Definition: dB.h:38
ArdourWindow * comment_window
Definition: route_ui.h:248
static UI * instance()
Definition: gtk_ui.h:119
virtual ~RouteUI()
Definition: route_ui.cc:88
virtual void set_color(const Gdk::Color &c)
Definition: route_ui.cc:1493
void set_remote_control_id(uint32_t id, bool notify_class_listeners=true)
Definition: route.cc:239
virtual void step_edit_changed(bool)
Definition: route_ui.cc:900
void session_rec_enable_changed()
Definition: route_ui.cc:1245
virtual void route_active_changed()
Definition: route_ui.h:195
void save_as_template()
Definition: route_ui.cc:1805
Gtk::CheckMenuItem * listen_mute_check
Definition: route_ui.h:178
void step_gain_up()
Definition: route_ui.cc:1876
PBD::Signal1< void, bool > StepEditStatusChange
Definition: midi_track.h:107
Gtk::Menu * solo_menu
Definition: route_ui.h:121
void set_denormal_protection(bool yn)
Definition: route.cc:3987
#define _(Text)
Definition: i18n.h:11
Gtk::Menu * sends_menu
Definition: route_ui.h:122
bool monitor_input_release(GdkEventButton *)
Definition: route_ui.cc:794
bool soloed() const
Definition: route.h:158
ArdourButton * rec_enable_button
Definition: route_ui.h:102
void route_rec_enable_changed()
Definition: route_ui.cc:1238
MuteMaster::MutePoint mute_points() const
Definition: route.cc:4130
boost::shared_ptr< ARDOUR::Route > _route
Definition: route_ui.h:87
void set_invert_button_state()
Definition: route_ui.cc:2003
bool phase_invert(uint32_t) const
Definition: route.cc:3975
PBD::Signal1< void, void * > solo_safe_changed
Definition: route.h:290
std::string comment()
Definition: route.h:100
virtual bool record_enabled() const
Definition: route.h:131
bool show_sends_release(GdkEventButton *)
Definition: route_ui.cc:1070
LIBARDOUR_API std::string user_route_template_directory()
IOSelectorWindow * output_selector
Definition: route_ui.h:251
bool denormal_protection() const
Definition: route.cc:3996
ArdourButton * solo_button
Definition: route_ui.h:101
#define X_(Text)
Definition: i18n.h:13
static Gtkmm2ext::ActiveState solo_isolate_active_state(boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:1118
PBD::Signal2< void, std::string, void * > gui_changed
Definition: route.h:324
ExplicitActive
Definition: widget_state.h:13
LIBARDOUR_API RCConfiguration * Config
Definition: globals.cc:119
uint32_t ntracks() const
Definition: session.cc:4870
SoloMuteRelease * _solo_release
Definition: route_ui.h:292
void comment_changed(void *src)
Definition: route_ui.cc:1660
void set_icon(Icon)
void set_color_from_rgba(Gdk::Color &, uint32_t)
Definition: utils.cc:276
bool listening_via_monitor() const
Definition: route.cc:785
void set_prompt(std::string prompt)
Definition: prompter.h:46
virtual void blink_rec_display(bool onoff)
Definition: route_ui.cc:1252
void reset()
Definition: route_ui.cc:206
bool monitor_disk_release(GdkEventButton *)
Definition: route_ui.cc:806
ArdourButton * monitor_input_button
Definition: route_ui.h:104
ImplicitActive
Definition: widget_state.h:13
Gdk::Color get_color(const std::string &prompt, bool &picked, const Gdk::Color *initial=0)
Definition: gtk_ui.cc:704
bool solo_press(GdkEventButton *)
Definition: route_ui.cc:502
Definition: amp.h:29
void toggle_comment_editor()
Definition: route_ui.cc:1612
void request_redraw()
Definition: route_ui.cc:2100
Gtk::Label name_label
Definition: axis_view.h:102
MonitorState
Definition: types.h:393
void set_phase_invert(uint32_t, bool yn)
Definition: route.cc:3955
const PBD::ID & id() const
Definition: stateful.h:68
static bool is_bind_action(GdkEventButton *)
void set_controllable(boost::shared_ptr< PBD::Controllable > c)
void set_just_one_solo(boost::shared_ptr< Route >, bool, SessionEvent::RTeventCallback after=rt_cleanup)
void parameter_changed(std::string const &)
Definition: route_ui.cc:1854
void remove_node(const std::string &id)
Definition: gui_object.cc:79
std::string to_s() const
Definition: id.cc:78
boost::shared_ptr< ARDOUR::Track > track() const
Definition: route_ui.cc:1738
ChanCount n_outputs() const
Definition: route.h:93
PBD::Signal0< void > active_changed
Definition: route.h:285
static Gtkmm2ext::ActiveState mute_active_state(ARDOUR::Session *, boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:1193
#define gui_context()
Definition: gui_thread.h:36
boost::shared_ptr< ARDOUR::Delivery > _current_delivery
Definition: route_ui.h:124
PBD::Signal1< void, void * > listen_changed
Definition: route.h:288
virtual void map_frozen()
Definition: route_ui.cc:1780
void setup_invert_buttons()
Definition: route_ui.cc:1955
bool self_soloed() const
Definition: route.h:164
boost::shared_ptr< RouteList > get_routes() const
Definition: session.h:229
static Gtkmm2ext::ActiveState solo_active_state(boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:1090
std::string name() const
Definition: route_ui.cc:1774
virtual Selection & get_selection() const =0
void set_active_state(Gtkmm2ext::ActiveState)
static Gtkmm2ext::ActiveState solo_safe_active_state(boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:1132
ARDOUR::RouteGroup * route_group() const
Definition: route_ui.cc:2171
PBD::ScopedConnectionList _session_connections
void step_gain_down()
Definition: route_ui.cc:1888
static GUIObjectState & gui_object_state()
Definition: axis_view.cc:98
bool multiple_mute_change
Definition: route_ui.h:96
T * get() const
Definition: shared_ptr.hpp:268
PBD::Signal1< void, std::string > ParameterChanged
Definition: configuration.h:44
void check_rec_enable_sensitivity()
Definition: route_ui.cc:1842
PBD::Signal0< void > RecordStateChanged
Definition: session.h:297
sigc::connection blink_connect(const sigc::slot< void, bool > &slot)
Definition: timers.cc:171
void get_result(std::string &str, bool strip=true)
Definition: prompter.cc:104
PBD::Signal0< void > mute_points_changed
Definition: route.h:294
void set_step_editing(bool yn)
Definition: midi_track.cc:757
PBD::Signal2< void, bool, void * > solo_changed
Definition: route.h:289
bool is_track() const
Definition: route_ui.cc:1732
void globally_set_send_gains_to_zero(boost::shared_ptr< Route > dest)
Definition: session.cc:2784
bool solo_isolate_button_release(GdkEventButton *)
Definition: route_ui.cc:1412
void create_selected_sends(ARDOUR::Placement, bool)
Definition: route_ui.cc:994
LIBARDOUR_API const char *const template_suffix
bool muted() const
Definition: route.cc:1031
bool is_monitoring() const
Definition: route_group.h:76
MonitorState monitoring_state() const
Definition: track.cc:894
void toggle_step_edit()
Definition: route_ui.cc:890
static uint32_t group_color(ARDOUR::RouteGroup *)
Definition: group_tabs.cc:616
void toggle_denormal_protection()
Definition: route_ui.cc:1697
void foreach_route_ui(Function f)
bool show_sends_press(GdkEventButton *)
Definition: route_ui.cc:1033
MonitorChoice monitoring_choice() const
Definition: track.h:55
void set_active(bool yn, void *)
Definition: route.cc:4002
void toggle_solo_isolated(Gtk::CheckMenuItem *)
Definition: route_ui.cc:1458
void self_delete()
Definition: route_ui.cc:220
void create_sends(ARDOUR::Placement, bool)
Definition: route_ui.cc:988
PBD::Signal1< void, void * > mute_changed
Definition: route.h:293
virtual void property_changed(const PBD::PropertyChange &)
Definition: route_ui.cc:1604
bool is_master() const
Definition: route.h:111
void set_active(bool)
ArdourButton * mute_button
Definition: route_ui.h:100
Gdk::Color _color
Definition: axis_view.h:98
boost::shared_ptr< SoloControllable > solo_control() const
Definition: route.h:410
bool multiple_solo_change
Definition: route_ui.h:97
void set_comment(std::string str, void *src)
Definition: route.cc:3067
void init_mute_menu(ARDOUR::MuteMaster::MutePoint, Gtk::CheckMenuItem *)
Definition: route_ui.cc:1363
RouteGroup * route_group() const
std::string name() const
boost::shared_ptr< IO > output()
Definition: io_processor.h:62
boost::shared_ptr< RouteList > route_list()
Definition: route_group.h:126
TrackSelection tracks
Definition: selection.h:81
static UIConfiguration * config()
Definition: ardour_ui.h:188
bool is_color() const
Definition: route_group.h:75
Gtk::CheckMenuItem * solo_isolated_check
Definition: route_ui.h:181
void set_text(const std::string &)
Gtk::CheckMenuItem * main_mute_check
Definition: route_ui.h:179
PBD::Signal0< void > MonitoringChanged
Definition: track.h:57
bool invert_press(GdkEventButton *)
Definition: route_ui.cc:2050
void set_monitoring(boost::shared_ptr< RouteList >, MonitorChoice, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
boost::shared_ptr< MuteControllable > mute_control() const
Definition: route.h:414
static boost::weak_ptr< ARDOUR::Route > _showing_sends_to
Definition: route_ui.h:306
bool solo_release(GdkEventButton *)
Definition: route_ui.cc:645
Definition: debug.h:30
std::vector< ArdourButton * > _invert_buttons
Definition: route_ui.h:302
boost::shared_ptr< IO > input() const
Definition: route.h:89
void solo_changed_so_update_mute()
Definition: route_ui.cc:1187
bool rec_enable_release(GdkEventButton *)
Definition: route_ui.cc:928
virtual void set_button_names()=0
uint32_t ModifierMask
Definition: keyboard.h:53
PBD::Signal0< void > RecordEnableChanged
Definition: track.h:167
virtual void stop_step_editing()
Definition: route_ui.h:261
static float dB_to_coefficient(float dB)
Definition: dB.h:30
void edit_output_configuration()
Definition: route_ui.cc:456
bool invert_release(GdkEventButton *, uint32_t i)
Definition: route_ui.cc:2035
FreezeState freeze_state() const
Definition: track.cc:175
bool contains(PropertyDescriptor< T > p) const
SoloMuteRelease * _mute_release
Definition: route_ui.h:293
void set_property(const std::string &id, const std::string &prop_name, const T &val)
Definition: gui_object.h:44
void page_gain_up()
Definition: route_ui.cc:1882
bool monitor_input_press(GdkEventButton *)
Definition: route_ui.cc:788
Gtk::TextView * comment_area
Definition: route_ui.h:249
boost::shared_ptr< IO > output() const
Definition: route.h:90
uint32_t remote_control_id() const
Definition: route.cc:286
bool mute_press(GdkEventButton *)
Definition: route_ui.cc:335
static Element default_elements
Definition: ardour_button.h:63
Off
Definition: widget_state.h:13
bool solo_safe_button_release(GdkEventButton *)
Definition: route_ui.cc:1449
boost::shared_ptr< ARDOUR::AudioTrack > audio_track() const
Definition: route_ui.cc:1750
Gtk::Menu * record_menu
Definition: route_ui.h:198
bool mute_release(GdkEventButton *)
Definition: route_ui.cc:443
void set_solo_isolated(boost::shared_ptr< RouteList >, bool, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
void invert_menu_toggled(uint32_t)
Definition: route_ui.cc:2082
void comment_editor_done_editing()
Definition: route_ui.cc:1674
void disconnect_input()
Definition: route_ui.cc:1720
void route_gui_changed(std::string)
Definition: route_ui.cc:2109
ArdourButton * solo_isolated_led
Definition: route_ui.h:110
std::list< boost::shared_ptr< Route > > RouteList
Definition: types.h:532
std::string route_state_id() const
Definition: route_ui.cc:1513
Placement
Definition: types.h:375
PBD::Signal0< void > phase_invert_changed
Definition: route.h:286
void toggle_solo_safe(Gtk::CheckMenuItem *)
Definition: route_ui.cc:1471
bool connected() const
Definition: audioengine.cc:919
PBD::ScopedConnectionList route_connections
Definition: route_ui.h:253
bool solo_isolated() const
Definition: route.cc:993
ARDOUR::Session * _session
boost::shared_ptr< ARDOUR::Route > route() const
Definition: route_ui.h:76
ArdourButton * solo_safe_led
Definition: route_ui.h:109
void set_sends_gain_to_zero()
Definition: route_ui.cc:1021
static PBD::Signal1< void, boost::shared_ptr< ARDOUR::Route > > BusSendDisplayChanged
Definition: route_ui.h:234
AudioEngine & engine()
Definition: session.h:546
Gtk::CheckMenuItem * denormal_menu_item
Definition: route_ui.h:207
int set_color_from_route()
Definition: route_ui.cc:1519
sigc::connection send_blink_connection
Definition: route_ui.h:116
bool ignore_comment_edit
Definition: route_ui.h:244
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
void set_mute(boost::shared_ptr< RouteList >, bool, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
void send_blink(bool)
Definition: route_ui.cc:1076
void update_solo_display()
Definition: route_ui.cc:1146
bool monitor_release(GdkEventButton *, ARDOUR::MonitorChoice)
Definition: route_ui.cc:812
ArdourButton * monitor_disk_button
Definition: route_ui.h:105
RouteUI(ARDOUR::Session *)
Definition: route_ui.cc:73
virtual void polarity_changed()
Definition: route_ui.cc:325
bool is_monitor() const
Definition: route.h:112
virtual void bus_send_display_changed(boost::shared_ptr< ARDOUR::Route >)
Definition: route_ui.cc:2159
boost::shared_ptr< ARDOUR::RouteList > routes_off
Definition: route_ui.h:286
void globally_add_internal_sends(boost::shared_ptr< Route > dest, Placement p, bool)
Definition: session.cc:2824
bool verify_new_route_name(const std::string &name)
Definition: route_ui.cc:1540
void init()
Definition: route_ui.cc:111