use Gtkmm2ext::BindingSet for the GUI

This commit is contained in:
Paul Davis 2025-03-10 18:49:02 -06:00
parent effe0bd879
commit 801099e057
14 changed files with 76 additions and 61 deletions

View file

@ -844,7 +844,7 @@ private:
ArdourWidgets::ArdourButton recorder_visibility_button;
ArdourWidgets::ArdourButton trigger_page_visibility_button;
bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::Bindings*);
bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::BindingSet*);
bool try_gtk_accel_binding (GtkWindow* win, GdkEventKey* ev, bool translate, GdkModifierType modifier);
bool main_window_delete_event (GdkEventAny*);

View file

@ -54,7 +54,7 @@ using namespace std;
bool
ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* event_window)
{
Gtkmm2ext::Bindings* bindings = 0;
Gtkmm2ext::BindingSet* bindings = nullptr;
Gtk::Window* window = 0;
if (virtual_keyboard_window && virtual_keyboard_window->get_visible()) {
@ -82,7 +82,7 @@ ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* event_window)
/* see if it uses the ardour binding system */
if (w) {
bindings = reinterpret_cast<Gtkmm2ext::Bindings*>(w->get_data ("ardour-bindings"));
bindings = reinterpret_cast<Gtkmm2ext::BindingSet*>(w->get_data ("ardour-bindings"));
}
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("main window key event, bindings = %1, global = %2\n", bindings, &global_bindings));
@ -93,19 +93,19 @@ ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* event_window)
/* see if window uses ardour binding system */
bindings = reinterpret_cast<Gtkmm2ext::Bindings*>(window->get_data ("ardour-bindings"));
bindings = reinterpret_cast<Gtkmm2ext::BindingSet*>(window->get_data ("ardour-bindings"));
}
/* An empty binding set is treated as if it doesn't exist */
if (bindings && bindings->empty()) {
bindings = 0;
bindings = nullptr;
}
return key_press_focus_accelerator_handler (*window, ev, bindings);
}
static Gtkmm2ext::Bindings*
static Gtkmm2ext::BindingSet*
get_bindings_from_widget_hierarchy (GtkWidget** w)
{
void* p = NULL;
@ -117,11 +117,11 @@ get_bindings_from_widget_hierarchy (GtkWidget** w)
*w = gtk_widget_get_parent (*w);
}
return reinterpret_cast<Gtkmm2ext::Bindings*> (p);
return reinterpret_cast<Gtkmm2ext::BindingSet*> (p);
}
bool
ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::Bindings* top_level_bindings)
ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::BindingSet* top_level_bindings)
{
GtkWindow* win = window.gobj();
GtkWidget* focus = gtk_window_get_focus (win);
@ -214,14 +214,17 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
while (focus) {
Gtkmm2ext::Bindings* focus_bindings = get_bindings_from_widget_hierarchy (&focus);
Gtkmm2ext::BindingSet* focus_bindings = get_bindings_from_widget_hierarchy (&focus);
if (focus_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing widget (%3) bindings %1 @ %2 for this event\n", focus_bindings->name(), focus_bindings, gtk_widget_get_name (focus)));
if (focus_bindings->activate (k, Bindings::Press)) {
for (auto & bindings : *focus_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing widget (%3) bindings %1 @ %2 for this event\n", bindings->name(), bindings, gtk_widget_get_name (focus)));
if (bindings->activate (k, Bindings::Press)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
}
}
if (focus) {
focus = gtk_widget_get_parent (focus);
@ -233,13 +236,15 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
*/
if (top_level_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing top level bindings %1 @ %2 for this event\n", top_level_bindings->name(), top_level_bindings));
}
for (auto & tlb : *top_level_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing top level bindings %1 @ %2 for this event\n", tlb->name(), tlb));
if (top_level_bindings && top_level_bindings->activate (k, Bindings::Press)) {
if (tlb->activate (k, Bindings::Press)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
}
}
/* Use any global bindings */
@ -273,14 +278,16 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
while (focus) {
Gtkmm2ext::Bindings* focus_bindings = get_bindings_from_widget_hierarchy (&focus);
Gtkmm2ext::BindingSet* focus_bindings = get_bindings_from_widget_hierarchy (&focus);
if (focus_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\t(nomod) using widget (%3) bindings %1 @ %2 for this event\n", focus_bindings->name(), focus_bindings, gtk_widget_get_name (focus)));
if (focus_bindings->activate (k, Bindings::Press)) {
for (auto & bindings : *focus_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\t(nomod) using widget (%3) bindings %1 @ %2 for this event\n", bindings->name(), bindings, gtk_widget_get_name (focus)));
if (bindings->activate (k, Bindings::Press)) {
return true;
}
}
}
if (focus) {
focus = gtk_widget_get_parent (focus);
@ -292,13 +299,15 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
*/
if (top_level_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\t(nomod) using top level bindings %1 @ %2 for this event\n", top_level_bindings->name(), top_level_bindings));
}
for (auto & tlb : *top_level_bindings) {
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\t(nomod)using top level bindings %1 @ %2 for this event\n", tlb->name(), tlb));
if (top_level_bindings && top_level_bindings->activate (k, Bindings::Press)) {
if (tlb->activate (k, Bindings::Press)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
}
}
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tnot yet handled, try global bindings (%1)\n", global_bindings));

View file

@ -155,7 +155,7 @@ EditingContext::EditingContext (std::string const & name)
, quantize_dialog (nullptr)
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
, bindings (nullptr)
, own_bindings (nullptr)
, mouse_mode (MouseObject)
, visual_change_queued (false)
, autoscroll_horizontal_allowed (false)
@ -2406,7 +2406,7 @@ EditingContext::register_grid_actions ()
ActionManager::register_action (editor_actions, X_("next-grid-choice"), _("Next Quantize Grid Choice"), sigc::mem_fun (*this, &EditingContext::next_grid_choice));
ActionManager::register_action (editor_actions, X_("prev-grid-choice"), _("Previous Quantize Grid Choice"), sigc::mem_fun (*this, &EditingContext::prev_grid_choice));
snap_actions = ActionManager::create_action_group (bindings, editor_name() + X_("Snap"));
snap_actions = ActionManager::create_action_group (own_bindings, editor_name() + X_("Snap"));
RadioAction::Group grid_choice_group;
ActionManager::register_radio_action (snap_actions, grid_choice_group, X_("grid-type-thirtyseconds"), grid_type_strings[(int)GridTypeBeatDiv32].c_str(), (sigc::bind (sigc::mem_fun(*this, &EditingContext::grid_type_chosen), Editing::GridTypeBeatDiv32)));
@ -3294,15 +3294,16 @@ EditingContext::load_shared_bindings ()
Bindings* midi_bindings = Bindings::get_bindings (X_("MIDI"));
register_midi_actions (midi_bindings);
Bindings* shared_bindings = Bindings::get_bindings (_name);
Bindings* shared_bindings = Bindings::get_bindings (X_("Editing"));
register_common_actions (shared_bindings);
/* Give this editing context the chance to add more mode mode actions */
add_mouse_mode_actions (_common_actions);
/* Attach bindings to the canvas for this editing context */
get_canvas()->set_data ("ardour-bindings", midi_bindings);
get_canvas_viewport()->set_data ("ardour-bindings", shared_bindings);
bindings.push_back (midi_bindings);
bindings.push_back (shared_bindings);
}
void

View file

@ -478,8 +478,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
void copy ();
void alt_delete_ ();
Gtkmm2ext::Bindings* get_bindings() const { return bindings; }
virtual void update_grid ();
protected:
@ -703,7 +701,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider
void pack_draw_box ();
void pack_snap_box ();
Gtkmm2ext::Bindings* bindings;
Gtkmm2ext::BindingSet bindings;
Gtkmm2ext::Bindings* own_bindings;
Editing::MouseMode mouse_mode;

View file

@ -732,6 +732,7 @@ Editor::enter (GdkEventCrossing*)
Editor::~Editor()
{
delete own_bindings;
delete tempo_marker_menu;
delete meter_marker_menu;
delete marker_menu;
@ -5688,7 +5689,7 @@ Editor::use_own_window (bool and_fill_it)
// win->signal_realize().connect (*this, &Editor::on_realize);
win->signal_event().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), win));
win->signal_event().connect (sigc::mem_fun (*this, &Editor::generic_event_handler));
win->set_data ("ardour-bindings", bindings);
set_widget_bindings (*win, bindings, ARDOUR_BINDING_KEY);
update_title ();
}

View file

@ -93,8 +93,8 @@ Editor::register_actions ()
{
RefPtr<Action> act;
editor_actions = ActionManager::create_action_group (bindings, X_("Editor"));
editor_menu_actions = ActionManager::create_action_group (bindings, X_("EditorMenu"));
editor_actions = ActionManager::create_action_group (own_bindings, X_("Editor"));
editor_menu_actions = ActionManager::create_action_group (own_bindings, X_("EditorMenu"));
/* non-operative menu items for menu bar */
@ -524,7 +524,7 @@ Editor::register_actions ()
toggle_reg_sens (editor_actions, "sound-midi-notes", _("Sound Selected MIDI Notes"), sigc::mem_fun (*this, &Editor::toggle_sound_midi_notes));
Glib::RefPtr<ActionGroup> marker_click_actions = ActionManager::create_action_group (bindings, X_("MarkerClickBehavior"));
Glib::RefPtr<ActionGroup> marker_click_actions = ActionManager::create_action_group (own_bindings, X_("MarkerClickBehavior"));
RadioAction::Group marker_click_group;
radio_reg_sens (marker_click_actions, marker_click_group, "marker-click-select-only", _("Marker Click Only Selects"), sigc::bind (sigc::mem_fun(*this, &Editor::marker_click_behavior_chosen), Editing::MarkerClickSelectOnly));
@ -532,7 +532,7 @@ Editor::register_actions ()
radio_reg_sens (marker_click_actions, marker_click_group, "marker-click-locate-when-stopped", _("Locate To Marker When Transport Is Not Rolling "), sigc::bind (sigc::mem_fun(*this, &Editor::marker_click_behavior_chosen), Editing::MarkerClickLocateWhenStopped));
ActionManager::register_action (editor_actions, X_("cycle-marker-click-behavior"), _("Next Marker Click Mode"), sigc::mem_fun (*this, &Editor::cycle_marker_click_behavior));
Glib::RefPtr<ActionGroup> lua_script_actions = ActionManager::create_action_group (bindings, X_("LuaAction"));
Glib::RefPtr<ActionGroup> lua_script_actions = ActionManager::create_action_group (own_bindings, X_("LuaAction"));
for (int i = 1; i <= MAX_LUA_ACTION_SCRIPTS; ++i) {
string const a = string_compose (X_("script-%1"), i);
@ -569,7 +569,7 @@ Editor::register_actions ()
/* RULERS */
Glib::RefPtr<ActionGroup> ruler_actions = ActionManager::create_action_group (bindings, X_("Rulers"));
Glib::RefPtr<ActionGroup> ruler_actions = ActionManager::create_action_group (own_bindings, X_("Rulers"));
ruler_minsec_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-minsec-ruler"), _("Mins:Secs"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_timecode_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-timecode-ruler"), _("Timecode"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_samples_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-samples-ruler"), _("Samples"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
@ -642,7 +642,7 @@ Editor::register_actions ()
/* REGION LIST */
Glib::RefPtr<ActionGroup> rl_actions = ActionManager::create_action_group (bindings, X_("RegionList"));
Glib::RefPtr<ActionGroup> rl_actions = ActionManager::create_action_group (own_bindings, X_("RegionList"));
RadioAction::Group sort_type_group;
RadioAction::Group sort_order_group;
@ -749,10 +749,10 @@ Editor::trigger_script_by_name (const std::string script_name, const std::string
void
Editor::load_bindings ()
{
bindings = Bindings::get_bindings (editor_name());
contents().set_data ("ardour-bindings", bindings);
own_bindings = Bindings::get_bindings (editor_name());
EditingContext::load_shared_bindings ();
bindings.push_back (own_bindings);
set_widget_bindings (contents(), bindings, Gtkmm2ext::ARDOUR_BINDING_KEY);
}
void
@ -1122,7 +1122,7 @@ Editor::reset_canvas_action_sensitivity (bool onoff)
void
Editor::register_region_actions ()
{
_region_actions = ActionManager::create_action_group (bindings, X_("Region"));
_region_actions = ActionManager::create_action_group (own_bindings, X_("Region"));
/* PART 1: actions that operate on the selection, and for which the edit point type and location is irrelevant */

View file

@ -162,7 +162,7 @@ Mixer_UI::Mixer_UI ()
Glib::RefPtr<ToggleAction> fb_act = ActionManager::get_toggle_action ("Mixer", "ToggleFoldbackStrip");
fb_act->set_sensitive (false);
contents().set_data ("ardour-bindings", bindings);
set_widget_bindings (contents(), *bindings, "ardour-bindings");
PresentationInfo::Change.connect (*this, invalidator (*this), std::bind (&Mixer_UI::presentation_info_changed, this, _1), gui_context());
Route::FanOut.connect (*this, invalidator (*this), std::bind (&Mixer_UI::fan_out, this, _1, false, true), gui_context());
@ -494,7 +494,7 @@ Mixer_UI::use_own_window (bool and_fill_it)
win->set_name ("MixerWindow");
ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Mixer"), this);
win->signal_event().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), win));
win->set_data ("ardour-bindings", bindings);
set_widget_bindings (*win, *bindings, "ardour-bindings");
update_title ();
if (!win->get_focus()) {
/* set focus widget to something, anything */

View file

@ -107,7 +107,7 @@ MonitorSection::MonitorSection ()
load_bindings ();
register_actions ();
set_data ("ardour-bindings", bindings);
set_widget_bindings (*this, *bindings, ARDOUR_BINDING_KEY);
channel_size_group = SizeGroup::create (SIZE_GROUP_HORIZONTAL);

View file

@ -99,7 +99,7 @@ Pianoroll::Pianoroll (std::string const & name)
Pianoroll::~Pianoroll ()
{
delete bindings;
delete own_bindings;
ActionManager::drop_action_group (editor_actions);
ActionManager::drop_action_group (snap_actions);
}
@ -114,14 +114,16 @@ Pianoroll::enter (GdkEventCrossing*)
void
Pianoroll::load_bindings ()
{
bindings = Bindings::get_bindings (editor_name());
own_bindings = Bindings::get_bindings (editor_name());
load_shared_bindings ();
bindings.push_back (own_bindings);
set_widget_bindings (*get_canvas(), bindings, ARDOUR_BINDING_KEY);
}
void
Pianoroll::register_actions ()
{
editor_actions = ActionManager::create_action_group (bindings, editor_name());
editor_actions = ActionManager::create_action_group (own_bindings, editor_name());
bind_mouse_mode_buttons ();
register_grid_actions ();
@ -425,7 +427,7 @@ Pianoroll::build_upper_toolbar ()
_toolbox.pack_start (*_toolbar_outer, false, false);
Bindings* pr_bindings = Bindings::get_bindings (X_("Pianoroll"));
_toolbox.set_data (X_("ardour-bindings"), pr_bindings);
set_widget_bindings (_toolbox, *pr_bindings, ARDOUR_BINDING_KEY);
_contents.add (_toolbox);
_contents.signal_enter_notify_event().connect (sigc::mem_fun (*this, &Pianoroll::enter), false);
@ -603,8 +605,11 @@ Pianoroll::bindings_changed ()
Bindings* midi_bindings = Bindings::get_bindings (X_("MIDI"));
Bindings* shared_bindings = Bindings::get_bindings (X_("Editing"));
_canvas_viewport->set_data (X_("ardour-bindings"), shared_bindings);
_canvas->set_data (X_("ardour-bindings"), midi_bindings);
BindingSet* bs = new BindingSet;
bs->push_back (midi_bindings);
bs->push_back (shared_bindings);
set_widget_bindings (*_canvas, *bs, ARDOUR_BINDING_KEY);
}
void

View file

@ -1957,7 +1957,7 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, std::function<PluginSelector*
* are available for context menus.
*/
processor_display.set_data ("ardour-bindings", bindings);
set_widget_bindings (processor_display, *bindings, ARDOUR_BINDING_KEY);
processor_display.SelectionAdded.connect (sigc::mem_fun (*this, &ProcessorBox::selection_added));
_width = Wide;

View file

@ -283,7 +283,7 @@ RecorderUI::RecorderUI ()
_pane.show ();
/* setup keybidings */
contents().set_data ("ardour-bindings", bindings);
set_widget_bindings (contents(), *bindings, ARDOUR_BINDING_KEY);
/* subscribe to signals */
AudioEngine::instance ()->Running.connect (_engine_connections, invalidator (*this), std::bind (&RecorderUI::start_updating, this), gui_context ());
@ -334,7 +334,7 @@ RecorderUI::use_own_window (bool and_fill_it)
win->set_name ("RecorderWindow");
ARDOUR_UI::instance ()->setup_toplevel_window (*win, _("Recorder"), this);
win->signal_event ().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), win));
win->set_data ("ardour-bindings", bindings);
set_widget_bindings (*win, *bindings, ARDOUR_BINDING_KEY);
update_title ();
#if 0 // TODO
if (!win->get_focus()) {

View file

@ -570,7 +570,7 @@ RegionEditor::RegionFxBox::RegionFxBox (std::shared_ptr<ARDOUR::Region> r)
_display.set_can_focus ();
_display.set_name ("ProcessorList");
_display.set_data ("regionfxbox", this);
_display.set_data ("ardour-bindings", bindings);
set_widget_bindings (_display, *bindings, ARDOUR_BINDING_KEY);
_display.set_size_request (104, -1); // TODO UI scale
_display.set_spacing (0);

View file

@ -90,7 +90,7 @@ StepEntry::StepEntry ()
, program_button (_("+"))
, se (0)
{
set_data ("ardour-bindings", bindings);
set_widget_bindings (*this, *bindings, "ardour-bindings");
Pango::FontDescription font (ARDOUR_UI_UTILS::sanitized_font ("ArdourSans 24"));
length_1_button.set_layout_font (font);

View file

@ -194,7 +194,7 @@ TriggerPage::TriggerPage ()
_sidebar_vbox.show_all ();
/* setup keybidings */
contents().set_data ("ardour-bindings", bindings);
set_widget_bindings (contents(), *bindings, ARDOUR_BINDING_KEY);
/* subscribe to signals */
Config->ParameterChanged.connect (*this, invalidator (*this), std::bind (&TriggerPage::parameter_changed, this, _1), gui_context ());
@ -219,7 +219,7 @@ TriggerPage::use_own_window (bool and_fill_it)
win->set_name ("TriggerWindow");
ARDOUR_UI::instance ()->setup_toplevel_window (*win, _("Cues"), this);
win->signal_event ().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), win));
win->set_data ("ardour-bindings", bindings);
set_widget_bindings (*win, *bindings, ARDOUR_BINDING_KEY);
update_title ();
#if 0 // TODO
if (!win->get_focus()) {