Files
coffee_crisis_arcade_edition/source/ui/window_message.h

243 lines
9.7 KiB
C++

#pragma once
#include <SDL3/SDL.h> // Para SDL_FPoint, SDL_FRect
#include <algorithm> // Para min
#include <memory> // Para allocator, shared_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "color.h" // Para Color
#include "param.h" // Para param
#include "text.h" // Para Text
class WindowMessage {
public:
enum class PositionMode {
CENTERED, // La ventana se centra en el punto especificado
FIXED // La esquina superior izquierda coincide con el punto
};
struct Config {
// Colores
Color bg_color;
Color border_color;
Color title_color;
Color text_color;
// Espaciado y dimensiones
float padding{15.0F};
float line_spacing{5.0F};
float title_separator_spacing{10.0F}; // Espacio extra para separador del título
// Límites de tamaño
float min_width{200.0F};
float min_height{100.0F};
float max_width_ratio{0.8F}; // % máximo de ancho de pantalla
float max_height_ratio{0.8F}; // % máximo de alto de pantalla
// Margen de seguridad para texto
float text_safety_margin{20.0F}; // Margen extra para evitar texto cortado
// Animaciones
float animation_duration{0.3F}; // Duración en segundos para todas las animaciones
// Constructor con valores por defecto
Config()
: bg_color{40, 40, 60, 220},
border_color{100, 100, 120, 255},
title_color{255, 255, 255, 255},
text_color{200, 200, 200, 255} {}
// Constructor que convierte desde ParamServiceMenu::WindowMessage
Config(const ParamServiceMenu::WindowMessage& param_config)
: bg_color(param_config.bg_color),
border_color(param_config.border_color),
title_color(param_config.title_color),
text_color(param_config.text_color),
padding(param_config.padding),
line_spacing(param_config.line_spacing),
title_separator_spacing(param_config.title_separator_spacing),
min_width(param_config.min_width),
min_height(param_config.min_height),
max_width_ratio(param_config.max_width_ratio),
max_height_ratio(param_config.max_height_ratio),
text_safety_margin(param_config.text_safety_margin),
animation_duration(param_config.animation_duration) {}
};
WindowMessage(
std::shared_ptr<Text> text_renderer,
std::string title = "",
const Config& config = Config{});
// Métodos principales
void render();
void update();
// Control de visibilidad
void show();
void hide();
[[nodiscard]] auto isVisible() const -> bool { return visible_; }
[[nodiscard]] auto isFullyVisible() const -> bool { return visible_ && !show_hide_animation_.active; }
[[nodiscard]] auto isAnimating() const -> bool { return resize_animation_.active || show_hide_animation_.active; }
// Configuración de contenido
void setTitle(const std::string& title);
void setText(const std::string& text);
void setTexts(const std::vector<std::string>& texts);
void addText(const std::string& text);
void clearTexts();
// Control de redimensionado automático
void enableAutoResize(bool enabled) { auto_resize_enabled_ = enabled; }
[[nodiscard]] auto isAutoResizeEnabled() const -> bool { return auto_resize_enabled_; }
// Configuración de posición y tamaño
void setPosition(float x, float y, PositionMode mode = PositionMode::CENTERED);
void setSize(float width, float height);
void centerOnScreen();
void autoSize(); // Ajusta automáticamente al contenido y reposiciona si es necesario
// Configuración de colores
void setBackgroundColor(const Color& color) { config_.bg_color = color; }
void setBorderColor(const Color& color) { config_.border_color = color; }
void setTitleColor(const Color& color) {
config_.title_color = color;
updateStyles();
}
void setTextColor(const Color& color) {
config_.text_color = color;
updateStyles();
}
// Configuración de espaciado
void setPadding(float padding) { config_.padding = padding; }
void setLineSpacing(float spacing) { config_.line_spacing = spacing; }
// Configuración avanzada
void setConfig(const Config& config) {
config_ = config;
updateStyles();
}
[[nodiscard]] auto getConfig() const -> const Config& { return config_; }
// Getters
[[nodiscard]] auto getRect() const -> const SDL_FRect& { return rect_; }
[[nodiscard]] auto getPositionMode() const -> PositionMode { return position_mode_; }
[[nodiscard]] auto getAnchorPoint() const -> SDL_FPoint { return anchor_; }
private:
std::shared_ptr<Text> text_renderer_;
Config config_;
// Estado de visibilidad y redimensionado
bool visible_ = false;
bool auto_resize_enabled_ = true; // Por defecto habilitado
// Contenido
std::string title_;
std::vector<std::string> texts_;
// Posición y tamaño
SDL_FRect rect_{0, 0, 300, 200};
PositionMode position_mode_ = PositionMode::CENTERED;
SDL_FPoint anchor_{0.0F, 0.0F};
// Animación de redimensionado
struct ResizeAnimation {
bool active = false;
float start_width, start_height;
float target_width, target_height;
float elapsed = 0.0F;
void start(float from_w, float from_h, float to_w, float to_h) {
start_width = from_w;
start_height = from_h;
target_width = to_w;
target_height = to_h;
elapsed = 0.0F;
active = true;
}
void stop() {
active = false;
elapsed = 0.0F;
}
[[nodiscard]] auto isFinished(float duration) const -> bool {
return elapsed >= duration;
}
[[nodiscard]] auto getProgress(float duration) const -> float {
return std::min(elapsed / duration, 1.0F);
}
} resize_animation_;
// Animación de mostrar/ocultar
struct ShowHideAnimation {
enum class Type { NONE,
SHOWING,
HIDING };
Type type = Type::NONE;
bool active = false;
float target_width, target_height; // Tamaño final al mostrar
float elapsed = 0.0F;
void startShow(float to_w, float to_h) {
type = Type::SHOWING;
target_width = to_w;
target_height = to_h;
elapsed = 0.0F;
active = true;
}
void startHide() {
type = Type::HIDING;
elapsed = 0.0F;
active = true;
}
void stop() {
type = Type::NONE;
active = false;
elapsed = 0.0F;
}
[[nodiscard]] auto isFinished(float duration) const -> bool {
return elapsed >= duration;
}
[[nodiscard]] auto getProgress(float duration) const -> float {
return std::min(elapsed / duration, 1.0F);
}
} show_hide_animation_;
// Estilos
Text::Style title_style_;
Text::Style text_style_;
// Métodos privados
void calculateAutoSize();
void updatePosition(); // Actualiza la posición según el modo y punto de anclaje
void updateStyles(); // Actualiza los estilos de texto cuando cambian los colores
void ensureTextFits(); // Verifica y ajusta para que todo el texto sea visible
void triggerAutoResize(); // Inicia redimensionado automático si está habilitado
void updateAnimation(float delta_time); // Actualiza la animación de redimensionado
void updateShowHideAnimation(float delta_time); // Actualiza la animación de mostrar/ocultar
void updateResizeAnimation(float delta_time); // Actualiza la animación de redimensionado
// Función de suavizado (ease-out)
[[nodiscard]] static auto easeOut(float t) -> float;
// Métodos para manejo de texto durante animación
[[nodiscard]] auto getTruncatedText(const std::string& text, float available_width) const -> std::string;
[[nodiscard]] auto getAvailableTextWidth() const -> float;
[[nodiscard]] auto shouldShowContent() const -> bool; // Si mostrar el contenido (texto, líneas, etc.)
[[nodiscard]] auto calculateContentHeight() const -> float;
[[nodiscard]] auto calculateContentWidth() const -> float;
[[nodiscard]] static auto getScreenWidth() -> float;
[[nodiscard]] static auto getScreenHeight() -> float;
};