PHASE 2: Refactorización completa del sistema de temas unificado

Arquitectura polimórfica implementada:
- Jerarquía: Theme (base) → StaticTheme / DynamicTheme (derivadas)
- Vector unificado de 10 temas (7 estáticos + 3 dinámicos)
- Eliminada lógica dual (if(dynamic_theme_active_) scattered)

Nuevos archivos:
- source/themes/theme.h: Interfaz base abstracta
- source/themes/static_theme.h/cpp: Temas estáticos (1 keyframe)
- source/themes/dynamic_theme.h/cpp: Temas dinámicos (N keyframes animados)
- source/theme_manager.h/cpp: Gestión unificada de temas

Mejoras de API:
- switchToTheme(0-9): Cambio a cualquier tema (índice 0-9)
- cycleTheme(): Cicla por todos los temas (Tecla B)
- update(delta_time): Actualización simplificada
- getInterpolatedColor(idx): Sin parámetro balls_

Bugs corregidos:
- Tecla B ahora cicla TODOS los 10 temas (antes solo 6)
- DEMO mode elige de TODOS los temas (antes excluía LAVENDER + dinámicos)
- Eliminada duplicación de keyframes en temas dinámicos (loop=true lo maneja)

Código reducido:
- theme_manager.cpp: 558 → 320 líneas (-43%)
- engine.cpp: Eliminados ~470 líneas de lógica de temas
- Complejidad significativamente reducida

Preparado para PHASE 3 (LERP universal entre cualquier par de temas)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-09 13:17:54 +02:00
parent b93028396a
commit a134ae428f
11 changed files with 988 additions and 680 deletions

View File

@@ -14,6 +14,7 @@
#include "defines.h" // for GravityDirection, ColorTheme, ShapeType
#include "external/texture.h" // for Texture
#include "shapes/shape.h" // for Shape (interfaz polimórfica)
#include "theme_manager.h" // for ThemeManager
// Modos de aplicación mutuamente excluyentes
enum class AppMode {
@@ -79,34 +80,8 @@ class Engine {
int current_screen_width_ = DEFAULT_SCREEN_WIDTH;
int current_screen_height_ = DEFAULT_SCREEN_HEIGHT;
// Sistema de temas
ColorTheme current_theme_ = ColorTheme::SUNSET;
ColorTheme target_theme_ = ColorTheme::SUNSET; // Tema destino para transición
bool transitioning_ = false; // ¿Estamos en transición?
float transition_progress_ = 0.0f; // Progreso de 0.0 a 1.0
float transition_duration_ = 0.5f; // Duración en segundos
// Estructura de tema de colores
struct ThemeColors {
const char* name_en; // Nombre en inglés (para debug)
const char* name_es; // Nombre en español (para display)
int text_color_r, text_color_g, text_color_b; // Color del texto del tema
float bg_top_r, bg_top_g, bg_top_b;
float bg_bottom_r, bg_bottom_g, bg_bottom_b;
std::vector<Color> ball_colors;
};
// Temas de colores definidos
ThemeColors themes_[7]; // 7 temas: SUNSET, OCEAN, NEON, FOREST, RGB, MONOCHROME, LAVENDER
// Sistema de Temas Dinámicos (animados)
DynamicTheme dynamic_themes_[3]; // 3 temas dinámicos predefinidos
bool dynamic_theme_active_ = false; // ¿Tema dinámico activo?
int current_dynamic_theme_index_ = -1; // Índice del tema dinámico actual (-1 = ninguno)
size_t current_keyframe_index_ = 0; // Keyframe actual
size_t target_keyframe_index_ = 1; // Próximo keyframe
float dynamic_transition_progress_ = 0.0f; // Progreso 0.0-1.0 hacia próximo keyframe
bool dynamic_theme_paused_ = false; // Pausa manual con Shift+D
// Sistema de temas (delegado a ThemeManager)
std::unique_ptr<ThemeManager> theme_manager_;
// Sistema de Figuras 3D (polimórfico)
SimulationMode current_mode_ = SimulationMode::PHYSICS;
@@ -135,7 +110,7 @@ class Engine {
int logo_current_flip_count_ = 0; // Flips observados hasta ahora
// Estado previo antes de entrar a Logo Mode (para restaurar al salir)
ColorTheme logo_previous_theme_ = ColorTheme::SUNSET;
int logo_previous_theme_ = 0; // Índice de tema (0-9)
size_t logo_previous_texture_index_ = 0;
float logo_previous_shape_scale_ = 1.0f;
@@ -163,13 +138,6 @@ class Engine {
void toggleRealFullscreen();
void toggleIntegerScaling();
std::string gravityDirectionToString(GravityDirection direction) const;
void initializeThemes();
// Sistema de Temas Dinámicos
void initializeDynamicThemes(); // Inicializar 3 temas dinámicos predefinidos
void updateDynamicTheme(); // Actualizar animación de tema dinámico (llamado cada frame)
void activateDynamicTheme(int index); // Activar tema dinámico (0-2)
void pauseDynamicTheme(); // Toggle pausa de animación (Shift+D)
// Sistema de gestión de estados (MANUAL/DEMO/DEMO_LITE/LOGO)
void setState(AppMode new_mode); // Cambiar modo de aplicación (mutuamente excluyente)
@@ -185,11 +153,6 @@ class Engine {
void enterLogoMode(bool from_demo = false); // Entrar al modo logo (manual o automático)
void exitLogoMode(bool return_to_demo = false); // Salir del modo logo
// Sistema de transiciones LERP
float lerp(float a, float b, float t) const { return a + (b - a) * t; }
Color getInterpolatedColor(size_t ball_index) const; // Obtener color interpolado durante transición
void startThemeTransition(ColorTheme new_theme);
// Sistema de cambio de sprites dinámico
void switchTexture(); // Cambia a siguiente textura disponible
void updateBallSizes(int old_size, int new_size); // Ajusta posiciones al cambiar tamaño
@@ -201,7 +164,6 @@ class Engine {
void zoomOut();
// Rendering
void renderGradientBackground();
void addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b, float scale = 1.0f);
// Sistema de Figuras 3D