#pragma once #include #include #include // for string, basic_string #include // for vector #include "utils/utils.h" // for Color class Text; namespace Ja { struct Sound; } // namespace Ja // Clase Menu class Menu { public: enum class Background : std::uint8_t { TRANSPARENT, SOLID }; enum class Sound : std::uint8_t { ACCEPT, MOVE, CANCEL }; explicit Menu(SDL_Renderer *renderer, const std::string &file = ""); // Constructor ~Menu(); // Destructor auto loadFromBytes(const std::vector &bytes, const std::string &name_for_logs = "") -> bool; // Carga el menu desde bytes en memoria void loadAudioFile(const std::string &file, Sound sound); // Carga los ficheros de audio [[nodiscard]] auto getName() const -> const std::string &; // Obtiene el nombre del menu auto getItemSelected() -> int; // Obtiene el valor de la variable void reset(); // Deja el menu apuntando al primer elemento void checkInput(); // Gestiona la entrada de teclado y mando durante el menu void update(); // Actualiza la logica del menu void render(); // Pinta el menu en pantalla void setBackgroundColor(Color color, int alpha); // Establece el color del rectangulo de fondo void setSelectorColor(Color color, int alpha); // Establece el color del rectangulo del selector void setSelectorTextColor(Color color); // Establece el color del texto del selector void centerMenuOnX(int value = 0); // Centra el menu respecto a un punto en el eje X void centerMenuOnY(int value); // Centra el menu respecto a un punto en el eje Y void centerMenuElementsOnX(); // Centra los elementos del menu en el eje X struct Item { std::string label; // Texto SDL_Rect rect; // Rectangulo que delimita el elemento int h_padding_down; // Espaciado bajo el elemento bool selectable; // Indica si se puede seleccionar bool greyed; // Indica si ha de aparecer con otro color mas oscuro bool linked_down; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector bool linked_up; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector bool visible; // Indica si el elemento es visible bool line; // Indica si el elemento lleva una linea a continuación }; void addItem(Item new_item); // Añade un item al menu void setItemCaption(int index, const std::string &text); // Cambia el texto de un item void setDefaultActionWhenCancel(int item); // Establece el indice del item que se usará por defecto al cancelar el menu void setSelectorPos(int index); // Coloca el selector en una posición específica void setSelectable(int index, bool value); // Establece el estado seleccionable de un item void setGreyed(int index, bool value); // Establece el estado agrisado de un item void setLinkedDown(int index, bool value); // Establece el estado de enlace de un item void setVisible(int index, bool value); // Establece el estado de visibilidad de un item void setName(const std::string &name); // Establece el nombre del menu void setPos(int x, int y); // Establece la posición del menu void setBackgroundType(Background value); // Establece el tipo de fondo del menu void setText(const std::string &font_png, const std::string &font_txt); // Establece la fuente de texto que se utilizará void setRectSize(int w = 0, int h = 0); // Establece el rectangulo de fondo del menu private: static constexpr int NO_OPTION = -1; // Centinela: ningún item seleccionado struct Rectangle { SDL_Rect rect; // Rectangulo Color color; // Color int a; // Transparencia }; struct Selector { float origin_y; // Coordenada de origen float target_y; // Coordenada de destino float desp_y; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps bool moving; // Indica si el selector está avanzando hacia el destino float origin_h; // Altura de origen float target_h; // Altura de destino float inc_h; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto bool resizing; // Indica si el selector está cambiando de tamaño float y; // Coordenada actual, usado para el desplazamiento float h; // Altura actual, usado para el cambio de tamaño int num_jumps; // Numero de pasos preestablecido para llegar al destino int index; // Elemento del menu que tiene el foco int previous_index; // Elemento que tenia el foco previamente Color previous_item_color; // Color del item nque tenia el foco previamente SDL_Rect rect; // Rectangulo del selector Color color; // Color del selector Color item_color; // Color del item Color jump_item_colors[8]; // Transición de colores para el item seleccionado int item_color_index; // Indice del color de transición para el item seleccionado int a; // Cantidad de transparencia para el rectangulo del selector }; auto load(const std::string &file_path) -> bool; // Carga la configuración del menu desde un archivo de texto auto parseFromStream(std::istream &file, const std::string &filename) -> bool; // Parser compartido (recibe cualquier istream) auto setVars(const std::string &var, const std::string &value) -> bool; // Asigna variables a partir de dos cadenas auto trySetSoundVar(const std::string &var, const std::string &value) -> bool; // Helper de setVars: variables de tipo sonido auto trySetColorVar(const std::string &var, const std::string &value) -> bool; // Helper de setVars: variables de tipo color static auto setItem(Item *item, const std::string &var, const std::string &value) -> bool; // Asigna variables a partir de dos cadenas void reorganize(); // Actualiza el menu para recolocarlo correctamente y establecer el tamaño void increaseSelectorIndex(); // Deja el menu apuntando al siguiente elemento void decreaseSelectorIndex(); // Deja el menu apuntando al elemento anterior void updateSelector(); // Actualiza la posicion y el estado del selector auto getWidestItem() -> int; // Obtiene la anchura del elemento más ancho del menu void checkMenuInput(Menu *menu); // Gestiona la entrada de teclado y mando durante el menu auto findWidth() -> int; // Calcula el ancho del menu auto findHeight() -> int; // Calcula el alto del menu void replaceElementsOnY(); // Recoloca los elementos del menu en el eje Y auto getSelectorHeight(int value) -> int; // Calcula la altura del selector void setSelectorItemColors(); // Calcula los colores del selector para el degradado // Objetos y punteros SDL_Renderer *renderer_; // Puntero al renderizador de la ventana Text *text_; // Texto para poder escribir los items del menu // Variables std::string name_; // Nombre del menu int x_; // Posición en el eje X de la primera letra del primer elemento int y_; // Posición en el eje Y de la primera letra del primer elemento int h_; // Altura del menu int w_; // Anchura del menu int item_selected_; // Índice del item del menu que ha sido seleccionado int default_action_when_cancel_; // Indice del item del menu que se selecciona cuando se cancela el menu Background background_type_; // Tipo de fondo para el menu int center_x_; // Centro del menu en el eje X int center_y_; // Centro del menu en el eje Y bool is_centered_on_x_; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X bool is_centered_on_y_; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y bool are_elements_centered_on_x_; // Variable para saber si los elementos van centrados en el eje X int widest_item_; // Anchura del elemento más ancho Ja::Sound *sound_accept_; // Sonido al aceptar o elegir una opción del menu Ja::Sound *sound_cancel_; // Sonido al cancelar el menu Ja::Sound *sound_move_; // Sonido al mover el selector Color color_greyed_; // Color para los elementos agrisados Rectangle rect_bg_; // Rectangulo de fondo del menu std::vector items_; // Estructura para cada elemento del menu Selector selector_; // Variables para pintar el selector del menu std::string font_png_; std::string font_txt_; };