zcatgui/CLAUDE.md
reugenio b352cf9672 docs: Update CLAUDE.md with actual project state
- Fix file structure to show what actually exists
- Update Zig 0.15.2 notes (ArrayListUnmanaged, file I/O)
- Update status: 16 tests passing, core implemented
- Add verification commands

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

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

16 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 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

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

# 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
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

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)

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

  • Crear estructura de directorios
  • build.zig con SDL2
  • CLAUDE.md
  • 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

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 - 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:

cd /mnt/cello2/arno/re/recode/zig/zcatgui
zig build test   # 16 tests deben pasar
zig build        # Compila hello y macro-demo