Link storage to mod menu.

This commit is contained in:
Dario 2025-01-21 22:56:47 -03:00 committed by Mr-Wiseguy
parent 8119daf62c
commit e8b8537c5a
6 changed files with 73 additions and 58 deletions

View file

@ -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. // 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::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( recomp::start(
project_version, project_version,
{}, {},

View file

@ -21,7 +21,7 @@ namespace recompui {
double value = 50.0; double value = 50.0;
double min_value = 0.0; double min_value = 0.0;
double max_value = 100.0; double max_value = 100.0;
double step_value = 1.0; double step_value = 0.0;
float slider_width_dp = 300.0; float slider_width_dp = 300.0;
std::vector<std::function<void(double)>> value_changed_callbacks; std::vector<std::function<void(double)>> value_changed_callbacks;

View file

@ -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) { void ConfigOptionElement::set_name(std::string_view name) {
this->name = name; this->name = name;
name_label->set_text(name); name_label->set_text(name);
@ -52,39 +56,45 @@ const std::string &ConfigOptionElement::get_description() const {
// ConfigOptionSlider // ConfigOptionSlider
void ConfigOptionSlider::slider_value_changed(double v) { 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. callback(id, v);
printf("%s changed to %f.\n", name.c_str(), 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<void(const std::string &, double)> callback) : ConfigOptionElement(parent) {
this->callback = callback;
slider = get_current_context().create_element<Slider>(this, percent ? SliderType::Percent : SliderType::Double); slider = get_current_context().create_element<Slider>(this, percent ? SliderType::Percent : SliderType::Double);
slider->set_value(value);
slider->set_min_value(min_value); slider->set_min_value(min_value);
slider->set_max_value(max_value); slider->set_max_value(max_value);
slider->set_step_value(step_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)); slider->add_value_changed_callback(std::bind(&ConfigOptionSlider::slider_value_changed, this, std::placeholders::_1));
} }
// ConfigOptionTextInput // ConfigOptionTextInput
void ConfigOptionTextInput::text_changed(const std::string &text) { 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. callback(id, text);
printf("%s changed to %s.\n", name.c_str(), text.c_str());
} }
ConfigOptionTextInput::ConfigOptionTextInput(Element *parent) : ConfigOptionElement(parent) { ConfigOptionTextInput::ConfigOptionTextInput(Element *parent, std::string_view value, std::function<void(const std::string &, const std::string &)> callback) : ConfigOptionElement(parent) {
this->callback = callback;
text_input = get_current_context().create_element<TextInput>(this); text_input = get_current_context().create_element<TextInput>(this);
text_input->set_text(value);
text_input->add_text_changed_callback(std::bind(&ConfigOptionTextInput::text_changed, this, std::placeholders::_1)); text_input->add_text_changed_callback(std::bind(&ConfigOptionTextInput::text_changed, this, std::placeholders::_1));
} }
// ConfigOptionRadio // ConfigOptionRadio
void ConfigOptionRadio::index_changed(uint32_t index) { 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<std::string> &options) : ConfigOptionElement(parent) { ConfigOptionRadio::ConfigOptionRadio(Element *parent, uint32_t value, const std::vector<std::string> &options, std::function<void(const std::string &, uint32_t)> callback) : ConfigOptionElement(parent) {
this->callback = callback;
radio = get_current_context().create_element<Radio>(this); radio = get_current_context().create_element<Radio>(this);
radio->set_index(value);
radio->add_index_changed_callback(std::bind(&ConfigOptionRadio::index_changed, this, std::placeholders::_1)); radio->add_index_changed_callback(std::bind(&ConfigOptionRadio::index_changed, this, std::placeholders::_1));
for (std::string_view option : options) { for (std::string_view option : options) {
radio->add_option(option); radio->add_option(option);
@ -164,26 +174,27 @@ void ConfigSubMenu::clear_options() {
hover_option_elements.clear(); 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_name(name);
option->set_description(description); option->set_description(description);
option->set_hover_callback(std::bind(&ConfigSubMenu::option_hovered, this, std::placeholders::_1, std::placeholders::_2)); option->set_hover_callback(std::bind(&ConfigSubMenu::option_hovered, this, std::placeholders::_1, std::placeholders::_2));
config_option_elements.emplace_back(option); 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) { 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<void(const std::string &, double)> callback) {
ConfigOptionSlider *option_slider = get_current_context().create_element<ConfigOptionSlider>(config_scroll_container, (min + max) / 2.0, min, max, step, percent); ConfigOptionSlider *option_slider = get_current_context().create_element<ConfigOptionSlider>(config_scroll_container, value, min, max, step, percent, callback);
add_option(option_slider, name, description); add_option(option_slider, id, name, description);
} }
void ConfigSubMenu::add_text_option(std::string_view name, std::string_view description) { void ConfigSubMenu::add_text_option(std::string_view id, std::string_view name, std::string_view description, std::string_view value, std::function<void(const std::string &, const std::string &)> callback) {
ConfigOptionTextInput *option_text_input = get_current_context().create_element<ConfigOptionTextInput>(config_scroll_container); ConfigOptionTextInput *option_text_input = get_current_context().create_element<ConfigOptionTextInput>(config_scroll_container, value, callback);
add_option(option_text_input, name, description); add_option(option_text_input, id, name, description);
} }
void ConfigSubMenu::add_radio_option(std::string_view name, std::string_view description, const std::vector<std::string> &options) { void ConfigSubMenu::add_radio_option(std::string_view id, std::string_view name, std::string_view description, uint32_t value, const std::vector<std::string> &options, std::function<void(const std::string &, uint32_t)> callback) {
ConfigOptionRadio *option_radio = get_current_context().create_element<ConfigOptionRadio>(config_scroll_container, options); ConfigOptionRadio *option_radio = get_current_context().create_element<ConfigOptionRadio>(config_scroll_container, value, options, callback);
add_option(option_radio, name, description); add_option(option_radio, id, name, description);
} }
// ElementConfigSubMenu // ElementConfigSubMenu

View file

@ -16,6 +16,7 @@ namespace recompui {
class ConfigOptionElement : public Element { class ConfigOptionElement : public Element {
protected: protected:
Label *name_label = nullptr; Label *name_label = nullptr;
std::string id;
std::string name; std::string name;
std::string description; std::string description;
std::function<void(ConfigOptionElement *, bool)> hover_callback = nullptr; std::function<void(ConfigOptionElement *, bool)> hover_callback = nullptr;
@ -24,6 +25,7 @@ protected:
public: public:
ConfigOptionElement(Element *parent); ConfigOptionElement(Element *parent);
virtual ~ConfigOptionElement(); virtual ~ConfigOptionElement();
void set_id(std::string_view id);
void set_name(std::string_view name); void set_name(std::string_view name);
void set_description(std::string_view description); void set_description(std::string_view description);
void set_hover_callback(std::function<void(ConfigOptionElement *, bool)> callback); void set_hover_callback(std::function<void(ConfigOptionElement *, bool)> callback);
@ -33,28 +35,31 @@ public:
class ConfigOptionSlider : public ConfigOptionElement { class ConfigOptionSlider : public ConfigOptionElement {
protected: protected:
Slider *slider = nullptr; Slider *slider = nullptr;
std::function<void(const std::string &, double)> callback;
void slider_value_changed(double v); void slider_value_changed(double v);
public: 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<void(const std::string &, double)> callback);
}; };
class ConfigOptionTextInput : public ConfigOptionElement { class ConfigOptionTextInput : public ConfigOptionElement {
protected: protected:
TextInput *text_input = nullptr; TextInput *text_input = nullptr;
std::function<void(const std::string &, const std::string &)> callback;
void text_changed(const std::string &text); void text_changed(const std::string &text);
public: public:
ConfigOptionTextInput(Element *parent); ConfigOptionTextInput(Element *parent, std::string_view value, std::function<void(const std::string &, const std::string &)> callback);
}; };
class ConfigOptionRadio : public ConfigOptionElement { class ConfigOptionRadio : public ConfigOptionElement {
protected: protected:
Radio *radio = nullptr; Radio *radio = nullptr;
std::function<void(const std::string &, uint32_t)> callback;
void index_changed(uint32_t index); void index_changed(uint32_t index);
public: public:
ConfigOptionRadio(Element *parent, const std::vector<std::string> &options); ConfigOptionRadio(Element *parent, uint32_t value, const std::vector<std::string> &options, std::function<void(const std::string &, uint32_t)> callback);
}; };
class ConfigSubMenu : public Element { class ConfigSubMenu : public Element {
@ -71,16 +76,16 @@ private:
void back_button_pressed(); void back_button_pressed();
void option_hovered(ConfigOptionElement *option, bool active); 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: public:
ConfigSubMenu(Element *parent); ConfigSubMenu(Element *parent);
virtual ~ConfigSubMenu(); virtual ~ConfigSubMenu();
void enter(std::string_view title); void enter(std::string_view title);
void clear_options(); 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_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<void(const std::string &, double)> callback);
void add_text_option(std::string_view name, std::string_view description); void add_text_option(std::string_view id, std::string_view name, std::string_view description, std::string_view value, std::function<void(const std::string &, const std::string &)> callback);
void add_radio_option(std::string_view name, std::string_view description, const std::vector<std::string> &options); void add_radio_option(std::string_view id, std::string_view name, std::string_view description, uint32_t value, const std::vector<std::string> &options, std::function<void(const std::string &, uint32_t)> callback);
}; };
class ElementConfigSubMenu : public Rml::Element { class ElementConfigSubMenu : public Rml::Element {

View file

@ -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); 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) { 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<std::monostate>(config_value)) {
continue;
}
switch (option.type) { switch (option.type) {
case recomp::mods::ConfigOptionType::Enum: { case recomp::mods::ConfigOptionType::Enum: {
const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(option.variant); const recomp::mods::ConfigOptionEnum &option_enum = std::get<recomp::mods::ConfigOptionEnum>(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<uint32_t>(config_value), option_enum.options, std::bind(&ModMenu::mod_enum_option_changed, this, std::placeholders::_1, std::placeholders::_2));
break; break;
} }
case recomp::mods::ConfigOptionType::Number: { case recomp::mods::ConfigOptionType::Number: {
const recomp::mods::ConfigOptionNumber &option_number = std::get<recomp::mods::ConfigOptionNumber>(option.variant); const recomp::mods::ConfigOptionNumber &option_number = std::get<recomp::mods::ConfigOptionNumber>(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<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));
break; break;
} }
case recomp::mods::ConfigOptionType::String: { 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<std::string>(config_value), std::bind(&ModMenu::mod_string_option_changed, this, std::placeholders::_1, std::placeholders::_2));
break; break;
} }
default: 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() { void ModMenu::create_mod_list() {
ContextId context = get_current_context(); ContextId context = get_current_context();

View file

@ -34,8 +34,11 @@ private:
void refresh_mods(); void refresh_mods();
void mod_toggled(bool enabled); void mod_toggled(bool enabled);
void mod_configure_requested(); 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(); void create_mod_list();
Container *body_container = nullptr; Container *body_container = nullptr;
Container *list_container = nullptr; Container *list_container = nullptr;
ScrollContainer *list_scroll_container = nullptr; ScrollContainer *list_scroll_container = nullptr;