diff --git a/docs/TABLES_ARCHITECTURE.md b/docs/TABLES_ARCHITECTURE.md index c265e50..16ce34f 100644 --- a/docs/TABLES_ARCHITECTURE.md +++ b/docs/TABLES_ARCHITECTURE.md @@ -241,19 +241,31 @@ pub fn toggleSort(current_column, current_direction, clicked_column) SortToggleR ### Edición de Celda ```zig -pub const EditKeyboardResult = struct { - committed: bool, // Enter presionado - cancelled: bool, // Escape 2x - reverted: bool, // Escape 1x (revertir a original) - navigate_next: bool, // Tab - navigate_prev: bool, // Shift+Tab - text_changed: bool, // Texto modificado +/// Dirección de navegación después de commit +pub const NavigateDirection = enum { + none, // Sin navegación + next_cell, // Tab → siguiente celda + prev_cell, // Shift+Tab → celda anterior + next_row, // Enter/↓ → siguiente fila + prev_row, // ↑ → fila anterior }; -/// Procesa teclado en modo edición +pub const EditKeyboardResult = struct { + committed: bool, // Enter/Tab/flechas presionados + cancelled: bool, // Escape 2x + reverted: bool, // Escape 1x (revertir a original) + navigate: NavigateDirection, // Dirección de navegación post-commit + text_changed: bool, // Texto modificado + handled: bool, // IMPORTANTE: evento fue procesado +}; + +/// Procesa teclado en modo edición (DRY - un solo lugar) pub fn handleEditingKeyboard(ctx, edit_buffer, edit_len, edit_cursor, escape_count, original_text) EditKeyboardResult ``` +> **IMPORTANTE:** El campo `handled` indica si table_core procesó el evento de teclado. +> Esto es crítico para evitar doble procesamiento de Tab (ver "Lecciones Aprendidas"). + ### Renderizado ```zig @@ -353,10 +365,55 @@ Tests incluidos: --- +## Lecciones Aprendidas + +### Bug: Color de fila alternando al presionar Tab (2025-12-27) + +**Síntoma:** Al navegar entre celdas con Tab, el color de la fila seleccionada alternaba +entre azul (con focus) y marrón/gris (sin focus), independientemente de si se modificaba +el contenido. + +**Causa raíz:** Tab se procesaba DOS veces: +1. Por VirtualAdvancedTable/CellEditor → navegación entre celdas +2. Por main.zig de la aplicación → cambio de focus entre widgets (`ctx.handleTabKey()`) + +Esto causaba que el focus del widget alternara incorrectamente cada frame. + +**Solución (3 partes):** + +1. **table_core.zig:** Añadir campo `handled` a `EditKeyboardResult` para indicar que el + evento fue procesado. + +2. **VirtualAdvancedTable:** Verificar `navigate_direction != .none` antes de procesar + Tab como `tab_out`. Si la tabla ya procesó Tab para navegación interna, no marcar + `tab_out = true`. + +3. **Aplicación (main.zig):** No llamar `ctx.handleTabKey()` cuando el panel activo + maneja Tab internamente (ej: cuando `active_tab == .configuracion`). + +**Regla general:** +> Cuando un widget procesa teclado internamente en `draw()`, la aplicación debe +> respetar esa decisión y NO procesar el mismo evento a nivel global. + +**Código clave:** +```zig +// VirtualAdvancedTable - handleKeyboard() +.tab => { + // IMPORTANTE: Solo si CellEditor no procesó Tab + if (result.navigate_direction == .none) { + result.tab_out = true; + result.tab_shift = event.modifiers.shift; + } +}, +``` + +--- + ## Historial de Cambios | Fecha | Cambio | |-------|--------| +| 2025-12-27 | Fix bug colores alternando + campo `handled` en EditKeyboardResult | | 2025-12-27 | Refactorización DRY: lógica común movida a table_core.zig | | 2025-12-26 | table_core.zig creado con funciones de renderizado compartidas | | 2025-12-17 | VirtualAdvancedTable añadido para tablas grandes |