# 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 de investigación ``` docs/research/GIO_UI_ANALYSIS.md # Análisis de Gio UI (Go) docs/research/IMMEDIATE_MODE_LIBS.md # Comparativa librerías immediate-mode docs/research/SIMIFACTU_FYNE_ANALYSIS.md # Requisitos extraídos de Simifactu 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ó. --- ## INFORMACIÓN DEL PROYECTO | Campo | Valor | |-------|-------| | **Nombre** | zcatgui | | **Versión** | v0.1.0 - EN DESARROLLO | | **Fecha inicio** | 2025-12-09 | | **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 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 ventanas ### 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/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 ```bash # Compilar zig build # Tests zig build test # Ejemplos (cuando estén implementados) zig build hello zig build button-demo zig build macro-demo # 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) ``` zcatgui/ ├── src/ │ ├── zcatgui.zig # Entry point, re-exports │ │ │ ├── core/ │ │ ├── context.zig # ✅ Context, ID system, command pool │ │ ├── layout.zig # ✅ Rect, Constraint, LayoutState │ │ ├── style.zig # ✅ Color, Style, Theme │ │ ├── input.zig # ✅ Key, KeyEvent, MouseEvent, InputState │ │ └── command.zig # ✅ DrawCommand list │ │ │ ├── widgets/ # ⏳ PENDIENTE (Fase 2) │ │ └── (vacío) │ │ │ ├── render/ │ │ ├── software.zig # ✅ SoftwareRenderer (ejecuta commands) │ │ ├── framebuffer.zig # ✅ Framebuffer RGBA │ │ └── font.zig # ✅ Bitmap font 8x8 │ │ │ ├── backend/ │ │ ├── backend.zig # ✅ Backend interface (vtable) │ │ └── sdl2.zig # ✅ SDL2 implementation │ │ │ └── macro/ │ └── macro.zig # ✅ MacroRecorder, MacroPlayer, MacroStorage │ ├── examples/ │ ├── hello.zig # ✅ Ejemplo básico de rendering │ └── macro_demo.zig # ✅ Demo del sistema de macros │ ├── docs/ │ ├── ARCHITECTURE.md # Arquitectura detallada │ └── research/ │ ├── GIO_UI_ANALYSIS.md │ ├── IMMEDIATE_MODE_LIBS.md │ └── SIMIFACTU_FYNE_ANALYSIS.md │ ├── build.zig ├── build.zig.zon └── CLAUDE.md # Este archivo ``` --- ## 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 (1 semana) - [ ] Context con event loop - [ ] Sistema de macros (grabación/reproducción teclas) - [ ] Software rasterizer básico (rects, text) - [ ] SDL2 backend - [ ] Button, Label (para probar) ### Fase 2: Widgets Esenciales (2 semanas) - [ ] Input (text entry) - [ ] Select (dropdown) - [ ] Checkbox - [ ] List - [ ] Layout system - [ ] Focus management ### Fase 3: Widgets Avanzados (2 semanas) - [ ] Table con edición - [ ] Split panels - [ ] Modal/Popup - [ ] Panel con título ### Fase 4: Pulido (1 semana) - [ ] Themes - [ ] Font handling robusto - [ ] Documentación - [ ] Examples completos --- ## 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 - writer cambió const file = try std.fs.cwd().createFile(path, .{}); _ = try file.write("data"); // Directo, no file.writer() // 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 | --- ## ESTADO ACTUAL **El proyecto está en FASE 1 PARCIAL** ### Completado (✅): - Estructura de directorios - build.zig con SDL2 - Documentación de investigación - Core: context, layout, style, input, command - Render: framebuffer, software renderer, font - Backend: SDL2 (window, events, display) - Macro: MacroRecorder, MacroPlayer, MacroStorage - Examples: hello.zig, macro_demo.zig - **16 tests pasando** ### Pendiente (⏳): - Widgets (Button, Label, Input, Select, Table, etc.) - Focus management - Themes - TTF fonts **Próximo paso**: Implementar widgets básicos (Button, Label, Input) ### Verificar que funciona: ```bash cd /mnt/cello2/arno/re/recode/zig/zcatgui zig build test # 16 tests deben pasar zig build # Compila hello y macro-demo ```