129 lines
4.9 KiB
C++
129 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#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<Text> element_text, std::shared_ptr<Text> 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<Text> element_text_;
|
|
std::shared_ptr<Text> 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<int, ServiceMenu::SETTINGS_GROUP_SIZE> 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<std::unique_ptr<MenuOption>> &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;
|
|
}; |