zcatgui/docs/PROPUESTA_WIDGETS_BROWSER.md
reugenio bd95013ffc fix(advanced_table): Teclado funciona - result.selected_row/col
Bug: Las flechas no movían la selección en AdvancedTable.

Causa raíz:
- handleKeyboard seteaba result.selection_changed = true
- PERO NO seteaba result.selected_row / result.selected_col
- zsimifactu sincroniza selección desde DataManager cada frame
- Sin esos valores, DataManager no se actualizaba
- Siguiente frame: selección se reseteaba al valor anterior

Solución:
- Añadir result.selected_row y result.selected_col a todas
  las teclas de navegación (up, down, left, right, page_up,
  page_down, home, end)

Cambios visuales:
- Celda seleccionada: borde + tinte sutil (15%) en lugar
  de fondo sólido azul

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 20:06:17 +01:00

201 lines
6.9 KiB
Markdown

# Propuesta: Widgets Browser Especializados
**Fecha:** 2025-12-17
**Origen:** Conversación zsimifactu sobre extracción de patrones reutilizables
**Estado:** PROPUESTA - Pendiente de implementación
---
## Resumen Ejecutivo
Se propone crear widgets especializados para navegación de datos tabulares que encapsulen patrones comunes identificados en zsimifactu. Estos widgets combinarían tabla + controles de navegación + filtros en componentes cohesivos.
---
## Widgets Propuestos
### 1. TableBrowser
Widget compuesto que integra:
- Tabla con scroll y selección
- Barra de estado con posición (ej: "15/520")
- Botones de navegación (|< < > >|)
- Soporte para filtros (opcional)
```
┌─────────────────────────────────────────────┐
│ [Filtro: ___________] [Tipo: v] │ ← Zona filtros (opcional)
├─────────────────────────────────────────────┤
│ Codigo │ Nombre │ Ciudad │ ← Header tabla
├────────┼─────────────────┼─────────────────┤
│ C0001 │ Empresa ABC │ Valencia │
│ C0002 │ Empresa XYZ │ Madrid │
│ ... │ ... │ ... │
├─────────────────────────────────────────────┤
│ [|<] [<] 15/520 [>] [>|] │ ← Navegación integrada
└─────────────────────────────────────────────┘
```
**Caso de uso:** Panel de lista en aplicaciones CRUD (WhoListPanel, DocListPanel, etc.)
### 2. ConfigBrowser
Widget especializado para visualizar/editar configuración:
- Lista de variables agrupadas por categoría
- Editor inline según tipo (checkbox, input, color picker)
- Búsqueda/filtro de variables
- Indicador de cambios pendientes
```
┌─────────────────────────────────────────────┐
│ [Buscar: ___________] │
├─────────────────────────────────────────────┤
│ ▼ General │
│ auto_guardar_cada [15 ] minutos │
│ backup_automatico [✓] │
├─────────────────────────────────────────────┤
│ ▼ Apariencia │
│ color_azul_empresa [■] RGB(40,80,120) │
│ font_size [14 ] │
├─────────────────────────────────────────────┤
│ ▶ Comportamiento (click para expandir) │
└─────────────────────────────────────────────┘
```
**Caso de uso:** Panel de configuración de aplicación
---
## Justificación Técnica
### Patrón Repetido en zsimifactu
En `WhoListPanel` y futuros paneles de lista se repite:
1. Tabla con datos
2. Callback para obtener celdas
3. Botones navegación (First/Prev/Next/Last)
4. Indicador posición
5. Manejo de selección → DataManager
Este código se duplicaría en cada panel de lista (DocListPanel, ProdListPanel, etc.).
### Beneficios de Encapsular
| Aspecto | Sin widget | Con TableBrowser |
|---------|------------|------------------|
| Líneas por panel | ~200 | ~50 |
| Bugs de navegación | Duplicados | Corregidos una vez |
| Consistencia UX | Manual | Automática |
| Nuevos paneles | Copy-paste | Instanciar widget |
---
## API Propuesta
### TableBrowser
```zig
const TableBrowser = struct {
table_state: widgets.table.TableState,
nav_state: NavState,
filter_state: ?FilterState,
pub const Config = struct {
columns: []const Column,
show_navigation: bool = true,
show_filters: bool = false,
row_height: u16 = 18,
};
pub const Callbacks = struct {
getCellData: *const fn (row: usize, col: usize) []const u8,
getRowCount: *const fn () usize,
onSelectionChanged: ?*const fn (row: usize) void = null,
};
pub fn init(config: Config) TableBrowser;
pub fn draw(self: *Self, ctx: *Context, rect: Rect, callbacks: Callbacks) DrawResult;
pub fn handleEvent(self: *Self, event: Event) bool;
// Navegación programática
pub fn goFirst(self: *Self) void;
pub fn goPrev(self: *Self) void;
pub fn goNext(self: *Self) void;
pub fn goLast(self: *Self) void;
pub fn getPosition(self: *Self) struct { current: usize, total: usize };
};
```
### ConfigBrowser
```zig
const ConfigBrowser = struct {
pub const Config = struct {
variables: []const ConfigVariable, // De zcatconfig
show_search: bool = true,
group_by_category: bool = true,
};
pub fn init(config: Config) ConfigBrowser;
pub fn draw(self: *Self, ctx: *Context, rect: Rect, config_ptr: anytype) DrawResult;
pub fn handleEvent(self: *Self, event: Event) bool;
// Estado
pub fn hasChanges(self: *Self) bool;
pub fn getChangedVariables(self: *Self) []const []const u8;
};
```
---
## Integración con zcatconfig
El `ConfigBrowser` se integraría naturalmente con la nueva librería `zcatconfig`:
```zig
const zcatconfig = @import("zcatconfig");
const ConfigBrowser = zcatgui.widgets.ConfigBrowser;
// En el proyecto consumidor:
const variables = @import("config/variables.zig");
const Config = @import("config/structures.zig").Config;
var config = Config{};
var browser = ConfigBrowser.init(.{
.variables = &variables.config_variables,
});
// En draw:
const result = browser.draw(ctx, rect, &config);
if (result.value_changed) {
try zcatconfig.save(&variables.config_variables, Config, &config, allocator, "config.txt");
}
```
---
## Priorización Sugerida
| Widget | Prioridad | Razón |
|--------|-----------|-------|
| TableBrowser | Alta | Necesario para DocListPanel, ProdListPanel |
| ConfigBrowser | Media | Panel config es nice-to-have, no bloqueante |
---
## Dependencias
- **TableBrowser**: Ninguna externa, usa widgets existentes (table, button)
- **ConfigBrowser**: Requiere `zcatconfig` como dependencia opcional
---
## Siguiente Paso
1. Revisar esta propuesta
2. Decidir si proceder con implementación
3. Crear issue/tarea en zcatgui
---
*Documento generado desde conversación zsimifactu 2025-12-17*