Add: Sistema de páginas para selección de temas + 5 nuevos temas
Implementación: - 5 nuevos temas (2 estáticos: CRIMSON, EMERALD / 3 dinámicos: FIRE, AURORA, VOLCANIC) - Sistema de páginas con Numpad Enter (Página 1 ↔ Página 2) - Shift+B para ciclar temas hacia atrás - Página 1: 9 temas estáticos + SUNRISE (Numpad 1-9, 0) - Página 2: 5 temas dinámicos animados (Numpad 1-5) Motivo: - Shift+Numpad no funciona en Windows (limitación hardware/OS) - Solución: Toggle de página con Numpad Enter Archivos modificados: - defines.h: Añadidos 5 nuevos ColorTheme enum values - theme_manager.h: Añadido cyclePrevTheme() + actualizada doc 10→15 temas - theme_manager.cpp: Implementados 5 nuevos temas + cyclePrevTheme() - engine.h: Añadida variable theme_page_ (0 o 1) - engine.cpp: Handlers Numpad Enter, KP_1-9,0 con sistema de páginas, SDLK_B con Shift detection - CLAUDE.md: Documentación actualizada con tablas de 2 páginas 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -9,10 +9,10 @@
|
||||
|
||||
void ThemeManager::initialize() {
|
||||
themes_.clear();
|
||||
themes_.reserve(10); // 7 estáticos + 3 dinámicos
|
||||
themes_.reserve(15); // 9 estáticos + 6 dinámicos
|
||||
|
||||
// ========================================
|
||||
// TEMAS ESTÁTICOS (índices 0-6)
|
||||
// TEMAS ESTÁTICOS (índices 0-8)
|
||||
// ========================================
|
||||
|
||||
// 0: SUNSET (Atardecer) - Naranjas, rojos, amarillos, rosas
|
||||
@@ -128,11 +128,37 @@ void ThemeManager::initialize() {
|
||||
}
|
||||
));
|
||||
|
||||
// 7: CRIMSON (Carmesí) - Fondo negro-rojo oscuro, pelotas rojas uniformes
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"CRIMSON",
|
||||
"CARMESI",
|
||||
255, 100, 100, // Color texto: rojo claro
|
||||
40.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo superior: rojo muy oscuro
|
||||
0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo inferior: negro puro
|
||||
std::vector<Color>{
|
||||
{220, 20, 60}, {220, 20, 60}, {220, 20, 60}, {220, 20, 60},
|
||||
{220, 20, 60}, {220, 20, 60}, {220, 20, 60}, {220, 20, 60}
|
||||
}
|
||||
));
|
||||
|
||||
// 8: EMERALD (Esmeralda) - Fondo negro-verde oscuro, pelotas verdes uniformes
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"EMERALD",
|
||||
"ESMERALDA",
|
||||
100, 255, 100, // Color texto: verde claro
|
||||
0.0f / 255.0f, 40.0f / 255.0f, 0.0f / 255.0f, // Fondo superior: verde muy oscuro
|
||||
0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo inferior: negro puro
|
||||
std::vector<Color>{
|
||||
{50, 205, 50}, {50, 205, 50}, {50, 205, 50}, {50, 205, 50},
|
||||
{50, 205, 50}, {50, 205, 50}, {50, 205, 50}, {50, 205, 50}
|
||||
}
|
||||
));
|
||||
|
||||
// ========================================
|
||||
// TEMAS DINÁMICOS (índices 7-9)
|
||||
// TEMAS DINÁMICOS (índices 9-14)
|
||||
// ========================================
|
||||
|
||||
// 7: SUNRISE (Amanecer) - Noche → Alba → Día (loop)
|
||||
// 9: SUNRISE (Amanecer) - Noche → Alba → Día (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"SUNRISE",
|
||||
"AMANECER",
|
||||
@@ -173,7 +199,7 @@ void ThemeManager::initialize() {
|
||||
true // Loop = true
|
||||
));
|
||||
|
||||
// 8: OCEAN WAVES (Olas Oceánicas) - Azul oscuro ↔ Turquesa (loop)
|
||||
// 10: OCEAN WAVES (Olas Oceánicas) - Azul oscuro ↔ Turquesa (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"OCEAN WAVES",
|
||||
"OLAS OCEANICAS",
|
||||
@@ -204,7 +230,7 @@ void ThemeManager::initialize() {
|
||||
true // Loop = true
|
||||
));
|
||||
|
||||
// 9: NEON PULSE (Pulso Neón) - Negro → Neón brillante (rápido ping-pong)
|
||||
// 11: NEON PULSE (Pulso Neón) - Negro → Neón brillante (rápido ping-pong)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"NEON PULSE",
|
||||
"PULSO NEON",
|
||||
@@ -234,6 +260,159 @@ void ThemeManager::initialize() {
|
||||
},
|
||||
true // Loop = true
|
||||
));
|
||||
|
||||
// 12: FIRE (Fuego Vivo) - Brasas → Llamas → Inferno (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"FIRE",
|
||||
"FUEGO",
|
||||
255, 150, 80, // Color texto: naranja cálido
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Brasas oscuras (estado inicial)
|
||||
{
|
||||
60.0f / 255.0f, 20.0f / 255.0f, 10.0f / 255.0f, // Fondo superior: rojo muy oscuro
|
||||
20.0f / 255.0f, 10.0f / 255.0f, 0.0f / 255.0f, // Fondo inferior: casi negro
|
||||
std::vector<Color>{
|
||||
{120, 40, 20}, {140, 35, 15}, {130, 38, 18}, {125, 42, 22},
|
||||
{135, 37, 16}, {128, 40, 20}, {132, 39, 19}, {138, 36, 17}
|
||||
},
|
||||
0.0f // Estado inicial
|
||||
},
|
||||
// Keyframe 1: Llamas naranjas (transición)
|
||||
{
|
||||
180.0f / 255.0f, 80.0f / 255.0f, 20.0f / 255.0f, // Fondo superior: naranja fuerte
|
||||
100.0f / 255.0f, 30.0f / 255.0f, 10.0f / 255.0f, // Fondo inferior: rojo oscuro
|
||||
std::vector<Color>{
|
||||
{255, 140, 0}, {255, 120, 10}, {255, 160, 20}, {255, 130, 5},
|
||||
{255, 150, 15}, {255, 125, 8}, {255, 145, 12}, {255, 135, 18}
|
||||
},
|
||||
3.5f // 3.5 segundos para llegar
|
||||
},
|
||||
// Keyframe 2: Inferno brillante (clímax)
|
||||
{
|
||||
255.0f / 255.0f, 180.0f / 255.0f, 80.0f / 255.0f, // Fondo superior: amarillo-naranja brillante
|
||||
220.0f / 255.0f, 100.0f / 255.0f, 30.0f / 255.0f, // Fondo inferior: naranja intenso
|
||||
std::vector<Color>{
|
||||
{255, 220, 100}, {255, 200, 80}, {255, 240, 120}, {255, 210, 90},
|
||||
{255, 230, 110}, {255, 205, 85}, {255, 225, 105}, {255, 215, 95}
|
||||
},
|
||||
3.0f // 3 segundos para llegar
|
||||
},
|
||||
// Keyframe 3: Vuelta a llamas (antes de reiniciar loop)
|
||||
{
|
||||
180.0f / 255.0f, 80.0f / 255.0f, 20.0f / 255.0f, // Fondo superior: naranja fuerte
|
||||
100.0f / 255.0f, 30.0f / 255.0f, 10.0f / 255.0f, // Fondo inferior: rojo oscuro
|
||||
std::vector<Color>{
|
||||
{255, 140, 0}, {255, 120, 10}, {255, 160, 20}, {255, 130, 5},
|
||||
{255, 150, 15}, {255, 125, 8}, {255, 145, 12}, {255, 135, 18}
|
||||
},
|
||||
3.5f // 3.5 segundos para volver
|
||||
}
|
||||
// Loop = true hará transición automática de keyframe 3 → keyframe 0
|
||||
},
|
||||
true // Loop = true (ciclo completo: brasas→llamas→inferno→llamas→brasas...)
|
||||
));
|
||||
|
||||
// 13: AURORA (Aurora Boreal) - Verde → Violeta → Cian (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"AURORA",
|
||||
"AURORA",
|
||||
150, 255, 200, // Color texto: verde claro
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Verde aurora (estado inicial)
|
||||
{
|
||||
30.0f / 255.0f, 80.0f / 255.0f, 60.0f / 255.0f, // Fondo superior: verde oscuro
|
||||
10.0f / 255.0f, 20.0f / 255.0f, 30.0f / 255.0f, // Fondo inferior: azul muy oscuro
|
||||
std::vector<Color>{
|
||||
{100, 255, 180}, {80, 240, 160}, {120, 255, 200}, {90, 245, 170},
|
||||
{110, 255, 190}, {85, 242, 165}, {105, 252, 185}, {95, 248, 175}
|
||||
},
|
||||
0.0f // Estado inicial
|
||||
},
|
||||
// Keyframe 1: Violeta aurora (transición)
|
||||
{
|
||||
120.0f / 255.0f, 60.0f / 255.0f, 180.0f / 255.0f, // Fondo superior: violeta
|
||||
40.0f / 255.0f, 20.0f / 255.0f, 80.0f / 255.0f, // Fondo inferior: violeta oscuro
|
||||
std::vector<Color>{
|
||||
{200, 100, 255}, {180, 80, 240}, {220, 120, 255}, {190, 90, 245},
|
||||
{210, 110, 255}, {185, 85, 242}, {205, 105, 252}, {195, 95, 248}
|
||||
},
|
||||
5.0f // 5 segundos para llegar (transición lenta)
|
||||
},
|
||||
// Keyframe 2: Cian aurora (clímax)
|
||||
{
|
||||
60.0f / 255.0f, 180.0f / 255.0f, 220.0f / 255.0f, // Fondo superior: cian brillante
|
||||
20.0f / 255.0f, 80.0f / 255.0f, 120.0f / 255.0f, // Fondo inferior: azul oscuro
|
||||
std::vector<Color>{
|
||||
{100, 220, 255}, {80, 200, 240}, {120, 240, 255}, {90, 210, 245},
|
||||
{110, 230, 255}, {85, 205, 242}, {105, 225, 252}, {95, 215, 248}
|
||||
},
|
||||
4.5f // 4.5 segundos para llegar
|
||||
},
|
||||
// Keyframe 3: Vuelta a violeta (antes de reiniciar)
|
||||
{
|
||||
120.0f / 255.0f, 60.0f / 255.0f, 180.0f / 255.0f, // Fondo superior: violeta
|
||||
40.0f / 255.0f, 20.0f / 255.0f, 80.0f / 255.0f, // Fondo inferior: violeta oscuro
|
||||
std::vector<Color>{
|
||||
{200, 100, 255}, {180, 80, 240}, {220, 120, 255}, {190, 90, 245},
|
||||
{210, 110, 255}, {185, 85, 242}, {205, 105, 252}, {195, 95, 248}
|
||||
},
|
||||
4.5f // 4.5 segundos para volver
|
||||
}
|
||||
// Loop = true hará transición automática de keyframe 3 → keyframe 0
|
||||
},
|
||||
true // Loop = true (ciclo: verde→violeta→cian→violeta→verde...)
|
||||
));
|
||||
|
||||
// 14: VOLCANIC (Erupción Volcánica) - Ceniza → Erupción → Lava (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"VOLCANIC",
|
||||
"VOLCAN",
|
||||
200, 120, 80, // Color texto: naranja apagado
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Ceniza oscura (pre-erupción)
|
||||
{
|
||||
40.0f / 255.0f, 40.0f / 255.0f, 45.0f / 255.0f, // Fondo superior: gris oscuro
|
||||
20.0f / 255.0f, 15.0f / 255.0f, 15.0f / 255.0f, // Fondo inferior: casi negro
|
||||
std::vector<Color>{
|
||||
{80, 80, 90}, {75, 75, 85}, {85, 85, 95}, {78, 78, 88},
|
||||
{82, 82, 92}, {76, 76, 86}, {84, 84, 94}, {79, 79, 89}
|
||||
},
|
||||
0.0f // Estado inicial
|
||||
},
|
||||
// Keyframe 1: Erupción naranja-roja (explosión)
|
||||
{
|
||||
180.0f / 255.0f, 60.0f / 255.0f, 30.0f / 255.0f, // Fondo superior: naranja-rojo
|
||||
80.0f / 255.0f, 20.0f / 255.0f, 10.0f / 255.0f, // Fondo inferior: rojo oscuro
|
||||
std::vector<Color>{
|
||||
{255, 80, 40}, {255, 100, 50}, {255, 70, 35}, {255, 90, 45},
|
||||
{255, 75, 38}, {255, 95, 48}, {255, 85, 42}, {255, 78, 40}
|
||||
},
|
||||
3.0f // 3 segundos para erupción (rápido)
|
||||
},
|
||||
// Keyframe 2: Lava brillante (clímax)
|
||||
{
|
||||
220.0f / 255.0f, 120.0f / 255.0f, 40.0f / 255.0f, // Fondo superior: naranja brillante
|
||||
180.0f / 255.0f, 60.0f / 255.0f, 20.0f / 255.0f, // Fondo inferior: naranja-rojo
|
||||
std::vector<Color>{
|
||||
{255, 180, 80}, {255, 200, 100}, {255, 170, 70}, {255, 190, 90},
|
||||
{255, 175, 75}, {255, 195, 95}, {255, 185, 85}, {255, 178, 78}
|
||||
},
|
||||
3.5f // 3.5 segundos para lava máxima
|
||||
},
|
||||
// Keyframe 3: Enfriamiento (vuelta a ceniza gradual)
|
||||
{
|
||||
100.0f / 255.0f, 80.0f / 255.0f, 70.0f / 255.0f, // Fondo superior: gris-naranja
|
||||
50.0f / 255.0f, 40.0f / 255.0f, 35.0f / 255.0f, // Fondo inferior: gris oscuro
|
||||
std::vector<Color>{
|
||||
{150, 120, 100}, {140, 110, 90}, {160, 130, 110}, {145, 115, 95},
|
||||
{155, 125, 105}, {142, 112, 92}, {158, 128, 108}, {148, 118, 98}
|
||||
},
|
||||
5.5f // 5.5 segundos para enfriamiento (lento)
|
||||
}
|
||||
// Loop = true hará transición automática de keyframe 3 → keyframe 0
|
||||
},
|
||||
true // Loop = true (ciclo: ceniza→erupción→lava→enfriamiento→ceniza...)
|
||||
));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -296,6 +475,17 @@ void ThemeManager::cycleTheme() {
|
||||
switchToTheme(next_theme_index);
|
||||
}
|
||||
|
||||
void ThemeManager::cyclePrevTheme() {
|
||||
// Calcular tema anterior con wraparound (14→13→...→1→0→14)
|
||||
int prev_theme_index = (current_theme_index_ - 1);
|
||||
if (prev_theme_index < 0) {
|
||||
prev_theme_index = static_cast<int>(themes_.size()) - 1; // Wrap to último tema
|
||||
}
|
||||
|
||||
// Usar switchToTheme() para obtener transición LERP automáticamente
|
||||
switchToTheme(prev_theme_index);
|
||||
}
|
||||
|
||||
void ThemeManager::pauseDynamic() {
|
||||
// Solo funciona si el tema actual es dinámico
|
||||
if (themes_[current_theme_index_]->needsUpdate()) {
|
||||
|
||||
Reference in New Issue
Block a user