Fix: Notificaciones con colores dinámicos y transiciones LERP
Problema resuelto: 1. Color del tema saliente: Notificaciones mostraban color del tema ANTIGUO 2. Sin transiciones LERP: Notificaciones no participaban en transiciones suaves Cambios implementados: - Arquitectura cambiada de estática a dinámica - Notifier ahora consulta ThemeManager cada frame en render() - Eliminados colores estáticos de struct Notification - Notifier::init() recibe puntero a ThemeManager - Notifier::show() ya no recibe parámetros de color - Simplificado showNotificationForAction() (-23 líneas) Fix crítico de inicialización: - ThemeManager ahora se inicializa ANTES de updatePhysicalWindowSize() - Previene nullptr en notifier_.init() que causaba que no se mostraran Resultado: - ✅ Notificaciones usan color del tema DESTINO (no origen) - ✅ Transiciones LERP suaves automáticas durante cambios de tema - ✅ Código más limpio y centralizado en ThemeManager - ✅ -50 líneas de código duplicado eliminadas 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -205,13 +205,14 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen) {
|
||||
|
||||
srand(static_cast<unsigned>(time(nullptr)));
|
||||
|
||||
// Calcular tamaño físico de ventana y tamaño de fuente absoluto
|
||||
updatePhysicalWindowSize();
|
||||
|
||||
// Inicializar ThemeManager
|
||||
// Inicializar ThemeManager PRIMERO (requerido por Notifier)
|
||||
theme_manager_ = std::make_unique<ThemeManager>();
|
||||
theme_manager_->initialize();
|
||||
|
||||
// Calcular tamaño físico de ventana y tamaño de fuente absoluto
|
||||
// NOTA: Debe llamarse DESPUÉS de inicializar ThemeManager porque notifier_.init() lo necesita
|
||||
updatePhysicalWindowSize();
|
||||
|
||||
initBalls(scenario_);
|
||||
}
|
||||
|
||||
@@ -1003,28 +1004,8 @@ void Engine::setText() {
|
||||
std::to_string(num_balls % 1000) + " Pelotas";
|
||||
}
|
||||
|
||||
// Obtener color del tema actual para la notificación
|
||||
int text_r, text_g, text_b;
|
||||
theme_manager_->getCurrentThemeTextColor(text_r, text_g, text_b);
|
||||
SDL_Color notification_color = {
|
||||
static_cast<Uint8>(text_r),
|
||||
static_cast<Uint8>(text_g),
|
||||
static_cast<Uint8>(text_b),
|
||||
255
|
||||
};
|
||||
|
||||
// Obtener color de fondo de la notificación desde el tema
|
||||
int bg_r, bg_g, bg_b;
|
||||
theme_manager_->getCurrentNotificationBackgroundColor(bg_r, bg_g, bg_b);
|
||||
SDL_Color notification_bg_color = {
|
||||
static_cast<Uint8>(bg_r),
|
||||
static_cast<Uint8>(bg_g),
|
||||
static_cast<Uint8>(bg_b),
|
||||
255
|
||||
};
|
||||
|
||||
// Mostrar notificación
|
||||
notifier_.show(notification_text, NOTIFICATION_DURATION, notification_color, notification_bg_color);
|
||||
// Mostrar notificación (colores se obtienen dinámicamente desde ThemeManager)
|
||||
notifier_.show(notification_text, NOTIFICATION_DURATION);
|
||||
|
||||
// Sistema antiguo (mantener temporalmente para compatibilidad)
|
||||
text_ = notification_text;
|
||||
@@ -1037,28 +1018,9 @@ void Engine::showNotificationForAction(const std::string& text) {
|
||||
// IMPORTANTE: Esta función solo se llama desde handlers de teclado (acciones manuales)
|
||||
// NUNCA se llama desde código automático (DEMO/LOGO), por lo tanto siempre mostramos notificación
|
||||
|
||||
// Obtener color del tema actual para el texto
|
||||
int text_r, text_g, text_b;
|
||||
theme_manager_->getCurrentThemeTextColor(text_r, text_g, text_b);
|
||||
SDL_Color notification_color = {
|
||||
static_cast<Uint8>(text_r),
|
||||
static_cast<Uint8>(text_g),
|
||||
static_cast<Uint8>(text_b),
|
||||
255
|
||||
};
|
||||
|
||||
// Obtener color de fondo de la notificación desde el tema
|
||||
int bg_r, bg_g, bg_b;
|
||||
theme_manager_->getCurrentNotificationBackgroundColor(bg_r, bg_g, bg_b);
|
||||
SDL_Color notification_bg_color = {
|
||||
static_cast<Uint8>(bg_r),
|
||||
static_cast<Uint8>(bg_g),
|
||||
static_cast<Uint8>(bg_b),
|
||||
255
|
||||
};
|
||||
|
||||
// Mostrar notificación
|
||||
notifier_.show(text, NOTIFICATION_DURATION, notification_color, notification_bg_color);
|
||||
// Los colores se obtienen dinámicamente cada frame desde ThemeManager en render()
|
||||
// Esto permite transiciones LERP suaves y siempre usar el color del tema actual
|
||||
notifier_.show(text, NOTIFICATION_DURATION);
|
||||
}
|
||||
|
||||
void Engine::pushBallsAwayFromGravity() {
|
||||
@@ -1466,10 +1428,10 @@ void Engine::updatePhysicalWindowSize() {
|
||||
|
||||
text_renderer_notifier_.init(renderer_, TEXT_FONT_PATH, notification_font_size, TEXT_ANTIALIASING);
|
||||
|
||||
// Inicializar/actualizar Notifier con nuevas dimensiones
|
||||
// Inicializar/actualizar Notifier con nuevas dimensiones y ThemeManager
|
||||
// NOTA: init() es seguro de llamar múltiples veces, solo actualiza punteros y dimensiones
|
||||
// Esto asegura que el notifier tenga las referencias correctas tras resize/fullscreen
|
||||
notifier_.init(renderer_, &text_renderer_notifier_, physical_window_width_, physical_window_height_);
|
||||
notifier_.init(renderer_, &text_renderer_notifier_, theme_manager_.get(), physical_window_width_, physical_window_height_);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "notifier.h"
|
||||
#include "../text/textrenderer.h"
|
||||
#include "../theme_manager.h"
|
||||
#include "../defines.h"
|
||||
#include "../utils/easing_functions.h"
|
||||
#include <SDL3/SDL.h>
|
||||
@@ -7,6 +8,7 @@
|
||||
Notifier::Notifier()
|
||||
: renderer_(nullptr)
|
||||
, text_renderer_(nullptr)
|
||||
, theme_manager_(nullptr)
|
||||
, window_width_(0)
|
||||
, window_height_(0)
|
||||
, current_notification_(nullptr) {
|
||||
@@ -16,12 +18,13 @@ Notifier::~Notifier() {
|
||||
clear();
|
||||
}
|
||||
|
||||
bool Notifier::init(SDL_Renderer* renderer, TextRenderer* text_renderer, int window_width, int window_height) {
|
||||
bool Notifier::init(SDL_Renderer* renderer, TextRenderer* text_renderer, ThemeManager* theme_manager, int window_width, int window_height) {
|
||||
renderer_ = renderer;
|
||||
text_renderer_ = text_renderer;
|
||||
theme_manager_ = theme_manager;
|
||||
window_width_ = window_width;
|
||||
window_height_ = window_height;
|
||||
return (renderer_ != nullptr && text_renderer_ != nullptr);
|
||||
return (renderer_ != nullptr && text_renderer_ != nullptr && theme_manager_ != nullptr);
|
||||
}
|
||||
|
||||
void Notifier::updateWindowSize(int window_width, int window_height) {
|
||||
@@ -29,7 +32,7 @@ void Notifier::updateWindowSize(int window_width, int window_height) {
|
||||
window_height_ = window_height;
|
||||
}
|
||||
|
||||
void Notifier::show(const std::string& text, Uint64 duration, SDL_Color color, SDL_Color bg_color) {
|
||||
void Notifier::show(const std::string& text, Uint64 duration) {
|
||||
if (text.empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -47,8 +50,7 @@ void Notifier::show(const std::string& text, Uint64 duration, SDL_Color color, S
|
||||
notif.state = NotificationState::SLIDING_IN;
|
||||
notif.alpha = 1.0f;
|
||||
notif.y_offset = -50.0f; // Comienza 50px arriba (fuera de pantalla)
|
||||
notif.color = color;
|
||||
notif.bg_color = bg_color;
|
||||
// NOTA: Los colores se obtienen dinámicamente desde ThemeManager en render()
|
||||
|
||||
// Añadir a cola
|
||||
notification_queue_.push(notif);
|
||||
@@ -115,10 +117,29 @@ void Notifier::update(Uint64 current_time) {
|
||||
}
|
||||
|
||||
void Notifier::render() {
|
||||
if (!current_notification_ || !text_renderer_ || !renderer_) {
|
||||
if (!current_notification_ || !text_renderer_ || !renderer_ || !theme_manager_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Obtener colores DINÁMICOS desde ThemeManager (incluye LERP automático)
|
||||
int text_r, text_g, text_b;
|
||||
theme_manager_->getCurrentThemeTextColor(text_r, text_g, text_b);
|
||||
SDL_Color text_color = {
|
||||
static_cast<Uint8>(text_r),
|
||||
static_cast<Uint8>(text_g),
|
||||
static_cast<Uint8>(text_b),
|
||||
static_cast<Uint8>(current_notification_->alpha * 255.0f)
|
||||
};
|
||||
|
||||
int bg_r, bg_g, bg_b;
|
||||
theme_manager_->getCurrentNotificationBackgroundColor(bg_r, bg_g, bg_b);
|
||||
SDL_Color bg_color = {
|
||||
static_cast<Uint8>(bg_r),
|
||||
static_cast<Uint8>(bg_g),
|
||||
static_cast<Uint8>(bg_b),
|
||||
255
|
||||
};
|
||||
|
||||
// Calcular dimensiones del texto en píxeles FÍSICOS
|
||||
// IMPORTANTE: Usar getTextWidthPhysical() en lugar de getTextWidth()
|
||||
// para obtener el ancho REAL de la fuente (sin escalado lógico)
|
||||
@@ -137,13 +158,9 @@ void Notifier::render() {
|
||||
|
||||
// Renderizar fondo semitransparente (con bypass de presentación lógica)
|
||||
float bg_alpha = current_notification_->alpha * NOTIFICATION_BG_ALPHA;
|
||||
renderBackground(x, y, bg_width, bg_height, bg_alpha, current_notification_->bg_color);
|
||||
renderBackground(x, y, bg_width, bg_height, bg_alpha, bg_color);
|
||||
|
||||
// Renderizar texto con alpha usando printAbsolute (tamaño físico fijo)
|
||||
Uint8 text_alpha = static_cast<Uint8>(current_notification_->alpha * 255.0f);
|
||||
SDL_Color text_color = current_notification_->color;
|
||||
text_color.a = text_alpha;
|
||||
|
||||
int text_x = x + NOTIFICATION_PADDING;
|
||||
int text_y = y + NOTIFICATION_PADDING;
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#include <queue>
|
||||
#include <memory>
|
||||
|
||||
// Forward declaration
|
||||
// Forward declarations
|
||||
class TextRenderer;
|
||||
class ThemeManager;
|
||||
|
||||
/**
|
||||
* @brief Sistema de notificaciones estilo iOS/Android
|
||||
@@ -34,20 +35,22 @@ public:
|
||||
NotificationState state;
|
||||
float alpha; // Opacidad 0.0-1.0
|
||||
float y_offset; // Offset Y para animación slide (píxeles)
|
||||
SDL_Color color;
|
||||
SDL_Color bg_color; // Color de fondo de la notificación (RGB)
|
||||
// NOTA: Los colores se obtienen dinámicamente desde ThemeManager en render()
|
||||
};
|
||||
|
||||
Notifier();
|
||||
~Notifier();
|
||||
|
||||
/**
|
||||
* @brief Inicializa el notifier con un TextRenderer
|
||||
* @brief Inicializa el notifier con un TextRenderer y ThemeManager
|
||||
* @param renderer SDL renderer para dibujar
|
||||
* @param text_renderer TextRenderer configurado con tamaño absoluto
|
||||
* @param theme_manager ThemeManager para obtener colores dinámicos con LERP
|
||||
* @param window_width Ancho de ventana física
|
||||
* @param window_height Alto de ventana física
|
||||
* @return true si inicialización exitosa
|
||||
*/
|
||||
bool init(SDL_Renderer* renderer, TextRenderer* text_renderer, int window_width, int window_height);
|
||||
bool init(SDL_Renderer* renderer, TextRenderer* text_renderer, ThemeManager* theme_manager, int window_width, int window_height);
|
||||
|
||||
/**
|
||||
* @brief Actualiza las dimensiones de la ventana (llamar en resize)
|
||||
@@ -60,10 +63,9 @@ public:
|
||||
* @brief Muestra una nueva notificación
|
||||
* @param text Texto a mostrar
|
||||
* @param duration Duración en milisegundos (0 = usar default)
|
||||
* @param color Color del texto
|
||||
* @param bg_color Color de fondo de la notificación
|
||||
* @note Los colores se obtienen dinámicamente desde ThemeManager cada frame
|
||||
*/
|
||||
void show(const std::string& text, Uint64 duration = 0, SDL_Color color = {255, 255, 255, 255}, SDL_Color bg_color = {0, 0, 0, 255});
|
||||
void show(const std::string& text, Uint64 duration = 0);
|
||||
|
||||
/**
|
||||
* @brief Actualiza las animaciones de notificaciones
|
||||
@@ -90,6 +92,7 @@ public:
|
||||
private:
|
||||
SDL_Renderer* renderer_;
|
||||
TextRenderer* text_renderer_;
|
||||
ThemeManager* theme_manager_; // Gestor de temas para obtener colores dinámicos con LERP
|
||||
int window_width_;
|
||||
int window_height_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user