fix: corregir padding asimétrico en HelpOverlay con getGlyphHeight()
Añade TextRenderer::getGlyphHeight() (ascent - descent, sin line_gap) y lo usa en calculateTextDimensions() para descontar el gap sobrante de la última línea, aproximando padding superior e inferior simétricos. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -30,7 +30,7 @@ HelpOverlay::HelpOverlay()
|
||||
{"SIMULACIÓN", ""},
|
||||
{"1-8", "Escenarios (10 a 50.000 pelotas)"},
|
||||
{"F", "Cambia entre figura y física"},
|
||||
{"B", "Modo Boids"},
|
||||
{"B", "Cambia entre boids y física"},
|
||||
{"ESPACIO", "Impulso contra gravedad"},
|
||||
{"G", "Activar / Desactivar gravedad"},
|
||||
{"CURSORES", "Dirección de gravedad"},
|
||||
@@ -47,9 +47,9 @@ HelpOverlay::HelpOverlay()
|
||||
|
||||
// COLUMNA 2: MODOS
|
||||
{"MODOS", ""},
|
||||
{"D", "Modo demo"},
|
||||
{"L", "Modo demo lite"},
|
||||
{"K", "Modo logo"},
|
||||
{"D", "Activar / Desactivar modo demo"},
|
||||
{"L", "Activar / Desactivar modo demo lite"},
|
||||
{"K", "Activar / Desactivar modo logo"},
|
||||
{"", ""}, // Separador
|
||||
|
||||
// COLUMNA 2: VISUAL
|
||||
@@ -202,14 +202,14 @@ void HelpOverlay::calculateTextDimensions(int& max_width, int& total_height) {
|
||||
column2_width_ = max_col2_width;
|
||||
column3_width_ = max_col3_width;
|
||||
|
||||
// Ancho total: 3 columnas + 4 paddings (izq, entre cols x2, der)
|
||||
max_width = max_col1_width + max_col2_width + max_col3_width + padding * 4;
|
||||
// Gap entre columnas: doble del padding para dar más respiro
|
||||
int col_gap = padding * 2;
|
||||
|
||||
// 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;
|
||||
// Ancho total: 3 columnas + padding izq/der + 2 gaps entre columnas
|
||||
max_width = max_col1_width + max_col2_width + max_col3_width + padding * 2 + col_gap * 2;
|
||||
|
||||
// Calcular altura real simulando exactamente lo que hace el render
|
||||
int col_heights[3] = {0, 0, 0};
|
||||
current_column = 0;
|
||||
|
||||
for (const auto& binding : key_bindings_) {
|
||||
@@ -218,23 +218,23 @@ void HelpOverlay::calculateTextDimensions(int& max_width, int& total_height) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int units = (binding.key[0] == '\0') ? 1 : 2; // separador = 1, línea/encabezado = 2
|
||||
|
||||
if (current_column == 0) {
|
||||
col1_half_lines += units;
|
||||
} else if (current_column == 1) {
|
||||
col2_half_lines += units;
|
||||
if (binding.key[0] == '\0') {
|
||||
col_heights[current_column] += line_height; // separador vacío
|
||||
} else if (binding.description[0] == '\0') {
|
||||
col_heights[current_column] += line_height; // encabezado
|
||||
} else {
|
||||
col3_half_lines += units;
|
||||
col_heights[current_column] += line_height; // línea normal
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
int content_height = std::max({col_heights[0], col_heights[1], col_heights[2]});
|
||||
|
||||
// Altura: título (2 líneas) + contenido + padding superior e inferior
|
||||
total_height = line_height * 2 + content_height + padding * 2;
|
||||
// Eliminar el line_gap de la última línea: ese gap es espacio entre líneas,
|
||||
// pero la última línea no tiene siguiente, así que queda como padding muerto.
|
||||
int glyph_height = text_renderer_->getGlyphHeight();
|
||||
int visual_content_height = content_height - (line_height - glyph_height);
|
||||
|
||||
total_height = visual_content_height + padding * 2;
|
||||
}
|
||||
|
||||
void HelpOverlay::calculateBoxDimensions() {
|
||||
@@ -341,31 +341,28 @@ void HelpOverlay::rebuildCachedTexture() {
|
||||
|
||||
// Configuración de espaciado
|
||||
int line_height = text_renderer_->getTextHeight();
|
||||
// Padding dinámico basado en altura física: 25px para >= 600px, escalado proporcionalmente para menores
|
||||
int padding = (physical_height_ >= 600) ? 25 : std::max(10, physical_height_ / 24);
|
||||
int col_gap = padding * 2;
|
||||
|
||||
// Posición X de inicio de cada columna
|
||||
int col_start[3];
|
||||
col_start[0] = padding;
|
||||
col_start[1] = padding + column1_width_ + col_gap;
|
||||
col_start[2] = padding + column1_width_ + col_gap + column2_width_ + col_gap;
|
||||
|
||||
// Ancho de cada columna (para centrado interno)
|
||||
int col_width[3] = {column1_width_, column2_width_, column3_width_};
|
||||
|
||||
int current_x = padding; // Coordenadas relativas a la textura (0,0)
|
||||
int current_y = padding;
|
||||
int current_column = 0;
|
||||
|
||||
// Título principal
|
||||
const char* title = "CONTROLES - ViBe3 Physics";
|
||||
int title_width = text_renderer_->getTextWidthPhysical(title);
|
||||
text_renderer_->printAbsolute(box_width_ / 2 - title_width / 2, current_y, title, category_color);
|
||||
current_y += line_height * 2;
|
||||
|
||||
int content_start_y = current_y;
|
||||
|
||||
// Renderizar cada línea
|
||||
for (const auto& binding : key_bindings_) {
|
||||
if (strcmp(binding.key, "[new_col]") == 0 && binding.description[0] == '\0') {
|
||||
if (current_column == 0) {
|
||||
current_column = 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;
|
||||
if (current_column < 2) {
|
||||
current_column++;
|
||||
current_y = content_start_y;
|
||||
}
|
||||
continue;
|
||||
@@ -376,22 +373,30 @@ void HelpOverlay::rebuildCachedTexture() {
|
||||
continue;
|
||||
}
|
||||
|
||||
int cx = col_start[current_column];
|
||||
int cw = col_width[current_column];
|
||||
|
||||
if (binding.description[0] == '\0') {
|
||||
if (binding.key[0] == '\0') {
|
||||
// Separador vacío: avanzar media línea
|
||||
current_y += line_height / 2;
|
||||
// Separador vacío: avanzar una línea completa
|
||||
current_y += line_height;
|
||||
} else {
|
||||
// Encabezado de sección
|
||||
text_renderer_->printAbsolute(current_x, current_y, binding.key, category_color);
|
||||
current_y += line_height + 2;
|
||||
// Encabezado de sección — centrado en la columna
|
||||
int w = text_renderer_->getTextWidthPhysical(binding.key);
|
||||
text_renderer_->printAbsolute(cx + (cw - w) / 2, current_y, binding.key, category_color);
|
||||
current_y += line_height;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Tecla en category_color, descripción en content_color
|
||||
text_renderer_->printAbsolute(current_x, current_y, binding.key, category_color);
|
||||
// Par tecla+descripción — centrado como bloque en la columna
|
||||
int key_width = text_renderer_->getTextWidthPhysical(binding.key);
|
||||
text_renderer_->printAbsolute(current_x + key_width + 10, current_y, binding.description, content_color);
|
||||
int desc_width = text_renderer_->getTextWidthPhysical(binding.description);
|
||||
int total_width = key_width + 10 + desc_width;
|
||||
int line_x = cx + (cw - total_width) / 2;
|
||||
|
||||
text_renderer_->printAbsolute(line_x, current_y, binding.key, category_color);
|
||||
text_renderer_->printAbsolute(line_x + key_width + 10, current_y, binding.description, content_color);
|
||||
|
||||
current_y += line_height;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user