#pragma once #include // Para SDL_Event #include // Para size_t #include // Para function #include // Para unique_ptr #include // Para string #include // Para pair #include // Para vector #include "define_buttons.h" // Para DefineButtons #include "ui_message.h" // Para UIMessage class MenuOption; class MenuRenderer; class ServiceMenu { public: // --- Enums y constantes --- enum class SettingsGroup { CONTROLS, VIDEO, AUDIO, SETTINGS, SYSTEM, MAIN }; enum class GroupAlignment { CENTERED, LEFT }; static constexpr size_t OPTIONS_HORIZONTAL_PADDING = 20; static constexpr size_t MIN_WIDTH = 240; static constexpr size_t MIN_GAP_OPTION_VALUE = 30; static constexpr size_t SETTINGS_GROUP_SIZE = 6; using StateChangeCallback = std::function; // --- Métodos de singleton --- static void init(); static void destroy(); static auto get() -> ServiceMenu *; ServiceMenu(const ServiceMenu &) = delete; auto operator=(const ServiceMenu &) -> ServiceMenu & = delete; // --- Métodos principales --- void toggle(); void render(); void update(); void reset(); // --- Lógica de navegación --- void setSelectorUp(); void setSelectorDown(); void adjustOption(bool adjust_up); void selectOption(); void moveBack(); // --- Método para manejar eventos --- void handleEvent(const SDL_Event &event); auto checkInput() -> bool; // --- Método principal para refresco externo --- void refresh(); // Refresca los valores y el layout del menú bajo demanda // --- Método para registrar el callback --- void setStateChangeCallback(StateChangeCallback callback); // --- Getters para el estado --- [[nodiscard]] auto isDefiningButtons() const -> bool; [[nodiscard]] auto isAnimating() const -> bool; // Nuevo getter // --- Getters para que el Renderer pueda leer el estado --- [[nodiscard]] auto isEnabled() const -> bool { return enabled_; } [[nodiscard]] auto getTitle() const -> const std::string & { return title_; } [[nodiscard]] auto getCurrentGroup() const -> SettingsGroup { return current_settings_group_; } [[nodiscard]] auto getCurrentGroupAlignment() const -> GroupAlignment; [[nodiscard]] auto getDisplayOptions() const -> const std::vector & { return display_options_; } [[nodiscard]] auto getAllOptions() const -> const std::vector> & { return options_; } [[nodiscard]] auto getSelectedIndex() const -> size_t { return selected_; } [[nodiscard]] auto getOptionPairs() const -> const std::vector> & { return option_pairs_; } [[nodiscard]] auto countOptionsInGroup(SettingsGroup group) const -> size_t; private: bool enabled_ = false; std::vector> options_; std::vector display_options_; std::vector> option_pairs_; SettingsGroup current_settings_group_; SettingsGroup previous_settings_group_; std::string title_; size_t selected_ = 0; size_t main_menu_selected_ = 0; std::unique_ptr restart_message_ui_; bool last_pending_changes_ = false; std::unique_ptr define_buttons_; std::unique_ptr renderer_; StateChangeCallback state_change_callback_; // --- Métodos de lógica interna --- void updateDisplayOptions(); void updateOptionPairs(); void initializeOptions(); void updateMenu(); void applySettings(); void applyControlsSettings(); void applyVideoSettings(); static void applyAudioSettings(); void applySettingsSettings(); [[nodiscard]] auto getOptionByCaption(const std::string &caption) const -> MenuOption *; void adjustListValues(); static void playMoveSound(); static void playAdjustSound(); static void playSelectSound(); static void playBackSound(); [[nodiscard]] static auto settingsGroupToString(SettingsGroup group) -> std::string; void setHiddenOptions(); void setEnabledInternal(bool enabled); // Método privado para cambiar estado y notificar // --- Constructores y destructor privados (singleton) --- ServiceMenu(); ~ServiceMenu() = default; // --- Instancia singleton --- static ServiceMenu *instance; };