docs(TABLES_ARCHITECTURE): Add 'Lecciones Aprendidas' section
Document the Tab double-processing bug and its solution: - Symptom: Row color alternating on Tab press - Root cause: Tab processed twice (widget + app level) - Solution: NavigateDirection + handled flag + app check - General rule for keyboard handling in immediate-mode widgets Also updated EditKeyboardResult API documentation with new fields.
This commit is contained in:
parent
60c3f9d456
commit
0026dbff2a
1 changed files with 65 additions and 8 deletions
|
|
@ -241,19 +241,31 @@ pub fn toggleSort(current_column, current_direction, clicked_column) SortToggleR
|
||||||
### Edición de Celda
|
### Edición de Celda
|
||||||
|
|
||||||
```zig
|
```zig
|
||||||
pub const EditKeyboardResult = struct {
|
/// Dirección de navegación después de commit
|
||||||
committed: bool, // Enter presionado
|
pub const NavigateDirection = enum {
|
||||||
cancelled: bool, // Escape 2x
|
none, // Sin navegación
|
||||||
reverted: bool, // Escape 1x (revertir a original)
|
next_cell, // Tab → siguiente celda
|
||||||
navigate_next: bool, // Tab
|
prev_cell, // Shift+Tab → celda anterior
|
||||||
navigate_prev: bool, // Shift+Tab
|
next_row, // Enter/↓ → siguiente fila
|
||||||
text_changed: bool, // Texto modificado
|
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
|
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
|
### Renderizado
|
||||||
|
|
||||||
```zig
|
```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
|
## Historial de Cambios
|
||||||
|
|
||||||
| Fecha | Cambio |
|
| 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-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-26 | table_core.zig creado con funciones de renderizado compartidas |
|
||||||
| 2025-12-17 | VirtualAdvancedTable añadido para tablas grandes |
|
| 2025-12-17 | VirtualAdvancedTable añadido para tablas grandes |
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue