#pragma once #include #include #include #include #include "color.h" #include "text.h" 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} {} }; WindowMessage( std::shared_ptr 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& 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_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 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; };