Consolidate Route context menus (Mixer, Editor, Cue Page)

Consistently hide elements that are not accessible on inactive
Routes; fix duplicate separators, and group items
This commit is contained in:
Robin Gareus 2024-09-05 20:35:24 +02:00
parent 4692227168
commit 00f6468606
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
3 changed files with 89 additions and 65 deletions

View file

@ -1090,8 +1090,6 @@ MixerStrip::build_route_ops_menu ()
/* do not allow rename if the track is record-enabled */ /* do not allow rename if the track is record-enabled */
items.back().set_sensitive (!is_track() || !track()->rec_enable_control()->get_value()); items.back().set_sensitive (!is_track() || !track()->rec_enable_control()->get_value());
} }
items.push_back (SeparatorElem());
} }
if ((!_route->is_singleton () || !active) if ((!_route->is_singleton () || !active)
@ -1100,11 +1098,18 @@ MixerStrip::build_route_ops_menu ()
#endif #endif
) )
{ {
if (active) {
items.push_back (SeparatorElem());
}
items.push_back (CheckMenuElem (_("Active"))); items.push_back (CheckMenuElem (_("Active")));
Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back()); Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
i->set_active (active); i->set_active (active);
i->set_sensitive (!_session->transport_rolling()); i->set_sensitive (!_session->transport_rolling());
i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), !_route->active(), false)); i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), !_route->active(), false));
}
/* Plugin / Processor related */
if (active) {
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
} }
@ -1113,18 +1118,6 @@ MixerStrip::build_route_ops_menu ()
Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back()); Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
i->set_active (_route->strict_io()); i->set_active (_route->strict_io());
i->signal_activate().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*_route, &Route::set_strict_io), !_route->strict_io()))); i->signal_activate().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*_route, &Route::set_strict_io), !_route->strict_io())));
items.push_back (SeparatorElem());
}
if (active && is_track()) {
Gtk::Menu* dio_menu = new Menu;
MenuList& dio_items = dio_menu->items();
dio_items.push_back (MenuElem (_("Record Pre-Fader"), sigc::bind (sigc::mem_fun (*this, &RouteUI::set_disk_io_point), DiskIOPreFader)));
dio_items.push_back (MenuElem (_("Record Post-Fader"), sigc::bind (sigc::mem_fun (*this, &RouteUI::set_disk_io_point), DiskIOPostFader)));
dio_items.push_back (MenuElem (_("Custom Record+Playback Positions"), sigc::bind (sigc::mem_fun (*this, &RouteUI::set_disk_io_point), DiskIOCustom)));
items.push_back (MenuElem (_("Disk I/O..."), *dio_menu));
items.push_back (SeparatorElem());
} }
uint32_t plugin_insert_cnt = 0; uint32_t plugin_insert_cnt = 0;
@ -1133,7 +1126,28 @@ MixerStrip::build_route_ops_menu ()
items.push_back (MenuElem (_("Pin Connections..."), sigc::mem_fun (*this, &RouteUI::manage_pins))); items.push_back (MenuElem (_("Pin Connections..."), sigc::mem_fun (*this, &RouteUI::manage_pins)));
} }
if (active) {
items.push_back (CheckMenuElem (_("Protect Against Denormals"), sigc::mem_fun (*this, &RouteUI::toggle_denormal_protection)));
denormal_menu_item = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
denormal_menu_item->set_active (_route->denormal_protection());
}
/* Disk I/O */
if (active && is_track()) {
items.push_back (SeparatorElem());
Gtk::Menu* dio_menu = new Menu;
MenuList& dio_items = dio_menu->items();
dio_items.push_back (MenuElem (_("Record Pre-Fader"), sigc::bind (sigc::mem_fun (*this, &RouteUI::set_disk_io_point), DiskIOPreFader)));
dio_items.push_back (MenuElem (_("Record Post-Fader"), sigc::bind (sigc::mem_fun (*this, &RouteUI::set_disk_io_point), DiskIOPostFader)));
dio_items.push_back (MenuElem (_("Custom Record+Playback Positions"), sigc::bind (sigc::mem_fun (*this, &RouteUI::set_disk_io_point), DiskIOCustom)));
items.push_back (MenuElem (_("Disk I/O..."), *dio_menu));
}
/* MIDI */
if (active && (std::dynamic_pointer_cast<MidiTrack>(_route) || _route->the_instrument ())) { if (active && (std::dynamic_pointer_cast<MidiTrack>(_route) || _route->the_instrument ())) {
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Patch Selector..."), items.push_back (MenuElem (_("Patch Selector..."),
sigc::mem_fun(*this, &RouteUI::select_midi_patch))); sigc::mem_fun(*this, &RouteUI::select_midi_patch)));
} }
@ -1142,13 +1156,8 @@ MixerStrip::build_route_ops_menu ()
// TODO ..->n_audio() > 1 && separate_output_groups) hard to check here every time. // TODO ..->n_audio() > 1 && separate_output_groups) hard to check here every time.
items.push_back (MenuElem (_("Fan out to Busses"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), true, true))); items.push_back (MenuElem (_("Fan out to Busses"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), true, true)));
items.push_back (MenuElem (_("Fan out to Tracks"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), false, true))); items.push_back (MenuElem (_("Fan out to Tracks"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), false, true)));
items.push_back (SeparatorElem());
} }
items.push_back (CheckMenuElem (_("Protect Against Denormals"), sigc::mem_fun (*this, &RouteUI::toggle_denormal_protection)));
denormal_menu_item = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
denormal_menu_item->set_active (_route->denormal_protection());
/* note that this relies on selection being shared across editor and /* note that this relies on selection being shared across editor and
* mixer (or global to the backend, in the future), which is the only * mixer (or global to the backend, in the future), which is the only
* sane thing for users anyway. * sane thing for users anyway.

View file

@ -326,6 +326,7 @@ RouteTimeAxisView::set_route (std::shared_ptr<Route> rt)
plist->add (ARDOUR::Properties::group_mute, true); plist->add (ARDOUR::Properties::group_mute, true);
plist->add (ARDOUR::Properties::group_solo, true); plist->add (ARDOUR::Properties::group_solo, true);
delete route_group_menu;
route_group_menu = new RouteGroupMenu (_session, plist); route_group_menu = new RouteGroupMenu (_session, plist);
gm.get_level_meter().signal_scroll_event().connect (sigc::mem_fun (*this, &RouteTimeAxisView::controls_ebox_scroll), false); gm.get_level_meter().signal_scroll_event().connect (sigc::mem_fun (*this, &RouteTimeAxisView::controls_ebox_scroll), false);
@ -406,6 +407,7 @@ RouteTimeAxisView::route_group_click (GdkEventButton *ev)
WeakRouteList r; WeakRouteList r;
r.push_back (route ()); r.push_back (route ());
route_group_menu->detach ();
route_group_menu->build (r); route_group_menu->build (r);
if (ev->button == 1) { if (ev->button == 1) {
Gtkmm2ext::anchored_menu_popup(route_group_menu->menu(), Gtkmm2ext::anchored_menu_popup(route_group_menu->menu(),
@ -630,10 +632,12 @@ RouteTimeAxisView::build_display_menu ()
TimeAxisView::build_display_menu (); TimeAxisView::build_display_menu ();
/* now fill it with our stuff */ bool active = _route->active ();
MenuList& items = display_menu->items(); MenuList& items = display_menu->items();
/* now fill it with our stuff */
if (active) {
items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color)));
items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor)));
@ -648,10 +652,11 @@ RouteTimeAxisView::build_display_menu ()
items.push_back (MenuElem (_("Height"), *_size_menu)); items.push_back (MenuElem (_("Height"), *_size_menu));
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
// Hook for derived classes to add type specific stuff /* Hook for derived classes to add type specific stuff */
append_extra_display_menu_items (); append_extra_display_menu_items ();
}
if (is_track()) { if (active && is_track()) {
Menu* layers_menu = manage (new Menu); Menu* layers_menu = manage (new Menu);
MenuList &layers_items = layers_menu->items(); MenuList &layers_items = layers_menu->items();
@ -795,8 +800,8 @@ RouteTimeAxisView::build_display_menu ()
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
} }
route_group_menu->detach ();
if (active) {
WeakRouteList r; WeakRouteList r;
for (TrackSelection::iterator i = _editor.get_selection().tracks.begin(); i != _editor.get_selection().tracks.end(); ++i) { for (TrackSelection::iterator i = _editor.get_selection().tracks.begin(); i != _editor.get_selection().tracks.end(); ++i) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i); RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
@ -810,17 +815,19 @@ RouteTimeAxisView::build_display_menu ()
} }
if (!_route->is_singleton ()) { if (!_route->is_singleton ()) {
route_group_menu->detach ();
route_group_menu->build (r); route_group_menu->build (r);
items.push_back (MenuElem (_("Group"), *route_group_menu->menu ())); items.push_back (MenuElem (_("Group"), *route_group_menu->menu ()));
} }
build_automation_action_menu (true); build_automation_action_menu (true);
items.push_back (MenuElem (_("Automation"), *automation_action_menu)); items.push_back (MenuElem (_("Automation"), *automation_action_menu));
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
}
int active = 0;
int inactive = 0; int n_active = 0;
int n_inactive = 0;
bool always_active = false; bool always_active = false;
TrackSelection const & s = _editor.get_selection().tracks; TrackSelection const & s = _editor.get_selection().tracks;
for (TrackSelection::const_iterator i = s.begin(); i != s.end(); ++i) { for (TrackSelection::const_iterator i = s.begin(); i != s.end(); ++i) {
@ -833,9 +840,9 @@ RouteTimeAxisView::build_display_menu ()
always_active |= r->route()->mixbus() != 0; always_active |= r->route()->mixbus() != 0;
#endif #endif
if (r->route()->active()) { if (r->route()->active()) {
++active; ++n_active;
} else { } else {
++inactive; ++n_inactive;
} }
} }
@ -876,10 +883,10 @@ RouteTimeAxisView::build_display_menu ()
items.push_back (CheckMenuElem (_("Active"))); items.push_back (CheckMenuElem (_("Active")));
i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back()); i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
bool click_sets_active = true; bool click_sets_active = true;
if (active > 0 && inactive == 0) { if (n_active > 0 && n_inactive == 0) {
i->set_active (true); i->set_active (true);
click_sets_active = false; click_sets_active = false;
} else if (active > 0 && inactive > 0) { } else if (n_active > 0 && n_inactive > 0) {
i->set_inconsistent (true); i->set_inconsistent (true);
} }
i->set_sensitive(! _session->transport_rolling() && ! always_active); i->set_sensitive(! _session->transport_rolling() && ! always_active);
@ -888,7 +895,7 @@ RouteTimeAxisView::build_display_menu ()
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Hide"), sigc::bind (sigc::mem_fun(_editor, &PublicEditor::hide_track_in_display), this, !_editor.get_selection().tracks.empty ()))); items.push_back (MenuElem (_("Hide"), sigc::bind (sigc::mem_fun(_editor, &PublicEditor::hide_track_in_display), this, !_editor.get_selection().tracks.empty ())));
if (_route && !_route->is_singleton ()) { if (active && _route && !_route->is_singleton ()) {
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Duplicate..."), boost::bind (&ARDOUR_UI::start_duplicate_routes, ARDOUR_UI::instance()))); items.push_back (MenuElem (_("Duplicate..."), boost::bind (&ARDOUR_UI::start_duplicate_routes, ARDOUR_UI::instance())));

View file

@ -258,8 +258,6 @@ TriggerStrip::build_route_ops_menu ()
/* do not allow rename if the track is record-enabled */ /* do not allow rename if the track is record-enabled */
items.back().set_sensitive (!is_track() || !track()->rec_enable_control()->get_value()); items.back().set_sensitive (!is_track() || !track()->rec_enable_control()->get_value());
} }
items.push_back (SeparatorElem());
} }
if ((!_route->is_singleton () || !active) if ((!_route->is_singleton () || !active)
@ -268,11 +266,18 @@ TriggerStrip::build_route_ops_menu ()
#endif #endif
) )
{ {
if (active) {
items.push_back (SeparatorElem());
}
items.push_back (CheckMenuElem (_("Active"))); items.push_back (CheckMenuElem (_("Active")));
Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back()); Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
i->set_active (active); i->set_active (active);
i->set_sensitive (!_session->transport_rolling()); i->set_sensitive (!_session->transport_rolling());
i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), !_route->active(), false)); i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), !_route->active(), false));
}
/* Plugin / Processor related */
if (active) {
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
} }
@ -286,12 +291,20 @@ TriggerStrip::build_route_ops_menu ()
uint32_t plugin_insert_cnt = 0; uint32_t plugin_insert_cnt = 0;
_route->foreach_processor (boost::bind (RouteUI::help_count_plugins, _1, & plugin_insert_cnt)); _route->foreach_processor (boost::bind (RouteUI::help_count_plugins, _1, & plugin_insert_cnt));
if (active && plugin_insert_cnt > 0) { if (active && plugin_insert_cnt > 0) {
items.push_back (MenuElem (_("Pin Connections..."), sigc::mem_fun (*this, &RouteUI::manage_pins))); items.push_back (MenuElem (_("Pin Connections..."), sigc::mem_fun (*this, &RouteUI::manage_pins)));
} }
if (active) {
items.push_back (CheckMenuElem (_("Protect Against Denormals"), sigc::mem_fun (*this, &RouteUI::toggle_denormal_protection)));
denormal_menu_item = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
denormal_menu_item->set_active (_route->denormal_protection());
}
/* MIDI */
if (active && (std::dynamic_pointer_cast<MidiTrack>(_route) || _route->the_instrument ())) { if (active && (std::dynamic_pointer_cast<MidiTrack>(_route) || _route->the_instrument ())) {
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Patch Selector..."), items.push_back (MenuElem (_("Patch Selector..."),
sigc::mem_fun(*this, &RouteUI::select_midi_patch))); sigc::mem_fun(*this, &RouteUI::select_midi_patch)));
} }
@ -300,13 +313,8 @@ TriggerStrip::build_route_ops_menu ()
// TODO ..->n_audio() > 1 && separate_output_groups) hard to check here every time. // TODO ..->n_audio() > 1 && separate_output_groups) hard to check here every time.
items.push_back (MenuElem (_("Fan out to Busses"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), true, true))); items.push_back (MenuElem (_("Fan out to Busses"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), true, true)));
items.push_back (MenuElem (_("Fan out to Tracks"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), false, true))); items.push_back (MenuElem (_("Fan out to Tracks"), sigc::bind (sigc::mem_fun (*this, &RouteUI::fan_out), false, true)));
items.push_back (SeparatorElem());
} }
items.push_back (CheckMenuElem (_("Protect Against Denormals"), sigc::mem_fun (*this, &RouteUI::toggle_denormal_protection)));
denormal_menu_item = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
denormal_menu_item->set_active (_route->denormal_protection());
/* note that this relies on selection being shared across editor and /* note that this relies on selection being shared across editor and
* mixer (or global to the backend, in the future), which is the only * mixer (or global to the backend, in the future), which is the only
* sane thing for users anyway. * sane thing for users anyway.