#pragma once #include #include #include #include #include #include #include "color.h" #include "ui/service_menu.h" class MenuOption; 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 element_text, std::shared_ptr title_text); // --- 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); // Getters [[nodiscard]] auto getRect() const -> const SDL_FRect & { return rect_; } private: // --- Referencias a los renderizadores de texto --- std::shared_ptr element_text_; std::shared_ptr title_text_; // --- Variables de estado de la vista (layout y animación) --- SDL_FRect rect_{}; SDL_FRect border_rect_{}; size_t width_ = 0; size_t height_ = 0; size_t options_height_ = 0; size_t options_padding_ = 0; size_t options_y_ = 0; size_t title_height_ = 0; size_t title_padding_ = 0; size_t upper_height_ = 0; 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; // --- 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 group_menu_widths_ = {}; // --- Métodos privados de la vista --- void initializeMaxSizes(); void setAnchors(const ServiceMenu *menu_state); auto calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect; void resize(const ServiceMenu *menu_state); void setSize(const ServiceMenu *menu_state); void updateAnimations(float delta_time); void updateResizeAnimation(float delta_time); void updateShowHideAnimation(float delta_time); void updatePosition(); void precalculateMenuWidths(const std::vector> &all_options, const ServiceMenu *menu_state); [[nodiscard]] auto getMenuWidthForGroup(ServiceMenu::SettingsGroup group) const -> int; [[nodiscard]] auto getAnimatedSelectedColor() const -> Color; void updateColorCounter(); 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; };