diff --git a/src/main/main.cpp b/src/main/main.cpp index 5cee17a..39fa02e 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -685,33 +685,6 @@ int main(int argc, char** argv) { // Register the .rtz texture pack file format with the previous content type as its only allowed content type. recomp::mods::register_mod_container_type("rtz", std::vector{ texture_pack_content_type_id }, false); - recomp::mods::scan_mods(); - - printf("Found mods:\n"); - for (const auto& mod : recomp::mods::get_mod_details("mm")) { - printf(" %s(%s)\n", mod.mod_id.c_str(), mod.version.to_string().c_str()); - if (!mod.authors.empty()) { - printf(" Authors: %s", mod.authors[0].c_str()); - for (size_t author_index = 1; author_index < mod.authors.size(); author_index++) { - const std::string& author = mod.authors[author_index]; - printf(", %s", author.c_str()); - } - printf("\n"); - printf(" Runtime toggleable: %d\n", mod.runtime_toggleable); - } - if (!mod.dependencies.empty()) { - printf(" Dependencies: %s:%s", mod.dependencies[0].mod_id.c_str(), mod.dependencies[0].version.to_string().c_str()); - for (size_t dep_index = 1; dep_index < mod.dependencies.size(); dep_index++) { - const recomp::mods::Dependency& dep = mod.dependencies[dep_index]; - printf(", %s:%s", dep.mod_id.c_str(), dep.version.to_string().c_str()); - } - printf("\n"); - } - // TODO load all mods as a temporary solution to not having a UI yet. - recomp::mods::enable_mod(mod.mod_id, true); - } - printf("\n"); - recomp::start( project_version, {}, diff --git a/src/ui/elements/ui_slider.h b/src/ui/elements/ui_slider.h index 60fdb18..a358db7 100644 --- a/src/ui/elements/ui_slider.h +++ b/src/ui/elements/ui_slider.h @@ -21,7 +21,7 @@ namespace recompui { double value = 50.0; double min_value = 0.0; double max_value = 100.0; - double step_value = 1.0; + double step_value = 0.0; float slider_width_dp = 300.0; std::vector> value_changed_callbacks; diff --git a/src/ui/ui_config_sub_menu.cpp b/src/ui/ui_config_sub_menu.cpp index 498763c..9954231 100644 --- a/src/ui/ui_config_sub_menu.cpp +++ b/src/ui/ui_config_sub_menu.cpp @@ -32,6 +32,10 @@ ConfigOptionElement::~ConfigOptionElement() { } +void ConfigOptionElement::set_id(std::string_view id) { + this->id = id; +} + void ConfigOptionElement::set_name(std::string_view name) { this->name = name; name_label->set_text(name); @@ -52,39 +56,45 @@ const std::string &ConfigOptionElement::get_description() const { // ConfigOptionSlider void ConfigOptionSlider::slider_value_changed(double v) { - // TODO: Hook up to whatever API Recomp exposes to set the value of the persisent configuration in mods. - printf("%s changed to %f.\n", name.c_str(), v); + callback(id, v); } -ConfigOptionSlider::ConfigOptionSlider(Element *parent, double value, double min_value, double max_value, double step_value, bool percent) : ConfigOptionElement(parent) { +ConfigOptionSlider::ConfigOptionSlider(Element *parent, double value, double min_value, double max_value, double step_value, bool percent, std::function callback) : ConfigOptionElement(parent) { + this->callback = callback; + slider = get_current_context().create_element(this, percent ? SliderType::Percent : SliderType::Double); - slider->set_value(value); slider->set_min_value(min_value); slider->set_max_value(max_value); slider->set_step_value(step_value); + slider->set_value(value); slider->add_value_changed_callback(std::bind(&ConfigOptionSlider::slider_value_changed, this, std::placeholders::_1)); } // ConfigOptionTextInput void ConfigOptionTextInput::text_changed(const std::string &text) { - // TODO: Hook up to whatever API Recomp exposes to set the value of the persisent configuration in mods. - printf("%s changed to %s.\n", name.c_str(), text.c_str()); + callback(id, text); } -ConfigOptionTextInput::ConfigOptionTextInput(Element *parent) : ConfigOptionElement(parent) { +ConfigOptionTextInput::ConfigOptionTextInput(Element *parent, std::string_view value, std::function callback) : ConfigOptionElement(parent) { + this->callback = callback; + text_input = get_current_context().create_element(this); + text_input->set_text(value); text_input->add_text_changed_callback(std::bind(&ConfigOptionTextInput::text_changed, this, std::placeholders::_1)); } // ConfigOptionRadio void ConfigOptionRadio::index_changed(uint32_t index) { - printf("%s changed to %d.\n", name.c_str(), index); + callback(id, index); } -ConfigOptionRadio::ConfigOptionRadio(Element *parent, const std::vector &options) : ConfigOptionElement(parent) { +ConfigOptionRadio::ConfigOptionRadio(Element *parent, uint32_t value, const std::vector &options, std::function callback) : ConfigOptionElement(parent) { + this->callback = callback; + radio = get_current_context().create_element(this); + radio->set_index(value); radio->add_index_changed_callback(std::bind(&ConfigOptionRadio::index_changed, this, std::placeholders::_1)); for (std::string_view option : options) { radio->add_option(option); @@ -164,26 +174,27 @@ void ConfigSubMenu::clear_options() { hover_option_elements.clear(); } -void ConfigSubMenu::add_option(ConfigOptionElement *option, std::string_view name, std::string_view description) { +void ConfigSubMenu::add_option(ConfigOptionElement *option, std::string_view id, std::string_view name, std::string_view description) { + option->set_id(id); option->set_name(name); option->set_description(description); option->set_hover_callback(std::bind(&ConfigSubMenu::option_hovered, this, std::placeholders::_1, std::placeholders::_2)); config_option_elements.emplace_back(option); } -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(config_scroll_container, (min + max) / 2.0, min, max, step, percent); - add_option(option_slider, name, description); +void ConfigSubMenu::add_slider_option(std::string_view id, std::string_view name, std::string_view description, double value, double min, double max, double step, bool percent, std::function callback) { + ConfigOptionSlider *option_slider = get_current_context().create_element(config_scroll_container, value, min, max, step, percent, callback); + add_option(option_slider, id, name, description); } -void ConfigSubMenu::add_text_option(std::string_view name, std::string_view description) { - ConfigOptionTextInput *option_text_input = get_current_context().create_element(config_scroll_container); - add_option(option_text_input, name, description); +void ConfigSubMenu::add_text_option(std::string_view id, std::string_view name, std::string_view description, std::string_view value, std::function callback) { + ConfigOptionTextInput *option_text_input = get_current_context().create_element(config_scroll_container, value, callback); + add_option(option_text_input, id, name, description); } -void ConfigSubMenu::add_radio_option(std::string_view name, std::string_view description, const std::vector &options) { - ConfigOptionRadio *option_radio = get_current_context().create_element(config_scroll_container, options); - add_option(option_radio, name, description); +void ConfigSubMenu::add_radio_option(std::string_view id, std::string_view name, std::string_view description, uint32_t value, const std::vector &options, std::function callback) { + ConfigOptionRadio *option_radio = get_current_context().create_element(config_scroll_container, value, options, callback); + add_option(option_radio, id, name, description); } // ElementConfigSubMenu diff --git a/src/ui/ui_config_sub_menu.h b/src/ui/ui_config_sub_menu.h index 946fd1c..0aefb21 100644 --- a/src/ui/ui_config_sub_menu.h +++ b/src/ui/ui_config_sub_menu.h @@ -16,6 +16,7 @@ namespace recompui { class ConfigOptionElement : public Element { protected: Label *name_label = nullptr; + std::string id; std::string name; std::string description; std::function hover_callback = nullptr; @@ -24,6 +25,7 @@ protected: public: ConfigOptionElement(Element *parent); virtual ~ConfigOptionElement(); + void set_id(std::string_view id); void set_name(std::string_view name); void set_description(std::string_view description); void set_hover_callback(std::function callback); @@ -33,28 +35,31 @@ public: class ConfigOptionSlider : public ConfigOptionElement { protected: Slider *slider = nullptr; + std::function callback; void slider_value_changed(double v); public: - ConfigOptionSlider(Element *parent, double value, double min_value, double max_value, double step_value, bool percent); + ConfigOptionSlider(Element *parent, double value, double min_value, double max_value, double step_value, bool percent, std::function callback); }; class ConfigOptionTextInput : public ConfigOptionElement { protected: TextInput *text_input = nullptr; + std::function callback; void text_changed(const std::string &text); public: - ConfigOptionTextInput(Element *parent); + ConfigOptionTextInput(Element *parent, std::string_view value, std::function callback); }; class ConfigOptionRadio : public ConfigOptionElement { protected: Radio *radio = nullptr; + std::function callback; void index_changed(uint32_t index); public: - ConfigOptionRadio(Element *parent, const std::vector &options); + ConfigOptionRadio(Element *parent, uint32_t value, const std::vector &options, std::function callback); }; class ConfigSubMenu : public Element { @@ -71,16 +76,16 @@ private: void back_button_pressed(); void option_hovered(ConfigOptionElement *option, bool active); - void add_option(ConfigOptionElement *option, std::string_view name, std::string_view description); + void add_option(ConfigOptionElement *option, std::string_view id, std::string_view name, std::string_view description); public: ConfigSubMenu(Element *parent); 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, 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::vector &options); + void add_slider_option(std::string_view id, std::string_view name, std::string_view description, double value, double min, double max, double step, bool percent, std::function callback); + void add_text_option(std::string_view id, std::string_view name, std::string_view description, std::string_view value, std::function callback); + void add_radio_option(std::string_view id, std::string_view name, std::string_view description, uint32_t value, const std::vector &options, std::function callback); }; class ElementConfigSubMenu : public Rml::Element { diff --git a/src/ui/ui_mod_menu.cpp b/src/ui/ui_mod_menu.cpp index 3746889..31e5d5a 100644 --- a/src/ui/ui_mod_menu.cpp +++ b/src/ui/ui_mod_menu.cpp @@ -112,19 +112,24 @@ void ModMenu::mod_configure_requested() { 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) { + recomp::mods::ConfigValueVariant config_value = recomp::mods::get_mod_config_value(mod_details[active_mod_index].mod_id, option.id); + if (std::holds_alternative(config_value)) { + continue; + } + switch (option.type) { case recomp::mods::ConfigOptionType::Enum: { const recomp::mods::ConfigOptionEnum &option_enum = std::get(option.variant); - config_sub_menu->add_radio_option(option.name, option.description, option_enum.options); + config_sub_menu->add_radio_option(option.id, option.name, option.description, std::get(config_value), option_enum.options, std::bind(&ModMenu::mod_enum_option_changed, this, std::placeholders::_1, std::placeholders::_2)); break; } case recomp::mods::ConfigOptionType::Number: { const recomp::mods::ConfigOptionNumber &option_number = std::get(option.variant); - config_sub_menu->add_slider_option(option.name, option.description, option_number.min, option_number.max, option_number.step, option_number.percent); + config_sub_menu->add_slider_option(option.id, option.name, option.description, std::get(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)); break; } case recomp::mods::ConfigOptionType::String: { - config_sub_menu->add_text_option(option.name, option.description); + config_sub_menu->add_text_option(option.id, option.name, option.description, std::get(config_value), std::bind(&ModMenu::mod_string_option_changed, this, std::placeholders::_1, std::placeholders::_2)); break; } default: @@ -145,6 +150,24 @@ void ModMenu::mod_configure_requested() { } } +void ModMenu::mod_enum_option_changed(const std::string &id, uint32_t value) { + if (active_mod_index >= 0) { + recomp::mods::set_mod_config_value(mod_details[active_mod_index].mod_id, id, value); + } +} + +void ModMenu::mod_string_option_changed(const std::string &id, const std::string &value) { + if (active_mod_index >= 0) { + recomp::mods::set_mod_config_value(mod_details[active_mod_index].mod_id, id, value); + } +} + +void ModMenu::mod_number_option_changed(const std::string &id, double value) { + if (active_mod_index >= 0) { + recomp::mods::set_mod_config_value(mod_details[active_mod_index].mod_id, id, value); + } +} + void ModMenu::create_mod_list() { ContextId context = get_current_context(); diff --git a/src/ui/ui_mod_menu.h b/src/ui/ui_mod_menu.h index 73b8061..2bb44f6 100644 --- a/src/ui/ui_mod_menu.h +++ b/src/ui/ui_mod_menu.h @@ -34,8 +34,11 @@ private: void refresh_mods(); void mod_toggled(bool enabled); void mod_configure_requested(); + void mod_enum_option_changed(const std::string &id, uint32_t value); + void mod_string_option_changed(const std::string &id, const std::string &value); + void mod_number_option_changed(const std::string &id, double value); void create_mod_list(); - + Container *body_container = nullptr; Container *list_container = nullptr; ScrollContainer *list_scroll_container = nullptr;