clang-format

This commit is contained in:
2026-03-23 08:58:31 +01:00
parent 302b86ddb4
commit 3ca744ee46
88 changed files with 7147 additions and 7090 deletions

View File

@@ -5,81 +5,81 @@
namespace Logger {
// Colores ANSI
inline constexpr const char* RESET = "\033[0m";
inline constexpr const char* RED = "\033[31m";
inline constexpr const char* GREEN = "\033[32m";
inline constexpr const char* YELLOW = "\033[33m";
inline constexpr const char* BLUE = "\033[34m";
inline constexpr const char* MAGENTA = "\033[35m";
inline constexpr const char* CYAN = "\033[36m";
inline constexpr const char* WHITE = "\033[37m";
// Colores ANSI
inline constexpr const char* RESET = "\033[0m";
inline constexpr const char* RED = "\033[31m";
inline constexpr const char* GREEN = "\033[32m";
inline constexpr const char* YELLOW = "\033[33m";
inline constexpr const char* BLUE = "\033[34m";
inline constexpr const char* MAGENTA = "\033[35m";
inline constexpr const char* CYAN = "\033[36m";
inline constexpr const char* WHITE = "\033[37m";
// Ancho total global para alineación
inline constexpr size_t TOTAL_WIDTH = 52;
// Ancho total global para alineación
inline constexpr size_t TOTAL_WIDTH = 52;
// Sección
inline void section(const std::string& title, const std::string& color = CYAN) {
std::cout << "\n"
<< color
<< "========================================\n"
<< " " << title << "\n"
<< "========================================"
<< RESET << "\n";
}
// Info
inline void info(const std::string& msg, const std::string& color = WHITE) {
std::cout << " " << color << msg << RESET << "\n";
}
// Put
inline void put(const std::string& msg, const std::string& color = WHITE) {
std::cout << color << msg << RESET << "\n";
}
// Error
inline void error(const std::string& msg) {
std::cout << RED << msg << RESET << "\n";
}
// CR
inline void cr() {
std::cout << "\n";
}
// Dots genérico
inline void dots(const std::string& prefix,
const std::string& middle,
const std::string& suffix,
const std::string& suffix_color = GREEN) {
size_t field_width = TOTAL_WIDTH > (prefix.size() + suffix.size())
? TOTAL_WIDTH - prefix.size() - suffix.size()
: 0;
std::string field_text;
if (middle.size() < field_width) {
field_text = middle + std::string(field_width - middle.size(), '.');
} else {
field_text = middle.substr(0, field_width);
// Sección
inline void section(const std::string& title, const std::string& color = CYAN) {
std::cout << "\n"
<< color
<< "========================================\n"
<< " " << title << "\n"
<< "========================================"
<< RESET << "\n";
}
std::cout << " " << prefix << field_text
<< suffix_color << suffix << RESET
<< "\n";
}
// Status con true/false, usando dots y sufijos fijos
inline void status(const std::string& name, bool ok) {
// Ambos sufijos tienen 9 caracteres → alineación perfecta
constexpr const char* OK_LABEL = "[ OK ]";
constexpr const char* ERROR_LABEL = "[ ERROR ]";
if (ok) {
dots(" ", name, OK_LABEL, GREEN);
} else {
dots(" ", name, ERROR_LABEL, RED);
// Info
inline void info(const std::string& msg, const std::string& color = WHITE) {
std::cout << " " << color << msg << RESET << "\n";
}
// Put
inline void put(const std::string& msg, const std::string& color = WHITE) {
std::cout << color << msg << RESET << "\n";
}
// Error
inline void error(const std::string& msg) {
std::cout << RED << msg << RESET << "\n";
}
// CR
inline void cr() {
std::cout << "\n";
}
// Dots genérico
inline void dots(const std::string& prefix,
const std::string& middle,
const std::string& suffix,
const std::string& suffix_color = GREEN) {
size_t field_width = TOTAL_WIDTH > (prefix.size() + suffix.size())
? TOTAL_WIDTH - prefix.size() - suffix.size()
: 0;
std::string field_text;
if (middle.size() < field_width) {
field_text = middle + std::string(field_width - middle.size(), '.');
} else {
field_text = middle.substr(0, field_width);
}
std::cout << " " << prefix << field_text
<< suffix_color << suffix << RESET
<< "\n";
}
// Status con true/false, usando dots y sufijos fijos
inline void status(const std::string& name, bool ok) {
// Ambos sufijos tienen 9 caracteres → alineación perfecta
constexpr const char* OK_LABEL = "[ OK ]";
constexpr const char* ERROR_LABEL = "[ ERROR ]";
if (ok) {
dots(" ", name, OK_LABEL, GREEN);
} else {
dots(" ", name, ERROR_LABEL, RED);
}
}
}
} // namespace Logger

View File

@@ -13,207 +13,207 @@
// --- Clase MenuOption: interfaz base para todas las opciones del menú ---
class MenuOption {
public:
// --- Enums ---
enum class Behavior {
ADJUST, // Solo puede ajustar valor (como IntOption, BoolOption, ListOption)
SELECT, // Solo puede ejecutar acción (como ActionOption, FolderOption)
BOTH // Puede tanto ajustar como ejecutar acción (como ActionListOption)
};
public:
// --- Enums ---
enum class Behavior {
ADJUST, // Solo puede ajustar valor (como IntOption, BoolOption, ListOption)
SELECT, // Solo puede ejecutar acción (como ActionOption, FolderOption)
BOTH // Puede tanto ajustar como ejecutar acción (como ActionListOption)
};
// --- Constructor y destructor ---
MenuOption(std::string caption, ServiceMenu::SettingsGroup group, bool hidden = false)
: caption_(std::move(caption)),
group_(group),
hidden_(hidden) {}
virtual ~MenuOption() = default;
// --- Constructor y destructor ---
MenuOption(std::string caption, ServiceMenu::SettingsGroup group, bool hidden = false)
: caption_(std::move(caption)),
group_(group),
hidden_(hidden) {}
virtual ~MenuOption() = default;
// --- Getters ---
[[nodiscard]] auto getCaption() const -> const std::string& { return caption_; }
[[nodiscard]] auto getGroup() const -> ServiceMenu::SettingsGroup { return group_; }
[[nodiscard]] auto isHidden() const -> bool { return hidden_; }
void setHidden(bool hidden) { hidden_ = hidden; }
// --- Getters ---
[[nodiscard]] auto getCaption() const -> const std::string& { return caption_; }
[[nodiscard]] auto getGroup() const -> ServiceMenu::SettingsGroup { return group_; }
[[nodiscard]] auto isHidden() const -> bool { return hidden_; }
void setHidden(bool hidden) { hidden_ = hidden; }
[[nodiscard]] virtual auto getBehavior() const -> Behavior = 0;
[[nodiscard]] virtual auto getValueAsString() const -> std::string { return ""; }
virtual void adjustValue(bool adjust_up) {}
[[nodiscard]] virtual auto getTargetGroup() const -> ServiceMenu::SettingsGroup { return ServiceMenu::SettingsGroup::MAIN; }
virtual void executeAction() {}
[[nodiscard]] virtual auto getBehavior() const -> Behavior = 0;
[[nodiscard]] virtual auto getValueAsString() const -> std::string { return ""; }
virtual void adjustValue(bool adjust_up) {}
[[nodiscard]] virtual auto getTargetGroup() const -> ServiceMenu::SettingsGroup { return ServiceMenu::SettingsGroup::MAIN; }
virtual void executeAction() {}
virtual auto getMaxValueWidth(Text* text_renderer) const -> int { return 0; } // Método virtual para que cada opción calcule el ancho de su valor más largo
virtual auto getMaxValueWidth(Text* text_renderer) const -> int { return 0; } // Método virtual para que cada opción calcule el ancho de su valor más largo
protected:
// --- Variables ---
std::string caption_;
ServiceMenu::SettingsGroup group_;
bool hidden_;
protected:
// --- Variables ---
std::string caption_;
ServiceMenu::SettingsGroup group_;
bool hidden_;
};
// --- Clases Derivadas ---
class BoolOption : public MenuOption {
public:
BoolOption(const std::string& cap, ServiceMenu::SettingsGroup grp, bool* var)
: MenuOption(cap, grp),
linked_variable_(var) {}
public:
BoolOption(const std::string& cap, ServiceMenu::SettingsGroup grp, bool* var)
: MenuOption(cap, grp),
linked_variable_(var) {}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
[[nodiscard]] auto getValueAsString() const -> std::string override {
return *linked_variable_ ? Lang::getText("[SERVICE_MENU] ON") : Lang::getText("[SERVICE_MENU] OFF");
}
void adjustValue(bool /*adjust_up*/) override {
*linked_variable_ = !*linked_variable_;
}
auto getMaxValueWidth(Text* text_renderer) const -> int override {
return std::max(
text_renderer->length(Lang::getText("[SERVICE_MENU] ON"), -2),
text_renderer->length(Lang::getText("[SERVICE_MENU] OFF"), -2));
}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
[[nodiscard]] auto getValueAsString() const -> std::string override {
return *linked_variable_ ? Lang::getText("[SERVICE_MENU] ON") : Lang::getText("[SERVICE_MENU] OFF");
}
void adjustValue(bool /*adjust_up*/) override {
*linked_variable_ = !*linked_variable_;
}
auto getMaxValueWidth(Text* text_renderer) const -> int override {
return std::max(
text_renderer->length(Lang::getText("[SERVICE_MENU] ON"), -2),
text_renderer->length(Lang::getText("[SERVICE_MENU] OFF"), -2));
}
private:
bool* linked_variable_;
private:
bool* linked_variable_;
};
class IntOption : public MenuOption {
public:
IntOption(const std::string& cap, ServiceMenu::SettingsGroup grp, int* var, int min, int max, int step)
: MenuOption(cap, grp),
linked_variable_(var),
min_value_(min),
max_value_(max),
step_value_(step) {}
public:
IntOption(const std::string& cap, ServiceMenu::SettingsGroup grp, int* var, int min, int max, int step)
: MenuOption(cap, grp),
linked_variable_(var),
min_value_(min),
max_value_(max),
step_value_(step) {}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
[[nodiscard]] auto getValueAsString() const -> std::string override { return std::to_string(*linked_variable_); }
void adjustValue(bool adjust_up) override {
int new_value = *linked_variable_ + (adjust_up ? step_value_ : -step_value_);
*linked_variable_ = std::clamp(new_value, min_value_, max_value_);
}
auto getMaxValueWidth(Text* text_renderer) const -> int override {
int max_width = 0;
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
[[nodiscard]] auto getValueAsString() const -> std::string override { return std::to_string(*linked_variable_); }
void adjustValue(bool adjust_up) override {
int new_value = *linked_variable_ + (adjust_up ? step_value_ : -step_value_);
*linked_variable_ = std::clamp(new_value, min_value_, max_value_);
}
auto getMaxValueWidth(Text* text_renderer) const -> int override {
int max_width = 0;
// Iterar por todos los valores posibles en el rango
for (int value = min_value_; value <= max_value_; value += step_value_) {
int width = text_renderer->length(std::to_string(value), -2);
max_width = std::max(max_width, width);
}
return max_width;
// Iterar por todos los valores posibles en el rango
for (int value = min_value_; value <= max_value_; value += step_value_) {
int width = text_renderer->length(std::to_string(value), -2);
max_width = std::max(max_width, width);
}
private:
int* linked_variable_;
int min_value_, max_value_, step_value_;
return max_width;
}
private:
int* linked_variable_;
int min_value_, max_value_, step_value_;
};
class ListOption : public MenuOption {
public:
ListOption(const std::string& cap, ServiceMenu::SettingsGroup grp, std::vector<std::string> values, std::function<std::string()> current_value_getter, std::function<void(const std::string&)> new_value_setter)
: MenuOption(cap, grp),
value_list_(std::move(values)),
getter_(std::move(current_value_getter)),
setter_(std::move(new_value_setter)) {
sync();
}
public:
ListOption(const std::string& cap, ServiceMenu::SettingsGroup grp, std::vector<std::string> values, std::function<std::string()> current_value_getter, std::function<void(const std::string&)> new_value_setter)
: MenuOption(cap, grp),
value_list_(std::move(values)),
getter_(std::move(current_value_getter)),
setter_(std::move(new_value_setter)) {
sync();
}
void sync() {
std::string current_value = getter_();
for (size_t i = 0; i < value_list_.size(); ++i) {
if (value_list_[i] == current_value) {
list_index_ = i;
return;
}
}
}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
[[nodiscard]] auto getValueAsString() const -> std::string override {
return value_list_.empty() ? "" : value_list_[list_index_];
}
void adjustValue(bool adjust_up) override {
if (value_list_.empty()) {
void sync() {
std::string current_value = getter_();
for (size_t i = 0; i < value_list_.size(); ++i) {
if (value_list_[i] == current_value) {
list_index_ = i;
return;
}
size_t size = value_list_.size();
list_index_ = (adjust_up) ? (list_index_ + 1) % size
: (list_index_ + size - 1) % size;
setter_(value_list_[list_index_]);
}
auto getMaxValueWidth(Text* text_renderer) const -> int override {
int max_w = 0;
for (const auto& val : value_list_) {
max_w = std::max(max_w, text_renderer->length(val, -2));
}
return max_w;
}
}
private:
std::vector<std::string> value_list_;
std::function<std::string()> getter_;
std::function<void(const std::string&)> setter_;
size_t list_index_{0};
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; }
[[nodiscard]] auto getValueAsString() const -> std::string override {
return value_list_.empty() ? "" : value_list_[list_index_];
}
void adjustValue(bool adjust_up) override {
if (value_list_.empty()) {
return;
}
size_t size = value_list_.size();
list_index_ = (adjust_up) ? (list_index_ + 1) % size
: (list_index_ + size - 1) % size;
setter_(value_list_[list_index_]);
}
auto getMaxValueWidth(Text* text_renderer) const -> int override {
int max_w = 0;
for (const auto& val : value_list_) {
max_w = std::max(max_w, text_renderer->length(val, -2));
}
return max_w;
}
private:
std::vector<std::string> value_list_;
std::function<std::string()> getter_;
std::function<void(const std::string&)> setter_;
size_t list_index_{0};
};
class FolderOption : public MenuOption {
public:
FolderOption(const std::string& cap, ServiceMenu::SettingsGroup grp, ServiceMenu::SettingsGroup target)
: MenuOption(cap, grp),
target_group_(target) {}
public:
FolderOption(const std::string& cap, ServiceMenu::SettingsGroup grp, ServiceMenu::SettingsGroup target)
: MenuOption(cap, grp),
target_group_(target) {}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
[[nodiscard]] auto getTargetGroup() const -> ServiceMenu::SettingsGroup override { return target_group_; }
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
[[nodiscard]] auto getTargetGroup() const -> ServiceMenu::SettingsGroup override { return target_group_; }
private:
ServiceMenu::SettingsGroup target_group_;
private:
ServiceMenu::SettingsGroup target_group_;
};
class ActionOption : public MenuOption {
public:
ActionOption(const std::string& cap, ServiceMenu::SettingsGroup grp, std::function<void()> action, bool hidden = false)
: MenuOption(cap, grp, hidden),
action_(std::move(action)) {}
public:
ActionOption(const std::string& cap, ServiceMenu::SettingsGroup grp, std::function<void()> action, bool hidden = false)
: MenuOption(cap, grp, hidden),
action_(std::move(action)) {}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
void executeAction() override {
if (action_) {
action_();
}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
void executeAction() override {
if (action_) {
action_();
}
}
private:
std::function<void()> action_;
private:
std::function<void()> action_;
};
// Opción de lista con acción
class ActionListOption : public MenuOption {
public:
using ValueGetter = std::function<std::string()>;
using ValueSetter = std::function<void(const std::string&)>;
using ActionExecutor = std::function<void()>;
public:
using ValueGetter = std::function<std::string()>;
using ValueSetter = std::function<void(const std::string&)>;
using ActionExecutor = std::function<void()>;
ActionListOption(const std::string& caption, ServiceMenu::SettingsGroup group, std::vector<std::string> options, ValueGetter getter, ValueSetter setter, ActionExecutor action_executor, bool hidden = false)
: MenuOption(caption, group, hidden),
options_(std::move(options)),
value_getter_(std::move(getter)),
value_setter_(std::move(setter)),
action_executor_(std::move(action_executor)) {
updateCurrentIndex();
}
ActionListOption(const std::string& caption, ServiceMenu::SettingsGroup group, std::vector<std::string> options, ValueGetter getter, ValueSetter setter, ActionExecutor action_executor, bool hidden = false)
: MenuOption(caption, group, hidden),
options_(std::move(options)),
value_getter_(std::move(getter)),
value_setter_(std::move(setter)),
action_executor_(std::move(action_executor)) {
updateCurrentIndex();
}
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::BOTH; }
[[nodiscard]] auto getValueAsString() const -> std::string override;
[[nodiscard]] auto getMaxValueWidth(Text* text) const -> int override;
void adjustValue(bool up) override;
void executeAction() override;
void sync(); // Sincroniza con el valor actual
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::BOTH; }
[[nodiscard]] auto getValueAsString() const -> std::string override;
[[nodiscard]] auto getMaxValueWidth(Text* text) const -> int override;
void adjustValue(bool up) override;
void executeAction() override;
void sync(); // Sincroniza con el valor actual
private:
std::vector<std::string> options_;
ValueGetter value_getter_;
ValueSetter value_setter_;
ActionExecutor action_executor_;
size_t current_index_{0};
private:
std::vector<std::string> options_;
ValueGetter value_getter_;
ValueSetter value_setter_;
ActionExecutor action_executor_;
size_t current_index_{0};
void updateCurrentIndex();
[[nodiscard]] auto findCurrentIndex() const -> size_t;
void updateCurrentIndex();
[[nodiscard]] auto findCurrentIndex() const -> size_t;
};

View File

@@ -15,115 +15,115 @@ 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
};
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);
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, float delta_time);
// --- Métodos principales de la vista ---
void render(const ServiceMenu* menu_state);
void update(const ServiceMenu* menu_state, float delta_time);
// --- 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 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);
// --- 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);
// 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_; }
// 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_;
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;
// --- 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;
// --- 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;
// --- Límites de tamaño máximo ---
size_t max_menu_width_ = 0;
size_t max_menu_height_ = 0;
// --- Estructuras de Animación ---
struct ResizeAnimation {
bool active = false;
float start_width, start_height;
float target_width, target_height;
float elapsed = 0.0F;
float duration = 0.2F;
// --- Estructuras de Animación ---
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_;
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;
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_;
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_ = {};
// --- 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);
// --- 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 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]] static auto easeOut(float t) -> float;
[[nodiscard]] auto shouldShowContent() const -> bool;
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]] static auto easeOut(float t) -> float;
[[nodiscard]] auto shouldShowContent() const -> bool;
};

View File

@@ -15,98 +15,98 @@ class Texture;
// --- Clase Notifier: gestiona las notificaciones en pantalla (singleton) ---
class Notifier {
public:
// --- Enums ---
enum class Position {
TOP, // Parte superior
BOTTOM, // Parte inferior
LEFT, // Lado izquierdo
MIDDLE, // Centro
RIGHT, // Lado derecho
};
public:
// --- Enums ---
enum class Position {
TOP, // Parte superior
BOTTOM, // Parte inferior
LEFT, // Lado izquierdo
MIDDLE, // Centro
RIGHT, // Lado derecho
};
// --- Métodos de singleton ---
static void init(const std::string& icon_file, std::shared_ptr<Text> text); // Inicializa el singleton
static void destroy(); // Libera el singleton
static auto get() -> Notifier*; // Obtiene la instancia
// --- Métodos de singleton ---
static void init(const std::string& icon_file, std::shared_ptr<Text> text); // Inicializa el singleton
static void destroy(); // Libera el singleton
static auto get() -> Notifier*; // Obtiene la instancia
// --- Métodos principales ---
void render(); // Dibuja las notificaciones por pantalla
void update(float delta_time); // Actualiza el estado de las notificaciones
// --- Métodos principales ---
void render(); // Dibuja las notificaciones por pantalla
void update(float delta_time); // Actualiza el estado de las notificaciones
// --- Gestión de notificaciones ---
void show(std::vector<std::string> texts, int icon = -1, const std::string& code = std::string()); // Muestra una notificación de texto por pantalla
[[nodiscard]] auto isActive() const -> bool { return !notifications_.empty(); } // Indica si hay notificaciones activas
auto getCodes() -> std::vector<std::string>; // Obtiene los códigos de las notificaciones activas
auto checkCode(const std::string& code) -> bool { return stringInVector(getCodes(), code); } // Comprueba si hay alguna notificación con un código concreto
// --- Gestión de notificaciones ---
void show(std::vector<std::string> texts, int icon = -1, const std::string& code = std::string()); // Muestra una notificación de texto por pantalla
[[nodiscard]] auto isActive() const -> bool { return !notifications_.empty(); } // Indica si hay notificaciones activas
auto getCodes() -> std::vector<std::string>; // Obtiene los códigos de las notificaciones activas
auto checkCode(const std::string& code) -> bool { return stringInVector(getCodes(), code); } // Comprueba si hay alguna notificación con un código concreto
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float STAY_DURATION_S = 2.5F; // Tiempo que se ve la notificación (150 frames @ 60fps)
static constexpr float ANIMATION_SPEED_PX_PER_S = 60.0F; // Velocidad de animación (1 pixel/frame @ 60fps)
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float STAY_DURATION_S = 2.5F; // Tiempo que se ve la notificación (150 frames @ 60fps)
static constexpr float ANIMATION_SPEED_PX_PER_S = 60.0F; // Velocidad de animación (1 pixel/frame @ 60fps)
// --- Enums privados ---
enum class State {
RISING, // Apareciendo
STAY, // Visible
VANISHING, // Desapareciendo
FINISHED, // Terminada
};
// --- Enums privados ---
enum class State {
RISING, // Apareciendo
STAY, // Visible
VANISHING, // Desapareciendo
FINISHED, // Terminada
};
enum class Shape {
ROUNDED, // Forma redondeada
SQUARED, // Forma cuadrada
};
enum class Shape {
ROUNDED, // Forma redondeada
SQUARED, // Forma cuadrada
};
// --- Estructuras privadas ---
struct Notification {
std::shared_ptr<Texture> texture; // Textura de la notificación
std::shared_ptr<Sprite> sprite; // Sprite asociado
std::vector<std::string> texts; // Textos a mostrar
SDL_FRect rect; // Rectángulo de la notificación
std::string code; // Código identificador de la notificación
State state{State::RISING}; // Estado de la notificación
Shape shape{Shape::SQUARED}; // Forma de la notificación
float timer{0.0F}; // Timer en segundos
int y{0}; // Posición vertical
int travel_dist{0}; // Distancia a recorrer
// --- Estructuras privadas ---
struct Notification {
std::shared_ptr<Texture> texture; // Textura de la notificación
std::shared_ptr<Sprite> sprite; // Sprite asociado
std::vector<std::string> texts; // Textos a mostrar
SDL_FRect rect; // Rectángulo de la notificación
std::string code; // Código identificador de la notificación
State state{State::RISING}; // Estado de la notificación
Shape shape{Shape::SQUARED}; // Forma de la notificación
float timer{0.0F}; // Timer en segundos
int y{0}; // Posición vertical
int travel_dist{0}; // Distancia a recorrer
// Constructor
explicit Notification()
: texture(nullptr),
sprite(nullptr),
rect{0, 0, 0, 0} {}
};
// Constructor
explicit Notification()
: texture(nullptr),
sprite(nullptr),
rect{0, 0, 0, 0} {}
};
// --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
std::shared_ptr<Text> text_; // Objeto para dibujar texto
// --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
std::shared_ptr<Text> text_; // Objeto para dibujar texto
// --- Variables de estado ---
std::vector<Notification> notifications_; // Lista de notificaciones activas
Color bg_color_; // Color de fondo de las notificaciones
// Nota: wait_time_ eliminado, ahora se usa STAY_DURATION_S
bool stack_; // Indica si las notificaciones se apilan
bool has_icons_; // Indica si el notificador tiene textura para iconos
// --- Variables de estado ---
std::vector<Notification> notifications_; // Lista de notificaciones activas
Color bg_color_; // Color de fondo de las notificaciones
// Nota: wait_time_ eliminado, ahora se usa STAY_DURATION_S
bool stack_; // Indica si las notificaciones se apilan
bool has_icons_; // Indica si el notificador tiene textura para iconos
// --- Métodos internos ---
void clearFinishedNotifications(); // Elimina las notificaciones cuyo estado es FINISHED
void clearAllNotifications(); // Elimina todas las notificaciones activas, sin importar el estado
[[nodiscard]] auto shouldProcessNotification(int index) const -> bool; // Determina si una notificación debe ser procesada (según su estado y posición)
void processNotification(int index, float delta_time); // Procesa una notificación en la posición dada: actualiza su estado y comportamiento visual
static void playNotificationSoundIfNeeded(const Notification& notification); // Reproduce sonido asociado si es necesario (dependiendo del estado o contenido)
void updateNotificationState(int index, float delta_time); // Actualiza el estado interno de una notificación (ej. de RISING a STAY)
void handleRisingState(int index, float delta_time); // Lógica de animación para el estado RISING (apareciendo)
void handleStayState(int index); // Lógica para mantener una notificación visible en el estado STAY
void handleVanishingState(int index, float delta_time); // Lógica de animación para el estado VANISHING (desapareciendo)
static void moveNotificationVertically(Notification& notification, float pixels_to_move); // Mueve verticalmente una notificación con la cantidad de pixels especificada
void transitionToStayState(int index); // Cambia el estado de una notificación de RISING a STAY cuando ha alcanzado su posición final
// --- Métodos internos ---
void clearFinishedNotifications(); // Elimina las notificaciones cuyo estado es FINISHED
void clearAllNotifications(); // Elimina todas las notificaciones activas, sin importar el estado
[[nodiscard]] auto shouldProcessNotification(int index) const -> bool; // Determina si una notificación debe ser procesada (según su estado y posición)
void processNotification(int index, float delta_time); // Procesa una notificación en la posición dada: actualiza su estado y comportamiento visual
static void playNotificationSoundIfNeeded(const Notification& notification); // Reproduce sonido asociado si es necesario (dependiendo del estado o contenido)
void updateNotificationState(int index, float delta_time); // Actualiza el estado interno de una notificación (ej. de RISING a STAY)
void handleRisingState(int index, float delta_time); // Lógica de animación para el estado RISING (apareciendo)
void handleStayState(int index); // Lógica para mantener una notificación visible en el estado STAY
void handleVanishingState(int index, float delta_time); // Lógica de animación para el estado VANISHING (desapareciendo)
static void moveNotificationVertically(Notification& notification, float pixels_to_move); // Mueve verticalmente una notificación con la cantidad de pixels especificada
void transitionToStayState(int index); // Cambia el estado de una notificación de RISING a STAY cuando ha alcanzado su posición final
// --- Constructores y destructor privados (singleton) ---
Notifier(const std::string& icon_file, std::shared_ptr<Text> text); // Constructor privado
~Notifier() = default; // Destructor privado
// --- Constructores y destructor privados (singleton) ---
Notifier(const std::string& icon_file, std::shared_ptr<Text> text); // Constructor privado
~Notifier() = default; // Destructor privado
// --- Instancia singleton ---
static Notifier* instance; // Instancia única de Notifier
// --- Instancia singleton ---
static Notifier* instance; // Instancia única de Notifier
};

View File

@@ -17,112 +17,112 @@ class MenuOption;
class MenuRenderer;
class ServiceMenu {
public:
// --- Enums y constantes ---
enum class SettingsGroup {
CONTROLS,
VIDEO,
AUDIO,
SETTINGS,
SYSTEM,
MAIN
};
enum class GroupAlignment {
CENTERED,
LEFT
};
static constexpr size_t OPTIONS_HORIZONTAL_PADDING = 20;
static constexpr size_t MIN_WIDTH = 240;
static constexpr size_t MIN_GAP_OPTION_VALUE = 30;
static constexpr size_t SETTINGS_GROUP_SIZE = 6;
public:
// --- Enums y constantes ---
enum class SettingsGroup {
CONTROLS,
VIDEO,
AUDIO,
SETTINGS,
SYSTEM,
MAIN
};
enum class GroupAlignment {
CENTERED,
LEFT
};
static constexpr size_t OPTIONS_HORIZONTAL_PADDING = 20;
static constexpr size_t MIN_WIDTH = 240;
static constexpr size_t MIN_GAP_OPTION_VALUE = 30;
static constexpr size_t SETTINGS_GROUP_SIZE = 6;
using StateChangeCallback = std::function<void(bool is_active)>;
using StateChangeCallback = std::function<void(bool is_active)>;
// --- Métodos de singleton ---
static void init();
static void destroy();
static auto get() -> ServiceMenu*;
ServiceMenu(const ServiceMenu&) = delete;
auto operator=(const ServiceMenu&) -> ServiceMenu& = delete;
// --- Métodos de singleton ---
static void init();
static void destroy();
static auto get() -> ServiceMenu*;
ServiceMenu(const ServiceMenu&) = delete;
auto operator=(const ServiceMenu&) -> ServiceMenu& = delete;
// --- Métodos principales ---
void toggle();
void render();
void update(float delta_time);
void reset();
// --- Métodos principales ---
void toggle();
void render();
void update(float delta_time);
void reset();
// --- Lógica de navegación ---
void setSelectorUp();
void setSelectorDown();
void adjustOption(bool adjust_up);
void selectOption();
void moveBack();
// --- Lógica de navegación ---
void setSelectorUp();
void setSelectorDown();
void adjustOption(bool adjust_up);
void selectOption();
void moveBack();
// --- Método para manejar eventos ---
void handleEvent(const SDL_Event& event);
auto checkInput() -> bool;
// --- Método para manejar eventos ---
void handleEvent(const SDL_Event& event);
auto checkInput() -> bool;
// --- Método principal para refresco externo ---
void refresh(); // Refresca los valores y el layout del menú bajo demanda
// --- Método principal para refresco externo ---
void refresh(); // Refresca los valores y el layout del menú bajo demanda
// --- Método para registrar el callback ---
void setStateChangeCallback(StateChangeCallback callback);
// --- Método para registrar el callback ---
void setStateChangeCallback(StateChangeCallback callback);
// --- Getters para el estado ---
[[nodiscard]] auto isDefiningButtons() const -> bool;
[[nodiscard]] auto isAnimating() const -> bool; // Nuevo getter
// --- Getters para el estado ---
[[nodiscard]] auto isDefiningButtons() const -> bool;
[[nodiscard]] auto isAnimating() const -> bool; // Nuevo getter
// --- Getters para que el Renderer pueda leer el estado ---
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
[[nodiscard]] auto getTitle() const -> const std::string& { return title_; }
[[nodiscard]] auto getCurrentGroup() const -> SettingsGroup { return current_settings_group_; }
[[nodiscard]] auto getCurrentGroupAlignment() const -> GroupAlignment;
[[nodiscard]] auto getDisplayOptions() const -> const std::vector<MenuOption*>& { return display_options_; }
[[nodiscard]] auto getAllOptions() const -> const std::vector<std::unique_ptr<MenuOption>>& { return options_; }
[[nodiscard]] auto getSelectedIndex() const -> size_t { return selected_; }
[[nodiscard]] auto getOptionPairs() const -> const std::vector<std::pair<std::string, std::string>>& { return option_pairs_; }
[[nodiscard]] auto countOptionsInGroup(SettingsGroup group) const -> size_t;
// --- Getters para que el Renderer pueda leer el estado ---
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
[[nodiscard]] auto getTitle() const -> const std::string& { return title_; }
[[nodiscard]] auto getCurrentGroup() const -> SettingsGroup { return current_settings_group_; }
[[nodiscard]] auto getCurrentGroupAlignment() const -> GroupAlignment;
[[nodiscard]] auto getDisplayOptions() const -> const std::vector<MenuOption*>& { return display_options_; }
[[nodiscard]] auto getAllOptions() const -> const std::vector<std::unique_ptr<MenuOption>>& { return options_; }
[[nodiscard]] auto getSelectedIndex() const -> size_t { return selected_; }
[[nodiscard]] auto getOptionPairs() const -> const std::vector<std::pair<std::string, std::string>>& { return option_pairs_; }
[[nodiscard]] auto countOptionsInGroup(SettingsGroup group) const -> size_t;
private:
bool enabled_ = false;
std::vector<std::unique_ptr<MenuOption>> options_;
std::vector<MenuOption*> display_options_;
std::vector<std::pair<std::string, std::string>> option_pairs_;
SettingsGroup current_settings_group_;
SettingsGroup previous_settings_group_;
std::string title_;
size_t selected_ = 0;
size_t main_menu_selected_ = 0;
std::unique_ptr<UIMessage> restart_message_ui_;
bool last_pending_changes_ = false;
std::unique_ptr<DefineButtons> define_buttons_;
std::unique_ptr<MenuRenderer> renderer_;
StateChangeCallback state_change_callback_;
private:
bool enabled_ = false;
std::vector<std::unique_ptr<MenuOption>> options_;
std::vector<MenuOption*> display_options_;
std::vector<std::pair<std::string, std::string>> option_pairs_;
SettingsGroup current_settings_group_;
SettingsGroup previous_settings_group_;
std::string title_;
size_t selected_ = 0;
size_t main_menu_selected_ = 0;
std::unique_ptr<UIMessage> restart_message_ui_;
bool last_pending_changes_ = false;
std::unique_ptr<DefineButtons> define_buttons_;
std::unique_ptr<MenuRenderer> renderer_;
StateChangeCallback state_change_callback_;
// --- Métodos de lógica interna ---
void updateDisplayOptions();
void updateOptionPairs();
void initializeOptions();
void updateMenu();
void applySettings();
void applyControlsSettings();
void applyVideoSettings();
static void applyAudioSettings();
void applySettingsSettings();
[[nodiscard]] auto getOptionByCaption(const std::string& caption) const -> MenuOption*;
void adjustListValues();
static void playMoveSound();
static void playAdjustSound();
static void playSelectSound();
static void playBackSound();
[[nodiscard]] static auto settingsGroupToString(SettingsGroup group) -> std::string;
void setHiddenOptions();
void setEnabledInternal(bool enabled); // Método privado para cambiar estado y notificar
// --- Métodos de lógica interna ---
void updateDisplayOptions();
void updateOptionPairs();
void initializeOptions();
void updateMenu();
void applySettings();
void applyControlsSettings();
void applyVideoSettings();
static void applyAudioSettings();
void applySettingsSettings();
[[nodiscard]] auto getOptionByCaption(const std::string& caption) const -> MenuOption*;
void adjustListValues();
static void playMoveSound();
static void playAdjustSound();
static void playSelectSound();
static void playBackSound();
[[nodiscard]] static auto settingsGroupToString(SettingsGroup group) -> std::string;
void setHiddenOptions();
void setEnabledInternal(bool enabled); // Método privado para cambiar estado y notificar
// --- Constructores y destructor privados (singleton) ---
ServiceMenu();
~ServiceMenu() = default;
// --- Constructores y destructor privados (singleton) ---
ServiceMenu();
~ServiceMenu() = default;
// --- Instancia singleton ---
static ServiceMenu* instance;
// --- Instancia singleton ---
static ServiceMenu* instance;
};

View File

@@ -9,48 +9,48 @@ class Text;
// Clase para mostrar mensajes animados en la interfaz de usuario
class UIMessage {
public:
// Constructor: recibe el renderizador de texto, el mensaje y el color
UIMessage(std::shared_ptr<Text> text_renderer, std::string message_text, const Color& color);
public:
// Constructor: recibe el renderizador de texto, el mensaje y el color
UIMessage(std::shared_ptr<Text> text_renderer, std::string message_text, const Color& color);
// Muestra el mensaje con animación de entrada
void show();
// Muestra el mensaje con animación de entrada
void show();
// Oculta el mensaje con animación de salida
void hide();
// Oculta el mensaje con animación de salida
void hide();
// Actualiza el estado de la animación (debe llamarse cada frame)
void update(float delta_time);
// Actualiza el estado de la animación (debe llamarse cada frame)
void update(float delta_time);
// Dibuja el mensaje en pantalla si está visible
void render();
// Dibuja el mensaje en pantalla si está visible
void render();
// Indica si el mensaje está visible actualmente
[[nodiscard]] auto isVisible() const -> bool;
// Indica si el mensaje está visible actualmente
[[nodiscard]] auto isVisible() const -> bool;
// Permite actualizar la posición del mensaje (por ejemplo, si el menú se mueve)
void setPosition(float new_base_x, float new_base_y);
// Permite actualizar la posición del mensaje (por ejemplo, si el menú se mueve)
void setPosition(float new_base_x, float new_base_y);
private:
// --- Configuración ---
std::shared_ptr<Text> text_renderer_; // Renderizador de texto
std::string text_; // Texto del mensaje a mostrar
Color color_; // Color del texto
private:
// --- Configuración ---
std::shared_ptr<Text> text_renderer_; // Renderizador de texto
std::string text_; // Texto del mensaje a mostrar
Color color_; // Color del texto
// --- Estado ---
bool visible_ = false; // Indica si el mensaje está visible
bool animating_ = false; // Indica si el mensaje está en proceso de animación
float base_x_ = 0.0F; // Posición X base donde se muestra el mensaje
float base_y_ = 0.0F; // Posición Y base donde se muestra el mensaje
float y_offset_ = 0.0F; // Desplazamiento vertical actual del mensaje (para animación)
// --- Estado ---
bool visible_ = false; // Indica si el mensaje está visible
bool animating_ = false; // Indica si el mensaje está en proceso de animación
float base_x_ = 0.0F; // Posición X base donde se muestra el mensaje
float base_y_ = 0.0F; // Posición Y base donde se muestra el mensaje
float y_offset_ = 0.0F; // Desplazamiento vertical actual del mensaje (para animación)
// --- Animación ---
float start_y_ = 0.0F; // Posición Y inicial de la animación
float target_y_ = 0.0F; // Posición Y objetivo de la animación
float animation_timer_ = 0.0F; // Timer actual de la animación en segundos
static constexpr float ANIMATION_DURATION_S = 0.133F; // Duración total de la animación (8 frames @ 60fps)
static constexpr float DESP = -8.0F; // Distancia a desplazarse
// --- Animación ---
float start_y_ = 0.0F; // Posición Y inicial de la animación
float target_y_ = 0.0F; // Posición Y objetivo de la animación
float animation_timer_ = 0.0F; // Timer actual de la animación en segundos
static constexpr float ANIMATION_DURATION_S = 0.133F; // Duración total de la animación (8 frames @ 60fps)
static constexpr float DESP = -8.0F; // Distancia a desplazarse
// Actualiza la interpolación de la animación (ease out/in cubic)
void updateAnimation(float delta_time);
// Actualiza la interpolación de la animación (ease out/in cubic)
void updateAnimation(float delta_time);
};

View File

@@ -12,232 +12,232 @@
#include "text.hpp" // 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
};
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;
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
// 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
// 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
// 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
// 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 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) {}
};
// 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{});
WindowMessage(
std::shared_ptr<Text> text_renderer,
std::string title = "",
const Config& config = Config{});
// Métodos principales
void render();
void update(float delta_time);
// Métodos principales
void render();
void update(float delta_time);
// 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; }
// 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();
// 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_; }
// 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 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 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;
}
// 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();
void stop() {
active = false;
elapsed = 0.0F;
}
[[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_; }
[[nodiscard]] auto isFinished(float duration) const -> bool {
return elapsed >= duration;
}
private:
std::shared_ptr<Text> text_renderer_;
Config config_;
[[nodiscard]] auto getProgress(float duration) const -> float {
return std::min(elapsed / duration, 1.0F);
}
} resize_animation_;
// Estado de visibilidad y redimensionado
bool visible_ = false;
bool auto_resize_enabled_ = true; // Por defecto habilitado
// Animación de mostrar/ocultar
struct ShowHideAnimation {
enum class Type { NONE,
SHOWING,
HIDING };
// Contenido
std::string title_;
std::vector<std::string> texts_;
Type type = Type::NONE;
bool active = false;
float target_width, target_height; // Tamaño final al mostrar
float elapsed = 0.0F;
// Posición y tamaño
SDL_FRect rect_{0, 0, 300, 200};
PositionMode position_mode_ = PositionMode::CENTERED;
SDL_FPoint anchor_{0.0F, 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;
}
// Animación de redimensionado
struct ResizeAnimation {
bool active = false;
float start_width, start_height;
float target_width, target_height;
float elapsed = 0.0F;
void startHide() {
type = Type::HIDING;
elapsed = 0.0F;
active = true;
}
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() {
type = Type::NONE;
active = false;
elapsed = 0.0F;
}
void stop() {
active = false;
elapsed = 0.0F;
}
[[nodiscard]] auto isFinished(float duration) const -> bool {
return elapsed >= duration;
}
[[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_;
[[nodiscard]] auto getProgress(float duration) const -> float {
return std::min(elapsed / duration, 1.0F);
}
} resize_animation_;
// Estilos
Text::Style title_style_;
Text::Style text_style_;
// Animación de mostrar/ocultar
struct ShowHideAnimation {
enum class Type { NONE,
SHOWING,
HIDING };
// 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
Type type = Type::NONE;
bool active = false;
float target_width, target_height; // Tamaño final al mostrar
float elapsed = 0.0F;
// Función de suavizado (ease-out)
[[nodiscard]] static auto easeOut(float t) -> float;
void startShow(float to_w, float to_h) {
type = Type::SHOWING;
target_width = to_w;
target_height = to_h;
elapsed = 0.0F;
active = true;
}
// 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.)
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;
[[nodiscard]] auto calculateContentHeight() const -> float;
[[nodiscard]] auto calculateContentWidth() const -> float;
[[nodiscard]] static auto getScreenWidth() -> float;
[[nodiscard]] static auto getScreenHeight() -> float;
};