Cambios: - TTF rasterization completo con bezier curves - Antialiasing via supersampling 2x - Integración TTF en SoftwareRenderer (setTtfFont) - Fix ArrayListUnmanaged para Zig 0.15.2 - Documentación REFERENCE.md actualizada CLAUDE.md actualizado con v0.16.0 y historial. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
837 lines
28 KiB
Markdown
837 lines
28 KiB
Markdown
# 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/teamdocs/LAST_UPDATE.md
|
|
```
|
|
|
|
### Paso 2: Leer normas completas si es necesario
|
|
```
|
|
/mnt/cello2/arno/re/recode/teamdocs/normas/NORMAS_TRABAJO_CONSENSUADAS.md
|
|
/mnt/cello2/arno/re/recode/teamdocs/QUICK_REFERENCE.md
|
|
/mnt/cello2/arno/re/recode/teamdocs/agenda/2025-12_diciembre.md # Trabajo diario
|
|
```
|
|
|
|
### 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
|
|
```bash
|
|
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ó.
|
|
|
|
---
|
|
|
|
## REGLA CRÍTICA: NO EJECUTAR BINARIOS GUI
|
|
|
|
**NUNCA ejecutar programas GUI directamente con `./programa` o en background**
|
|
|
|
Los procesos GUI no terminan correctamente desde Claude Code y dejan shells zombie que:
|
|
1. Consumen contexto de la conversación con mensajes "Background Bash running"
|
|
2. Fuerzan compactaciones prematuras del contexto
|
|
3. Degradan severamente la calidad de la sesión de trabajo
|
|
|
|
**Alternativas:**
|
|
- Para verificar que compila: `zig build` (sin ejecutar)
|
|
- Para probar muy brevemente: `timeout 2s ./programa 2>&1 || true`
|
|
- **Mejor opción**: Pedir al usuario que lo pruebe y reporte
|
|
|
|
Esta regla está documentada en teamdocs desde 2025-11-30.
|
|
|
|
---
|
|
|
|
## PROTOCOLO DE DOCUMENTACIÓN (2025-12-16)
|
|
|
|
**LEER PRIMERO**: `/mnt/cello2/arno/re/recode/teamdocs/ESTRUCTURA_DOCUMENTACION.md`
|
|
|
|
### Principios clave:
|
|
- **Agenda = ÍNDICE** (QUÉ + CUÁNDO + link), NO documento técnico
|
|
- **Detalles técnicos → `agenda/hitos/`**
|
|
- **Límite ~300 líneas** por archivo
|
|
- Si necesita más de 5 líneas de explicación → crear hito en `hitos/`
|
|
|
|
### Al documentar:
|
|
1. Entrada breve en agenda (3-5 líneas máx)
|
|
2. Link a hito si hay detalles técnicos
|
|
3. Nomenclatura: `hitos/YYYY-MM-DD_nombre_proyecto.md`
|
|
|
|
---
|
|
|
|
## TAREA ACTUAL: Fuentes TTF con Antialiasing
|
|
|
|
**Documento completo**: `/mnt/cello2/arno/re/recode/teamdocs/Conversaciones/TAREA_TTF_ZCATGUI.md`
|
|
|
|
### Problema
|
|
zsimifactu se ve "años 90" con fuentes bitmap 8x16. Necesitamos TTF con antialiasing.
|
|
|
|
### Estado de ttf.zig (637 líneas)
|
|
- ✅ Parsing TTF completo
|
|
- ✅ Lookup de glyphs
|
|
- ✅ Métricas
|
|
- ❌ `drawGlyphPlaceholder()` solo dibuja rectángulos, NO renderiza contornos
|
|
|
|
### Fases de implementación
|
|
1. Parsear contornos (puntos + Bezier cuadráticas)
|
|
2. Rasterización básica (scanline)
|
|
3. Antialiasing (coverage-based)
|
|
4. Integración con SoftwareRenderer
|
|
|
|
### Referencia
|
|
- **stb_truetype.h** (~5000 líneas C) - implementación de referencia
|
|
|
|
---
|
|
|
|
## INFORMACIÓN DEL PROYECTO
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Nombre** | zcatgui |
|
|
| **Versión** | v0.16.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:
|
|
|
|
1. **Software Rendering por defecto** - Funciona en cualquier ordenador sin GPU
|
|
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
|
|
|
|
### 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
|
|
|
|
```bash
|
|
# 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/teamdocs/
|
|
|
|
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
1. KISS - menos código = menos bugs
|
|
2. Vim lo hace así y funciona
|
|
3. 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**:
|
|
1. Fase 1: Solo teclado (macros de teclas)
|
|
2. Fase 2: Mouse → traducir a teclas equivalentes
|
|
|
|
### API Propuesta
|
|
|
|
```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;
|
|
};
|
|
```
|
|
|
|
### 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
|
|
|
|
---
|
|
|
|
## 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)
|
|
|
|
```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 (Arno)**: Desarrollador principal
|
|
- **Claude**: Asistente de programación (Claude Code / Opus 4.5)
|
|
|
|
---
|
|
|
|
## NOTAS ZIG 0.15.2
|
|
|
|
```zig
|
|
// 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) |
|
|
| 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), tests con AdwaitaSans |
|
|
|
|
---
|
|
|
|
## ESTADO ACTUAL
|
|
|
|
**✅ PROYECTO COMPLETADO - v0.16.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:
|
|
```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 |
|
|
|----------|------|-------------|
|
|
| **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](https://github.com/rxi/microui) - Arquitectura mínima
|
|
- [DVUI](https://github.com/david-vanderson/dvui) - Zig GUI reference
|
|
- [Gio](https://gioui.org/) - Go immediate-mode
|
|
- [Dear ImGui](https://github.com/ocornut/imgui) - C++ reference
|