ServiceMenu: afegida animació de apertura/tancament

This commit is contained in:
2025-08-09 20:44:56 +02:00
parent 5a02518de3
commit 2b35ac0187
4 changed files with 351 additions and 209 deletions

View File

@@ -31,7 +31,9 @@ ServiceMenu::ServiceMenu()
auto element_text = Resource::get()->getText("04b_25_flat");
auto title_text = Resource::get()->getText("04b_25_flat_2x");
// El renderer ahora se inicializa con su configuración
renderer_ = std::make_unique<MenuRenderer>(this, element_text, title_text);
restart_message_ui_ = std::make_unique<UIMessage>(element_text, Lang::getText("[SERVICE_MENU] NEED_RESTART_MESSAGE"), param.service_menu.title_color);
define_buttons_ = std::make_unique<DefineButtons>();
@@ -39,44 +41,53 @@ ServiceMenu::ServiceMenu()
}
void ServiceMenu::toggle() {
if (define_buttons_ && define_buttons_->isEnabled()) {
return; // No se puede mostrar u ocultar el menu de servicio si se estan definiendo los botones
}
if (define_buttons_ && define_buttons_->isEnabled()) return;
if (isAnimating() && !define_buttons_->isEnabled()) return; // No permitir toggle durante una animación
playBackSound();
enabled_ = !enabled_;
if (enabled_) {
// Primero resetea el estado y luego muestra la animación
//reset();
Options::gamepad_manager.assignAndLinkGamepads();
renderer_->show(this);
} else {
reset();
// Al cerrar, solo inicia la animación de ocultar
renderer_->hide();
// NO llames a reset() aquí
}
}
void ServiceMenu::render() {
if (!enabled_) {
return;
// Condición corregida: renderiza si está habilitado O si se está animando
if (enabled_ || isAnimating()) {
renderer_->render(this);
} else {
return; // Si no está ni habilitado ni animándose, no dibujes nada.
}
renderer_->render(this);
// El mensaje de reinicio se dibuja por encima, así que lo gestionamos aquí
const float MSG_X = param.game.game_area.center_x;
const float MSG_Y = renderer_->getRect().y + 39.0F;
restart_message_ui_->setPosition(MSG_X, MSG_Y);
restart_message_ui_->render();
// El mensaje de reinicio y otros elementos solo deben aparecer si está completamente visible,
// no durante la animación.
if (enabled_ && !isAnimating()) {
const float MSG_X = param.game.game_area.center_x;
const float MSG_Y = renderer_->getRect().y + 39.0F;
restart_message_ui_->setPosition(MSG_X, MSG_Y);
restart_message_ui_->render();
// Renderizar DefineButtons si está activo (se dibuja por encima de todo)
if (define_buttons_ && define_buttons_->isEnabled()) {
define_buttons_->render();
if (define_buttons_ && define_buttons_->isEnabled()) {
define_buttons_->render();
}
}
}
void ServiceMenu::update() {
if (!enabled_) {
return;
}
// El renderer siempre se actualiza para manejar sus animaciones
renderer_->update(this);
if (!enabled_) return;
// Lógica de actualización del mensaje de reinicio y botones
bool now_pending = Options::pending_changes.has_pending_changes;
if (now_pending != last_pending_changes_) {
now_pending ? restart_message_ui_->show() : restart_message_ui_->hide();
@@ -84,11 +95,8 @@ void ServiceMenu::update() {
}
restart_message_ui_->update();
// Actualizar DefineButtons
if (define_buttons_) {
define_buttons_->update();
// Si DefineButtons ha terminado y está listo para cerrar completamente
if (define_buttons_->isEnabled() && define_buttons_->isReadyToClose()) {
define_buttons_->disable();
}
@@ -102,7 +110,22 @@ void ServiceMenu::reset() {
previous_settings_group_ = SettingsGroup::MAIN;
initializeOptions();
updateMenu();
renderer_->setLayout(this); // Notifica al renderer para que calcule el layout inicial
renderer_->setLayout(this);
}
void ServiceMenu::moveBack() {
// Si estamos en una subpantalla, no llamamos a toggle
if (current_settings_group_ != SettingsGroup::MAIN) {
playBackSound();
current_settings_group_ = previous_settings_group_;
selected_ = (current_settings_group_ == SettingsGroup::MAIN) ? main_menu_selected_ : 0;
updateMenu();
return;
}
// Si estamos en la pantalla principal, llamamos a toggle() para cerrar con animación.
// toggle() ya reproduce el sonido, por lo que no es necesario aquí.
toggle();
}
// --- Lógica de Navegación ---
@@ -159,17 +182,6 @@ void ServiceMenu::selectOption() {
playSelectSound();
}
void ServiceMenu::moveBack() {
playBackSound();
if (current_settings_group_ == SettingsGroup::MAIN) {
enabled_ = false;
return;
}
current_settings_group_ = previous_settings_group_;
selected_ = (current_settings_group_ == SettingsGroup::MAIN) ? main_menu_selected_ : 0;
updateMenu();
}
// --- Lógica Interna ---
void ServiceMenu::updateDisplayOptions() {
@@ -554,16 +566,13 @@ void ServiceMenu::handleEvent(const SDL_Event &event) {
}
bool ServiceMenu::checkInput() {
if (!enabled_) {
return false;
}
if (define_buttons_ && define_buttons_->isEnabled()) {
// --- Guardas ---
// No procesar input si el menú no está habilitado, si se está animando o si se definen botones
if (!enabled_ || isAnimating() || (define_buttons_ && define_buttons_->isEnabled())) {
return false;
}
static auto input = Input::get();
using Action = Input::Action;
const std::vector<std::pair<Action, std::function<void()>>> actions = {
@@ -594,4 +603,13 @@ bool ServiceMenu::checkInput() {
}
return false;
}
// --- Nuevo Getter ---
auto ServiceMenu::isAnimating() const -> bool {
return renderer_ && renderer_->isAnimating();
}
auto ServiceMenu::isDefiningButtons() const -> bool {
return define_buttons_ && define_buttons_->isEnabled();
}