From 3c52d2aa0e57736fc9861e17e82f2794f3297391 Mon Sep 17 00:00:00 2001 From: reugenio Date: Thu, 18 Dec 2025 22:00:38 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20Refactorizar=20CLAUDE.md=20(1006?= =?UTF-8?q?=E2=86=92354=20l=C3=ADneas,=20-65%)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cambios: - Extraer historial de versiones a CHANGELOG.md - Condensar secciones con enlaces a docs existentes - Mantener completo: protocolo inicio, reglas críticas, documentación teamdocs, rutas, comandos - Eliminar duplicación con docs/ARCHITECTURE.md y REFERENCE.md CLAUDE.md sigue siendo autosuficiente para inicio de conversación. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CHANGELOG.md | 56 ++++ CLAUDE.md | 857 +++++++-------------------------------------------- 2 files changed, 159 insertions(+), 754 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5ba9682 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,56 @@ +# zcatgui - Historial de Versiones + +> Extraído de CLAUDE.md para mantener archivo principal conciso. +> Ver CLAUDE.md para documentación del proyecto. + +--- + +## Historial Completo + +| 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) | +| 2025-12-11 | v0.15.1 | FocusSystem rediseñado: registration_group/active_group, focus implícito | +| 2025-12-11 | v0.15.2 | Widgets adaptados a FocusSystem: numberentry, textarea, select, radio, slider, tabs | +| 2025-12-16 | v0.16.0 | TTF rasterization con antialiasing (supersampling 2x) | +| 2025-12-16 | v0.16.1 | Fuente embebida: TtfFont.initEmbedded() | +| 2025-12-16 | v0.16.2 | Fix TTF: DroidSans (187KB) reemplaza AdwaitaSans (variable). Y-flip rasterización. | +| 2025-12-17 | v0.17.0 | ⭐ Integración zcatttf v1.0 - TTF FUNCIONA PERFECTAMENTE | +| 2025-12-17 | v0.18.0 | Paridad Visual DVUI Fase 1: RenderMode dual, esquinas redondeadas, sombras | +| 2025-12-17 | v0.19.0 | Paridad Visual DVUI Fase 2: HoverTransition, Focus Ring AA en 9 widgets | +| 2025-12-17 | v0.20.0 | AdvancedTable: 8 fases completas (~2,700 LOC) - Schema, CRUD, Sorting, Lookup | +| 2025-12-17 | v0.21.0 | AdvancedTable: +990 LOC (multi-select, search, validation) | +| 2025-12-17 | v0.21.1 | Fix: AdvancedTable teclado - result.selected_row/col en handleKeyboard | + +--- + +## Hitos Importantes + +### v0.17.0 - TTF Funcional (2025-12-17) +Integración de zcatttf v1.0. El texto TTF ahora se renderiza perfectamente. +→ Detalle: `docs/research/` y teamdocs hitos + +### v0.18.0-v0.19.0 - Paridad Visual DVUI (2025-12-17) +Sistema de rendering dual (simple/fancy), esquinas redondeadas, sombras, transiciones hover, focus ring AA. +→ Detalle: `docs/research/DVUI_AUDIT_2025-12-17.md` + +### v0.20.0-v0.21.1 - AdvancedTable (2025-12-17) +Widget de tabla avanzada con schema, CRUD, sorting, lookup, multi-select, search, validation. +→ Detalle: `docs/ADVANCED_TABLE_MERGE_PLAN.md` diff --git a/CLAUDE.md b/CLAUDE.md index d1041eb..246b8c9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -18,16 +18,15 @@ /mnt/cello2/arno/re/recode/teamdocs/agenda/2025-12_diciembre.md # Trabajo diario ``` -### Paso 3: Leer documentación +### Paso 3: Leer documentación del proyecto ``` REFERENCE.md # ⭐ MANUAL DE REFERENCIA COMPLETO -docs/BUG_ADVANCEDTABLE_KEYBOARD_2025-12-17.md # ✅ BUG RESUELTO -docs/ADVANCED_TABLE_MERGE_PLAN.md # Plan merge Table → AdvancedTable -docs/research/DVUI_AUDIT_2025-12-17.md # Auditoría DVUI +CHANGELOG.md # Historial de versiones 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 +docs/MOBILE_WEB_BACKENDS.md # Documentación backends mobile/web +docs/research/DVUI_AUDIT_2025-12-17.md # Auditoría DVUI (paridad visual) +docs/research/WIDGET_COMPARISON.md # Comparativa zcatgui vs DVUI vs Gio ``` ### Paso 4: Verificar estado del proyecto @@ -80,201 +79,32 @@ Resumen breve (1-2 frases). Resultado principal. --- -## ⭐ Paridad Visual DVUI - FASES 1+2 COMPLETADAS ✅ - -> **Estado**: Fases 1 y 2 completadas (2025-12-17) -> **Auditoría original**: `docs/research/DVUI_AUDIT_2025-12-17.md` (570 líneas) - -### El Problema (RESUELTO) - -zcatgui tenía MÁS widgets que DVUI pero DVUI **se veía mejor** por falta de: -1. ✅ **Esquinas redondeadas** → `fillRoundedRect` con edge-fade AA -2. ✅ **Anti-aliasing en bordes** → edge-fade technique implementada -3. ✅ **Transiciones suaves** → HoverTransition en Button/Select -4. ✅ **Sombras en paneles/modales** → Panel/Modal con shadow -5. ✅ **Focus ring AA** → 9 widgets con focus ring - -### Sistema Dual Implementado - -```zig -// style.zig -pub const RenderMode = enum { simple, fancy }; -var global_render_mode: RenderMode = .fancy; // Default: bonito - -// Uso en widgets -if (Style.isFancy() and config.corner_radius > 0) { - ctx.pushCommand(Command.roundedRect(...)); -} else { - ctx.pushCommand(Command.rect(...)); -} -``` - -### Widgets Actualizados - -| Widget | corner_radius | shadow | Notas | -|--------|---------------|--------|-------| -| Button | 4 | - | Esquinas redondeadas en fancy mode | -| Panel | 6 | ✅ offset 4px | Borde y shadow | -| TextInput | 3 | - | Esquinas sutiles | -| Select | 3 | - | Esquinas sutiles | -| Modal | 8 | ✅ offset 6px | Diálogo + botones + input | - -### Código Añadido - -- `framebuffer.zig`: +350 LOC (`fillRoundedRect`, `drawRoundedRect`, edge-fade AA) -- `command.zig`: +69 LOC (nuevos comandos `rounded_rect`, `rounded_rect_outline`) -- `style.zig`: +33 LOC (RenderMode system) -- Widgets: ~120 LOC entre todos - -**Total: ~590 líneas nuevas/modificadas** - -### Fase 2: Transiciones + Focus Ring ✅ COMPLETADA - -**HoverTransition helper** (`animation.zig`): -- `update()` y `updateWithPress()` para animar hacia target -- `blend()` y `blendThree()` para interpolar colores -- Speed configurable (default ~125ms transición) - -**Focus ring helper** (`command.zig`): -- `focusRing()` y `focusRingColor()` para indicador de foco -- Dibuja 2px fuera del widget con AA -- Color primario semi-transparente (alpha 180) - -**Widgets con focus ring:** -| Widget | Transiciones | Focus Ring | Esquinas | -|--------|--------------|------------|----------| -| Button | ✅ `buttonStateful()` | - | ✅ | -| Select | ✅ Automático | ✅ | ✅ | -| TextInput | - | ✅ | ✅ | -| NumberEntry | - | ✅ | ✅ | -| Radio | - | ✅ (opción) | ✅ | -| Slider | - | ✅ (thumb) | ✅ | -| Tabs | - | ✅ (tab) | ✅ | -| Table | - | ✅ (borde) | - | -| TextArea | - | ✅ | ✅ | - -```zig -// Button con transiciones (opcional) -var btn_state = button.ButtonState{}; -if (button.buttonStateful(&ctx, &btn_state, "Click me")) { ... } - -// Focus ring se dibuja automáticamente cuando widget tiene foco -``` - -### Fase 3: Efectos Avanzados (OPCIONAL) - -- Mejorar uso de gradientes -- Blur effect para backdrops - -### Documentación de Referencia - -- `docs/research/DVUI_AUDIT_2025-12-17.md` - Auditoría completa -- `docs/research/WIDGET_COMPARISON.md` - Comparativa (actualizar después) - ---- - -## ✅ TTF Rendering - RESUELTO (2025-12-17) ⭐⭐⭐ - -> **Estado**: ✅ COMPLETADO - zcatttf v1.0 integrado y funcionando perfectamente -> **Documentación**: `/mnt/cello2/arno/re/recode/teamdocs/agenda/hitos/2025-12-17_zcatttf_v1.0.md` - -### El Problema (16-17 Dic) - -El texto TTF se renderizaba como garabatos ilegibles. 2 días de debugging con múltiples intentos fallidos. - -### Solución: zcatttf v1.0 - -**TRADUCCIÓN LITERAL** de stb_truetype.h, sin intentar "mejorar" o "reimaginar". - -**Bug final:** `y_offset = iy0` (negativo) → `y_offset = -iy0` (positivo). -El bearing_y debe ser positivo para glyphs encima de la baseline. - -### Lección Clave - -> **"No reimplementar, TRADUCIR"** -> Si existe código C que funciona, traducirlo literalmente. -> La humildad técnica es fundamental. - -| Campo | Valor | -|-------|-------| -| **Librería** | `/mnt/cello2/arno/re/recode/zig/zcatttf/` | -| **Versión** | v1.0 | -| **Algoritmo** | Traducción literal stb_truetype (~1,200 LOC rasterize.zig) | -| **Estado** | ✅ FUNCIONA PERFECTAMENTE en zsimifactu | - -### Archivos clave -- `src/render/ttf.zig` - Wrapper sobre zcatttf (API compatible) -- `src/render/embedded_font.zig` - Fuente DroidSans embebida -- `build.zig.zon` - Dependencia de zcatttf - -### Uso -```zig -var ttf = try TtfFont.initEmbedded(allocator); -defer ttf.deinit(); -ttf.setSize(14); -ttf.drawText(fb, x, y, "Hola UTF-8: áéíóú ñ €", color, clip); -``` - ---- - -## Fuentes TTF: Estado Técnico - -### Estado actual (v0.19.0) - FUNCIONAL -- ✅ Parsing TTF via zcatttf (cmap format 4 y 12) -- ✅ Rasterización con áreas trapezoidales (antialiasing) -- ✅ Fuente embebida (DroidSans) -- ✅ Soporte UTF-8 completo (áéíóú ñ €) -- ✅ Cache de glyphs renderizados - -### Uso actual -```zig -const ttf = @import("render/ttf.zig"); - -// Opción 1: Fuente embebida -var font = try ttf.TtfFont.initEmbedded(allocator); - -// Opción 2: Cargar archivo -var font = try ttf.TtfFont.loadFromFile(allocator, "/path/to/font.ttf"); - -defer font.deinit(); -font.setSize(14); -font.drawText(fb, x, y, "Texto con UTF-8: ñ €", color, clip); -``` - ---- - ## INFORMACIÓN DEL PROYECTO | Campo | Valor | |-------|-------| | **Nombre** | zcatgui | -| **Versión** | v0.19.0 | +| **Versión** | v0.21.1 | | **Fecha inicio** | 2025-12-09 | | **Estado** | ✅ COMPLETO - 37 widgets, ~35K LOC, 4 backends, TTF funcional | | **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: +**zcatgui** es una librería GUI immediate-mode para Zig: 1. **Software Rendering por defecto** - Funciona en cualquier ordenador sin GPU -2. **Cross-platform** - Linux, Windows, macOS, **Web (WASM)**, **Android**, **iOS** +2. **Cross-platform** - Linux, Windows, macOS, Web (WASM), Android, iOS 3. **SSH compatible** - Funciona via X11 forwarding -4. **Sistema de Macros** - Grabación/reproducción de acciones (piedra angular) -5. **Sin dependencias pesadas** - Solo SDL2 para desktop, nativo para mobile/web +4. **Sistema de Macros** - Grabación/reproducción de acciones +5. **Sin dependencias pesadas** - Solo SDL2 para desktop ### 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 @@ -286,7 +116,7 @@ font.drawText(fb, x, y, "Texto con UTF-8: ñ €", color, clip); # Proyecto hermano (TUI) /mnt/cello2/arno/re/recode/zig/zcatui/ -# Proyecto de referencia (usa Fyne, queremos replicar funcionalidad) +# Proyecto de referencia (Fyne/Go) /mnt/cello2/arno/re/recode/go/simifactu/ # Normas del equipo @@ -309,21 +139,18 @@ 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 +cd web && python3 -m http.server # Servir en localhost:8000 # Android (requiere NDK) zig build android # ARM64 para dispositivo -zig build android-x86 # x86_64 para emulador -# iOS (requiere Xcode en macOS) +# iOS (requiere macOS + Xcode) zig build ios # ARM64 para dispositivo -zig build ios-sim # ARM64 para simulador # Git git status @@ -339,8 +166,6 @@ git push ``` ┌─────────────────────────────────────────────────────────────┐ -│ IMMEDIATE MODE │ -├─────────────────────────────────────────────────────────────┤ │ while (running) { │ │ events = pollEvents(); // Input │ │ updateState(events); // TÚ manejas estado │ @@ -348,397 +173,134 @@ git push │ 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 4: Widgets (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 2: Core UI (Context, Layout, Style, Input, Commands) │ ├─────────────────────────────────────────────────────────────┤ -│ Capa 1: Rendering │ -│ (Software Rasterizer, Framebuffer, Fonts) │ +│ Capa 1: Rendering (Software Rasterizer, Framebuffer, Fonts)│ ├─────────────────────────────────────────────────────────────┤ -│ Capa 0: Backend │ -│ (SDL2 - ventanas, eventos, display) │ +│ Capa 0: Backend (SDL2 - ventanas, eventos, display) │ └─────────────────────────────────────────────────────────────┘ ``` -### Estructura de Archivos (ACTUAL v0.16.0) +→ Detalle completo: `docs/ARCHITECTURE.md` + +--- + +## ESTRUCTURA DE ARCHIVOS ``` 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) -│ │ +│ ├── zcatgui.zig # Entry point, re-exports +│ ├── core/ # Context, Layout, Style, Input, Command, etc. │ ├── 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 +│ ├── render/ # Software renderer, fonts, animation, effects +│ ├── backend/ # SDL2, WASM, Android, iOS +│ ├── macro/ # MacroRecorder, MacroPlayer +│ └── utils/ # FrameArena, ObjectPool, Benchmark +├── examples/ # Demos: hello, widgets, table, wasm, android +├── web/ # WASM support +├── ios/ # iOS bridge (Objective-C) +├── docs/ # Documentación detallada ├── CLAUDE.md # Este archivo -└── REFERENCE.md # ⭐ Manual de referencia completo (1370 líneas) +├── REFERENCE.md # ⭐ Manual de referencia completo +└── CHANGELOG.md # Historial de versiones ``` --- -## SISTEMA DE MACROS (PIEDRA ANGULAR) +## ESTADO ACTUAL (v0.21.1) -### Concepto +### Widgets (37 total) -El sistema de macros permite **grabar y reproducir** todas las acciones del usuario. +| Categoría | Widgets | +|-----------|---------| +| **Básicos** | Label, Button, Checkbox, Radio, Slider, TextInput, NumberEntry | +| **Contenedores** | Panel, Split, Modal, Scroll, Tabs, Menu | +| **Datos** | List, Table, Tree, ReorderableList, VirtualScroll | +| **Feedback** | Progress, Tooltip, Toast, Spinner | +| **Input avanzado** | AutoComplete, Select, TextArea, ColorPicker, DatePicker | +| **Especial** | Image, Icon, Canvas, Chart, RichText | +| **Navegación** | Breadcrumb, Focus, Badge/TagGroup | -**Principio**: Grabar teclas raw, no comandos abstractos. +### Backends (5 plataformas) +- **SDL2**: Desktop (Linux, Windows, macOS) +- **WASM**: Navegadores web (Canvas 2D) +- **Android**: ANativeActivity + ANativeWindow +- **iOS**: UIKit bridge (Objective-C) -``` -Usuario pulsa: Tab, Tab, Enter, "texto", Escape -Grabamos: [Tab, Tab, Enter, t, e, x, t, o, Escape] -Reproducimos: Inyectamos exactamente esas teclas -``` +### Core Systems +- Context (FrameArena, dirty rectangles, ID system) +- Input (keyboard, mouse, touch, shortcuts, gestures) +- Rendering (software renderer, AA, effects) +- Animation (20+ easing functions, springs) +- Themes (dark, light, high_contrast, nord, dracula) -### Por qué teclas raw (no comandos) +### Métricas +- ~35,000 LOC en 81 archivos fuente +- 0 warnings, 0 memory leaks +- WASM: ~18KB compilado -| 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 | +→ Detalle completo: `REFERENCE.md` -**Decisión**: Teclas raw (como Vim). Razones: -1. KISS - menos código = menos bugs -2. Vim lo hace así y funciona -3. El estado inicial es controlable +--- -### Manejo del ratón +## HITOS RECIENTES -**Casi todo lo que hace el ratón se puede expresar como teclado**: +### TTF Rendering ✅ (2025-12-17) +Integración zcatttf v1.0 - texto TTF funciona perfectamente. +→ Librería: `/mnt/cello2/arno/re/recode/zig/zcatttf/` -| 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 | +### Paridad Visual DVUI ✅ (2025-12-17) +Sistema dual (simple/fancy), esquinas redondeadas, sombras, transiciones, focus ring AA. +→ Detalle: `docs/research/DVUI_AUDIT_2025-12-17.md` -**Estrategia**: -1. Fase 1: Solo teclado (macros de teclas) -2. Fase 2: Mouse → traducir a teclas equivalentes +### AdvancedTable ✅ (2025-12-17) +Widget ~3,700 LOC con schema, CRUD, sorting, lookup, multi-select, search, validation. +→ Detalle: `docs/ADVANCED_TABLE_MERGE_PLAN.md` -### API Propuesta +--- + +## SISTEMA DE MACROS + +Grabar y reproducir acciones del usuario con teclas raw (como Vim). ```zig 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; + pub fn play(events: []const KeyEvent, inject_fn: fn(KeyEvent) void) void; }; ``` -### Casos de Uso - -1. **Testing automatizado**: Grabar sesión → convertir en test -2. **Tutoriales**: Macros que se ejecutan paso a paso -3. **Repetición**: Grabar tarea repetitiva, asignar a hotkey -4. **Debugging**: "¿Cómo llegaste a este bug?" → envía el macro -5. **Demos**: Grabar demos que se reproducen en la app +→ Detalle: `src/macro/macro.zig` --- -## WIDGETS PRIORITARIOS +## DECISIONES DE DISEÑO -Basado en análisis de Simifactu (ver `docs/research/SIMIFACTU_FYNE_ANALYSIS.md`): +| Decisión | Razón | +|----------|-------| +| Immediate Mode | Control total, sin threading hell, estado explícito | +| Software Rendering | Máxima compatibilidad (SSH, HP viejo, cualquier driver) | +| Macros con teclas raw | Simple como Vim, menos código = menos bugs | +| SDL2 backend | Cross-platform probado, fácil de usar | +| Bitmap + TTF fonts | Bitmap siempre funciona, TTF para flexibilidad | -| # | 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) - -```zig -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 - -1. **Funciona SIEMPRE** - No depende de drivers GPU -2. **SSH compatible** - X11 forwarding funciona -3. **Máxima compatibilidad** - Desde HP viejo hasta Lenovo nuevo -4. **Simple de debugear** - Es solo un array de pixels - -### Fonts - -**Dos opciones soportadas**: -1. **Bitmap fonts** (embebidos) - Siempre funcionan, rápidos -2. **TTF** (stb_truetype) - Más flexible, opcional - ---- - -## PLAN DE DESARROLLO - -### Fase 0: Setup ✅ COMPLETADA -- [x] Crear estructura de directorios -- [x] build.zig con SDL2 -- [x] CLAUDE.md -- [x] Documentación de investigación - -### Fase 1: Core + Macros ✅ COMPLETADA -- [x] Context con event loop -- [x] Sistema de macros (grabación/reproducción teclas) -- [x] Software rasterizer básico (rects, text, lines) -- [x] SDL2 backend -- [x] Framebuffer RGBA - -### Fase 2: Widgets Esenciales ✅ COMPLETADA -- [x] Label (static text) -- [x] Button (clickable, importance levels) -- [x] TextInput (editable text, cursor, selection) -- [x] Checkbox (boolean toggle) -- [x] Select (dropdown) -- [x] List (scrollable selection) -- [x] 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 Gio -- `docs/research/IMMEDIATE_MODE_LIBS.md` - Comparativa de librerías -- `docs/research/SIMIFACTU_FYNE_ANALYSIS.md` - Requisitos de Simifactu -- `docs/ARCHITECTURE.md` - Decisiones de arquitectura - -### Links externos - -- [microui GitHub](https://github.com/rxi/microui) -- [DVUI GitHub](https://github.com/david-vanderson/dvui) -- [Gio UI](https://gioui.org/) -- [Dear ImGui](https://github.com/ocornut/imgui) - ---- - -## 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 (R.Eugenio)**: Desarrollador principal -- **Claude**: Asistente de programación (Claude Code / Opus 4.5) +→ Detalle: `docs/ARCHITECTURE.md` --- @@ -749,251 +311,38 @@ Widgets → Commands → Software Rasterizer → Framebuffer → SDL_Texture → 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 +try list.append(allocator, item); // allocator en cada operación -// 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 +// stdout 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 +// build.zig.zon .{ .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) | -| 2025-12-11 | v0.15.1 | FocusSystem rediseñado: registration_group/active_group, focus implícito | -| 2025-12-11 | v0.15.2 | Widgets adaptados a FocusSystem: numberentry, textarea, select, radio, slider, tabs | -| 2025-12-16 | v0.16.0 | TTF rasterization con antialiasing (supersampling 2x) | -| 2025-12-16 | v0.16.1 | Fuente embebida: TtfFont.initEmbedded() | -| 2025-12-16 | v0.16.2 | Fix TTF: DroidSans (187KB) reemplaza AdwaitaSans (variable). Y-flip rasterización. | -| 2025-12-17 | v0.17.0 | ⭐⭐⭐ Integración zcatttf v1.0 - TTF FUNCIONA PERFECTAMENTE | -| 2025-12-17 | v0.18.0 | Paridad Visual DVUI Fase 1: RenderMode dual, esquinas redondeadas, sombras | -| 2025-12-17 | v0.19.0 | Paridad Visual DVUI Fase 2: HoverTransition, Focus Ring AA en 9 widgets | -| 2025-12-17 | v0.20.0 | AdvancedTable: 8 fases completas (~2,700 LOC) - Schema, CRUD, Sorting, Lookup | -| 2025-12-17 | v0.21.0 | AdvancedTable: +990 LOC (multi-select, search, validation) | -| 2025-12-17 | v0.21.1 | Fix: AdvancedTable teclado - result.selected_row/col en handleKeyboard | - ---- - -## ✅ BUG RESUELTO: AdvancedTable Teclado - -> **Estado:** RESUELTO (2025-12-17 19:30) -> **Documentación:** `docs/BUG_ADVANCEDTABLE_KEYBOARD_2025-12-17.md` - -### 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, y sin esos valores no actualizaba DataManager → reset 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). - ---- - -## ESTADO ACTUAL - -**✅ PROYECTO COMPLETADO - v0.21.1** - -> **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: -```bash -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 | - ---- - -## SISTEMA DE FOCUS - RESUELTO (2025-12-11) - -El sistema de focus fue rediseñado y ahora funciona correctamente. - -### Documentación completa - -``` -/mnt/cello2/arno/re/recode/zig/zcatgui/docs/FOCUS_TRANSITION_2025-12-11.md -``` - -### Arquitectura final - -``` - FocusSystem - | - +---------------+---------------+ - | | - FocusGroup 1 FocusGroup 2 - (Panel Lista) (Panel Detalle) - | | - Table widget TextInput widgets - | | - - registerFocusable() - registerFocusable() - - hasFocus() -> true/false - hasFocus() -> true/false -``` - -### Conceptos clave - -- **registration_group**: Grupo donde se registran widgets durante draw -- **active_group**: Grupo con focus de teclado (solo cambia con F6/clic) -- **Focus implícito**: Primer widget del grupo activo tiene focus si `focused_index == null` - -### API para widgets - -```zig -// 1. Generar ID único basado en dirección del state -const widget_id: u64 = @intFromPtr(state); - -// 2. Registrar en el grupo de focus activo -ctx.registerFocusable(widget_id); - -// 3. Al hacer clic, solicitar focus -if (clicked) { - ctx.requestFocus(widget_id); -} - -// 4. Verificar si tiene focus -const has_focus = ctx.hasFocus(widget_id); -state.focused = has_focus; -``` - -### Widgets integrados con FocusSystem - -| Widget | Estado | -|--------|--------| -| Table | Adaptado - inicializa selected_row/col a 0 | -| TextInput | Correcto | -| NumberEntry | Adaptado | -| TextArea | Adaptado | -| Select | Adaptado | -| Radio | Adaptado | -| Slider | Adaptado | -| Tabs | Adaptado | - -### Widgets sin FocusSystem (no lo necesitan) - -- **Modales**: Menu, Modal, Tooltip, Toast -- **Acción única**: Button, Checkbox, Switch -- **Solo visualización**: Label, Progress, Badge, Icon, Image - ---- - ## PROYECTOS RELACIONADOS | Proyecto | Ruta | Descripción | |----------|------|-------------| -| **zcatttf** | `/mnt/cello2/arno/re/recode/zig/zcatttf/` | ⭐ Librería TTF v1.0 - COMPLETA (dependencia de zcatgui) | -| **zsimifactu** | `/mnt/cello2/arno/re/recode/zig/zsimifactu/` | App de facturación Zig (consumidor principal) | -| **zcatui** | `/mnt/cello2/arno/re/recode/zig/zcatui/` | TUI library (proyecto hermano) | -| **zcatp2p** | `/mnt/cello2/arno/re/recode/zig/zcatp2p/` | Librería P2P (v1.0.0 completa) | -| **simifactu** | `/mnt/cello2/arno/re/recode/go/simifactu/` | App de referencia (Fyne/Go) | +| **zcatttf** | `/mnt/cello2/arno/re/recode/zig/zcatttf/` | Librería TTF v1.0 (dependencia) | +| **zsimifactu** | `/mnt/cello2/arno/re/recode/zig/zsimifactu/` | App facturación (consumidor principal) | +| **zcatui** | `/mnt/cello2/arno/re/recode/zig/zcatui/` | TUI library (hermano) | +| **zcatp2p** | `/mnt/cello2/arno/re/recode/zig/zcatp2p/` | Librería P2P v1.0.0 | +| **simifactu** | `/mnt/cello2/arno/re/recode/go/simifactu/` | App referencia (Fyne/Go) | + +--- + +## EQUIPO + +- **Usuario (R.Eugenio)**: Desarrollador principal +- **Claude**: Asistente de programación (Claude Code / Opus 4.5) ---