1 #include <gdkmm/pixbuf.h>
3 #include "pbd/compose.h"
6 #include "gtkmm2ext/bindable_button.h"
7 #include "gtkmm2ext/tearoff.h"
8 #include "gtkmm2ext/actions.h"
9 #include "gtkmm2ext/motionfeedback.h"
11 #include "ardour/dB.h"
12 #include "ardour/monitor_processor.h"
13 #include "ardour/route.h"
14 #include "ardour/utils.h"
16 #include "ardour_ui.h"
17 #include "gui_thread.h"
18 #include "monitor_section.h"
19 #include "public_editor.h"
20 #include "volume_controller.h"
25 using namespace ARDOUR
;
27 using namespace Gtkmm2ext
;
31 Glib::RefPtr
<ActionGroup
> MonitorSection::monitor_actions
;
32 Glib::RefPtr
<Gdk::Pixbuf
> MonitorSection::big_knob_pixbuf
;
33 Glib::RefPtr
<Gdk::Pixbuf
> MonitorSection::little_knob_pixbuf
;
35 MonitorSection::MonitorSection (Session
* s
)
42 , solo_boost_control (0)
43 , solo_cut_control (0)
44 , solo_in_place_button (solo_model_group
, _("SiP"))
45 , afl_button (solo_model_group
, _("AFL"))
46 , pfl_button (solo_model_group
, _("PFL"))
47 , cut_all_button (_("MUTE"))
48 , dim_all_button (_("dim"))
49 , mono_button (_("mono"))
50 , rude_solo_button (_("soloing"))
51 , rude_iso_button (_("isolated"))
52 , rude_audition_button (_("auditioning"))
53 , exclusive_solo_button (_("Exclusive"))
54 , solo_mute_override_button (_("Solo/Mute"))
56 Glib::RefPtr
<Action
> act
;
58 if (!monitor_actions
) {
60 /* do some static stuff */
73 dim_control
= new VolumeController (little_knob_pixbuf
, boost::shared_ptr
<Controllable
>(), 0.0, 0.01, 0.1, true, 30, 30, true);
75 HBox
* dim_packer
= manage (new HBox
);
78 spin_label
= manage (new Label (_("Dim")));
79 spin_packer
= manage (new VBox
);
81 spin_packer
->set_spacing (6);
82 spin_packer
->pack_start (*dim_control
, false, false);
83 spin_packer
->pack_start (*spin_label
, false, false);
85 dim_packer
->set_spacing (12);
86 dim_packer
->pack_start (*spin_packer
, true, false);
90 rude_solo_button
.set_name ("TransportSoloAlert");
91 rude_solo_button
.show ();
93 rude_iso_button
.set_name ("MonitorIsoAlert");
94 rude_iso_button
.show ();
96 rude_audition_button
.set_name ("TransportAuditioningAlert");
97 rude_audition_button
.show ();
99 ARDOUR_UI::Blink
.connect (sigc::mem_fun (*this, &MonitorSection::do_blink
));
101 rude_solo_button
.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_solo
), false);
102 UI::instance()->set_tip (rude_solo_button
, _("When active, something is soloed.\nClick to de-solo everything"));
104 rude_iso_button
.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_isolate
), false);
105 UI::instance()->set_tip (rude_iso_button
, _("When active, something is solo-isolated.\nClick to de-isolate everything"));
107 rude_audition_button
.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_audition
), false);
108 UI::instance()->set_tip (rude_audition_button
, _("When active, auditioning is active.\nClick to stop the audition"));
110 solo_model_box
.set_spacing (6);
111 solo_model_box
.pack_start (solo_in_place_button
, false, false);
112 solo_model_box
.pack_start (afl_button
, false, false);
113 solo_model_box
.pack_start (pfl_button
, false, false);
115 solo_in_place_button
.show ();
118 solo_model_box
.show ();
120 act
= ActionManager::get_action (X_("Solo"), X_("solo-use-in-place"));
122 act
->connect_proxy (solo_in_place_button
);
125 act
= ActionManager::get_action (X_("Solo"), X_("solo-use-afl"));
127 act
->connect_proxy (afl_button
);
130 act
= ActionManager::get_action (X_("Solo"), X_("solo-use-pfl"));
132 act
->connect_proxy (pfl_button
);
137 solo_boost_control
= new VolumeController (little_knob_pixbuf
, boost::shared_ptr
<Controllable
>(), 0.0, 0.01, 0.1, true, 30, 30, true);
139 HBox
* solo_packer
= manage (new HBox
);
140 solo_packer
->set_spacing (12);
141 solo_packer
->show ();
143 spin_label
= manage (new Label (_("Solo Boost")));
144 spin_packer
= manage (new VBox
);
145 spin_packer
->show ();
146 spin_packer
->set_spacing (6);
147 spin_packer
->pack_start (*solo_boost_control
, false, false);
148 spin_packer
->pack_start (*spin_label
, false, false);
150 solo_packer
->pack_start (*spin_packer
, false, true);
154 solo_cut_control
= new VolumeController (little_knob_pixbuf
, boost::shared_ptr
<Controllable
>(), 0.0, 0.1, 0.5, true, 30, 30, true);
156 spin_label
= manage (new Label (_("SiP Cut")));
157 spin_packer
= manage (new VBox
);
158 spin_packer
->show ();
159 spin_packer
->set_spacing (6);
160 spin_packer
->pack_start (*solo_cut_control
, false, false);
161 spin_packer
->pack_start (*spin_label
, false, false);
163 solo_packer
->pack_start (*spin_packer
, false, true);
165 exclusive_solo_button
.set_name (X_("MonitorOptButton"));
166 ARDOUR_UI::instance()->set_tip (&exclusive_solo_button
, _("Exclusive solo means that only 1 solo is active at a time"));
168 act
= ActionManager::get_action (X_("Monitor"), X_("toggle-exclusive-solo"));
170 act
->connect_proxy (exclusive_solo_button
);
173 solo_mute_override_button
.set_name (X_("MonitorOptButton"));
174 ARDOUR_UI::instance()->set_tip (&solo_mute_override_button
, _("If enabled, solo will override mute\n(a soloed & muted track or bus will be audible)"));
176 act
= ActionManager::get_action (X_("Monitor"), X_("toggle-mute-overrides-solo"));
178 act
->connect_proxy (solo_mute_override_button
);
181 HBox
* solo_opt_box
= manage (new HBox
);
182 solo_opt_box
->set_spacing (12);
183 solo_opt_box
->set_homogeneous (true);
184 solo_opt_box
->pack_start (exclusive_solo_button
);
185 solo_opt_box
->pack_start (solo_mute_override_button
);
186 solo_opt_box
->show ();
188 upper_packer
.set_spacing (12);
190 Gtk::HBox
* rude_box
= manage (new HBox
);
191 rude_box
->pack_start (rude_solo_button
, true, true);
192 rude_box
->pack_start (rude_iso_button
, true, true);
194 upper_packer
.pack_start (*rude_box
, false, false);
195 upper_packer
.pack_start (rude_audition_button
, false, false);
196 upper_packer
.pack_start (solo_model_box
, false, false);
197 upper_packer
.pack_start (*solo_opt_box
, false, false);
198 upper_packer
.pack_start (*solo_packer
, false, false);
200 act
= ActionManager::get_action (X_("Monitor"), X_("monitor-cut-all"));
202 act
->connect_proxy (cut_all_button
);
205 act
= ActionManager::get_action (X_("Monitor"), X_("monitor-dim-all"));
207 act
->connect_proxy (dim_all_button
);
210 act
= ActionManager::get_action (X_("Monitor"), X_("monitor-mono"));
212 act
->connect_proxy (mono_button
);
215 cut_all_button
.set_name (X_("MonitorMuteButton"));
216 cut_all_button
.unset_flags (Gtk::CAN_FOCUS
);
217 cut_all_button
.set_size_request (50,50);
218 cut_all_button
.show ();
220 HBox
* bbox
= manage (new HBox
);
222 bbox
->set_spacing (12);
223 bbox
->pack_start (mono_button
, true, true);
224 bbox
->pack_start (dim_all_button
, true, true);
226 dim_all_button
.set_name (X_("MonitorDimButton"));
227 dim_all_button
.unset_flags (Gtk::CAN_FOCUS
);
228 mono_button
.set_name (X_("MonitorMonoButton"));
229 mono_button
.unset_flags (Gtk::CAN_FOCUS
);
231 lower_packer
.set_spacing (12);
232 lower_packer
.pack_start (*bbox
, false, false);
233 lower_packer
.pack_start (cut_all_button
, false, false);
237 gain_control
= new VolumeController (big_knob_pixbuf
, boost::shared_ptr
<Controllable
>(), 1.0, 0.01, 0.1, true, 80, 80, false);
239 spin_label
= manage (new Label (_("Monitor")));
240 spin_packer
= manage (new VBox
);
241 spin_packer
->show ();
242 spin_packer
->set_spacing (6);
243 spin_packer
->pack_start (*gain_control
, false, false);
244 spin_packer
->pack_start (*spin_label
, false, false);
246 lower_packer
.pack_start (*spin_packer
, true, true);
248 vpacker
.set_border_width (12);
249 vpacker
.set_spacing (12);
250 vpacker
.pack_start (upper_packer
, false, false);
251 vpacker
.pack_start (*dim_packer
, false, false);
252 vpacker
.pack_start (main_table
, false, false);
253 vpacker
.pack_start (lower_packer
, false, false);
255 hpacker
.set_border_width (12);
256 hpacker
.set_spacing (12);
257 hpacker
.pack_start (vpacker
, true, true);
259 gain_control
->show_all ();
260 dim_control
->show_all ();
261 solo_boost_control
->show_all ();
265 upper_packer
.show ();
266 lower_packer
.show ();
271 assign_controllables ();
273 _tearoff
= new TearOff (hpacker
);
275 /* if torn off, make this a normal window */
276 _tearoff
->tearoff_window().set_type_hint (Gdk::WINDOW_TYPE_HINT_NORMAL
);
277 _tearoff
->tearoff_window().set_title (X_("Monitor"));
278 _tearoff
->tearoff_window().signal_key_press_event().connect (sigc::ptr_fun (forward_key_press
), false);
280 /* catch changes that affect us */
282 Config
->ParameterChanged
.connect (config_connection
, invalidator (*this), ui_bind (&MonitorSection::parameter_changed
, this, _1
), gui_context());
285 MonitorSection::~MonitorSection ()
287 for (ChannelButtons::iterator i
= _channel_buttons
.begin(); i
!= _channel_buttons
.end(); ++i
) {
291 _channel_buttons
.clear ();
295 delete solo_boost_control
;
300 MonitorSection::set_session (Session
* s
)
302 AxisView::set_session (s
);
306 _route
= _session
->monitor_out ();
309 /* session with monitor section */
310 _monitor
= _route
->monitor_control ();
311 assign_controllables ();
313 /* session with no monitor section */
323 control_connections
.drop_connections ();
324 rude_iso_button
.set_active (false);
325 rude_solo_button
.set_active (false);
327 assign_controllables ();
331 MonitorSection::ChannelButtonSet::ChannelButtonSet ()
337 cut
.set_name (X_("MonitorMuteButton"));
338 dim
.set_name (X_("MonitorDimButton"));
339 solo
.set_name (X_("MixerSoloButton"));
340 invert
.set_name (X_("MonitorInvertButton"));
342 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (cut
.gobj()), false);
343 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dim
.gobj()), false);
344 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (invert
.gobj()), false);
345 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (solo
.gobj()), false);
347 cut
.unset_flags (Gtk::CAN_FOCUS
);
348 dim
.unset_flags (Gtk::CAN_FOCUS
);
349 solo
.unset_flags (Gtk::CAN_FOCUS
);
350 invert
.unset_flags (Gtk::CAN_FOCUS
);
354 MonitorSection::populate_buttons ()
360 Glib::RefPtr
<Action
> act
;
361 uint32_t nchans
= _monitor
->output_streams().n_audio();
363 main_table
.resize (nchans
+1, 5);
364 main_table
.set_col_spacings (6);
365 main_table
.set_row_spacings (6);
366 main_table
.set_homogeneous (true);
368 Label
* l1
= manage (new Label (X_("out")));
369 main_table
.attach (*l1
, 0, 1, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
370 l1
= manage (new Label (X_("cut")));
371 main_table
.attach (*l1
, 1, 2, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
372 l1
= manage (new Label (X_("dim")));
373 main_table
.attach (*l1
, 2, 3, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
374 l1
= manage (new Label (X_("solo")));
375 main_table
.attach (*l1
, 3, 4, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
376 l1
= manage (new Label (X_("inv")));
377 main_table
.attach (*l1
, 4, 5, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
379 const uint32_t row_offset
= 1;
381 for (uint32_t i
= 0; i
< nchans
; ++i
) {
394 snprintf (buf
, sizeof (buf
), "%d", i
+1);
398 Label
* label
= manage (new Label (l
));
399 main_table
.attach (*label
, 0, 1, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
401 ChannelButtonSet
* cbs
= new ChannelButtonSet
;
403 _channel_buttons
.push_back (cbs
);
405 main_table
.attach (cbs
->cut
, 1, 2, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
406 main_table
.attach (cbs
->dim
, 2, 3, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
407 main_table
.attach (cbs
->solo
, 3, 4, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
408 main_table
.attach (cbs
->invert
, 4, 5, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
410 snprintf (buf
, sizeof (buf
), "monitor-cut-%u", i
+1);
411 act
= ActionManager::get_action (X_("Monitor"), buf
);
413 act
->connect_proxy (cbs
->cut
);
416 snprintf (buf
, sizeof (buf
), "monitor-dim-%u", i
+1);
417 act
= ActionManager::get_action (X_("Monitor"), buf
);
419 act
->connect_proxy (cbs
->dim
);
422 snprintf (buf
, sizeof (buf
), "monitor-solo-%u", i
+1);
423 act
= ActionManager::get_action (X_("Monitor"), buf
);
425 act
->connect_proxy (cbs
->solo
);
428 snprintf (buf
, sizeof (buf
), "monitor-invert-%u", i
+1);
429 act
= ActionManager::get_action (X_("Monitor"), buf
);
431 act
->connect_proxy (cbs
->invert
);
435 main_table
.show_all ();
439 MonitorSection::set_button_names ()
441 rec_enable_button_label
.set_text ("rec");
442 mute_button_label
.set_text ("rec");
443 solo_button_label
.set_text ("rec");
447 MonitorSection::toggle_exclusive_solo ()
453 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "toggle-exclusive-solo");
455 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
456 Config
->set_exclusive_solo (tact
->get_active());
463 MonitorSection::toggle_mute_overrides_solo ()
469 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "toggle-mute-overrides-solo");
471 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
472 Config
->set_solo_mute_override (tact
->get_active());
477 MonitorSection::dim_all ()
483 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "monitor-dim-all");
485 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
486 _monitor
->set_dim_all (tact
->get_active());
492 MonitorSection::cut_all ()
498 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "monitor-cut-all");
500 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
501 _monitor
->set_cut_all (tact
->get_active());
506 MonitorSection::mono ()
512 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "monitor-mono");
514 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
515 _monitor
->set_mono (tact
->get_active());
520 MonitorSection::cut_channel (uint32_t chn
)
527 snprintf (buf
, sizeof (buf
), "monitor-cut-%u", chn
);
529 --chn
; // 0-based in backend
531 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
533 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
534 _monitor
->set_cut (chn
, tact
->get_active());
539 MonitorSection::dim_channel (uint32_t chn
)
546 snprintf (buf
, sizeof (buf
), "monitor-dim-%u", chn
);
548 --chn
; // 0-based in backend
550 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
552 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
553 _monitor
->set_dim (chn
, tact
->get_active());
559 MonitorSection::solo_channel (uint32_t chn
)
566 snprintf (buf
, sizeof (buf
), "monitor-solo-%u", chn
);
568 --chn
; // 0-based in backend
570 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
572 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
573 _monitor
->set_solo (chn
, tact
->get_active());
579 MonitorSection::invert_channel (uint32_t chn
)
586 snprintf (buf
, sizeof (buf
), "monitor-invert-%u", chn
);
588 --chn
; // 0-based in backend
590 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
592 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
593 _monitor
->set_polarity (chn
, tact
->get_active());
598 MonitorSection::register_actions ()
602 Glib::RefPtr
<Action
> act
;
604 monitor_actions
= ActionGroup::create (X_("Monitor"));
605 ActionManager::add_action_group (monitor_actions
);
607 ActionManager::register_toggle_action (monitor_actions
, "monitor-mono", "", "Switch monitor to mono",
608 sigc::mem_fun (*this, &MonitorSection::mono
));
610 ActionManager::register_toggle_action (monitor_actions
, "monitor-cut-all", "", "Cut monitor",
611 sigc::mem_fun (*this, &MonitorSection::cut_all
));
613 ActionManager::register_toggle_action (monitor_actions
, "monitor-dim-all", "", "Dim monitor",
614 sigc::mem_fun (*this, &MonitorSection::dim_all
));
616 act
= ActionManager::register_toggle_action (monitor_actions
, "toggle-exclusive-solo", "", "Toggle exclusive solo mode",
617 sigc::mem_fun (*this, &MonitorSection::toggle_exclusive_solo
));
619 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
620 tact
->set_active (Config
->get_exclusive_solo());
622 act
= ActionManager::register_toggle_action (monitor_actions
, "toggle-mute-overrides-solo", "", "Toggle mute overrides solo mode",
623 sigc::mem_fun (*this, &MonitorSection::toggle_mute_overrides_solo
));
625 tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
626 tact
->set_active (Config
->get_solo_mute_override());
629 /* note the 1-based counting (for naming - backend uses 0-based) */
631 for (uint32_t chn
= 1; chn
<= 16; ++chn
) {
633 action_name
= string_compose (X_("monitor-cut-%1"), chn
);
634 action_descr
= string_compose (_("Cut monitor channel %1"), chn
);
635 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "", action_descr
.c_str(),
636 sigc::bind (sigc::mem_fun (*this, &MonitorSection::cut_channel
), chn
));
638 action_name
= string_compose (X_("monitor-dim-%1"), chn
);
639 action_descr
= string_compose (_("Dim monitor channel %1"), chn
+1);
640 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "", action_descr
.c_str(),
641 sigc::bind (sigc::mem_fun (*this, &MonitorSection::dim_channel
), chn
));
643 action_name
= string_compose (X_("monitor-solo-%1"), chn
);
644 action_descr
= string_compose (_("Solo monitor channel %1"), chn
+1);
645 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "", action_descr
.c_str(),
646 sigc::bind (sigc::mem_fun (*this, &MonitorSection::solo_channel
), chn
));
648 action_name
= string_compose (X_("monitor-invert-%1"), chn
);
649 action_descr
= string_compose (_("Invert monitor channel %1"), chn
+1);
650 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "", action_descr
.c_str(),
651 sigc::bind (sigc::mem_fun (*this, &MonitorSection::invert_channel
), chn
));
656 Glib::RefPtr
<ActionGroup
> solo_actions
= ActionGroup::create (X_("Solo"));
657 RadioAction::Group solo_group
;
659 ActionManager::register_radio_action (solo_actions
, solo_group
, "solo-use-in-place", "", "In-place solo",
660 sigc::mem_fun (*this, &MonitorSection::solo_use_in_place
));
661 ActionManager::register_radio_action (solo_actions
, solo_group
, "solo-use-afl", "", "After Fade Listen (AFL) solo",
662 sigc::mem_fun (*this, &MonitorSection::solo_use_afl
));
663 ActionManager::register_radio_action (solo_actions
, solo_group
, "solo-use-pfl", "", "Pre Fade Listen (PFL) solo",
664 sigc::mem_fun (*this, &MonitorSection::solo_use_pfl
));
666 ActionManager::add_action_group (solo_actions
);
670 MonitorSection::solo_use_in_place ()
672 /* this is driven by a toggle on a radio group, and so is invoked twice,
673 once for the item that became inactive and once for the one that became
677 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Solo"), X_("solo-use-in-place"));
680 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
682 Config
->set_solo_control_is_listen_control (!ract
->get_active());
688 MonitorSection::solo_use_afl ()
690 /* this is driven by a toggle on a radio group, and so is invoked twice,
691 once for the item that became inactive and once for the one that became
695 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Solo"), X_("solo-use-afl"));
697 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
699 if (ract
->get_active()) {
700 Config
->set_listen_position (AfterFaderListen
);
701 Config
->set_solo_control_is_listen_control (true);
708 MonitorSection::solo_use_pfl ()
710 /* this is driven by a toggle on a radio group, and so is invoked twice,
711 once for the item that became inactive and once for the one that became
715 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Solo"), X_("solo-use-afl"));
717 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
719 if (ract
->get_active()) {
720 Config
->set_listen_position (PreFaderListen
);
721 Config
->set_solo_control_is_listen_control (true);
728 MonitorSection::setup_knob_images ()
732 big_knob_pixbuf
= MotionFeedback::render_pixbuf (80);
736 error
<< "No usable large knob image" << endmsg
;
737 throw failed_constructor ();
740 if (!big_knob_pixbuf
) {
741 error
<< "No usable large knob image" << endmsg
;
742 throw failed_constructor ();
747 little_knob_pixbuf
= MotionFeedback::render_pixbuf (30);
751 error
<< "No usable small knob image" << endmsg
;
752 throw failed_constructor ();
755 if (!little_knob_pixbuf
) {
756 error
<< "No usable small knob image" << endmsg
;
757 throw failed_constructor ();
763 MonitorSection::update_solo_model ()
765 const char* action_name
;
766 Glib::RefPtr
<Action
> act
;
768 if (Config
->get_solo_control_is_listen_control()) {
769 switch (Config
->get_listen_position()) {
770 case AfterFaderListen
:
771 action_name
= X_("solo-use-afl");
774 action_name
= X_("solo-use-pfl");
778 action_name
= X_("solo-use-in-place");
781 act
= ActionManager::get_action (X_("Solo"), action_name
);
783 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
785 ract
->set_active (true);
791 MonitorSection::map_state ()
793 if (!_route
|| !_monitor
) {
797 Glib::RefPtr
<Action
> act
;
799 update_solo_model ();
801 act
= ActionManager::get_action (X_("Monitor"), "monitor-cut-all");
803 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
805 tact
->set_active (_monitor
->cut_all());
809 act
= ActionManager::get_action (X_("Monitor"), "monitor-dim-all");
811 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
813 tact
->set_active (_monitor
->dim_all());
817 act
= ActionManager::get_action (X_("Monitor"), "monitor-mono");
819 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
821 tact
->set_active (_monitor
->mono());
825 uint32_t nchans
= _monitor
->output_streams().n_audio();
827 assert (nchans
== _channel_buttons
.size ());
829 for (uint32_t n
= 0; n
< nchans
; ++n
) {
831 char action_name
[32];
833 snprintf (action_name
, sizeof (action_name
), "monitor-cut-%u", n
+1);
834 act
= ActionManager::get_action (X_("Monitor"), action_name
);
836 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
838 tact
->set_active (_monitor
->cut (n
));
842 snprintf (action_name
, sizeof (action_name
), "monitor-dim-%u", n
+1);
843 act
= ActionManager::get_action (X_("Monitor"), action_name
);
845 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
847 tact
->set_active (_monitor
->dimmed (n
));
851 snprintf (action_name
, sizeof (action_name
), "monitor-solo-%u", n
+1);
852 act
= ActionManager::get_action (X_("Monitor"), action_name
);
854 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
856 tact
->set_active (_monitor
->soloed (n
));
860 snprintf (action_name
, sizeof (action_name
), "monitor-invert-%u", n
+1);
861 act
= ActionManager::get_action (X_("Monitor"), action_name
);
863 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
865 tact
->set_active (_monitor
->inverted (n
));
872 MonitorSection::do_blink (bool onoff
)
875 audition_blink (onoff
);
879 MonitorSection::audition_blink (bool onoff
)
885 if (_session
->is_auditioning()) {
887 rude_audition_button
.set_state (STATE_ACTIVE
);
889 rude_audition_button
.set_state (STATE_NORMAL
);
892 rude_audition_button
.set_active (false);
893 rude_audition_button
.set_state (STATE_NORMAL
);
898 MonitorSection::solo_blink (bool onoff
)
904 if (_session
->soloing() || _session
->listening()) {
906 rude_solo_button
.set_state (STATE_ACTIVE
);
908 rude_solo_button
.set_state (STATE_NORMAL
);
911 if (_session
->soloing()) {
912 rude_iso_button
.set_active (_session
->solo_isolated());
916 // rude_solo_button.set_active (false);
917 rude_solo_button
.set_state (STATE_NORMAL
);
918 rude_iso_button
.set_active (false);
923 MonitorSection::cancel_solo (GdkEventButton
*)
926 if (_session
->soloing()) {
927 _session
->set_solo (_session
->get_routes(), false);
928 } else if (_session
->listening()) {
929 _session
->set_listen (_session
->get_routes(), false);
937 MonitorSection::cancel_isolate (GdkEventButton
*)
940 boost::shared_ptr
<RouteList
> rl (_session
->get_routes ());
941 _session
->set_solo_isolated (rl
, false, Session::rt_cleanup
, true);
948 MonitorSection::cancel_audition (GdkEventButton
*)
951 _session
->cancel_audition();
957 MonitorSection::parameter_changed (std::string name
)
959 if (name
== "solo-control-is-listen-control" ||
960 name
== "listen-position") {
961 update_solo_model ();
966 MonitorSection::assign_controllables ()
968 boost::shared_ptr
<Controllable
> none
;
971 /* too early - GUI controls not set up yet */
976 solo_cut_control
->set_controllable (_session
->solo_cut_control());
978 solo_cut_control
->set_controllable (none
);
982 gain_control
->set_controllable (_route
->gain_control());
984 gain_control
->set_controllable (none
);
989 cut_all_button
.set_controllable (_monitor
->cut_control());
990 cut_all_button
.watch ();
991 dim_all_button
.set_controllable (_monitor
->dim_control());
992 dim_all_button
.watch ();
993 mono_button
.set_controllable (_monitor
->mono_control());
994 mono_button
.watch ();
996 dim_control
->set_controllable (_monitor
->dim_level_control ());
997 solo_boost_control
->set_controllable (_monitor
->solo_boost_control ());
1001 cut_all_button
.set_controllable (none
);
1002 dim_all_button
.set_controllable (none
);
1003 mono_button
.set_controllable (none
);
1005 dim_control
->set_controllable (none
);
1006 solo_boost_control
->set_controllable (none
);
1011 MonitorSection::state_id() const
1013 return "monitor-section";