diff --git a/source/MenuOption.h b/source/MenuOption.h index fd30697..d697c29 100644 --- a/source/MenuOption.h +++ b/source/MenuOption.h @@ -4,7 +4,7 @@ #include #include #include -#include // para std::clamp +#include // para std::clamp #include "service_menu.h" // Necesitamos las enums como SettingsGroup #include "options.h" // Para acceder a las variables de configuración #include "lang.h" // Para las traducciones @@ -12,25 +12,20 @@ // --- Interfaz Base para todas las Opciones del Menú --- -class MenuOption -{ +class MenuOption { public: // Enum para el comportamiento, similar al anterior pero más integrado - enum class Behavior - { - ADJUST, - SELECT - }; + enum class Behavior { ADJUST, SELECT }; // Constructor base MenuOption(std::string caption, ServiceMenu::SettingsGroup group, bool hidden = false) : caption_(std::move(caption)), group_(group), hidden_(hidden) {} - + // Destructor virtual para permitir la destrucción polimórfica correcta virtual ~MenuOption() = default; // Métodos comunes que todas las opciones deben tener - const std::string &getCaption() const { return caption_; } + const std::string& getCaption() const { return caption_; } ServiceMenu::SettingsGroup getGroup() const { return group_; } bool isHidden() const { return hidden_; } void setHidden(bool hidden) { hidden_ = hidden; } @@ -38,9 +33,9 @@ public: // Métodos virtuales que las clases derivadas implementarán según su naturaleza virtual Behavior getBehavior() const = 0; virtual std::string getValueAsString() const { return ""; } - virtual void adjustValue(bool adjust_up) {} // Implementado por opciones ajustables + virtual void adjustValue(bool adjust_up) {} // Implementado por opciones ajustables virtual ServiceMenu::SettingsGroup getTargetGroup() const { return ServiceMenu::SettingsGroup::MAIN; } // Implementado por FolderOption - virtual void executeAction() {} // Implementado por ActionOption + virtual void executeAction() {} // Implementado por ActionOption protected: std::string caption_; @@ -48,71 +43,67 @@ protected: bool hidden_; }; + // --- Clases Derivadas --- -// 1. Opción Booleana (On/Off) -class BoolOption : public MenuOption -{ +// 1. Opción Booleana (On/Off) - Sin cambios +class BoolOption : public MenuOption { public: - BoolOption(const std::string &cap, ServiceMenu::SettingsGroup grp, bool *var) + BoolOption(const std::string& cap, ServiceMenu::SettingsGroup grp, bool* var) : MenuOption(cap, grp), linked_variable_(var) {} Behavior getBehavior() const override { return Behavior::ADJUST; } - std::string getValueAsString() const override - { + std::string getValueAsString() const override { return *linked_variable_ ? Lang::getText("[SERVICE_MENU] ON") : Lang::getText("[SERVICE_MENU] OFF"); } - void adjustValue(bool /*adjust_up*/) override - { + void adjustValue(bool /*adjust_up*/) override { *linked_variable_ = !*linked_variable_; } - private: - bool *linked_variable_; + bool* linked_variable_; }; -// 2. Opción de Entero (Volumen, Tamaño Ventana, etc.) -class IntOption : public MenuOption -{ +// 2. Opción de Entero (Volumen, Tamaño Ventana, etc.) - Sin cambios +class IntOption : public MenuOption { public: - IntOption(const std::string &cap, ServiceMenu::SettingsGroup grp, int *var, int min, int max, int step) + IntOption(const std::string& cap, ServiceMenu::SettingsGroup grp, int* var, int min, int max, int step) : MenuOption(cap, grp), linked_variable_(var), min_value_(min), max_value_(max), step_value_(step) {} Behavior getBehavior() const override { return Behavior::ADJUST; } std::string getValueAsString() const override { return std::to_string(*linked_variable_); } - void adjustValue(bool adjust_up) override - { + void adjustValue(bool adjust_up) override { int newValue = *linked_variable_ + (adjust_up ? step_value_ : -step_value_); *linked_variable_ = std::clamp(newValue, min_value_, max_value_); } - private: - int *linked_variable_; + int* linked_variable_; int min_value_, max_value_, step_value_; }; -// 3. Opción de Lista (Idioma, Dificultad) -class ListOption : public MenuOption -{ +// 3. Opción de Lista (Idioma, Dificultad) - *** CORREGIDO *** +class ListOption : public MenuOption { public: - ListOption(const std::string &cap, ServiceMenu::SettingsGroup grp, std::string *var, std::vector values) - : MenuOption(cap, grp), linked_variable_(var), value_list_(std::move(values)), list_index_(0) {} - - void sync() - { // Sincroniza el índice con el valor actual de la variable - for (size_t i = 0; i < value_list_.size(); ++i) - { - std::string code; - if (linked_variable_ == &Options::pending_changes.new_language) - { - code = Lang::getCodeFromName(value_list_[i]); - } - else if (linked_variable_ == &Options::pending_changes.new_difficulty) - { - code = Options::getDifficultyCodeFromName(value_list_[i]); - } - if (code == *linked_variable_) - { + // El constructor ahora es más abstracto. Acepta funciones para obtener y establecer el valor. + ListOption(const std::string& cap, ServiceMenu::SettingsGroup grp, + std::vector values, + std::function current_value_getter, + std::function new_value_setter) + : MenuOption(cap, grp), + value_list_(std::move(values)), + getter_(std::move(current_value_getter)), + setter_(std::move(new_value_setter)), + list_index_(0) + { + sync(); // Sincroniza el índice con el valor actual al momento de la creación. + } + + // Se mantiene pública en caso de que necesitemos resincronizar desde fuera. + void sync() { + std::string current_value = getter_(); + for (size_t i = 0; i < value_list_.size(); ++i) { + // Asume que el getter devuelve un string que coincide con uno de los de la lista. + // Para que esto funcione, necesitarás funciones como `Lang::getNameFromCode`. + if (value_list_[i] == current_value) { list_index_ = i; return; } @@ -120,62 +111,51 @@ public: } Behavior getBehavior() const override { return Behavior::ADJUST; } - std::string getValueAsString() const override { return value_list_.empty() ? "" : value_list_[list_index_]; } - void adjustValue(bool adjust_up) override - { - if (value_list_.empty()) - return; + + std::string getValueAsString() const override { + return value_list_.empty() ? "" : value_list_[list_index_]; + } + + void adjustValue(bool adjust_up) override { + if (value_list_.empty()) return; size_t size = value_list_.size(); list_index_ = (adjust_up) ? (list_index_ + 1) % size : (list_index_ + size - 1) % size; - - // Actualiza la variable real y comprueba cambios pendientes - if (linked_variable_ == &Options::pending_changes.new_language) - { - *linked_variable_ = Lang::getCodeFromName(value_list_[list_index_]); - } - else if (linked_variable_ == &Options::pending_changes.new_difficulty) - { - *linked_variable_ = Options::getDifficultyCodeFromName(value_list_[list_index_]); - } - Options::checkPendingChanges(); + + // Usa la función setter para actualizar la variable de configuración real. + setter_(value_list_[list_index_]); } private: - std::string *linked_variable_; std::vector value_list_; + std::function getter_; + std::function setter_; size_t list_index_; }; -// 4. Opción Carpeta (Navega a otro sub-menú) -class FolderOption : public MenuOption -{ + +// 4. Opción Carpeta (Navega a otro sub-menú) - Sin cambios +class FolderOption : public MenuOption { public: - FolderOption(const std::string &cap, ServiceMenu::SettingsGroup grp, ServiceMenu::SettingsGroup target) + FolderOption(const std::string& cap, ServiceMenu::SettingsGroup grp, ServiceMenu::SettingsGroup target) : MenuOption(cap, grp), target_group_(target) {} Behavior getBehavior() const override { return Behavior::SELECT; } ServiceMenu::SettingsGroup getTargetGroup() const override { return target_group_; } - private: ServiceMenu::SettingsGroup target_group_; }; -// 5. Opción de Acción (Ejecuta una función) -class ActionOption : public MenuOption -{ +// 5. Opción de Acción (Ejecuta una función) - Sin cambios +class ActionOption : public MenuOption { public: - // Usamos std::function para poder pasar cualquier función/lambda - ActionOption(const std::string &cap, ServiceMenu::SettingsGroup grp, std::function action, bool hidden = false) + ActionOption(const std::string& cap, ServiceMenu::SettingsGroup grp, std::function action, bool hidden = false) : MenuOption(cap, grp, hidden), action_(std::move(action)) {} Behavior getBehavior() const override { return Behavior::SELECT; } - void executeAction() override - { - if (action_) - action_(); + void executeAction() override { + if (action_) action_(); } - private: std::function action_; }; diff --git a/source/lang.cpp b/source/lang.cpp index 9fea0a7..140ecd4 100644 --- a/source/lang.cpp +++ b/source/lang.cpp @@ -93,6 +93,18 @@ namespace Lang return languages[0].code; } + // Devuelve el nombre de un idioma a partir de un código + std::string getNameFromCode(Code code) + { + for (const auto& lang : languages) + { + if (lang.code == code) + return lang.name; + } + // Si no se encuentra, devuelve el nombre del primer idioma por defecto + return languages[0].name; + } + // Actualiza los nombres de los idiomas void updateLanguageNames() { diff --git a/source/lang.h b/source/lang.h index 0c35512..6515817 100644 --- a/source/lang.h +++ b/source/lang.h @@ -39,6 +39,9 @@ namespace Lang // Devuelve el código de un idioma a partir de un nombre Code getCodeFromName(const std::string& name); + // Devuelve el nombre de un idioma a partir de un código + std::string getNameFromCode(Code code); + // Actualiza los nombres de los idiomas void updateLanguageNames(); diff --git a/source/options.cpp b/source/options.cpp index 0ec7b3d..a180eee 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -431,4 +431,15 @@ namespace Options // Si no se encuentra, devuelve el primero por defecto return difficulties[0].code; } + + std::string getDifficultyNameFromCode(DifficultyCode code) + { + for (const auto &difficulty : difficulties) + { + if (difficulty.code == code) + return difficulty.name; + } + // Si no se encuentra, devuelve el nombre del primero por defecto + return difficulties[0].name; + } } // namespace Options \ No newline at end of file diff --git a/source/options.h b/source/options.h index fdd0835..6f4d783 100644 --- a/source/options.h +++ b/source/options.h @@ -139,4 +139,5 @@ namespace Options void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables void checkPendingChanges(); DifficultyCode getDifficultyCodeFromName(const std::string& name); + std::string getDifficultyNameFromCode(DifficultyCode code); } // namespace Options \ No newline at end of file diff --git a/source/service_menu.cpp b/source/service_menu.cpp index e1eabf7..d5761a3 100644 --- a/source/service_menu.cpp +++ b/source/service_menu.cpp @@ -48,10 +48,35 @@ void ServiceMenu::initializeOptions() // --- Settings --- options_.push_back(std::make_unique(Lang::getText("[SERVICE_MENU] AUTOFIRE"), SettingsGroup::SETTINGS, &Options::settings.autofire)); - options_.push_back(std::make_unique(Lang::getText("[SERVICE_MENU] LANGUAGE"), SettingsGroup::SETTINGS, &Options::pending_changes.new_language, - std::vector{Lang::getText("[SERVICE_MENU] LANG_ES"), Lang::getText("[SERVICE_MENU] LANG_BA"), Lang::getText("[SERVICE_MENU] LANG_EN")})); - options_.push_back(std::make_unique(Lang::getText("[SERVICE_MENU] DIFFICULTY"), SettingsGroup::SETTINGS, &Options::pending_changes.new_difficulty, - std::vector{Lang::getText("[SERVICE_MENU] EASY"), Lang::getText("[SERVICE_MENU] NORMAL"), Lang::getText("[SERVICE_MENU] HARD")})); + // Opción de Idioma + options_.push_back(std::make_unique( + Lang::getText("[SERVICE_MENU] LANGUAGE"), + SettingsGroup::SETTINGS, + std::vector{Lang::getText("[SERVICE_MENU] LANG_ES"), Lang::getText("[SERVICE_MENU] LANG_BA"), Lang::getText("[SERVICE_MENU] LANG_EN")}, + // Getter: Devuelve el nombre del idioma actual + []() + { return Lang::getNameFromCode(Options::pending_changes.new_language); }, + // Setter: Establece el nuevo idioma a partir de su nombre + [](const std::string &val) + { + Options::pending_changes.new_language = Lang::getCodeFromName(val); + Options::checkPendingChanges(); + })); + + // Opción de Dificultad + options_.push_back(std::make_unique( + Lang::getText("[SERVICE_MENU] DIFFICULTY"), + SettingsGroup::SETTINGS, + std::vector{Lang::getText("[SERVICE_MENU] EASY"), Lang::getText("[SERVICE_MENU] NORMAL"), Lang::getText("[SERVICE_MENU] HARD")}, + // Getter: Devuelve el nombre de la dificultad actual + []() + { return Options::getDifficultyNameFromCode(Options::pending_changes.new_difficulty); }, + // Setter: Establece la nueva dificultad a partir de su nombre + [](const std::string &val) + { + Options::pending_changes.new_difficulty = Options::getDifficultyCodeFromName(val); + Options::checkPendingChanges(); + })); options_.push_back(std::make_unique(Lang::getText("[SERVICE_MENU] ENABLE_SHUTDOWN"), SettingsGroup::SETTINGS, &Options::settings.shutdown_enabled)); // --- System (con lambdas para las acciones) ---