diff --git a/source/ui/help_overlay.cpp b/source/ui/help_overlay.cpp index 01c866b..5a747a8 100644 --- a/source/ui/help_overlay.cpp +++ b/source/ui/help_overlay.cpp @@ -18,20 +18,21 @@ HelpOverlay::HelpOverlay() box_y_(0), column1_width_(0), column2_width_(0), + column3_width_(0), cached_texture_(nullptr), last_category_color_({0, 0, 0, 255}), last_content_color_({0, 0, 0, 255}), last_bg_color_({0, 0, 0, 255}), texture_needs_rebuild_(true) { - // Llenar lista de controles (organizados por categoría, equilibrado en 2 columnas) + // Llenar lista de controles (organizados por categoría, equilibrado en 3 columnas) key_bindings_ = { // COLUMNA 1: SIMULACIÓN {"SIMULACIÓN", ""}, - {"1-8", "Escenarios (10 a 50,000 pelotas)"}, - {"F", "Toggle Física - Última Figura"}, - {"B", "Modo Boids (enjambre)"}, + {"1-8", "Escenarios (10 a 50.000 pelotas)"}, + {"F", "Cambia entre figura y física"}, + {"B", "Modo Boids"}, {"ESPACIO", "Impulso contra gravedad"}, - {"G", "Toggle Gravedad ON/OFF"}, + {"G", "Activar / Desactivar gravedad"}, {"CURSORES", "Dirección de gravedad"}, {"", ""}, // Separador @@ -39,40 +40,42 @@ HelpOverlay::HelpOverlay() {"FIGURAS 3D", ""}, {"Q/W/E/R", "Esfera/Lissajous/Hélice/Toroide"}, {"T/Y/U/I", "Cubo/Cilindro/Icosaedro/Átomo"}, - {"O", "Forma PNG"}, {"Num+/-", "Escalar figura"}, {"Num*", "Reset escala"}, - {"Num/", "Toggle profundidad"}, + {"Num/", "Activar / Desactivar profundidad"}, + {"[new_col]", ""}, // CAMBIO DE COLUMNA -> COLUMNA 2 + + // COLUMNA 2: MODOS + {"MODOS", ""}, + {"D", "Modo demo"}, + {"L", "Modo demo lite"}, + {"K", "Modo logo"}, {"", ""}, // Separador - // COLUMNA 1: VISUAL + // COLUMNA 2: VISUAL {"VISUAL", ""}, {"C", "Tema siguiente"}, {"Shift+C", "Tema anterior"}, {"NumEnter", "Página de temas"}, - {"N", "Cambiar sprite"}, - {"[new_col]", ""}, // Separador -> CAMBIO DE COLUMNA - - // COLUMNA 2: PANTALLA - {"PANTALLA", ""}, - {"F1/F2", "Zoom out/in (ventana)"}, - {"F3", "Fullscreen letterbox"}, - {"F4", "Fullscreen real"}, - {"F5", "Escalado (F3 activo)"}, - {"V", "Toggle V-Sync"}, - {"", ""}, // Separador - - // COLUMNA 2: MODOS - {"MODOS", ""}, - {"D", "Modo DEMO"}, {"Shift+D", "Pausar tema dinámico"}, - {"L", "Modo DEMO LITE"}, - {"K", "Modo LOGO (easter egg)"}, + {"N", "Cambiar tamaño de pelota"}, + {"X", "Ciclar presets PostFX"}, + {"[new_col]", ""}, // CAMBIO DE COLUMNA -> COLUMNA 3 + + // COLUMNA 3: PANTALLA + {"PANTALLA", ""}, + {"F1", "Disminuye ventana"}, + {"F2", "Aumenta ventana"}, + {"F3", "Pantalla completa"}, + {"F4", "Pantalla completa real"}, + {"F5", "Activar / Desactivar PostFX"}, + {"F6", "Cambia el escalado de pantalla"}, + {"V", "Activar / Desactivar V-Sync"}, {"", ""}, // Separador - // COLUMNA 2: DEBUG/AYUDA + // COLUMNA 3: DEBUG/AYUDA {"DEBUG/AYUDA", ""}, - {"F12", "Toggle info debug"}, + {"F12", "Activar / Desactivar info debug"}, {"H", "Esta ayuda"}, {"ESC", "Salir"}}; } @@ -157,12 +160,13 @@ void HelpOverlay::calculateTextDimensions(int& max_width, int& total_height) { // Calcular ancho máximo por columna int max_col1_width = 0; int max_col2_width = 0; + int max_col3_width = 0; int current_column = 0; for (const auto& binding : key_bindings_) { // Cambio de columna if (strcmp(binding.key, "[new_col]") == 0) { - current_column = 1; + current_column++; continue; } @@ -186,48 +190,51 @@ void HelpOverlay::calculateTextDimensions(int& max_width, int& total_height) { // Actualizar máximo de columna correspondiente if (current_column == 0) { max_col1_width = std::max(max_col1_width, line_width); - } else { + } else if (current_column == 1) { max_col2_width = std::max(max_col2_width, line_width); + } else { + max_col3_width = std::max(max_col3_width, line_width); } } // Almacenar anchos de columnas en miembros para uso posterior column1_width_ = max_col1_width; column2_width_ = max_col2_width; + column3_width_ = max_col3_width; - // Ancho total: 2 columnas + 3 paddings (izq, medio, der) - max_width = max_col1_width + max_col2_width + padding * 3; + // Ancho total: 3 columnas + 4 paddings (izq, entre cols x2, der) + max_width = max_col1_width + max_col2_width + max_col3_width + padding * 4; - // Altura: contar líneas REALES en cada columna - int col1_lines = 0; - int col2_lines = 0; + // Altura: contar unidades de altura por columna (en "medias líneas" para precisión) + // - línea normal = 2 unidades, encabezado = 2 unidades (+2px ignorados aquí), separador = 1 unidad + int col1_half_lines = 0; + int col2_half_lines = 0; + int col3_half_lines = 0; current_column = 0; for (const auto& binding : key_bindings_) { - // Cambio de columna if (strcmp(binding.key, "[new_col]") == 0) { - current_column = 1; + current_column++; continue; } - // Separador vacío no cuenta como línea - if (binding.key[0] == '\0') { - continue; - } + int units = (binding.key[0] == '\0') ? 1 : 2; // separador = 1, línea/encabezado = 2 - // Contar línea (ya sea encabezado o contenido) if (current_column == 0) { - col1_lines++; + col1_half_lines += units; + } else if (current_column == 1) { + col2_half_lines += units; } else { - col2_lines++; + col3_half_lines += units; } } - // Usar la columna más larga para calcular altura - int max_column_lines = std::max(col1_lines, col2_lines); + // Convertir a altura real: unidades * (line_height / 2) + int max_half_lines = std::max({col1_half_lines, col2_half_lines, col3_half_lines}); + int content_height = max_half_lines * line_height / 2; // Altura: título (2 líneas) + contenido + padding superior e inferior - total_height = line_height * 2 + max_column_lines * line_height + padding * 2; + total_height = line_height * 2 + content_height + padding * 2; } void HelpOverlay::calculateBoxDimensions() { @@ -354,34 +361,35 @@ void HelpOverlay::rebuildCachedTexture() { if (strcmp(binding.key, "[new_col]") == 0 && binding.description[0] == '\0') { if (current_column == 0) { current_column = 1; - current_x = padding + column1_width_ + padding; // Usar ancho real de columna 1 + current_x = padding + column1_width_ + padding; + current_y = content_start_y; + } else if (current_column == 1) { + current_column = 2; + current_x = padding + column1_width_ + padding + column2_width_ + padding; current_y = content_start_y; } continue; } - // CHECK PADDING INFERIOR ANTES de escribir la línea (AMBAS COLUMNAS) - // Verificar si la PRÓXIMA línea cabrá dentro del box con padding inferior + // CHECK PADDING INFERIOR ANTES de escribir la línea if (current_y + line_height >= box_height_ - padding) { - if (current_column == 0) { - // Columna 0 llena: cambiar a columna 1 - current_column = 1; - current_x = padding + column1_width_ + padding; - current_y = content_start_y; - } else { - // Columna 1 llena: omitir resto de texto (no cabe) - // Preferible omitir que sobresalir del overlay - continue; - } + continue; } if (binding.description[0] == '\0') { - text_renderer_->printAbsolute(current_x, current_y, binding.key, category_color); - current_y += line_height + 2; + if (binding.key[0] == '\0') { + // Separador vacío: avanzar media línea + current_y += line_height / 2; + } else { + // Encabezado de sección + text_renderer_->printAbsolute(current_x, current_y, binding.key, category_color); + current_y += line_height + 2; + } continue; } - text_renderer_->printAbsolute(current_x, current_y, binding.key, content_color); + // Tecla en category_color, descripción en content_color + text_renderer_->printAbsolute(current_x, current_y, binding.key, category_color); int key_width = text_renderer_->getTextWidthPhysical(binding.key); text_renderer_->printAbsolute(current_x + key_width + 10, current_y, binding.description, content_color); diff --git a/source/ui/help_overlay.hpp b/source/ui/help_overlay.hpp index f2598bb..8e9cd1c 100644 --- a/source/ui/help_overlay.hpp +++ b/source/ui/help_overlay.hpp @@ -76,6 +76,7 @@ class HelpOverlay { // Anchos individuales de cada columna (para evitar solapamiento) int column1_width_; int column2_width_; + int column3_width_; // Sistema de caché para optimización de rendimiento SDL_Texture* cached_texture_; // Textura cacheada del overlay completo diff --git a/source/ui/ui_manager.cpp b/source/ui/ui_manager.cpp index de5ba13..e43dfcc 100644 --- a/source/ui/ui_manager.cpp +++ b/source/ui/ui_manager.cpp @@ -100,7 +100,7 @@ void UIManager::initialize(SDL_Renderer* renderer, ThemeManager* theme_manager, // Crear y configurar sistema de ayuda (overlay) help_overlay_ = new HelpOverlay(); - help_overlay_->initialize(renderer, theme_manager_, physical_width, physical_height, current_font_size_); + help_overlay_->initialize(renderer, theme_manager_, physical_width, physical_height, std::max(9, current_font_size_ - 1)); // Inicializar FPS counter fps_last_time_ = SDL_GetTicks(); @@ -195,7 +195,7 @@ void UIManager::updatePhysicalWindowSize(int width, int height) { // Actualizar help overlay con font size actual Y nuevas dimensiones (atómicamente) if (help_overlay_) { - help_overlay_->updateAll(current_font_size_, width, height); + help_overlay_->updateAll(std::max(9, current_font_size_ - 1), width, height); } // Actualizar otros componentes de UI con nuevas dimensiones