mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-06-03 01:58:53 -04:00
Update codebase with changes for Zelda 64: Recompiled 1.2
This commit is contained in:
+271
-44
@@ -1,5 +1,8 @@
|
||||
#include "ui_mod_menu.h"
|
||||
#include "ui_mod_menu.h"
|
||||
#include "ui_utils.h"
|
||||
#include "recomp_ui.h"
|
||||
#include "banjo_support.h"
|
||||
#include "banjo_render.h"
|
||||
|
||||
#include "librecomp/mods.hpp"
|
||||
|
||||
@@ -24,51 +27,65 @@ static bool is_mod_enabled_or_auto(const std::string &mod_id) {
|
||||
}
|
||||
|
||||
// ModEntryView
|
||||
#define COL_TEXT_DEFAULT 242, 242, 242
|
||||
#define COL_TEXT_DIM 204, 204, 204
|
||||
#define COL_SECONDARY 23, 214, 232
|
||||
constexpr float modEntryHeight = 120.0f;
|
||||
constexpr float modEntryPadding = 4.0f;
|
||||
|
||||
ModEntryView::ModEntryView(Element *parent) : Element(parent) {
|
||||
extern const std::string mod_tab_id;
|
||||
const std::string mod_tab_id = "#tab_mods";
|
||||
|
||||
ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType::Update)) {
|
||||
ContextId context = get_current_context();
|
||||
|
||||
set_display(Display::Flex);
|
||||
set_flex_direction(FlexDirection::Row);
|
||||
set_width(100.0f, Unit::Percent);
|
||||
set_height_auto();
|
||||
set_padding_top(4.0f);
|
||||
set_padding_right(8.0f);
|
||||
set_padding_bottom(4.0f);
|
||||
set_padding_left(8.0f);
|
||||
set_border_width(1.1f);
|
||||
set_border_color(Color{ 242, 242, 242, 12 });
|
||||
set_background_color(Color{ 242, 242, 242, 12 });
|
||||
set_padding(modEntryPadding);
|
||||
set_border_left_width(2.0f);
|
||||
set_border_color(Color{ COL_TEXT_DEFAULT, 12 });
|
||||
set_background_color(Color{ COL_TEXT_DEFAULT, 12 });
|
||||
set_cursor(Cursor::Pointer);
|
||||
set_color(Color{ COL_TEXT_DEFAULT, 255 });
|
||||
|
||||
checked_style.set_border_color(Color{ 242, 242, 242, 160 });
|
||||
hover_style.set_border_color(Color{ 242, 242, 242, 64 });
|
||||
checked_hover_style.set_border_color(Color{ 242, 242, 242, 204 });
|
||||
checked_style.set_border_color(Color{ COL_TEXT_DEFAULT, 160 });
|
||||
checked_style.set_color(Color{ 255, 255, 255, 255 });
|
||||
checked_style.set_background_color(Color{ 26, 24, 32, 255 });
|
||||
hover_style.set_border_color(Color{ COL_TEXT_DEFAULT, 64 });
|
||||
checked_hover_style.set_border_color(Color{ COL_TEXT_DEFAULT, 255 });
|
||||
pulsing_style.set_border_color(Color{ 23, 214, 232, 244 });
|
||||
|
||||
{
|
||||
thumbnail_image = context.create_element<Image>(this, "");
|
||||
thumbnail_image->set_width(100.0f);
|
||||
thumbnail_image->set_height(100.0f);
|
||||
thumbnail_image->set_min_width(100.0f);
|
||||
thumbnail_image->set_min_height(100.0f);
|
||||
thumbnail_image->set_width(modEntryHeight);
|
||||
thumbnail_image->set_height(modEntryHeight);
|
||||
thumbnail_image->set_min_width(modEntryHeight);
|
||||
thumbnail_image->set_min_height(modEntryHeight);
|
||||
thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 });
|
||||
|
||||
|
||||
body_container = context.create_element<Container>(this, FlexDirection::Column, JustifyContent::FlexStart);
|
||||
body_container = context.create_element<Element>(this);
|
||||
body_container->set_width_auto();
|
||||
body_container->set_height(100.0f);
|
||||
body_container->set_margin_left(16.0f);
|
||||
body_container->set_overflow(Overflow::Hidden);
|
||||
body_container->set_padding_top(8.0f);
|
||||
body_container->set_padding_bottom(8.0f);
|
||||
body_container->set_max_height(modEntryHeight);
|
||||
body_container->set_overflow_y(Overflow::Hidden);
|
||||
|
||||
{
|
||||
name_label = context.create_element<Label>(body_container, LabelStyle::Normal);
|
||||
description_label = context.create_element<Label>(body_container, LabelStyle::Small);
|
||||
description_label->set_margin_top(4.0f);
|
||||
description_label->set_color(Color{ COL_TEXT_DIM, 255 });
|
||||
} // body_container
|
||||
} // this
|
||||
|
||||
add_style(&checked_style, checked_state);
|
||||
add_style(&hover_style, hover_state);
|
||||
add_style(&checked_hover_style, { checked_state, hover_state });
|
||||
add_style(&pulsing_style, { focus_state });
|
||||
}
|
||||
|
||||
ModEntryView::~ModEntryView() {
|
||||
@@ -92,12 +109,32 @@ void ModEntryView::set_selected(bool selected) {
|
||||
set_style_enabled(checked_state, selected);
|
||||
}
|
||||
|
||||
void ModEntryView::set_focused(bool focused) {
|
||||
set_style_enabled(focus_state, focused);
|
||||
}
|
||||
|
||||
void ModEntryView::process_event(const Event &e) {
|
||||
switch (e.type) {
|
||||
case EventType::Update:
|
||||
if (is_style_enabled(focus_state)) {
|
||||
pulsing_style.set_color(recompui::get_pulse_color(750));
|
||||
apply_styles();
|
||||
queue_update();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ModEntryButton
|
||||
|
||||
ModEntryButton::ModEntryButton(Element *parent, uint32_t mod_index) : Element(parent, Events(EventType::Click, EventType::Hover, EventType::Focus, EventType::Drag)) {
|
||||
this->mod_index = mod_index;
|
||||
|
||||
set_drag(Drag::Drag);
|
||||
enable_focus();
|
||||
|
||||
ContextId context = get_current_context();
|
||||
view = context.create_element<ModEntryView>(this);
|
||||
@@ -131,16 +168,20 @@ void ModEntryButton::set_selected(bool selected) {
|
||||
view->set_selected(selected);
|
||||
}
|
||||
|
||||
void ModEntryButton::set_focused(bool focused) {
|
||||
view->set_focused(focused);
|
||||
view->queue_update();
|
||||
}
|
||||
|
||||
void ModEntryButton::process_event(const Event& e) {
|
||||
switch (e.type) {
|
||||
case EventType::Click:
|
||||
case EventType::Focus:
|
||||
selected_callback(mod_index);
|
||||
set_focused(std::get<EventFocus>(e.variant).active);
|
||||
break;
|
||||
case EventType::Hover:
|
||||
view->set_style_enabled(hover_state, std::get<EventHover>(e.variant).active);
|
||||
break;
|
||||
case EventType::Focus:
|
||||
break;
|
||||
case EventType::Drag:
|
||||
drag_callback(mod_index, std::get<EventDrag>(e.variant));
|
||||
break;
|
||||
@@ -205,13 +246,15 @@ void ModEntrySpacer::set_target_height(float target_height, bool animate_to_targ
|
||||
|
||||
// ModMenu
|
||||
|
||||
void ModMenu::refresh_mods() {
|
||||
void ModMenu::refresh_mods(bool scan_mods) {
|
||||
for (const std::string &thumbnail : loaded_thumbnails) {
|
||||
recompui::release_image(thumbnail);
|
||||
}
|
||||
|
||||
recomp::mods::scan_mods();
|
||||
mod_details = recomp::mods::get_mod_details(game_mod_id);
|
||||
if (scan_mods) {
|
||||
recomp::mods::scan_mods();
|
||||
}
|
||||
mod_details = recomp::mods::get_all_mod_details(game_mod_id);
|
||||
create_mod_list();
|
||||
}
|
||||
|
||||
@@ -221,13 +264,30 @@ void ModMenu::open_mods_folder() {
|
||||
std::wstring path_wstr = mods_directory.wstring();
|
||||
ShellExecuteW(NULL, L"open", path_wstr.c_str(), NULL, NULL, SW_SHOWDEFAULT);
|
||||
#elif defined(__linux__)
|
||||
std::string command = "xdg-open " + mods_directory.string() + " &";
|
||||
std::string command = "xdg-open \"" + mods_directory.string() + "\" &";
|
||||
std::system(command.c_str());
|
||||
#elif defined(__APPLE__)
|
||||
std::string command = "open \"" + mods_directory.string() + "\"";
|
||||
std::system(command.c_str());
|
||||
#else
|
||||
static_assert(false, "Not implemented for this platform.");
|
||||
#endif
|
||||
}
|
||||
|
||||
void ModMenu::open_install_dialog() {
|
||||
banjo::open_file_dialog_multiple([](bool success, const std::list<std::filesystem::path>& paths) {
|
||||
if (success) {
|
||||
ContextId old_context = recompui::try_close_current_context();
|
||||
|
||||
recompui::drop_files(paths);
|
||||
|
||||
if (old_context != ContextId::null()) {
|
||||
old_context.open();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ModMenu::mod_toggled(bool enabled) {
|
||||
if (active_mod_index >= 0) {
|
||||
recomp::mods::enable_mod(mod_details[active_mod_index].mod_id, enabled);
|
||||
@@ -255,11 +315,41 @@ void ModMenu::mod_selected(uint32_t mod_index) {
|
||||
bool configure_enabled = !config_schema.options.empty();
|
||||
mod_details_panel->set_mod_details(mod_details[mod_index], thumbnail_src, toggle_checked, toggle_enabled, auto_enabled, configure_enabled);
|
||||
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) {
|
||||
refresh_button->set_nav(NavDirection::Up, configure_button);
|
||||
mods_folder_button->set_nav(NavDirection::Up, configure_button);
|
||||
}
|
||||
else if (toggle_enabled) {
|
||||
refresh_button->set_nav(NavDirection::Up, enable_toggle);
|
||||
mods_folder_button->set_nav(NavDirection::Up, enable_toggle);
|
||||
}
|
||||
else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::mod_dragged(uint32_t mod_index, EventDrag drag) {
|
||||
constexpr float spacer_height = 110.0f;
|
||||
constexpr float spacer_height = modEntryHeight + modEntryPadding * 2.0f;
|
||||
|
||||
switch (drag.phase) {
|
||||
case DragPhase::Start: {
|
||||
for (size_t i = 0; i < mod_entry_buttons.size(); i++) {
|
||||
@@ -274,6 +364,7 @@ void ModMenu::mod_dragged(uint32_t mod_index, EventDrag drag) {
|
||||
float left = mod_entry_buttons[mod_index]->get_absolute_left() - get_absolute_left();
|
||||
float top = mod_entry_buttons[mod_index]->get_absolute_top() - (height / 2.0f); // TODO: Figure out why this adjustment is even necessary.
|
||||
mod_entry_buttons[mod_index]->set_display(Display::None);
|
||||
mod_entry_buttons[mod_index]->set_focused(false);
|
||||
mod_entry_floating_view->set_display(Display::Flex);
|
||||
mod_entry_floating_view->set_mod_details(mod_details[mod_index]);
|
||||
mod_entry_floating_view->set_mod_thumbnail(generate_thumbnail_src_for_mod(mod_details[mod_index].mod_id));
|
||||
@@ -332,7 +423,7 @@ void ModMenu::mod_dragged(uint32_t mod_index, EventDrag drag) {
|
||||
|
||||
// Re-order the mods and update all the details on the menu.
|
||||
recomp::mods::set_mod_index(game_mod_id, mod_details[mod_index].mod_id, mod_drag_target_index);
|
||||
mod_details = recomp::mods::get_mod_details(game_mod_id);
|
||||
mod_details = recomp::mods::get_all_mod_details(game_mod_id);
|
||||
for (size_t i = 0; i < mod_entry_buttons.size(); i++) {
|
||||
mod_entry_buttons[i]->set_mod_details(mod_details[i]);
|
||||
mod_entry_buttons[i]->set_mod_thumbnail(generate_thumbnail_src_for_mod(mod_details[i].mod_id));
|
||||
@@ -356,6 +447,22 @@ ContextId get_config_sub_menu_context_id() {
|
||||
return sub_menu_context;
|
||||
}
|
||||
|
||||
bool ModMenu::handle_special_config_options(const recomp::mods::ConfigOption& option, const recomp::mods::ConfigValueVariant& config_value) {
|
||||
if (banjo::renderer::is_texture_pack_enable_config_option(option, true)) {
|
||||
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant);
|
||||
|
||||
config_sub_menu->add_radio_option(option.id, option.name, option.description, std::get<uint32_t>(config_value), option_enum.options,
|
||||
[this](const std::string &id, uint32_t value) {
|
||||
mod_enum_option_changed(id, value);
|
||||
mod_hd_textures_enabled_changed(value);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ModMenu::mod_configure_requested() {
|
||||
if (active_mod_index >= 0) {
|
||||
// Record the context that was open when this function was called and close it.
|
||||
@@ -373,19 +480,26 @@ void ModMenu::mod_configure_requested() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handle_special_config_options(option, config_value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (option.type) {
|
||||
case recomp::mods::ConfigOptionType::Enum: {
|
||||
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant);
|
||||
config_sub_menu->add_radio_option(option.id, option.name, option.description, std::get<uint32_t>(config_value), option_enum.options, std::bind(&ModMenu::mod_enum_option_changed, this, std::placeholders::_1, std::placeholders::_2));
|
||||
config_sub_menu->add_radio_option(option.id, option.name, option.description, std::get<uint32_t>(config_value), option_enum.options,
|
||||
[this](const std::string &id, uint32_t value){ mod_enum_option_changed(id, value); });
|
||||
break;
|
||||
}
|
||||
case recomp::mods::ConfigOptionType::Number: {
|
||||
const recomp::mods::ConfigOptionNumber &option_number = std::get<recomp::mods::ConfigOptionNumber>(option.variant);
|
||||
config_sub_menu->add_slider_option(option.id, option.name, option.description, std::get<double>(config_value), option_number.min, option_number.max, option_number.step, option_number.percent, std::bind(&ModMenu::mod_number_option_changed, this, std::placeholders::_1, std::placeholders::_2));
|
||||
config_sub_menu->add_slider_option(option.id, option.name, option.description, std::get<double>(config_value), option_number.min, option_number.max, option_number.step, option_number.percent,
|
||||
[this](const std::string &id, double value){ mod_number_option_changed(id, value); });
|
||||
break;
|
||||
}
|
||||
case recomp::mods::ConfigOptionType::String: {
|
||||
config_sub_menu->add_text_option(option.id, option.name, option.description, std::get<std::string>(config_value), std::bind(&ModMenu::mod_string_option_changed, this, std::placeholders::_1, std::placeholders::_2));
|
||||
config_sub_menu->add_text_option(option.id, option.name, option.description, std::get<std::string>(config_value),
|
||||
[this](const std::string &id, const std::string &value){ mod_string_option_changed(id, value); });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -424,6 +538,17 @@ void ModMenu::mod_number_option_changed(const std::string &id, double value) {
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::mod_hd_textures_enabled_changed(uint32_t value) {
|
||||
if (active_mod_index >= 0) {
|
||||
if (value) {
|
||||
banjo::renderer::secondary_enable_texture_pack(mod_details[active_mod_index].mod_id);
|
||||
}
|
||||
else {
|
||||
banjo::renderer::secondary_disable_texture_pack(mod_details[active_mod_index].mod_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::create_mod_list() {
|
||||
ContextId context = get_current_context();
|
||||
|
||||
@@ -432,12 +557,14 @@ void ModMenu::create_mod_list() {
|
||||
mod_entry_buttons.clear();
|
||||
mod_entry_spacers.clear();
|
||||
|
||||
Toggle* enable_toggle = mod_details_panel->get_enable_toggle();
|
||||
|
||||
// Create the child elements for the list scroll.
|
||||
for (size_t mod_index = 0; mod_index < mod_details.size(); mod_index++) {
|
||||
const std::vector<char> &thumbnail = recomp::mods::get_mod_thumbnail(mod_details[mod_index].mod_id);
|
||||
std::string thumbnail_name = generate_thumbnail_src_for_mod(mod_details[mod_index].mod_id);
|
||||
if (!thumbnail.empty()) {
|
||||
recompui::queue_image_from_bytes(thumbnail_name, thumbnail);
|
||||
recompui::queue_image_from_bytes_file(thumbnail_name, thumbnail);
|
||||
loaded_thumbnails.emplace(thumbnail_name);
|
||||
}
|
||||
|
||||
@@ -445,14 +572,28 @@ void ModMenu::create_mod_list() {
|
||||
mod_entry_spacers.emplace_back(spacer);
|
||||
|
||||
ModEntryButton *mod_entry = context.create_element<ModEntryButton>(list_scroll_container, mod_index);
|
||||
mod_entry->set_mod_selected_callback(std::bind(&ModMenu::mod_selected, this, std::placeholders::_1));
|
||||
mod_entry->set_mod_drag_callback(std::bind(&ModMenu::mod_dragged, this, std::placeholders::_1, std::placeholders::_2));
|
||||
mod_entry->set_mod_selected_callback([this](uint32_t mod_index){ mod_selected(mod_index); });
|
||||
mod_entry->set_mod_drag_callback([this](uint32_t mod_index, recompui::EventDrag drag){ mod_dragged(mod_index, drag); });
|
||||
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_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);
|
||||
}
|
||||
|
||||
Rml::ElementTabSet* tabset = recompui::get_config_tabset();
|
||||
if (tabset && tabset->GetActiveTab() == recompui::config_tab_to_index(ConfigTab::Mods)) {
|
||||
recompui::set_config_tabset_mod_nav();
|
||||
}
|
||||
|
||||
// Add one extra spacer at the bottom.
|
||||
ModEntrySpacer *spacer = context.create_element<ModEntrySpacer>(list_scroll_container);
|
||||
mod_entry_spacers.emplace_back(spacer);
|
||||
@@ -467,6 +608,27 @@ void ModMenu::create_mod_list() {
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::process_event(const Event &e) {
|
||||
if (e.type == EventType::Update) {
|
||||
if (mods_dirty) {
|
||||
refresh_mods(mod_scan_queued);
|
||||
mods_dirty = false;
|
||||
mod_scan_queued = false;
|
||||
}
|
||||
if (ultramodern::is_game_started()) {
|
||||
install_mods_button->set_enabled(false);
|
||||
refresh_button->set_enabled(false);
|
||||
}
|
||||
if (active_mod_index != -1) {
|
||||
bool auto_enabled = recomp::mods::is_mod_auto_enabled(mod_details[active_mod_index].mod_id);
|
||||
bool toggle_enabled = !auto_enabled && (mod_details[active_mod_index].runtime_toggleable || !ultramodern::is_game_started());
|
||||
if (!toggle_enabled) {
|
||||
mod_details_panel->disable_toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||
game_mod_id = "bk";
|
||||
|
||||
@@ -498,8 +660,8 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||
} // list_container
|
||||
|
||||
mod_details_panel = context.create_element<ModDetailsPanel>(body_container);
|
||||
mod_details_panel->set_mod_toggled_callback(std::bind(&ModMenu::mod_toggled, this, std::placeholders::_1));
|
||||
mod_details_panel->set_mod_configure_pressed_callback(std::bind(&ModMenu::mod_configure_requested, this));
|
||||
mod_details_panel->set_mod_toggled_callback([this](bool enabled){ mod_toggled(enabled); });
|
||||
mod_details_panel->set_mod_configure_pressed_callback([this](){ mod_configure_requested(); });
|
||||
} // body_container
|
||||
|
||||
body_empty_container = context.create_element<Container>(this, FlexDirection::Column, JustifyContent::SpaceBetween);
|
||||
@@ -511,23 +673,32 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||
context.create_element<Element>(body_empty_container);
|
||||
} // body_empty_container
|
||||
|
||||
footer_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::SpaceBetween);
|
||||
footer_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::FlexStart);
|
||||
footer_container->set_width(100.0f, recompui::Unit::Percent);
|
||||
footer_container->set_align_items(recompui::AlignItems::Center);
|
||||
footer_container->set_background_color(Color{ 0, 0, 0, 89 });
|
||||
footer_container->set_border_top_width(1.1f);
|
||||
footer_container->set_border_top_color(Color{ 255, 255, 255, 25 });
|
||||
footer_container->set_padding(20.0f);
|
||||
footer_container->set_gap(20.0f);
|
||||
footer_container->set_border_bottom_left_radius(16.0f);
|
||||
footer_container->set_border_bottom_right_radius(16.0f);
|
||||
{
|
||||
refresh_button = context.create_element<Button>(footer_container, "Refresh", recompui::ButtonStyle::Primary);
|
||||
refresh_button->add_pressed_callback(std::bind(&ModMenu::refresh_mods, this));
|
||||
Button* configure_button = mod_details_panel->get_configure_button();
|
||||
install_mods_button = context.create_element<Button>(footer_container, "Install Mods", recompui::ButtonStyle::Primary);
|
||||
install_mods_button->add_pressed_callback([this](){ open_install_dialog(); });
|
||||
|
||||
context.create_element<Label>(footer_container, "⚠ UNDER CONSTRUCTION ⚠", LabelStyle::Small);
|
||||
Element* footer_spacer = context.create_element<Element>(footer_container);
|
||||
footer_spacer->set_flex(1.0f, 0.0f);
|
||||
|
||||
refresh_button = context.create_element<Button>(footer_container, "Refresh", recompui::ButtonStyle::Primary);
|
||||
refresh_button->add_pressed_callback([this](){ refresh_mods(true); });
|
||||
refresh_button->set_nav_manual(NavDirection::Up, mod_tab_id);
|
||||
|
||||
mods_folder_button = context.create_element<Button>(footer_container, "Open Mods Folder", recompui::ButtonStyle::Primary);
|
||||
mods_folder_button->add_pressed_callback(std::bind(&ModMenu::open_mods_folder, this));
|
||||
mods_folder_button->add_pressed_callback([this](){ open_mods_folder(); });
|
||||
mods_folder_button->set_nav(NavDirection::Up, configure_button);
|
||||
mods_folder_button->set_nav_manual(NavDirection::Up, mod_tab_id);
|
||||
} // footer_container
|
||||
} // this
|
||||
|
||||
@@ -536,11 +707,9 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||
mod_entry_floating_view->set_position(Position::Absolute);
|
||||
mod_entry_floating_view->set_selected(true);
|
||||
|
||||
refresh_mods();
|
||||
|
||||
context.close();
|
||||
|
||||
sub_menu_context = recompui::create_context("assets/config_sub_menu.rml");
|
||||
sub_menu_context = recompui::create_context(banjo::get_asset_path("config_sub_menu.rml"));
|
||||
sub_menu_context.open();
|
||||
Rml::ElementDocument* sub_menu_doc = sub_menu_context.get_document();
|
||||
Rml::Element* config_sub_menu_generic = sub_menu_doc->GetElementById("config_sub_menu");
|
||||
@@ -556,6 +725,64 @@ ModMenu::~ModMenu() {
|
||||
|
||||
// Placeholder class until the rest of the UI refactor is finished.
|
||||
|
||||
recompui::ModMenu* mod_menu;
|
||||
|
||||
void update_mod_list(bool scan_mods) {
|
||||
if (mod_menu) {
|
||||
recompui::ContextId ui_context = recompui::get_config_context_id();
|
||||
bool opened = ui_context.open_if_not_already();
|
||||
|
||||
mod_menu->set_mods_dirty(scan_mods);
|
||||
mod_menu->queue_update();
|
||||
|
||||
if (opened) {
|
||||
ui_context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_game_started() {
|
||||
if (mod_menu) {
|
||||
recompui::ContextId ui_context = recompui::get_config_context_id();
|
||||
bool opened = ui_context.open_if_not_already();
|
||||
|
||||
mod_menu->queue_update();
|
||||
|
||||
if (opened) {
|
||||
ui_context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_config_tabset_mod_nav() {
|
||||
if (mod_menu) {
|
||||
Rml::ElementTabSet* tabset = recompui::get_config_tabset();
|
||||
Rml::Element* tabs = recompui::get_child_by_tag(tabset, "tabs");
|
||||
if (tabs != nullptr) {
|
||||
size_t num_children = tabs->GetNumChildren();
|
||||
Element* first_mod_entry = mod_menu->get_first_mod_entry();
|
||||
if (first_mod_entry != nullptr) {
|
||||
std::string id = "#" + first_mod_entry->get_id();
|
||||
for (size_t i = 0; i < num_children; i++) {
|
||||
tabs->GetChild(i)->SetProperty(Rml::PropertyId::NavDown, Rml::Property{ id, Rml::Unit::STRING });
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < num_children; i++) {
|
||||
tabs->GetChild(i)->SetProperty(Rml::PropertyId::NavDown, Rml::Style::Nav::Auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void focus_mod_configure_button() {
|
||||
Element* configure_button = mod_menu->get_mod_configure_button();
|
||||
if (configure_button) {
|
||||
configure_button->focus();
|
||||
}
|
||||
}
|
||||
|
||||
ElementModMenu::ElementModMenu(const Rml::String &tag) : Rml::Element(tag) {
|
||||
SetProperty("width", "100%");
|
||||
SetProperty("height", "100%");
|
||||
|
||||
Reference in New Issue
Block a user