Cambios principales: - Nuevo FocusSystem unificado en core/focus.zig - Separación registration_group / active_group para multi-panel - Focus implícito para primer widget del grupo activo - Table inicializa selected_row/col a 0 cuando tiene datos - Corregido test navKeyPressed (usaba setKeyState en vez de handleKeyEvent) Bug resuelto: tabla no respondía a teclado sin clic previo Causa: selected_col quedaba en -1, selectedCell() retornaba null Documentación: docs/FOCUS_TRANSITION_2025-12-11.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
26 KiB
zcatgui - GUI Library para Zig
IMPORTANTE PARA CLAUDE: Lee la sección "PROTOCOLO DE INICIO" antes de hacer cualquier cosa.
PROTOCOLO DE INICIO (LEER PRIMERO)
Paso 1: Leer normas del equipo
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/LAST_UPDATE.md
Paso 2: Leer normas completas si es necesario
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/NORMAS_TRABAJO_CONSENSUADAS.md
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/QUICK_REFERENCE.md
Paso 3: Leer documentación
REFERENCE.md # ⭐ MANUAL DE REFERENCIA COMPLETO (1370 líneas)
docs/DEVELOPMENT_PLAN.md # Plan de desarrollo por fases
docs/MOBILE_WEB_BACKENDS.md # Documentación backends mobile/web
docs/research/WIDGET_COMPARISON.md # Comparativa zcatgui vs DVUI vs Gio
docs/ARCHITECTURE.md # Arquitectura y decisiones de diseño
Paso 4: Verificar estado del proyecto
cd /mnt/cello2/arno/re/recode/zig/zcatgui
git status
git log --oneline -3
zig build test
Paso 5: Continuar trabajo
Una vez verificado el estado, continúa desde donde se dejó.
INFORMACIÓN DEL PROYECTO
| Campo | Valor |
|---|---|
| Nombre | zcatgui |
| Versión | v0.15.0 |
| Fecha inicio | 2025-12-09 |
| Estado | ✅ COMPLETO - 37 widgets, ~35K LOC, 4 backends |
| Lenguaje | Zig 0.15.2 |
| Paradigma | Immediate Mode GUI |
| Inspiración | Gio (Go), microui (C), DVUI (Zig), Dear ImGui (C++) |
| Proyecto hermano | zcatui (TUI library) |
Descripción
zcatgui es una librería GUI immediate-mode para Zig con las siguientes características:
- Software Rendering por defecto - Funciona en cualquier ordenador sin GPU
- Cross-platform - Linux, Windows, macOS, Web (WASM), Android, iOS
- SSH compatible - Funciona via X11 forwarding
- Sistema de Macros - Grabación/reproducción de acciones (piedra angular)
- Sin dependencias pesadas - Solo SDL2 para desktop, nativo para mobile/web
Filosofía
"Máxima compatibilidad, mínimas dependencias, control total del usuario"
- Funciona en cualquier ordenador (viejo HP, nuevo Lenovo, servidor SSH)
- Software rendering primero, GPU opcional después
- Sistema de macros integrado desde el diseño
- Immediate mode = estado explícito, sin threading hell
RUTAS IMPORTANTES
# Este proyecto
/mnt/cello2/arno/re/recode/zig/zcatgui/
# Proyecto hermano (TUI)
/mnt/cello2/arno/re/recode/zig/zcatui/
# Proyecto de referencia (usa Fyne, queremos replicar funcionalidad)
/mnt/cello2/arno/re/recode/go/simifactu/
# Normas del equipo
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/
# Compilador Zig 0.15.2
/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
COMANDOS FRECUENTES
# Compilar (desktop)
zig build
# Tests
zig build test
# Ejemplos desktop
zig build hello
zig build macro-demo
zig build widgets-demo
zig build table-demo
# WASM (navegador)
zig build wasm # Genera web/zcatgui-demo.wasm
cd web && python3 -m http.server # Servir y abrir localhost:8000
# Android (requiere NDK)
zig build android # ARM64 para dispositivo
zig build android-x86 # x86_64 para emulador
# iOS (requiere Xcode en macOS)
zig build ios # ARM64 para dispositivo
zig build ios-sim # ARM64 para simulador
# Git
git status
git add -A && git commit -m "mensaje"
git push
ARQUITECTURA
Paradigma: Immediate Mode
┌─────────────────────────────────────────────────────────────┐
│ IMMEDIATE MODE │
├─────────────────────────────────────────────────────────────┤
│ while (running) { │
│ events = pollEvents(); // Input │
│ updateState(events); // TÚ manejas estado │
│ commands = drawUI(state); // Genera comandos │
│ render(commands); // Dibuja │
│ } │
└─────────────────────────────────────────────────────────────┘
vs Retained Mode (Fyne):
- Framework mantiene árbol de widgets
- Callbacks para cambios
- fyne.Do() para threading
- Estado oculto, sincronización compleja
Capas de la Librería
┌─────────────────────────────────────────────────────────────┐
│ Capa 4: Widgets de alto nivel │
│ (Table, Panel, Select, Modal, etc.) │
├─────────────────────────────────────────────────────────────┤
│ Capa 3: Sistema de Macros │
│ (Grabación, Reproducción, Inyección de teclas) │
├─────────────────────────────────────────────────────────────┤
│ Capa 2: Core UI │
│ (Context, Layout, Style, Input, Commands) │
├─────────────────────────────────────────────────────────────┤
│ Capa 1: Rendering │
│ (Software Rasterizer, Framebuffer, Fonts) │
├─────────────────────────────────────────────────────────────┤
│ Capa 0: Backend │
│ (SDL2 - ventanas, eventos, display) │
└─────────────────────────────────────────────────────────────┘
Estructura de Archivos (ACTUAL v0.15.0)
zcatgui/
├── src/
│ ├── zcatgui.zig # Entry point, re-exports, conditional backend imports
│ │
│ ├── core/
│ │ ├── context.zig # ✅ Context, ID system, command pool, FrameArena
│ │ ├── layout.zig # ✅ Rect, Constraint, LayoutState
│ │ ├── style.zig # ✅ Color, Style, Theme (5 themes)
│ │ ├── input.zig # ✅ Key, KeyEvent, MouseEvent, InputState
│ │ ├── command.zig # ✅ DrawCommand list
│ │ ├── clipboard.zig # ✅ Clipboard support
│ │ ├── dragdrop.zig # ✅ Drag & drop system
│ │ ├── shortcuts.zig # ✅ Keyboard shortcuts manager
│ │ ├── focus_group.zig # ✅ Focus groups
│ │ ├── accessibility.zig # ✅ Accessibility (ARIA roles)
│ │ └── gesture.zig # ✅ Gesture recognizer (tap, swipe, pinch, rotate)
│ │
│ ├── widgets/ # 37 widgets implementados
│ │ ├── widgets.zig # Re-exports
│ │ ├── label.zig, button.zig, text_input.zig, checkbox.zig
│ │ ├── select.zig, list.zig, focus.zig, table.zig
│ │ ├── split.zig, panel.zig, modal.zig, autocomplete.zig
│ │ ├── slider.zig, scroll.zig, tabs.zig, radio.zig, menu.zig
│ │ ├── progress.zig, tooltip.zig, toast.zig
│ │ ├── textarea.zig, tree.zig, badge.zig
│ │ ├── number_entry.zig, reorderable.zig
│ │ ├── breadcrumb.zig, image.zig, icon.zig
│ │ ├── color_picker.zig, date_picker.zig, chart.zig
│ │ └── calendar.zig
│ │
│ ├── render/
│ │ ├── software.zig # ✅ SoftwareRenderer
│ │ ├── framebuffer.zig # ✅ Framebuffer RGBA (u32 pixels)
│ │ ├── font.zig # ✅ Bitmap font 8x8
│ │ ├── ttf.zig # ✅ TTF font support (stb_truetype)
│ │ ├── animation.zig # ✅ Animation system, easing, springs
│ │ ├── effects.zig # ✅ Shadows, gradients, blur
│ │ └── antialiasing.zig # ✅ Anti-aliased rendering
│ │
│ ├── backend/
│ │ ├── backend.zig # ✅ Backend interface (VTable)
│ │ ├── sdl2.zig # ✅ SDL2 (desktop: Linux/Win/Mac)
│ │ ├── wasm.zig # ✅ WASM (navegador)
│ │ ├── android.zig # ✅ Android (ANativeActivity)
│ │ └── ios.zig # ✅ iOS (UIKit bridge)
│ │
│ ├── macro/
│ │ └── macro.zig # ✅ MacroRecorder, MacroPlayer, MacroStorage
│ │
│ ├── panels/
│ │ └── panels.zig # ✅ Lego Panels architecture
│ │
│ └── utils/
│ └── utils.zig # ✅ FrameArena, ObjectPool, Benchmark
│
├── examples/
│ ├── hello.zig # Ejemplo básico
│ ├── macro_demo.zig # Demo macros
│ ├── widgets_demo.zig # Demo widgets
│ ├── table_demo.zig # Demo Table/Split/Panel
│ ├── wasm_demo.zig # ✅ Demo WASM (navegador)
│ └── android_demo.zig # ✅ Demo Android
│
├── web/ # ✅ WASM support
│ ├── index.html # Demo HTML
│ ├── zcatgui.js # JavaScript glue code
│ └── zcatgui-demo.wasm # Compiled WASM (~18KB)
│
├── ios/ # ✅ iOS support
│ ├── ZcatguiBridge.h # Objective-C header
│ └── ZcatguiBridge.m # UIKit implementation
│
├── docs/
│ ├── ARCHITECTURE.md
│ ├── DEVELOPMENT_PLAN.md # ⭐ Plan maestro
│ ├── MOBILE_WEB_BACKENDS.md # ✅ Documentación mobile/web
│ └── research/
│ ├── GIO_UI_ANALYSIS.md
│ ├── IMMEDIATE_MODE_LIBS.md
│ ├── WIDGET_COMPARISON.md
│ └── SIMIFACTU_FYNE_ANALYSIS.md
│
├── build.zig # Build con targets: wasm, android, ios
├── build.zig.zon
├── CLAUDE.md # Este archivo
└── REFERENCE.md # ⭐ Manual de referencia completo (1370 líneas)
SISTEMA DE MACROS (PIEDRA ANGULAR)
Concepto
El sistema de macros permite grabar y reproducir todas las acciones del usuario.
Principio: Grabar teclas raw, no comandos abstractos.
Usuario pulsa: Tab, Tab, Enter, "texto", Escape
Grabamos: [Tab, Tab, Enter, t, e, x, t, o, Escape]
Reproducimos: Inyectamos exactamente esas teclas
Por qué teclas raw (no comandos)
| Enfoque | Pros | Contras |
|---|---|---|
| Teclas raw | Simple, mínima memoria, reproducción exacta | Depende del estado inicial |
| Comandos semánticos | Más robusto | Complejo, más memoria, traducción bidireccional |
Decisión: Teclas raw (como Vim). Razones:
- KISS - menos código = menos bugs
- Vim lo hace así y funciona
- El estado inicial es controlable
Manejo del ratón
Casi todo lo que hace el ratón se puede expresar como teclado:
| Acción ratón | Equivalente teclado |
|---|---|
| Click en botón | Tab hasta focus + Enter |
| Click en fila 5 | Flechas hasta fila 5 |
| Scroll down | PageDown o flechas |
| Drag splitter | Ctrl+flechas |
Estrategia:
- Fase 1: Solo teclado (macros de teclas)
- Fase 2: Mouse → traducir a teclas equivalentes
API Propuesta
pub const MacroRecorder = struct {
events: ArrayList(KeyEvent),
recording: bool,
pub fn start(self: *MacroRecorder) void;
pub fn stop(self: *MacroRecorder) []const KeyEvent;
pub fn record(self: *MacroRecorder, key: KeyEvent) void;
pub fn save(self: *MacroRecorder, path: []const u8) !void;
pub fn load(allocator: Allocator, path: []const u8) !MacroRecorder;
};
pub const MacroPlayer = struct {
pub fn play(
events: []const KeyEvent,
inject_fn: *const fn(KeyEvent) void,
delay_ms: u32,
) void;
};
Casos de Uso
- Testing automatizado: Grabar sesión → convertir en test
- Tutoriales: Macros que se ejecutan paso a paso
- Repetición: Grabar tarea repetitiva, asignar a hotkey
- Debugging: "¿Cómo llegaste a este bug?" → envía el macro
- Demos: Grabar demos que se reproducen en la app
WIDGETS PRIORITARIOS
Basado en análisis de Simifactu (ver docs/research/SIMIFACTU_FYNE_ANALYSIS.md):
| # | Widget | Prioridad | Descripción |
|---|---|---|---|
| 1 | Table | CRÍTICA | Edición in-situ, navegación teclado, dirty tracking |
| 2 | Input | CRÍTICA | Text entry con validación |
| 3 | Select | CRÍTICA | Dropdown selection |
| 4 | Panel | ALTA | Container con título y bordes |
| 5 | Split | ALTA | HSplit/VSplit draggable |
| 6 | Button | ALTA | Con estados disabled, importance |
| 7 | Modal | MEDIA | Diálogos modales |
| 8 | List | MEDIA | Lista seleccionable |
| 9 | Checkbox | MEDIA | Toggle boolean |
| 10 | Label | BAJA | Texto estático |
RENDERING
Software Rasterizer (Command List approach)
pub const DrawCommand = union(enum) {
rect: struct {
x: i32,
y: i32,
w: u32,
h: u32,
color: Color,
},
text: struct {
x: i32,
y: i32,
text: []const u8,
color: Color,
font: *Font,
},
line: struct {
x1: i32,
y1: i32,
x2: i32,
y2: i32,
color: Color,
},
clip: struct {
x: i32,
y: i32,
w: u32,
h: u32,
},
clip_end,
};
Flujo:
Widgets → Commands → Software Rasterizer → Framebuffer → SDL_Texture → Display
Por qué Software Rendering
- Funciona SIEMPRE - No depende de drivers GPU
- SSH compatible - X11 forwarding funciona
- Máxima compatibilidad - Desde HP viejo hasta Lenovo nuevo
- Simple de debugear - Es solo un array de pixels
Fonts
Dos opciones soportadas:
- Bitmap fonts (embebidos) - Siempre funcionan, rápidos
- TTF (stb_truetype) - Más flexible, opcional
PLAN DE DESARROLLO
Fase 0: Setup ✅ COMPLETADA
- Crear estructura de directorios
- build.zig con SDL2
- CLAUDE.md
- Documentación de investigación
Fase 1: Core + Macros ✅ COMPLETADA
- Context con event loop
- Sistema de macros (grabación/reproducción teclas)
- Software rasterizer básico (rects, text, lines)
- SDL2 backend
- Framebuffer RGBA
Fase 2: Widgets Esenciales ✅ COMPLETADA
- Label (static text)
- Button (clickable, importance levels)
- TextInput (editable text, cursor, selection)
- Checkbox (boolean toggle)
- Select (dropdown)
- List (scrollable selection)
- Focus management (FocusManager, FocusRing)
Fase 3: Widgets Avanzados (PENDIENTE)
- Table con edición (CRÍTICO)
- Split panels (HSplit/VSplit draggable)
- Panel (container con título)
- Modal/Popup
Fase 4: Pulido (PENDIENTE)
- Themes hot-reload
- TTF fonts (stb_truetype)
- Documentación completa
- Más examples
REFERENCIAS Y RECURSOS
Librerías estudiadas
| Librería | Lenguaje | LOC | Valor para nosotros |
|---|---|---|---|
| microui | C | 1,100 | Referencia arquitectura mínima |
| DVUI | Zig | 15,000 | Único ejemplo Zig native |
| Dear ImGui | C++ | 60,000 | API design, features |
| Gio | Go | - | Immediate mode moderno |
| Nuklear | C | 30,000 | Vertex buffer approach |
Documentación detallada
docs/research/GIO_UI_ANALYSIS.md- Análisis completo de Giodocs/research/IMMEDIATE_MODE_LIBS.md- Comparativa de libreríasdocs/research/SIMIFACTU_FYNE_ANALYSIS.md- Requisitos de Simifactudocs/ARCHITECTURE.md- Decisiones de arquitectura
Links externos
DECISIONES DE DISEÑO CONSENSUADAS
1. Immediate Mode vs Retained Mode
Decisión: Immediate Mode Razón: Control total, sin threading hell (fyne.Do()), estado explícito
2. Software Rendering vs GPU
Decisión: Software por defecto, GPU opcional futuro Razón: Máxima compatibilidad (SSH, HP viejo, cualquier driver)
3. Sistema de Macros
Decisión: Teclas raw, no comandos abstractos Razón: Simple, como Vim, menos código = menos bugs
4. Backend inicial
Decisión: SDL2 Razón: Cross-platform probado, fácil de usar
5. Fonts
Decisión: Bitmap embebido + TTF opcional Razón: Bitmap siempre funciona, TTF para flexibilidad
6. Enfoque de desarrollo
Decisión: Híbrido (estudiar DVUI/microui, implementar desde cero) Razón: Aprender haciendo, control total, sin dependencias no deseadas
RELACIÓN CON ZCATUI
zcatui (TUI) y zcatgui (GUI) son proyectos hermanos:
| Aspecto | zcatui | zcatgui |
|---|---|---|
| Target | Terminal (ANSI) | Ventana gráfica |
| Rendering | Escape codes | Software rasterizer |
| Paradigma | Immediate mode | Immediate mode |
| Layout | Constraint-based | Constraint-based (reusar) |
| Style | Color/Modifier | Color/Style (reusar) |
| Widgets | 35 widgets | En desarrollo |
Código a reutilizar de zcatui:
- Sistema de Layout (Constraint, Flex)
- Sistema de Style (Color, Style)
- Conceptos de Focus
- Patterns de widgets
EQUIPO
- Usuario (Arno): Desarrollador principal
- Claude: Asistente de programación (Claude Code / Opus 4.5)
NOTAS ZIG 0.15.2
// Sleep
std.Thread.sleep(ns) // NO std.time.sleep
// ArrayList - CAMBIÓ en 0.15
// VIEJO: std.ArrayList(T).init(allocator)
// NUEVO: std.ArrayListUnmanaged(T) + pasar allocator a cada operación
var list: std.ArrayListUnmanaged(T) = .{};
defer list.deinit(allocator);
try list.append(allocator, item); // allocator en cada append
// HashMap
var map = std.AutoHashMap(K, V).init(allocator);
defer map.deinit();
// Error handling
fn foo() !T { ... }
const result = try foo();
const result = foo() catch |err| { ... };
// File I/O - cambió en 0.15
const file = try std.fs.cwd().createFile(path, .{});
_ = try file.write("data"); // Directo
// stdout - cambió en 0.15
const stdout = std.fs.File.stdout(); // NO std.io.getStdOut()
// O usar std.debug.print() que es más simple
// build.zig.zon - requiere fingerprint
.{
.fingerprint = 0x...,
.name = .proyecto, // enum literal, no string
...
}
HISTORIAL
| Fecha | Versión | Cambios |
|---|---|---|
| 2025-12-09 | v0.1.0 | Proyecto creado, estructura base, documentación |
| 2025-12-09 | v0.2.0 | Widgets Fase 2 completados (Label, Button, TextInput, Checkbox, Select, List, Focus) |
| 2025-12-09 | v0.3.0 | Widgets Fase 3 completados (Table editable, Split panels, Panel container) |
| 2025-12-09 | v0.3.5 | Keyboard integration: InputState ahora trackea teclas, Table responde a flechas/Enter/Escape/Tab/F2 |
| 2025-12-09 | v0.4.0 | Modal widget: diálogos modales (alert, confirm, input), plan extendido documentado |
| 2025-12-09 | v0.5.0 | AutoComplete widget, comparativa DVUI/Gio/zcatui en WIDGET_COMPARISON.md |
| 2025-12-09 | v0.6.0 | FASE 1 Optimización: FrameArena, ObjectPool, dirty rectangles, Benchmark suite |
| 2025-12-09 | v0.7.0 | FASE 2: Progress, Tooltip, Toast, Spinner |
| 2025-12-09 | v0.8.0 | FASE 2: TextArea, Tree, Badge/TagGroup |
| 2025-12-09 | v0.9.0 | FASE 3: Image, ReorderableList, ColorPicker, DatePicker |
| 2025-12-09 | v0.10.0 | FASE 4: NumberEntry, RichText, Breadcrumb |
| 2025-12-09 | v0.11.0 | FASE 5: Canvas, Charts (line/bar/pie), Icon system (60+ icons) |
| 2025-12-09 | v0.12.0 | FASE 6: Clipboard, DragDrop, Shortcuts, FocusGroups |
| 2025-12-09 | v0.13.0 | FASE 7: Animation/Easing, Effects (shadow/gradient/blur), VirtualScroll, AA rendering |
| 2025-12-09 | v0.14.0 | FASE 8: Accessibility system, Testing framework, 274 tests |
| 2025-12-09 | v0.14.1 | FASE 9: Gio parity - 12 widgets + gesture system |
| 2025-12-09 | v0.15.0 | FASE 10: Mobile/Web - WASM, Android, iOS backends |
| 2025-12-09 | v0.15.0 | Documentación: REFERENCE.md completo (1370 líneas) |
ESTADO ACTUAL
✅ PROYECTO COMPLETADO - v0.15.0
Para detalles técnicos completos, ver
REFERENCE.md(1370 líneas de documentación)
Widgets (37 total):
Básicos (7): Label, Button, Checkbox, Radio, Slider, TextInput, NumberEntry
Contenedores (6): Panel, Split, Modal, Scroll, Tabs, Menu
Datos (5): List, Table, Tree, ReorderableList, VirtualScroll
Feedback (4): Progress, Tooltip, Toast, Spinner
Input avanzado (5): AutoComplete, Select, TextArea, ColorPicker, DatePicker
Especial (5): Image, Icon, Canvas, Chart, RichText
Navegación (2): Breadcrumb, Focus
Sistema (1): Badge/TagGroup
Backends (5 plataformas):
- SDL2: Desktop (Linux, Windows, macOS)
- WASM: Navegadores web (Canvas 2D)
- Android: ANativeActivity + ANativeWindow
- iOS: UIKit bridge (Objective-C)
Core Systems:
- Context: FrameArena (O(1) reset), dirty rectangles, ID system
- Input: Keyboard, mouse, touch, shortcuts, focus groups, gestures
- Rendering: Software renderer, anti-aliasing, effects (shadow, gradient, blur)
- Animation: Easing functions (20+), AnimationManager, Springs
- Accessibility: Roles, states, announcements, live regions
- Testing: TestRunner, SnapshotTester, Assertions
- Macros: Recording, playback, storage
- Themes: 5 themes (dark, light, high_contrast, nord, dracula)
- Clipboard: SDL2 clipboard integration
- Drag & Drop: Type-filtered drop zones
- Gestures: Tap, double-tap, long-press, swipe, pinch, rotate
Métricas:
- ~35,000 LOC en 81 archivos fuente
- 0 warnings, 0 memory leaks
- WASM: ~18KB compilado
Verificar que funciona:
cd /mnt/cello2/arno/re/recode/zig/zcatgui
# Tests
/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig build test
# Desktop
/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig build
# WASM (genera web/zcatgui-demo.wasm)
/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig build wasm
# Android (requiere NDK)
/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig build android
# iOS (requiere macOS + Xcode)
/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig build ios
DOCUMENTACIÓN DISPONIBLE
| Documento | Descripción |
|---|---|
| REFERENCE.md | ⭐ Manual de referencia completo (1370 líneas) |
| docs/DEVELOPMENT_PLAN.md | Plan de desarrollo por fases (10 fases completadas) |
| docs/MOBILE_WEB_BACKENDS.md | Guía de backends WASM/Android/iOS |
| docs/ARCHITECTURE.md | Decisiones de arquitectura |
| docs/research/ | Análisis de librerías de referencia |
TAREA PENDIENTE PRIORITARIA: SISTEMA DE FOCUS (2025-12-11)
IMPORTANTE: Esta seccion describe trabajo incompleto que DEBE completarse. La sesion anterior hizo multiples intentos sin exito. Se requiere un analisis profundo antes de hacer mas cambios.
Documento de transicion (LEER PRIMERO)
/mnt/cello2/arno/re/recode/zig/zcatgui/docs/FOCUS_TRANSITION_2025-12-11.md
Resumen del problema
El sistema de focus fue rediseñado (unificado de dos sistemas a uno) pero NO FUNCIONA:
- Al iniciar app, ambos paneles muestran focus visual
- Teclado no responde hasta hacer clic (flechas, Tab)
- Despues de clic en panel derecho, flechas siguen moviendo tabla izquierda
Cambios realizados en esta sesion
Archivos creados:
core/focus.zig- Nuevo FocusSystem unificado
Archivos eliminados:
widgets/focus.zig- FocusManager viejocore/focus_group.zig- FocusGroupManager viejo
Archivos modificados:
core/context.zig- Usa FocusSystem, metodos de convenienciawidgets/table.zig- Añadidohandle_tabconfig, usa ctx.hasFocus()widgets/text_input.zig- Usa ctx.hasFocus(), ctx.requestFocus()zcatgui.zig- Exporta FocusSystem, FocusGroupbackend/backend.zig- Nuevo evento window_exposedbackend/sdl2.zig- Emite window_exposed
Lo que funciona
- Repintado al volver de Alt+Tab
- Navegacion por tabla post-clic
- Tab entre TextInputs post-clic
- Compilacion sin errores
Lo que NO funciona
- Focus inicial automatico
- Teclado antes de primer clic
- Focus visual exclusivo (ambos paneles lo muestran)
- Aislamiento de grupos (flechas afectan tabla aunque focus este en otro panel)
Hipotesis del bug
Ver documento de transicion para hipotesis detalladas. Resumen:
- Cambio de
active_groupdurante draw rompe logica - Focus visual no sincronizado con estado real
- Table procesa teclado independientemente
- Widgets no se registran en grupo correcto
Regla para continuar
Analizar primero, planificar despues, implementar al final. NO hacer cambios incrementales sin entender la causa raiz.
PROYECTOS RELACIONADOS
| Proyecto | Ruta | Descripción |
|---|---|---|
| zcatui | /mnt/cello2/arno/re/recode/zig/zcatui/ |
TUI library (proyecto hermano) |
| simifactu | /mnt/cello2/arno/re/recode/go/simifactu/ |
App de referencia (Fyne) |
REFERENCIAS EXTERNAS
- microui - Arquitectura mínima
- DVUI - Zig GUI reference
- Gio - Go immediate-mode
- Dear ImGui - C++ reference