From e1b2b72e3a8aa386274aae66e262e3dce5b73248 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 16 Apr 2025 18:53:13 -0300 Subject: [PATCH] Fixing navigation of mods menu. --- include/recomp_ui.h | 1 + src/ui/ui_config.cpp | 81 ++++++++++++++++++++------------- src/ui/ui_mod_details_panel.cpp | 15 ++++++ src/ui/ui_mod_menu.cpp | 35 +++++++++----- 4 files changed, 89 insertions(+), 43 deletions(-) diff --git a/include/recomp_ui.h b/include/recomp_ui.h index 9f23bec..a3ac45b 100644 --- a/include/recomp_ui.h +++ b/include/recomp_ui.h @@ -69,6 +69,7 @@ namespace recompui { }; void set_config_tab(ConfigTab tab); + Rml::ElementTabSet* get_config_tab(); enum class ButtonVariant { Primary, diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp index 4ca933e..6f38a7f 100644 --- a/src/ui/ui_config.cpp +++ b/src/ui/ui_config.cpp @@ -22,6 +22,26 @@ Rml::DataModelHandle sound_options_model_handle; // True if controller config menu is open, false if keyboard config menu is open, undefined otherwise bool configuring_controller = false; +static int config_tab_to_index(recompui::ConfigTab tab) { + switch (tab) { + case recompui::ConfigTab::General: + return 0; + case recompui::ConfigTab::Controls: + return 1; + case recompui::ConfigTab::Graphics: + return 2; + case recompui::ConfigTab::Sound: + return 3; + case recompui::ConfigTab::Mods: + return 4; + case recompui::ConfigTab::Debug: + return 5; + default: + assert(false && "Unknown config tab."); + return 0; + } +} + template void get_option(const T& input, Rml::Variant& output) { std::string value = ""; @@ -522,6 +542,25 @@ public: [](const std::string& param, Rml::Event& event) { zelda64::set_time(debug_context.set_time_day, debug_context.set_time_hour, debug_context.set_time_minute); }); + +#if 0 + class TabChangeListener : public Rml::EventListener { + void ProcessEvent(Rml::Event &event) override { + int new_tab_index = event.GetParameter("tab_index", 0); + if (new_tab_index == config_tab_to_index(recompui::ConfigTab::Mods)) { + // Hook up this element to the mods menu's first list entry. + recompui::get_config_tab()->SetProperty(Rml::PropertyId::NavDown, Rml::Style::Nav::None); + } + else { + // Revert the navigation to auto. + recompui::get_config_tab()->SetProperty(Rml::PropertyId::NavDown, Rml::Style::Nav::None); + } + } + }; + + static TabChangeListener tab_change_listener; + recompui::get_config_tab()->AddEventListener(Rml::EventId::Tabchange, &tab_change_listener); +#endif } void bind_config_list_events(Rml::DataModelConstructor &constructor) { @@ -957,42 +996,20 @@ void recompui::toggle_fullscreen() { } void recompui::set_config_tab(ConfigTab tab) { + get_config_tab()->SetActiveTab(config_tab_to_index(tab)); +} + +Rml::ElementTabSet* recompui::get_config_tab() { ContextId config_context = recompui::get_config_context_id(); - - Rml::ElementDocument* doc = config_context.get_document(); + + Rml::ElementDocument *doc = config_context.get_document(); assert(doc != nullptr); - Rml::Element* tabset_el = doc->GetElementById("config_tabset"); + Rml::Element *tabset_el = doc->GetElementById("config_tabset"); assert(tabset_el != nullptr); - Rml::ElementTabSet* tabset = rmlui_dynamic_cast(tabset_el); + Rml::ElementTabSet *tabset = rmlui_dynamic_cast(tabset_el); assert(tabset != nullptr); - int tab_index = 0; - - switch (tab) { - case ConfigTab::General: - tab_index = 0; - break; - case ConfigTab::Controls: - tab_index = 1; - break; - case ConfigTab::Graphics: - tab_index = 2; - break; - case ConfigTab::Sound: - tab_index = 3; - break; - case ConfigTab::Mods: - tab_index = 4; - break; - case ConfigTab::Debug: - tab_index = 5; - break; - default: - assert(false); - return; - } - - tabset->SetActiveTab(tab_index); -} + return tabset; +} \ No newline at end of file diff --git a/src/ui/ui_mod_details_panel.cpp b/src/ui/ui_mod_details_panel.cpp index 85df6b0..9606ca3 100644 --- a/src/ui/ui_mod_details_panel.cpp +++ b/src/ui/ui_mod_details_panel.cpp @@ -105,6 +105,13 @@ void ModDetailsPanel::set_mod_details(const recomp::mods::ModDetails& details, c enable_toggle->set_enabled(toggle_enabled); configure_button->set_enabled(configure_enabled); enable_label->set_display(toggle_label_visible ? Display::Block : Display::None); + + if (configure_enabled) { + enable_toggle->set_nav(NavDirection::Right, configure_button); + } + else { + enable_toggle->set_nav_none(NavDirection::Right); + } } void ModDetailsPanel::set_mod_toggled_callback(std::function callback) { @@ -117,10 +124,18 @@ void ModDetailsPanel::set_mod_configure_pressed_callback(std::function c void ModDetailsPanel::setup_mod_navigation(Element* nav_target) { enable_toggle->set_nav(NavDirection::Left, nav_target); + + if (enable_toggle->is_enabled()) { + configure_button->set_nav(NavDirection::Left, enable_toggle); + } + else { + configure_button->set_nav(NavDirection::Left, nav_target); + } } void ModDetailsPanel::clear_mod_navigation() { enable_toggle->set_nav_none(NavDirection::Left); + configure_button->set_nav_none(NavDirection::Left); } void ModDetailsPanel::enable_toggle_checked(bool checked) { diff --git a/src/ui/ui_mod_menu.cpp b/src/ui/ui_mod_menu.cpp index d31738a..85f6a2b 100644 --- a/src/ui/ui_mod_menu.cpp +++ b/src/ui/ui_mod_menu.cpp @@ -288,13 +288,15 @@ void ModMenu::mod_selected(uint32_t mod_index) { mod_entry_buttons[active_mod_index]->set_selected(true); mod_details_panel->setup_mod_navigation(mod_entry_buttons[mod_index]); + + // Navigation from the bottom bar. + Button *configure_button = mod_details_panel->get_configure_button(); + Toggle *enable_toggle = mod_details_panel->get_enable_toggle(); if (configure_enabled) { - Button* configure_button = mod_details_panel->get_configure_button(); refresh_button->set_nav(NavDirection::Up, configure_button); mods_folder_button->set_nav(NavDirection::Up, configure_button); } else if (toggle_enabled) { - Toggle* enable_toggle = mod_details_panel->get_enable_toggle(); refresh_button->set_nav(NavDirection::Up, enable_toggle); mods_folder_button->set_nav(NavDirection::Up, enable_toggle); } @@ -302,6 +304,17 @@ void ModMenu::mod_selected(uint32_t mod_index) { refresh_button->set_nav_manual(NavDirection::Up, mod_tab_id); mods_folder_button->set_nav_manual(NavDirection::Up, mod_tab_id); } + + // Navigation from the mod list. + if (toggle_enabled) { + mod_entry_buttons[active_mod_index]->set_nav(NavDirection::Right, enable_toggle); + } + else if (configure_enabled) { + mod_entry_buttons[active_mod_index]->set_nav(NavDirection::Right, configure_button); + } + else { + mod_entry_buttons[active_mod_index]->set_nav_none(NavDirection::Right); + } } } @@ -534,16 +547,18 @@ void ModMenu::create_mod_list() { mod_entry->set_mod_details(mod_details[mod_index]); mod_entry->set_mod_thumbnail(thumbnail_name); mod_entry->set_mod_enabled(is_mod_enabled_or_auto(mod_details[mod_index].mod_id)); - mod_entry->set_nav(NavDirection::Right, enable_toggle); - if (mod_index == 0) { - mod_entry->set_nav_manual(NavDirection::Up, mod_tab_id); - } - if (mod_index == mod_details.size() - 1) { - mod_entry->set_nav(NavDirection::Down, install_mods_button); - } mod_entry_buttons.emplace_back(mod_entry); } + if (!mod_entry_buttons.empty()) { + mod_entry_buttons.front()->set_nav_manual(NavDirection::Up, mod_tab_id); + mod_entry_buttons.back()->set_nav(NavDirection::Down, install_mods_button); + install_mods_button->set_nav(NavDirection::Up, mod_entry_buttons.back()); + } + else { + install_mods_button->set_nav_manual(NavDirection::Up, mod_tab_id); + } + // Add one extra spacer at the bottom. ModEntrySpacer *spacer = context.create_element(list_scroll_container); mod_entry_spacers.emplace_back(spacer); @@ -633,11 +648,9 @@ ModMenu::ModMenu(Element *parent) : Element(parent) { footer_container->set_border_bottom_left_radius(16.0f); footer_container->set_border_bottom_right_radius(16.0f); { - Toggle* enable_toggle = mod_details_panel->get_enable_toggle(); Button* configure_button = mod_details_panel->get_configure_button(); install_mods_button = context.create_element