From 37a7a9eccbdd254fc6a45f85e5275ce243af78bf Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 13 Jun 2025 20:03:50 +0200 Subject: [PATCH] ServiceMenu: treballant en les animacions --- source/resource.cpp | 2 +- source/service_menu.cpp | 53 +++++++++++++++++++++++++++++++++++++---- source/service_menu.h | 21 ++++++++++++++-- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/source/resource.cpp b/source/resource.cpp index c92e352..70866ab 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -486,7 +486,7 @@ void Resource::updateLoadingProgress(std::string name) updateProgressBar(); renderProgress(); checkEvents(); - SDL_Delay(100); + //SDL_Delay(100); } // Inicializa los rectangulos que definen la barra de progreso diff --git a/source/service_menu.cpp b/source/service_menu.cpp index 8483ceb..c451e70 100644 --- a/source/service_menu.cpp +++ b/source/service_menu.cpp @@ -67,6 +67,9 @@ void ServiceMenu::render() SDL_SetRenderDrawColor(Screen::get()->getRenderer(), title_color_.r, title_color_.g, title_color_.b, 255); SDL_RenderRect(Screen::get()->getRenderer(), &rect_); + // Si está animando el resize, no pintar el contenido + //if (resizing_) return; + // TITULO y += title_padding_; title_text_->writeDX(TEXT_COLOR | TEXT_CENTER, param.game.game_area.center_x, y, lang::getText("[SERVICE_MENU] TITLE"), -4, title_color_); @@ -101,6 +104,11 @@ void ServiceMenu::render() // Actualiza el estado del menú de servicio (colores, animaciones, etc.) void ServiceMenu::update() { + if (resizing_) { + updateResizeAnimation(); + // No actualizar colores ni animaciones mientras se redimensiona + return; + } if (enabled_) { updateCounter(); @@ -138,21 +146,57 @@ void ServiceMenu::setAnchors() void ServiceMenu::setOptionsPosition() { resize(); - options_y_ = rect_.y + upper_height_ + lower_padding_; + //options_y_ = rect_.y + upper_height_ + lower_padding_; + + SDL_FRect new_rect = { + (param.game.width - width_) / 2, + (param.game.height - height_) / 2, + static_cast(width_), + static_cast(height_)}; + options_y_ = new_rect.y + upper_height_ + lower_padding_; + } // Cambia el tamaño de la ventana de menu void ServiceMenu::resize() { lower_height_ = ((display_options_.size() - 1) * (options_height_ + options_padding_)) + options_height_ + (lower_padding_ * 2); - width_ = 240; height_ = upper_height_ + lower_height_; - rect_ = { + SDL_FRect new_rect = { (param.game.width - width_) / 2, (param.game.height - height_) / 2, static_cast(width_), static_cast(height_)}; + + // Si el rect actual es diferente al nuevo, inicia animación + if (rect_.x != new_rect.x || rect_.y != new_rect.y || rect_.w != new_rect.w || rect_.h != new_rect.h) { + rect_anim_from_ = rect_; + rect_anim_to_ = new_rect; + resize_anim_step_ = 0; + resizing_ = true; + } else { + rect_ = new_rect; + resizing_ = false; + } +} + +void ServiceMenu::updateResizeAnimation() +{ + if (!resizing_) return; + ++resize_anim_step_; + float t = static_cast(resize_anim_step_) / resize_anim_steps_; + if (t >= 1.0f) { + rect_ = rect_anim_to_; + resizing_ = false; + return; + } + // EaseOutQuad + float ease = 1 - (1 - t) * (1 - t); + rect_.x = rect_anim_from_.x + (rect_anim_to_.x - rect_anim_from_.x) * ease; + rect_.y = rect_anim_from_.y + (rect_anim_to_.y - rect_anim_from_.y) * ease; + rect_.w = rect_anim_from_.w + (rect_anim_to_.w - rect_anim_from_.w) * ease; + rect_.h = rect_anim_from_.h + (rect_anim_to_.h - rect_anim_from_.h) * ease; } // Actualiza el contador interno para animaciones o efectos visuales @@ -462,4 +506,5 @@ void ServiceMenu::AdjustListValues() option->list_index = i; } } -} \ No newline at end of file +} + diff --git a/source/service_menu.h b/source/service_menu.h index 9906387..d41e11e 100644 --- a/source/service_menu.h +++ b/source/service_menu.h @@ -35,13 +35,18 @@ public: // --- Getters --- bool isEnabled() const { return enabled_; } // Indica si el menú de servicio está activo + // --- Métodos para animación de resize --- + void setResizeAnimationSteps(int steps) { resize_anim_steps_ = steps; } + private: // --- Tipos internos --- using OptionPairs = std::vector>; // --- Constantes --- - static constexpr const char *MENU_SOUND_ = "clock.wav"; // Sonido al navegar por el menú - static constexpr int OPTIONS_HORIZONTAL_PADDING_ = 20; // Relleno horizontal de las opciones + static constexpr const char *MENU_SOUND_ = "clock.wav"; // Sonido al navegar por el menú + static constexpr size_t OPTIONS_HORIZONTAL_PADDING_ = 20; // Relleno horizontal de las opciones + static constexpr size_t MIN_WIDTH_ = 240; // Anchura mínima del menu + static constexpr size_t MIN_GAP_OPTION_VALUE_ = 20; // Espacio mínimo entre una opción y su valor // --- Enumeraciones internas --- enum class Aspect @@ -201,12 +206,21 @@ private: size_t upper_height_; // Altura de la parte de arriba del menu: la del titulo size_t lower_height_; // Altira de la parte baja del menu: la que tiene las opciones size_t lower_padding_; // Espaciado vertical mínimo entre los bordes y el contenido de la zona inferior + size_t options_width_; // Anchura de la opcion + valor más larga + + // --- Variables para animación de resize --- + SDL_FRect rect_anim_from_{}; // Estado inicial de la animación + SDL_FRect rect_anim_to_{}; // Estado objetivo de la animación + int resize_anim_step_ = 0; // Paso actual de la animación + int resize_anim_steps_ = 8; // Total de pasos de la animación + bool resizing_ = false; // Si está animando el resize // --- Métodos internos: Anclaje y aspecto --- void setAnchors(); // Establece el valor de las variables de anclaje Color getSelectedColor() const; // Devuelve el color del elemento seleccionado void setOptionsPosition(); // Establce la posición donde empezar a escribir las opciones del menu void resize(); // Cambia el tamaño de la ventana de menu + size_t getOptionsWidth(); // Obtiene el ancho de las opciones del menu // --- Métodos internos: Gestión de opciones --- void initializeOptions(); // Crea todas las opciones del menú de servicio @@ -225,6 +239,9 @@ private: GroupAlignment getGroupAlignment(SettingsGroup group) const; // Devuelve la alineación del grupo OptionEntry *getOptionEntryByCaption(const std::string &caption); // Devuelve un puntero a OptionEntry a partir del caption + // --- Métodos internos: Animación de resize --- + void updateResizeAnimation(); + // --- Patrón Singleton --- ServiceMenu(); // Constructor privado ~ServiceMenu() = default; // Destructor privado