ServiceMenu: afegida animació de apertura/tancament

This commit is contained in:
2025-08-09 20:44:56 +02:00
parent 5a02518de3
commit 2b35ac0187
4 changed files with 351 additions and 209 deletions

View File

@@ -1,28 +1,43 @@
#pragma once
#include <SDL3/SDL.h> // Para SDL_FRect, Uint32
#include <SDL3/SDL.h>
#include <array> // Para array
#include <cstddef> // Para size_t
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include <vector> // Para vector
#include <array>
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
#include "color.h" // Para Color
#include "ui/service_menu.h" // Para ServiceMenu
#include "color.h"
#include "ui/service_menu.h"
class MenuOption;
// Forward declarations
class Text;
class MenuRenderer {
public:
// --- Nuevo: Enum para el modo de posicionamiento ---
enum class PositionMode {
CENTERED, // La ventana se centra en el punto especificado
FIXED // La esquina superior izquierda coincide con el punto
};
MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text);
// Métodos principales de la vista
// --- Métodos principales de la vista ---
void render(const ServiceMenu *menu_state);
void update(const ServiceMenu *menu_state);
// --- Nuevos: Métodos de control de visibilidad y animación ---
void show(const ServiceMenu *menu_state);
void hide();
[[nodiscard]] auto isVisible() const -> bool { return visible_; }
[[nodiscard]] auto isFullyVisible() const -> bool { return visible_ && !show_hide_animation_.active && !resize_animation_.active; }
[[nodiscard]] auto isAnimating() const -> bool { return resize_animation_.active || show_hide_animation_.active; }
// --- Nuevos: Métodos de configuración de posición ---
void setPosition(float x, float y, PositionMode mode);
// Método para notificar al renderer que el layout puede haber cambiado
void onLayoutChanged(const ServiceMenu *menu_state);
void setLayout(const ServiceMenu *menu_state);
@@ -49,17 +64,41 @@ class MenuRenderer {
size_t lower_height_ = 0;
size_t lower_padding_ = 0;
Uint32 color_counter_ = 0;
bool visible_ = false;
// --- Posicionamiento ---
PositionMode position_mode_ = PositionMode::CENTERED;
float anchor_x_ = 0.0f;
float anchor_y_ = 0.0f;
// --- Límites de tamaño máximo ---
size_t max_menu_width_ = 0;
size_t max_menu_height_ = 0;
// --- Variables para animación de resize ---
SDL_FRect rect_anim_from_{};
SDL_FRect rect_anim_to_{};
int resize_anim_step_ = 0;
int resize_anim_steps_ = 8;
bool resizing_ = false;
// --- Estructuras de Animación (inspirado en WindowMessage) ---
struct ResizeAnimation {
bool active = false;
float start_width, start_height;
float target_width, target_height;
float elapsed = 0.0f;
float duration = 0.2f;
void start(float from_w, float from_h, float to_w, float to_h);
void stop();
} resize_animation_;
struct ShowHideAnimation {
enum class Type { NONE, SHOWING, HIDING };
Type type = Type::NONE;
bool active = false;
float target_width, target_height;
float elapsed = 0.0f;
float duration = 0.25f;
void startShow(float to_w, float to_h);
void startHide();
void stop();
} show_hide_animation_;
// --- Anchos precalculados ---
std::array<int, ServiceMenu::SETTINGS_GROUP_SIZE> group_menu_widths_ = {};
@@ -70,7 +109,12 @@ class MenuRenderer {
auto calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect;
void resize(const ServiceMenu *menu_state);
void setSize(const ServiceMenu *menu_state);
void updateResizeAnimation();
void updateAnimations(float delta_time);
void updateResizeAnimation(float delta_time);
void updateShowHideAnimation(float delta_time);
void updatePosition();
void precalculateMenuWidths(const std::vector<std::unique_ptr<MenuOption>> &all_options, const ServiceMenu *menu_state);
[[nodiscard]] auto getMenuWidthForGroup(ServiceMenu::SettingsGroup group) const -> int;
[[nodiscard]] auto getAnimatedSelectedColor() const -> Color;
@@ -78,4 +122,6 @@ class MenuRenderer {
auto setRect(SDL_FRect rect) -> SDL_FRect;
[[nodiscard]] auto getTruncatedValueWidth(const std::string &value, int available_width) const -> int;
[[nodiscard]] auto getTruncatedValue(const std::string &value, int available_width) const -> std::string;
[[nodiscard]] auto easeOut(float t) const -> float;
[[nodiscard]] auto shouldShowContent() const -> bool;
};