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"
10 #include "ardour/dB.h"
11 #include "ardour/monitor_processor.h"
12 #include "ardour/route.h"
13 #include "ardour/utils.h"
15 #include "ardour_ui.h"
16 #include "monitor_section.h"
17 #include "public_editor.h"
19 #include "volume_controller.h"
23 using namespace ARDOUR
;
25 using namespace Gtkmm2ext
;
29 Glib::RefPtr
<ActionGroup
> MonitorSection::monitor_actions
;
30 Glib::RefPtr
<Gdk::Pixbuf
> MonitorSection::big_knob_pixbuf
;
31 Glib::RefPtr
<Gdk::Pixbuf
> MonitorSection::little_knob_pixbuf
;
34 fixup_prelight (GdkEventCrossing
* /* ignored */, GtkWidget
* widget
)
36 GtkRcStyle
* style
= gtk_rc_style_copy (gtk_widget_get_modifier_style (widget
));
37 int current
= gtk_widget_get_state (widget
);
39 style
->fg
[GTK_STATE_PRELIGHT
] = style
->fg
[current
];
40 style
->bg
[GTK_STATE_PRELIGHT
] = style
->bg
[current
];
42 gtk_widget_modify_style(widget
, style
);
43 g_object_unref(style
);
49 block_prelight (Gtk::Widget
& w
)
51 w
.signal_enter_notify_event().connect (sigc::bind (sigc::ptr_fun (fixup_prelight
), w
.gobj()), false);
54 MonitorSection::MonitorSection (Session
* s
)
59 , gain_adjustment (1.0, 0.0, 1.0, 0.01, 0.1)
61 , dim_adjustment (0.2, 0.0, 1.0, 0.01, 0.1)
63 , solo_boost_adjustment (1.0, 1.0, 2.0, 0.01, 0.1)
64 , solo_boost_control (0)
65 , solo_cut_adjustment (0.0, 0.0, 1.0, 0.01, 0.1)
66 , solo_cut_control (0)
67 , solo_in_place_button (solo_model_group
, _("SiP"))
68 , afl_button (solo_model_group
, _("AFL"))
69 , pfl_button (solo_model_group
, _("PFL"))
70 , cut_all_button (_("MUTE"))
71 , dim_all_button (_("dim"))
72 , mono_button (_("mono"))
73 , rude_solo_button (_("soloing"))
76 Glib::RefPtr
<Action
> act
;
78 if (!monitor_actions
) {
80 /* do some static stuff */
93 dim_control
= new VolumeController (little_knob_pixbuf
, &dim_adjustment
, false, 30, 30);
94 dim_adjustment
.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::dim_level_changed
));
96 HBox
* dim_packer
= manage (new HBox
);
99 spin_label
= manage (new Label (_("Dim Cut")));
100 spin_packer
= manage (new VBox
);
101 spin_packer
->show ();
102 spin_packer
->set_spacing (6);
103 spin_packer
->pack_start (*dim_control
, false, false);
104 spin_packer
->pack_start (*spin_label
, false, false);
106 dim_packer
->set_spacing (12);
107 dim_packer
->pack_start (*spin_packer
, true, true);
111 rude_solo_button
.set_name ("TransportSoloAlert");
112 rude_solo_button
.show ();
113 block_prelight (rude_solo_button
);
115 ARDOUR_UI::Blink
.connect (sigc::mem_fun (*this, &MonitorSection::solo_blink
));
116 rude_solo_button
.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_solo
), false);
117 UI::instance()->set_tip (rude_solo_button
, _("When active, something is soloed.\nClick to de-solo everything"));
120 solo_model_box
.set_spacing (6);
121 solo_model_box
.pack_start (solo_in_place_button
, false, false);
122 solo_model_box
.pack_start (afl_button
, false, false);
123 solo_model_box
.pack_start (pfl_button
, false, false);
125 solo_in_place_button
.show ();
128 solo_model_box
.show ();
130 act
= ActionManager::get_action (X_("Solo"), X_("solo-use-in-place"));
132 act
->connect_proxy (solo_in_place_button
);
135 act
= ActionManager::get_action (X_("Solo"), X_("solo-use-afl"));
137 act
->connect_proxy (afl_button
);
140 act
= ActionManager::get_action (X_("Solo"), X_("solo-use-pfl"));
142 act
->connect_proxy (pfl_button
);
148 solo_boost_control
= new VolumeController (little_knob_pixbuf
, &solo_boost_adjustment
, false, 30, 30);
149 solo_boost_adjustment
.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::solo_boost_changed
));
151 HBox
* solo_packer
= manage (new HBox
);
152 solo_packer
->set_spacing (12);
153 solo_packer
->show ();
155 spin_label
= manage (new Label (_("Solo Boost")));
156 spin_packer
= manage (new VBox
);
157 spin_packer
->show ();
158 spin_packer
->set_spacing (6);
159 spin_packer
->pack_start (*solo_boost_control
, false, false);
160 spin_packer
->pack_start (*spin_label
, false, false);
162 solo_packer
->pack_start (*spin_packer
, true, true);
166 solo_cut_control
= new VolumeController (little_knob_pixbuf
, &solo_cut_adjustment
, false, 30, 30);
167 // solo_cut_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::solo_cut_changed));
169 spin_label
= manage (new Label (_("SiP Cut")));
170 spin_packer
= manage (new VBox
);
171 spin_packer
->show ();
172 spin_packer
->set_spacing (6);
173 spin_packer
->pack_start (*solo_cut_control
, false, false);
174 spin_packer
->pack_start (*spin_label
, false, false);
176 solo_packer
->pack_start (*spin_packer
, true, true);
178 upper_packer
.set_spacing (12);
179 upper_packer
.pack_start (rude_solo_button
, false, false);
180 upper_packer
.pack_start (solo_model_box
, false, false);
181 upper_packer
.pack_start (*solo_packer
, false, false);
183 act
= ActionManager::get_action (X_("Monitor"), X_("monitor-cut-all"));
185 act
->connect_proxy (cut_all_button
);
188 act
= ActionManager::get_action (X_("Monitor"), X_("monitor-dim-all"));
190 act
->connect_proxy (dim_all_button
);
193 act
= ActionManager::get_action (X_("Monitor"), X_("monitor-mono"));
195 act
->connect_proxy (mono_button
);
198 cut_all_button
.set_size_request (50,50);
199 cut_all_button
.show ();
201 HBox
* bbox
= manage (new HBox
);
203 bbox
->set_spacing (12);
204 bbox
->pack_start (mono_button
, true, true);
205 bbox
->pack_start (dim_all_button
, true, true);
207 lower_packer
.set_spacing (12);
208 lower_packer
.pack_start (*bbox
, false, false);
209 lower_packer
.pack_start (cut_all_button
, false, false);
213 gain_control
= new VolumeController (big_knob_pixbuf
, &gain_adjustment
, false, 80, 80);
214 gain_adjustment
.signal_value_changed().connect (sigc::mem_fun (*this, &MonitorSection::gain_value_changed
));
216 spin_label
= manage (new Label (_("Gain")));
217 spin_packer
= manage (new VBox
);
218 spin_packer
->show ();
219 spin_packer
->set_spacing (6);
220 spin_packer
->pack_start (*gain_control
, false, false);
221 spin_packer
->pack_start (*spin_label
, false, false);
223 lower_packer
.pack_start (*spin_packer
, true, true);
225 vpacker
.set_border_width (12);
226 vpacker
.set_spacing (12);
227 vpacker
.pack_start (upper_packer
, false, false);
228 vpacker
.pack_start (*dim_packer
, false, false);
229 vpacker
.pack_start (main_table
, false, false);
230 vpacker
.pack_start (lower_packer
, false, false);
232 hpacker
.set_border_width (12);
233 hpacker
.set_spacing (12);
234 hpacker
.pack_start (vpacker
, true, true);
236 gain_control
->show_all ();
237 dim_control
->show_all ();
238 solo_boost_control
->show_all ();
242 upper_packer
.show ();
243 lower_packer
.show ();
249 _tearoff
= new TearOff (hpacker
);
251 /* if torn off, make this a normal window */
252 _tearoff
->tearoff_window().set_type_hint (Gdk::WINDOW_TYPE_HINT_NORMAL
);
253 _tearoff
->tearoff_window().set_title (X_("Monitor"));
254 _tearoff
->tearoff_window().signal_key_press_event().connect (sigc::ptr_fun (forward_key_press
), false);
257 MonitorSection::~MonitorSection ()
259 for (ChannelButtons::iterator i
= _channel_buttons
.begin(); i
!= _channel_buttons
.end(); ++i
) {
263 _channel_buttons
.clear ();
267 delete solo_boost_control
;
272 MonitorSection::set_session (Session
* s
)
274 AxisView::set_session (s
);
278 _route
= _session
->control_out ();
281 /* session with control outs */
282 _monitor
= _route
->monitor_control ();
284 /* session with no control outs */
295 /* both might be null */
298 MonitorSection::ChannelButtonSet::ChannelButtonSet ()
304 cut
.set_name (X_("MixerMuteButton"));
305 dim
.set_name (X_("MixerMuteButton"));
306 solo
.set_name (X_("MixerSoloButton"));
308 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (cut
.gobj()), false);
309 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dim
.gobj()), false);
310 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (invert
.gobj()), false);
311 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (solo
.gobj()), false);
313 block_prelight (cut
);
314 block_prelight (dim
);
315 block_prelight (solo
);
316 block_prelight (invert
);
320 MonitorSection::populate_buttons ()
326 Glib::RefPtr
<Action
> act
;
327 uint32_t nchans
= _monitor
->output_streams().n_audio();
329 main_table
.resize (nchans
+1, 5);
330 main_table
.set_col_spacings (6);
331 main_table
.set_row_spacings (6);
332 main_table
.set_homogeneous (true);
334 Label
* l1
= manage (new Label (X_("out")));
335 main_table
.attach (*l1
, 0, 1, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
336 l1
= manage (new Label (X_("cut")));
337 main_table
.attach (*l1
, 1, 2, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
338 l1
= manage (new Label (X_("dim")));
339 main_table
.attach (*l1
, 2, 3, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
340 l1
= manage (new Label (X_("solo")));
341 main_table
.attach (*l1
, 3, 4, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
342 l1
= manage (new Label (X_("inv")));
343 main_table
.attach (*l1
, 4, 5, 0, 1, SHRINK
|FILL
, SHRINK
|FILL
);
345 const uint32_t row_offset
= 1;
347 for (uint32_t i
= 0; i
< nchans
; ++i
) {
360 snprintf (buf
, sizeof (buf
), "%d", i
+1);
364 Label
* label
= manage (new Label (l
));
365 main_table
.attach (*label
, 0, 1, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
367 ChannelButtonSet
* cbs
= new ChannelButtonSet
;
369 _channel_buttons
.push_back (cbs
);
371 main_table
.attach (cbs
->cut
, 1, 2, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
372 main_table
.attach (cbs
->dim
, 2, 3, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
373 main_table
.attach (cbs
->solo
, 3, 4, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
374 main_table
.attach (cbs
->invert
, 4, 5, i
+row_offset
, i
+row_offset
+1, SHRINK
|FILL
, SHRINK
|FILL
);
376 snprintf (buf
, sizeof (buf
), "monitor-cut-%u", i
+1);
377 act
= ActionManager::get_action (X_("Monitor"), buf
);
379 act
->connect_proxy (cbs
->cut
);
382 snprintf (buf
, sizeof (buf
), "monitor-dim-%u", i
+1);
383 act
= ActionManager::get_action (X_("Monitor"), buf
);
385 act
->connect_proxy (cbs
->dim
);
388 snprintf (buf
, sizeof (buf
), "monitor-solo-%u", i
+1);
389 act
= ActionManager::get_action (X_("Monitor"), buf
);
391 act
->connect_proxy (cbs
->solo
);
394 snprintf (buf
, sizeof (buf
), "monitor-invert-%u", i
+1);
395 act
= ActionManager::get_action (X_("Monitor"), buf
);
397 act
->connect_proxy (cbs
->invert
);
401 main_table
.show_all ();
405 MonitorSection::set_button_names ()
407 rec_enable_button_label
.set_text ("rec");
408 mute_button_label
.set_text ("rec");
409 solo_button_label
.set_text ("rec");
413 MonitorSection::dim_all ()
419 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "monitor-dim-all");
421 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
422 _monitor
->set_dim_all (tact
->get_active());
428 MonitorSection::cut_all ()
434 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "monitor-cut-all");
436 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
437 _monitor
->set_cut_all (tact
->get_active());
442 MonitorSection::mono ()
448 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), "monitor-mono");
450 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
451 _monitor
->set_mono (tact
->get_active());
456 MonitorSection::cut_channel (uint32_t chn
)
463 snprintf (buf
, sizeof (buf
), "monitor-cut-%u", chn
);
465 --chn
; // 0-based in backend
467 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
469 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
470 _monitor
->set_cut (chn
, tact
->get_active());
475 MonitorSection::dim_channel (uint32_t chn
)
482 snprintf (buf
, sizeof (buf
), "monitor-dim-%u", chn
);
484 --chn
; // 0-based in backend
486 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
488 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
489 _monitor
->set_dim (chn
, tact
->get_active());
495 MonitorSection::solo_channel (uint32_t chn
)
502 snprintf (buf
, sizeof (buf
), "monitor-solo-%u", chn
);
504 --chn
; // 0-based in backend
506 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
508 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
509 _monitor
->set_solo (chn
, tact
->get_active());
515 MonitorSection::invert_channel (uint32_t chn
)
522 snprintf (buf
, sizeof (buf
), "monitor-invert-%u", chn
);
524 --chn
; // 0-based in backend
526 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Monitor"), buf
);
528 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic(act
);
529 _monitor
->set_polarity (chn
, tact
->get_active());
534 MonitorSection::register_actions ()
539 monitor_actions
= ActionGroup::create (X_("Monitor"));
540 ActionManager::add_action_group (monitor_actions
);
542 ActionManager::register_toggle_action (monitor_actions
, "monitor-mono", "",
543 sigc::mem_fun (*this, &MonitorSection::mono
));
545 ActionManager::register_toggle_action (monitor_actions
, "monitor-cut-all", "",
546 sigc::mem_fun (*this, &MonitorSection::cut_all
));
548 ActionManager::register_toggle_action (monitor_actions
, "monitor-dim-all", "",
549 sigc::mem_fun (*this, &MonitorSection::dim_all
));
551 /* note the 1-based counting (for naming - backend uses 0-based) */
553 for (uint32_t chn
= 1; chn
<= 16; ++chn
) {
555 /* for the time being, do not use the action description because it always
556 shows up in the buttons, which is undesirable.
559 action_name
= string_compose (X_("monitor-cut-%1"), chn
);
560 action_descr
= string_compose (_("Cut Monitor Chn %1"), chn
);
561 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "",
562 sigc::bind (sigc::mem_fun (*this, &MonitorSection::cut_channel
), chn
));
564 action_name
= string_compose (X_("monitor-dim-%1"), chn
);
565 action_descr
= string_compose (_("Dim Monitor Chn %1"), chn
+1);
566 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "",
567 sigc::bind (sigc::mem_fun (*this, &MonitorSection::dim_channel
), chn
));
569 action_name
= string_compose (X_("monitor-solo-%1"), chn
);
570 action_descr
= string_compose (_("Solo Monitor Chn %1"), chn
);
571 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "",
572 sigc::bind (sigc::mem_fun (*this, &MonitorSection::solo_channel
), chn
));
574 action_name
= string_compose (X_("monitor-invert-%1"), chn
);
575 action_descr
= string_compose (_("Invert Monitor Chn %1"), chn
);
576 ActionManager::register_toggle_action (monitor_actions
, action_name
.c_str(), "",
577 sigc::bind (sigc::mem_fun (*this, &MonitorSection::invert_channel
), chn
));
582 Glib::RefPtr
<ActionGroup
> solo_actions
= ActionGroup::create (X_("Solo"));
583 RadioAction::Group solo_group
;
585 ActionManager::register_radio_action (solo_actions
, solo_group
, "solo-use-in-place", "",
586 sigc::mem_fun (*this, &MonitorSection::solo_use_in_place
));
587 ActionManager::register_radio_action (solo_actions
, solo_group
, "solo-use-afl", "",
588 sigc::mem_fun (*this, &MonitorSection::solo_use_afl
));
589 ActionManager::register_radio_action (solo_actions
, solo_group
, "solo-use-pfl", "",
590 sigc::mem_fun (*this, &MonitorSection::solo_use_pfl
));
592 ActionManager::add_action_group (solo_actions
);
596 MonitorSection::solo_use_in_place ()
598 /* this is driven by a toggle on a radio group, and so is invoked twice,
599 once for the item that became inactive and once for the one that became
603 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Solo"), X_("solo-use-in-place"));
606 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
608 Config
->set_solo_control_is_listen_control (!ract
->get_active());
614 MonitorSection::solo_use_afl ()
616 /* this is driven by a toggle on a radio group, and so is invoked twice,
617 once for the item that became inactive and once for the one that became
621 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Solo"), X_("solo-use-afl"));
623 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
625 if (ract
->get_active()) {
626 Config
->set_listen_position (AfterFaderListen
);
627 Config
->set_solo_control_is_listen_control (true);
634 MonitorSection::solo_use_pfl ()
636 /* this is driven by a toggle on a radio group, and so is invoked twice,
637 once for the item that became inactive and once for the one that became
641 Glib::RefPtr
<Action
> act
= ActionManager::get_action (X_("Solo"), X_("solo-use-afl"));
643 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
645 if (ract
->get_active()) {
646 Config
->set_listen_position (PreFaderListen
);
647 Config
->set_solo_control_is_listen_control (true);
654 MonitorSection::setup_knob_images ()
658 big_knob_pixbuf
= ::get_icon ("bigknob");
662 error
<< "No knob image found (or not loadable) at "
665 throw failed_constructor ();
670 little_knob_pixbuf
= ::get_icon ("littleknob");
674 error
<< "No knob image found (or not loadable) at "
677 throw failed_constructor ();
682 MonitorSection::gain_value_changed ()
685 _route
->set_gain (slider_position_to_gain (gain_adjustment
.get_value()), this);
690 MonitorSection::dim_level_changed ()
693 _monitor
->set_dim_level (dim_adjustment
.get_value());
698 MonitorSection::solo_boost_changed ()
701 _monitor
->set_solo_boost_level (solo_boost_adjustment
.get_value());
706 MonitorSection::nonlinear_gain_printer (SpinButton
* button
)
708 double val
= button
->get_adjustment()->get_value();
710 snprintf (buf
, sizeof (buf
), "%.1f", accurate_coefficient_to_dB (slider_position_to_gain (val
)));
711 button
->set_text (buf
);
716 MonitorSection::linear_gain_printer (SpinButton
* button
)
718 double val
= button
->get_adjustment()->get_value();
720 snprintf (buf
, sizeof (buf
), "%.1f", accurate_coefficient_to_dB (val
));
721 button
->set_text (buf
);
726 MonitorSection::map_state ()
728 if (!_route
|| !_monitor
) {
732 gain_control
->get_adjustment()->set_value (gain_to_slider_position (_route
->gain_control()->get_value()));
733 dim_control
->get_adjustment()->set_value (_monitor
->dim_level());
734 solo_boost_control
->get_adjustment()->set_value (_monitor
->solo_boost_level());
736 const char *action_name
;
738 if (Config
->get_solo_control_is_listen_control()) {
739 switch (Config
->get_listen_position()) {
740 case AfterFaderListen
:
741 action_name
= X_("solo-use-afl");
744 action_name
= X_("solo-use-afl");
748 action_name
= X_("solo-use-in-place");
751 Glib::RefPtr
<Action
> act
;
753 act
= ActionManager::get_action (X_("Solo"), action_name
);
755 Glib::RefPtr
<RadioAction
> ract
= Glib::RefPtr
<RadioAction
>::cast_dynamic (act
);
757 ract
->set_active (true);
761 act
= ActionManager::get_action (X_("Monitor"), "monitor-cut-all");
763 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
765 cerr
<< "Set monitor cut all action to " << _monitor
->cut_all () << endl
;
766 tact
->set_active (_monitor
->cut_all());
768 cerr
<< " no global cut action\n";
771 cerr
<< " no global cut action2\n";
774 act
= ActionManager::get_action (X_("Monitor"), "monitor-dim-all");
776 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
778 tact
->set_active (_monitor
->dim_all());
782 act
= ActionManager::get_action (X_("Monitor"), "monitor-mono");
784 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
786 tact
->set_active (_monitor
->mono());
790 uint32_t nchans
= _monitor
->output_streams().n_audio();
792 assert (nchans
== _channel_buttons
.size ());
794 for (uint32_t n
= 0; n
< nchans
; ++n
) {
796 char action_name
[32];
798 snprintf (action_name
, sizeof (action_name
), "monitor-cut-%u", n
+1);
799 act
= ActionManager::get_action (X_("Monitor"), action_name
);
801 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
803 tact
->set_active (_monitor
->cut (n
));
807 snprintf (action_name
, sizeof (action_name
), "monitor-dim-%u", n
+1);
808 act
= ActionManager::get_action (X_("Monitor"), action_name
);
810 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
812 tact
->set_active (_monitor
->dimmed (n
));
816 snprintf (action_name
, sizeof (action_name
), "monitor-solo-%u", n
+1);
817 act
= ActionManager::get_action (X_("Monitor"), action_name
);
819 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
821 tact
->set_active (_monitor
->soloed (n
));
825 snprintf (action_name
, sizeof (action_name
), "monitor-invert-%u", n
+1);
826 act
= ActionManager::get_action (X_("Monitor"), action_name
);
828 Glib::RefPtr
<ToggleAction
> tact
= Glib::RefPtr
<ToggleAction
>::cast_dynamic (act
);
830 tact
->set_active (_monitor
->inverted (n
));
837 MonitorSection::solo_blink (bool onoff
)
843 if (_session
->soloing() || _session
->listening()) {
845 rude_solo_button
.set_state (STATE_ACTIVE
);
847 rude_solo_button
.set_state (STATE_NORMAL
);
850 // rude_solo_button.set_active (false);
851 rude_solo_button
.set_state (STATE_NORMAL
);
856 MonitorSection::cancel_solo (GdkEventButton
* ev
)
859 if (_session
->soloing()) {
860 _session
->set_solo (_session
->get_routes(), false);
861 } else if (_session
->listening()) {
862 _session
->set_listen (_session
->get_routes(), false);