Add support for config schema.

This commit is contained in:
Dario 2025-01-19 23:33:57 -03:00 committed by Mr-Wiseguy
parent 1bd61451fa
commit 1b31f66821
6 changed files with 37 additions and 18 deletions

View File

@ -2,7 +2,6 @@
#include "recomp.h"
#include "librecomp/overlays.hpp"
#include "librecomp/config.hpp"
#include "zelda_config.h"
#include "recomp_input.h"
#include "recomp_ui.h"

View File

@ -53,11 +53,12 @@ void ConfigOptionSlider::slider_value_changed(double v) {
printf("%s changed to %f.\n", name.c_str(), v);
}
ConfigOptionSlider::ConfigOptionSlider(double value, double min_value, double max_value, Element *parent) : ConfigOptionElement(parent) {
slider = get_current_context().create_element<Slider>(SliderType::Percent, this);
ConfigOptionSlider::ConfigOptionSlider(double value, double min_value, double max_value, double step_value, bool percent, Element *parent) : ConfigOptionElement(parent) {
slider = get_current_context().create_element<Slider>(percent ? SliderType::Percent : SliderType::Double, this);
slider->set_value(value);
slider->set_min_value(min_value);
slider->set_max_value(max_value);
slider->set_step_value(step_value);
slider->add_value_changed_callback(std::bind(&ConfigOptionSlider::slider_value_changed, this, std::placeholders::_1));
}
@ -79,7 +80,7 @@ void ConfigOptionRadio::index_changed(uint32_t index) {
printf("%s changed to %d.\n", name.c_str(), index);
}
ConfigOptionRadio::ConfigOptionRadio(const std::initializer_list<std::string_view> &options, Element *parent) : ConfigOptionElement(parent) {
ConfigOptionRadio::ConfigOptionRadio(const std::vector<std::string> &options, Element *parent) : ConfigOptionElement(parent) {
radio = get_current_context().create_element<Radio>(this);
radio->add_index_changed_callback(std::bind(&ConfigOptionRadio::index_changed, this, std::placeholders::_1));
for (std::string_view option : options) {
@ -166,8 +167,8 @@ void ConfigSubMenu::add_option(ConfigOptionElement *option, std::string_view nam
config_option_elements.emplace_back(option);
}
void ConfigSubMenu::add_slider_option(std::string_view name, std::string_view description, double min, double max) {
ConfigOptionSlider *option_slider = get_current_context().create_element<ConfigOptionSlider>((min + max) / 2.0, min, max, config_scroll_container);
void ConfigSubMenu::add_slider_option(std::string_view name, std::string_view description, double min, double max, double step, bool percent) {
ConfigOptionSlider *option_slider = get_current_context().create_element<ConfigOptionSlider>((min + max) / 2.0, min, max, step, percent, config_scroll_container);
add_option(option_slider, name, description);
}
@ -176,7 +177,7 @@ void ConfigSubMenu::add_text_option(std::string_view name, std::string_view desc
add_option(option_text_input, name, description);
}
void ConfigSubMenu::add_radio_option(std::string_view name, std::string_view description, const std::initializer_list<std::string_view> &options) {
void ConfigSubMenu::add_radio_option(std::string_view name, std::string_view description, const std::vector<std::string> &options) {
ConfigOptionRadio *option_radio = get_current_context().create_element<ConfigOptionRadio>(options, config_scroll_container);
add_option(option_radio, name, description);
}

View File

@ -36,7 +36,7 @@ protected:
void slider_value_changed(double v);
public:
ConfigOptionSlider(double value, double min_value, double max_value, Element *parent);
ConfigOptionSlider(double value, double min_value, double max_value, double step_value, bool percent, Element *parent);
};
class ConfigOptionTextInput : public ConfigOptionElement {
@ -54,7 +54,7 @@ protected:
void index_changed(uint32_t index);
public:
ConfigOptionRadio(const std::initializer_list<std::string_view> &options, Element *parent);
ConfigOptionRadio(const std::vector<std::string> &options, Element *parent);
};
class ConfigSubMenu : public Element {
@ -80,9 +80,9 @@ public:
virtual ~ConfigSubMenu();
void enter(std::string_view title);
void clear_options();
void add_slider_option(std::string_view name, std::string_view description, double min, double max);
void add_slider_option(std::string_view name, std::string_view description, double min, double max, double step, bool percent);
void add_text_option(std::string_view name, std::string_view description);
void add_radio_option(std::string_view name, std::string_view description, const std::initializer_list<std::string_view> &options);
void add_radio_option(std::string_view name, std::string_view description, const std::vector<std::string> &options);
void set_enter_sub_menu_callback(std::function<void()> callback);
void set_quit_sub_menu_callback(std::function<void()> callback);
};

View File

@ -1,14 +1,13 @@
#include "ui_elements.h"
#include "librecomp/config.hpp"
struct RecompElementConfig {
struct RecompCustomElement {
Rml::String tag;
std::unique_ptr<Rml::ElementInstancer> instancer;
};
#define CUSTOM_ELEMENT(s, e) { s, std::make_unique< Rml::ElementInstancerGeneric< e > >() }
static RecompElementConfig custom_elements[] = {
static RecompCustomElement custom_elements[] = {
CUSTOM_ELEMENT("recomp-mod-menu", recompui::ElementModMenu),
CUSTOM_ELEMENT("recomp-config-sub-menu", recompui::ElementConfigSubMenu),
};

View File

@ -99,9 +99,30 @@ void ModMenu::mod_toggled(bool enabled) {
void ModMenu::mod_configure_requested() {
if (active_mod_index >= 0) {
ext_config_sub_menu->clear_options();
ext_config_sub_menu->add_slider_option("Slider Option", "Description for slider option.", 0.0, 100.0);
ext_config_sub_menu->add_text_option("Text Option", "Description for simple option.");
ext_config_sub_menu->add_radio_option("Radio Option", "Description for radio option.", { "First", "Second", "Third" });
const recomp::mods::ConfigSchema &config_schema = recomp::mods::get_mod_config_schema(mod_details[active_mod_index].mod_id);
for (const recomp::mods::ConfigOption &option : config_schema.options) {
switch (option.type) {
case recomp::mods::ConfigOptionType::Enum: {
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant);
ext_config_sub_menu->add_radio_option(option.name, option.description, option_enum.options);
break;
}
case recomp::mods::ConfigOptionType::Number: {
const recomp::mods::ConfigOptionNumber &option_number = std::get<recomp::mods::ConfigOptionNumber>(option.variant);
ext_config_sub_menu->add_slider_option(option.name, option.description, option_number.min, option_number.max, option_number.step, option_number.percent);
break;
}
case recomp::mods::ConfigOptionType::String: {
ext_config_sub_menu->add_text_option(option.name, option.description);
break;
}
default:
assert(false && "Unknown config option type.");
break;
}
}
ext_config_sub_menu->enter(mod_details[active_mod_index].mod_id);
}
}

View File

@ -23,7 +23,6 @@
#include "ui_elements.h"
#include "ui_mod_menu.h"
#include "ui_renderer.h"
#include "librecomp/config.hpp"
bool can_focus(Rml::Element* element) {
return element->GetOwnerDocument() != nullptr && element->GetProperty(Rml::PropertyId::TabIndex)->Get<Rml::Style::TabIndex>() != Rml::Style::TabIndex::None;