UIMessage: creada
This commit is contained in:
81
source/UIMessage.cpp
Normal file
81
source/UIMessage.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "UIMessage.h"
|
||||||
|
#include <cmath> // Para pow
|
||||||
|
#include "screen.h" // Para param y TEXT_CENTER
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, const std::string& message_text, const Color& color)
|
||||||
|
: text_renderer_(text_renderer), text_(message_text), color_(color)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMessage::show(float base_x, float base_y)
|
||||||
|
{
|
||||||
|
if (visible_ && target_y_ == 0.0f) return; // Ya está visible y quieto
|
||||||
|
|
||||||
|
base_x_ = base_x;
|
||||||
|
base_y_ = base_y;
|
||||||
|
start_y_ = -8.0f; // Empieza 8 píxeles arriba
|
||||||
|
target_y_ = 0.0f; // La posición final es el base_y
|
||||||
|
y_offset_ = start_y_;
|
||||||
|
anim_step_ = 0;
|
||||||
|
animating_ = true;
|
||||||
|
visible_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMessage::hide()
|
||||||
|
{
|
||||||
|
if (!visible_) return;
|
||||||
|
|
||||||
|
start_y_ = y_offset_;
|
||||||
|
target_y_ = -8.0f; // Sube 8 píxeles para desaparecer
|
||||||
|
anim_step_ = 0;
|
||||||
|
animating_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMessage::update()
|
||||||
|
{
|
||||||
|
if (animating_)
|
||||||
|
{
|
||||||
|
updateAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMessage::updateAnimation()
|
||||||
|
{
|
||||||
|
anim_step_++;
|
||||||
|
float t = static_cast<float>(anim_step_) / ANIMATION_STEPS;
|
||||||
|
|
||||||
|
// Ease Out Cubic para una animación más suave
|
||||||
|
t = 1 - pow(1 - t, 3);
|
||||||
|
y_offset_ = start_y_ + (target_y_ - start_y_) * t;
|
||||||
|
|
||||||
|
if (anim_step_ >= ANIMATION_STEPS)
|
||||||
|
{
|
||||||
|
y_offset_ = target_y_;
|
||||||
|
animating_ = false;
|
||||||
|
|
||||||
|
// Si el objetivo era ocultarlo (target_y negativo), lo marcamos como no visible
|
||||||
|
if (target_y_ < 0.0f) {
|
||||||
|
visible_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMessage::render()
|
||||||
|
{
|
||||||
|
if (visible_)
|
||||||
|
{
|
||||||
|
text_renderer_->writeDX(
|
||||||
|
TEXT_COLOR | TEXT_CENTER,
|
||||||
|
base_x_,
|
||||||
|
base_y_ + y_offset_,
|
||||||
|
text_,
|
||||||
|
-2,
|
||||||
|
color_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UIMessage::isVisible() const
|
||||||
|
{
|
||||||
|
return visible_;
|
||||||
|
}
|
||||||
40
source/UIMessage.h
Normal file
40
source/UIMessage.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "text.h"
|
||||||
|
#include "utils.h" // Para Color
|
||||||
|
|
||||||
|
class UIMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UIMessage(std::shared_ptr<Text> text_renderer, const std::string& message_text, const Color& color);
|
||||||
|
|
||||||
|
void show(float base_x, float base_y);
|
||||||
|
void hide();
|
||||||
|
void update();
|
||||||
|
void render();
|
||||||
|
|
||||||
|
bool isVisible() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Configuración
|
||||||
|
std::shared_ptr<Text> text_renderer_;
|
||||||
|
std::string text_;
|
||||||
|
Color color_;
|
||||||
|
|
||||||
|
// Estado
|
||||||
|
bool visible_ = false;
|
||||||
|
bool animating_ = false;
|
||||||
|
float base_x_ = 0.0f;
|
||||||
|
float base_y_ = 0.0f;
|
||||||
|
float y_offset_ = 0.0f;
|
||||||
|
|
||||||
|
// Animación
|
||||||
|
float start_y_ = 0.0f;
|
||||||
|
float target_y_ = 0.0f;
|
||||||
|
int anim_step_ = 0;
|
||||||
|
static constexpr int ANIMATION_STEPS = 12;
|
||||||
|
|
||||||
|
void updateAnimation();
|
||||||
|
};
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
#include "UIMessage.h"
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
ServiceMenu *ServiceMenu::instance_ = nullptr;
|
ServiceMenu *ServiceMenu::instance_ = nullptr;
|
||||||
@@ -30,6 +31,10 @@ ServiceMenu::ServiceMenu()
|
|||||||
current_settings_group_(SettingsGroup::MAIN),
|
current_settings_group_(SettingsGroup::MAIN),
|
||||||
previous_settings_group_(current_settings_group_)
|
previous_settings_group_(current_settings_group_)
|
||||||
{
|
{
|
||||||
|
restart_message_ui_ = std::make_unique<UIMessage>(
|
||||||
|
element_text_,
|
||||||
|
Lang::getText("[SERVICE_MENU] NEED_RESTART_MESSAGE"),
|
||||||
|
title_color_);
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,20 +73,8 @@ void ServiceMenu::render()
|
|||||||
SDL_RenderRect(Screen::get()->getRenderer(), &rect_);
|
SDL_RenderRect(Screen::get()->getRenderer(), &rect_);
|
||||||
|
|
||||||
// MENSAJE DE RESTART
|
// MENSAJE DE RESTART
|
||||||
if (restart_msg_visible_ || restart_msg_animating_)
|
restart_message_ui_->render();
|
||||||
{
|
|
||||||
// Al pintar el mensaje, calcula la posición base en ese frame:
|
|
||||||
float base_y = rect_.y + restart_msg_base_offset_;
|
|
||||||
float msg_y = base_y + restart_msg_y_;
|
|
||||||
element_text_->writeDX(
|
|
||||||
TEXT_COLOR | TEXT_CENTER,
|
|
||||||
param.game.game_area.center_x,
|
|
||||||
msg_y,
|
|
||||||
Lang::getText("[SERVICE_MENU] NEED_RESTART_MESSAGE"),
|
|
||||||
-2,
|
|
||||||
title_color_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TITULO
|
// TITULO
|
||||||
y += title_padding_;
|
y += title_padding_;
|
||||||
title_text_->writeDX(TEXT_COLOR | TEXT_CENTER, param.game.game_area.center_x, y, title_, -4, title_color_);
|
title_text_->writeDX(TEXT_COLOR | TEXT_CENTER, param.game.game_area.center_x, y, title_, -4, title_color_);
|
||||||
@@ -134,32 +127,21 @@ void ServiceMenu::update()
|
|||||||
bool now_pending = Options::pending_changes.has_pending_changes;
|
bool now_pending = Options::pending_changes.has_pending_changes;
|
||||||
if (now_pending != last_pending_changes_)
|
if (now_pending != last_pending_changes_)
|
||||||
{
|
{
|
||||||
float y_offset = 39.0f; // O el que uses
|
|
||||||
if (now_pending)
|
if (now_pending)
|
||||||
showRestartMessage(y_offset);
|
{
|
||||||
|
float msg_x = param.game.game_area.center_x;
|
||||||
|
float msg_y = rect_.y + 39.0f; // Posición Y base del mensaje
|
||||||
|
restart_message_ui_->show(msg_x, msg_y);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
hideRestartMessage(y_offset);
|
{
|
||||||
|
restart_message_ui_->hide();
|
||||||
|
}
|
||||||
last_pending_changes_ = now_pending;
|
last_pending_changes_ = now_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animación del mensaje de reinicio
|
// Animación del mensaje de reinicio
|
||||||
if (restart_msg_animating_)
|
restart_message_ui_->update();
|
||||||
{
|
|
||||||
++restart_msg_anim_step_;
|
|
||||||
float t = static_cast<float>(restart_msg_anim_step_) / restart_msg_anim_steps_;
|
|
||||||
// Ease out cubic
|
|
||||||
t = 1 - pow(1 - t, 3);
|
|
||||||
restart_msg_y_ = restart_msg_start_y_ + (restart_msg_target_y_ - restart_msg_start_y_) * t;
|
|
||||||
|
|
||||||
if (restart_msg_anim_step_ >= restart_msg_anim_steps_)
|
|
||||||
{
|
|
||||||
restart_msg_y_ = restart_msg_target_y_;
|
|
||||||
restart_msg_animating_ = false;
|
|
||||||
// Si se oculta, asegúrate de que no se pinte más
|
|
||||||
if (!restart_msg_visible_)
|
|
||||||
restart_msg_y_ = restart_msg_target_y_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula y establece los anclajes y dimensiones del menú
|
// Calcula y establece los anclajes y dimensiones del menú
|
||||||
@@ -669,27 +651,4 @@ std::string ServiceMenu::settingsGroupToString(SettingsGroup group) const
|
|||||||
default:
|
default:
|
||||||
return Lang::getText("[SERVICE_MENU] TITLE");
|
return Lang::getText("[SERVICE_MENU] TITLE");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Inicia la animación para mostrar el mensaje de reinicio
|
|
||||||
void ServiceMenu::showRestartMessage(float y_offset)
|
|
||||||
{
|
|
||||||
restart_msg_start_y_ = -8.0f; // Empieza 8 píxeles arriba del destino
|
|
||||||
restart_msg_target_y_ = 0.0f; // El destino siempre es offset 0 respecto a base_y
|
|
||||||
restart_msg_y_ = restart_msg_start_y_;
|
|
||||||
restart_msg_anim_step_ = 0;
|
|
||||||
restart_msg_animating_ = true;
|
|
||||||
restart_msg_visible_ = true;
|
|
||||||
restart_msg_base_offset_ = y_offset; // Nueva variable para recordar el offset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicia la animación para ocultar el mensaje de reinicio
|
|
||||||
void ServiceMenu::hideRestartMessage(float y_offset)
|
|
||||||
{
|
|
||||||
restart_msg_start_y_ = restart_msg_y_;
|
|
||||||
restart_msg_target_y_ = -6.0f; // Sube 8 píxeles arriba del destino
|
|
||||||
restart_msg_anim_step_ = 0;
|
|
||||||
restart_msg_animating_ = true;
|
|
||||||
restart_msg_visible_ = false;
|
|
||||||
restart_msg_base_offset_ = y_offset;
|
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
#include "UIMessage.h"
|
||||||
|
|
||||||
class Text;
|
class Text;
|
||||||
|
|
||||||
@@ -217,16 +218,8 @@ private:
|
|||||||
int resize_anim_steps_ = 8; // Total de pasos de la animación
|
int resize_anim_steps_ = 8; // Total de pasos de la animación
|
||||||
bool resizing_ = false; // Si está animando el resize
|
bool resizing_ = false; // Si está animando el resize
|
||||||
|
|
||||||
// --- Variables para el mensaje de reinicio ---
|
std::unique_ptr<UIMessage> restart_message_ui_;
|
||||||
float restart_msg_y_ = 0.0f;
|
bool last_pending_changes_ = false;
|
||||||
float restart_msg_target_y_ = 0.0f;
|
|
||||||
float restart_msg_start_y_ = 0.0f;
|
|
||||||
int restart_msg_anim_step_ = 0;
|
|
||||||
static constexpr int restart_msg_anim_steps_ = 6; // 8 pasos
|
|
||||||
bool restart_msg_animating_ = false;
|
|
||||||
bool restart_msg_visible_ = false;
|
|
||||||
|
|
||||||
float restart_msg_base_offset_ = 0.0f;
|
|
||||||
|
|
||||||
int group_menu_widths_[5];
|
int group_menu_widths_[5];
|
||||||
|
|
||||||
@@ -261,9 +254,6 @@ private:
|
|||||||
void precalculateMenuWidths();
|
void precalculateMenuWidths();
|
||||||
int getMenuWidthForGroup(SettingsGroup group) const;
|
int getMenuWidthForGroup(SettingsGroup group) const;
|
||||||
|
|
||||||
void showRestartMessage(float y);
|
|
||||||
void hideRestartMessage(float y);
|
|
||||||
|
|
||||||
// --- Patrón Singleton ---
|
// --- Patrón Singleton ---
|
||||||
ServiceMenu(); // Constructor privado
|
ServiceMenu(); // Constructor privado
|
||||||
~ServiceMenu() = default; // Destructor privado
|
~ServiceMenu() = default; // Destructor privado
|
||||||
@@ -275,6 +265,4 @@ private:
|
|||||||
|
|
||||||
// --- Método para reproducir el sonido del menú ---
|
// --- Método para reproducir el sonido del menú ---
|
||||||
void playMenuSound(); // Reproduce el sonido del menú
|
void playMenuSound(); // Reproduce el sonido del menú
|
||||||
|
|
||||||
bool last_pending_changes_ = false; // Último estado conocido de pending_changes
|
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user