From b393008497420662bce1ebdaa6b49d8a4463b1ca Mon Sep 17 00:00:00 2001 From: reugenio Date: Mon, 8 Dec 2025 17:01:41 +0100 Subject: [PATCH] Update CLAUDE.md to v1.3 with complete documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents all features implemented in this session: - Input widget (readline-style) - Popup and Modal widgets - Menu and MenuBar widgets - Animation system (Easing, Animation, Timer) - Clipboard OSC 52 support - 10 example demos Updated roadmap with pending features: - Scrollable containers - Textarea widget - Tree widget - File picker - Hyperlinks OSC 8 - Image protocol - Notifications OSC 9/777 Includes summary of LEGO panels study from simifactu-fyne 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 580 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 326 insertions(+), 254 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a4b7841..d349f0c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,7 +3,7 @@ > **Última actualización**: 2025-12-08 > **Lenguaje**: Zig 0.15.2 > **Inspiración**: [ratatui](https://github.com/ratatui/ratatui) + [crossterm](https://github.com/crossterm-rs/crossterm) (Rust) -> **Estado**: v1.2 - Renderizado + Eventos integrados +> **Estado**: v1.3 - Widgets completos + Animaciones + Clipboard + Menus ## Descripción del Proyecto @@ -19,7 +19,7 @@ ## Estado Actual del Proyecto -### Implementación Completa (v1.2) - 2025-12-08 +### Implementación Completa (v1.3) - 2025-12-08 | Componente | Estado | Archivo | |------------|--------|---------| @@ -44,7 +44,7 @@ | Half-block | ✅ | `half_block.zig` | | Scrollbar symbols | ✅ | `scrollbar.zig` | | Markers | ✅ | `marker.zig` | -| **Widgets** | ✅ Completo (13 widgets) | `src/widgets/` | +| **Widgets** | ✅ Completo (17 widgets) | `src/widgets/` | | Block | ✅ | `block.zig` | | Paragraph | ✅ | `paragraph.zig` | | List | ✅ | `list.zig` | @@ -58,25 +58,215 @@ | Chart | ✅ | `chart.zig` | | Calendar (Monthly) | ✅ | `calendar.zig` | | Clear | ✅ | `clear.zig` | +| Input (readline-style) | ✅ | `input.zig` | +| Popup | ✅ | `popup.zig` | +| Modal | ✅ | `popup.zig` | +| Menu + MenuBar | ✅ | `menu.zig` | +| **Extras** | ✅ Completo | | +| Animation system | ✅ | `src/animation.zig` | +| Clipboard (OSC 52) | ✅ | `src/clipboard.zig` | + +### Examples (10 demos) + +| Ejemplo | Descripción | Comando | +|---------|-------------|---------| +| hello | Minimal TUI app | `zig build hello` | +| events_demo | Keyboard/mouse events | `zig build events-demo` | +| list_demo | Lista navegable | `zig build list-demo` | +| table_demo | Tabla con selección | `zig build table-demo` | +| dashboard | Demo completo | `zig build dashboard` | +| input_demo | Input readline-style | `zig build input-demo` | +| animation_demo | Easing functions | `zig build animation-demo` | +| clipboard_demo | OSC 52 clipboard | `zig build clipboard-demo` | +| menu_demo | MenuBar + Modal | `zig build menu-demo` | ### Tests -| Archivo | Tests | -|---------|-------| -| barchart.zig | 16 | -| table.zig | 14 | -| calendar.zig | 10 | -| canvas.zig | 10 | -| list.zig | 10 | -| tabs.zig | 9 | -| chart.zig | 8 | -| gauge.zig | 8 | -| sparkline.zig | 6 | -| scrollbar.zig | 5 | -| block.zig | 3 | -| paragraph.zig | 2 | -| clear.zig | 2 | -| **Total widgets** | **103** | +| Módulo | Tests | +|--------|-------| +| Widgets (13 originales) | 103 | +| Animation | 12 | +| Clipboard | 8 | +| Popup | 5 | +| Menu | 5 | +| Events | 29 | +| **Total** | **~160+** | + +--- + +## Widgets Nuevos (v1.3) + +### Input (readline-style) +Input de texto con edición avanzada. +```zig +var state = InputState.init(allocator); +defer state.deinit(); + +const input = Input.init() + .setBlock(Block.init().title("Name").borders(Borders.all)) + .setPlaceholder("Enter your name..."); +input.render(area, buf, &state); + +// Keyboard handling +if (state.handleKey(key_event)) { + // Key was consumed by input +} +``` + +**Features:** +- Cursor movement (←→, Home, End) +- Word navigation (Ctrl+←→) +- Delete (Backspace, Del, Ctrl+W, Ctrl+U, Ctrl+K) +- Kill/yank (Ctrl+K, Ctrl+Y) +- History (↑↓) +- Unicode support + +### Popup +Overlay flotante. +```zig +const popup = Popup.init() + .setSize(40, 10) + .setBlock(Block.init().title("Info").borders(Borders.all)) + .setDimBackground(true) + .center(); +popup.render(area, buf); +``` + +### Modal +Diálogo con botones. +```zig +var modal = Modal.init() + .setTitle("Confirm") + .setMessage(&.{"Are you sure?"}) + .setButtons(&.{ + .{ .label = "OK" }, + .{ .label = "Cancel" }, + }); +modal.render(area, buf); + +// Navigation +modal.focusNext(); // Tab +modal.focusPrev(); // Shift+Tab +const selected = modal.getFocusedButton(); +``` + +**Helpers:** +```zig +const confirm = confirmDialog("Title", &.{"Message"}); +const alert = alertDialog("Title", &.{"Message"}); +const yesno = yesNoCancelDialog("Title", &.{"Message"}); +``` + +### Menu + MenuBar +Sistema de menús. +```zig +const file_menu = Menu.init().setItems(&.{ + MenuItem.action("New", 'n').setShortcut("Ctrl+", 'N'), + MenuItem.action("Open", 'o'), + MenuItem.separator(), + MenuItem.action("Exit", 'q'), +}); + +var menu_bar = MenuBar.init().setItems(&.{ + MenuBarItem.init("File", file_menu), + MenuBarItem.init("Edit", edit_menu), +}); + +menu_bar.render(area, buf); + +// Navigation +menu_bar.selectNext(); // → +menu_bar.selectPrev(); // ← +menu_bar.openSelected(); // Enter +menu_bar.closeMenus(); // Esc + +// Dropdown +if (menu_bar.open_menu) |idx| { + const dropdown_area = menu_bar.getDropdownArea(area, idx); + var menu = getCurrentMenu(); + menu.render(dropdown_area, buf); +} +``` + +**MenuItem types:** +- `.action` - Clickable action +- `.separator` - Visual separator +- `.submenu` - Opens nested menu +- `.toggle` - Checkbox option + +--- + +## Sistema de Animaciones + +### Easing Functions +```zig +const Easing = zcatui.Easing; + +// Available: +Easing.linear +Easing.easeIn / easeOut / easeInOut +Easing.easeInCubic / easeOutCubic / easeInOutCubic +Easing.easeInExpo / easeOutExpo +Easing.easeOutBounce +Easing.easeOutElastic +Easing.easeOutBack +``` + +### Animation +```zig +var anim = Animation.init(0, 100, 2000) // 0→100 over 2 seconds + .setEasing(Easing.easeOutBounce) + .setRepeat(-1) // Infinite + .setPingPong(true); // Reverse on repeat + +// In game loop: +anim.advance(delta_ms); +const value = anim.getValue(); // f64 +const percent = anim.getValueU16(); // u16 (0-65535) +``` + +### Timer +```zig +var timer = Timer.repeating(1000); // 1 second + +if (timer.advance(delta_ms)) { + // Timer triggered! +} +``` + +### AnimationGroup +```zig +var group = AnimationGroup.parallel(&animations); +// or +var group = AnimationGroup.sequential(&animations); + +group.advance(delta_ms); +if (group.isComplete()) { ... } +``` + +--- + +## Clipboard (OSC 52) + +```zig +const clipboard = zcatui.clipboard; +const writer = term.backend.stdout.deprecatedWriter(); + +// Copy to system clipboard +try clipboard.copy(allocator, writer, "Hello!"); + +// Copy to X11 primary selection +try clipboard.copySmallTo(writer, "Text", .primary); + +// Copy to both +try clipboard.copySmallTo(writer, "Text", .both); + +// Clear clipboard +try clipboard.clear(writer); +``` + +**Terminal support:** xterm, iTerm2, kitty, alacritty, WezTerm, foot +**tmux:** Enable with `set -g set-clipboard on` --- @@ -84,8 +274,6 @@ ### Diseño: Immediate Mode Rendering -Como ratatui, usamos **renderizado inmediato con buffers intermedios**: - ``` ┌─────────────┐ ┌────────┐ ┌──────────┐ │ Application │───▶│ Buffer │───▶│ Terminal │ @@ -110,6 +298,8 @@ zcatui/ │ ├── text.zig # Text, Line, Span, Alignment │ ├── event.zig # Event, KeyEvent, MouseEvent, KeyCode │ ├── cursor.zig # Cursor control (shapes, position) +│ ├── animation.zig # Easing, Animation, Timer +│ ├── clipboard.zig # OSC 52 clipboard support │ ├── event/ │ │ ├── reader.zig # EventReader + polling │ │ └── parse.zig # Escape sequence parser @@ -138,154 +328,30 @@ zcatui/ │ ├── canvas.zig # Drawing (braille/half-block) │ ├── chart.zig # Line/scatter/bar graphs │ ├── calendar.zig # Monthly calendar -│ └── clear.zig # Clear/reset area +│ ├── clear.zig # Clear/reset area +│ ├── input.zig # Readline-style input +│ ├── popup.zig # Popup + Modal +│ └── menu.zig # Menu + MenuBar ├── examples/ -│ ├── hello.zig # Minimal example -│ └── events_demo.zig # Interactive keyboard/mouse demo +│ ├── hello.zig +│ ├── events_demo.zig +│ ├── list_demo.zig +│ ├── table_demo.zig +│ ├── dashboard.zig +│ ├── input_demo.zig +│ ├── animation_demo.zig +│ ├── clipboard_demo.zig +│ └── menu_demo.zig ├── docs/ -│ ├── ARCHITECTURE.md # Arquitectura detallada -│ ├── WIDGETS.md # Documentación de widgets -│ └── API.md # Referencia de API +│ ├── ARCHITECTURE.md +│ ├── WIDGETS.md +│ └── API.md ├── build.zig └── CLAUDE.md ``` --- -## Widgets Implementados - -### Block -Contenedor base con bordes y títulos. -```zig -const block = Block.init() - .title("Mi Título") - .borders(Borders.all) - .borderStyle(Style.default.fg(Color.blue)); -block.render(area, buf); -``` - -### Paragraph -Texto con word-wrapping y scroll. -```zig -const para = Paragraph.init(text) - .setBlock(block) - .setWrap(.{ .trim = true }) - .setAlignment(.center); -para.render(area, buf); -``` - -### List (con ListState) -Lista seleccionable con scroll automático. -```zig -var state = ListState.init(); -state.select(2); -const list = List.init(items) - .setBlock(block) - .setHighlightStyle(Style.default.bg(Color.yellow)); -list.renderStateful(area, buf, &state); -``` - -### Table (con TableState) -Tabla multi-columna con selección. -```zig -var state = TableState.init(); -const table = Table.init(rows, widths) - .setHeader(header_row) - .setHighlightStyle(Style.default.bg(Color.blue)); -table.renderStateful(area, buf, &state); -``` - -### Gauge y LineGauge -Barras de progreso. -```zig -const gauge = Gauge.init() - .setRatio(0.75) - .setLabel("75%") - .setGaugeStyle(Style.default.fg(Color.green)); -gauge.render(area, buf); -``` - -### Tabs -Navegación por pestañas. -```zig -const tabs = Tabs.init(&titles) - .select(1) - .setHighlightStyle(Style.default.fg(Color.yellow)); -tabs.render(area, buf); -``` - -### Sparkline -Mini gráficos de línea. -```zig -const spark = Sparkline.init() - .setData(&data) - .setMax(100) - .setStyle(Style.default.fg(Color.cyan)); -spark.render(area, buf); -``` - -### Scrollbar (con ScrollbarState) -Indicador de scroll. -```zig -var state = ScrollbarState.init(100).setPosition(25); -const scrollbar = Scrollbar.init(.vertical_right); -scrollbar.render(area, buf, &state); -``` - -### BarChart -Gráficos de barras con grupos. -```zig -const chart = BarChart.init() - .setData(&bar_groups) - .setBarWidth(5) - .setBarGap(1); -chart.render(area, buf); -``` - -### Canvas -Dibujo libre con diferentes marcadores. -```zig -const canvas = Canvas.init() - .setXBounds(0, 100) - .setYBounds(0, 100) - .setMarker(.braille) - .paint(struct { - pub fn draw(ctx: *Painter) void { - ctx.drawLine(0, 0, 100, 100, Color.red); - ctx.drawCircle(50, 50, 25, Color.blue); - } - }.draw); -canvas.render(area, buf); -``` - -### Chart -Gráficos de línea/scatter/barras con ejes. -```zig -const chart = Chart.init(&datasets) - .setXAxis(x_axis) - .setYAxis(y_axis) - .setLegendPosition(.top_right); -chart.render(area, buf); -``` - -### Calendar (Monthly) -Calendario mensual. -```zig -const cal = Monthly.init(Date.init(2024, 12, 1)) - .showMonthHeader(Style.default.fg(Color.blue)) - .showWeekdaysHeader(Style.default) - .withEvents(events); -cal.render(area, buf); -``` - -### Clear -Limpia/resetea un área. -```zig -Clear.init().render(area, buf); -``` - ---- - ## Stack Técnico | Componente | Elección | @@ -301,18 +367,94 @@ Clear.init().render(area, buf); ## Comandos ```bash -# Compilar +# Compilar todo zig build # Tests zig build test -# Tests con resumen -zig build test --summary all +# Ejecutar ejemplos +zig build hello +zig build events-demo +zig build list-demo +zig build table-demo +zig build dashboard +zig build input-demo +zig build animation-demo +zig build clipboard-demo +zig build menu-demo ``` --- +## Funcionalidades Pendientes (Roadmap) + +### Prioridad Alta +- [ ] **Scrollable containers** - Viewport para contenido largo +- [ ] **Textarea widget** - Input multilínea con scroll + +### Prioridad Media +- [ ] **Sistema LEGO panels** - Patrones de simifactu-fyne (isDirty, composites) +- [ ] **Context menu** - Menú contextual (right-click) +- [ ] **Tooltips** - Información emergente + +### Prioridad Baja +- [ ] **Hyperlinks OSC 8** - Links clickeables en terminal +- [ ] **Image protocol** - Kitty/iTerm2 inline images +- [ ] **Notifications OSC 9/777** - Desktop notifications +- [ ] **Tree widget** - Árbol expandible/colapsable +- [ ] **File picker** - Selección de archivos + +### Performance +- [ ] Lazy rendering para widgets grandes +- [ ] Pooling de memoria para cells +- [ ] SIMD para operaciones de buffer masivas + +### Documentación +- [ ] Tutorial paso a paso +- [ ] API reference generada +- [ ] Más ejemplos + +--- + +## Estudio: Sistema LEGO Panels (simifactu-fyne) + +Se realizó un análisis completo del sistema de paneles de simifactu-fyne. Los patrones clave son: + +### 1. Autonomous Panel Interface +Cada panel se auto-gestiona: conoce su ID, tipo, sabe construir su UI y refrescarse. + +### 2. isDirty Pattern +Desacopla notificación (O(1)) de actualización (O(n)): +- Observer notifica → solo pone flag `isDirty = true` +- Refresh loop verifica `isDirty()` +- Panel actualiza solo si necesario +- Flags granulares: `dirtyData`, `dirtyColors`, `dirtyConfig`, `dirtySorting` + +### 3. Composición LEGO +Paneles pequeños se combinan en layouts: +- HSplit: Dos paneles lado a lado +- VSplit/Border: Top/center/bottom +- Composites: Paneles que contienen otros paneles + +### 4. WindowComposer +Orquestador que maneja: +- Registro de paneles por posición (left, center, right, top) +- Navegación de foco (NextPanel, PreviousPanel) +- Broadcasting de eventos + +### 5. Callbacks para comunicación +```go +listPanel.OnItemSelected = func(item Item) { + detailPanel.LoadItem(item) +} +``` + +**Archivos de referencia:** +- `/mnt/cello2/arno/re/recode/go/simifactu-fyne/internal/ui/panels_v3/` + +--- + ## Equipo y Metodología ### Quiénes Somos @@ -341,67 +483,6 @@ zig build test --summary all --- -## Principios de Desarrollo - -### Estándares Zig Open Source (#24 de NORMAS) - -> **Este proyecto será público. El código debe ser ejemplar.** - -| Aspecto | Estándar | -|---------|----------| -| **Claridad** | Código autoexplicativo, nombres descriptivos | -| **Comentarios** | Doc comments (`///`) en TODAS las funciones públicas | -| **Estructura** | Organización lógica, separación de responsabilidades | -| **Idiomático** | snake_case, error handling explícito, sin magia | - -### Principios Generales - -- **DRY**: Una sola función por tarea -- **Fragmentación**: <400 líneas core, <200 líneas utils -- **Testing progresivo**: Compilar y probar cada cambio -- **Funcionalidad > Performance**: Primero que funcione, luego optimizar - ---- - -## API de Zig 0.15.2 - Cambios Importantes - -> Ver guía completa: `TEAM_STANDARDS/INFRASTRUCTURE/ZIG_0.15_GUIA.md` - -### Cambios Clave para este Proyecto - -| Componente | Zig 0.15 | -|------------|----------| -| stdout | `std.fs.File.stdout().deprecatedWriter()` | -| ArrayList | `std.array_list.Managed(T).init(alloc)` | -| file.reader() | `file.deprecatedReader()` | -| sleep | `std.Thread.sleep()` | - ---- - -## Otros Proyectos del Ecosistema - -### Proyectos Zig -| Proyecto | Descripción | Estado | -|----------|-------------|--------| -| **service-monitor** | Monitor HTTP/TCP con notificaciones | Completado | -| **zcatui** | TUI library inspirada en ratatui | v1.0 Completo | - -### Proyectos Go (referencia) -| Proyecto | Descripción | -|----------|-------------| -| **simifactu** | API facturación electrónica | -| **ms-web** (mundisofa) | Web e-commerce | -| **0fiS** | Aplicación desktop Fyne | - -### Infraestructura -| Recurso | Ubicación | -|---------|-----------| -| **Git server** | git.reugenio.com (Forgejo) | -| **Servidor** | Simba (188.245.244.244) | -| **Docs infra** | `TEAM_STANDARDS/INFRASTRUCTURE/` | - ---- - ## Control de Versiones ```bash @@ -434,35 +515,28 @@ zig build test --summary all # Tests con detalles --- -## Optimizaciones de Performance (v1.1) - -### Implementadas -- [x] **Symbol compacto**: Almacena UTF-8 directamente (4 bytes max), evita conversión en cada render -- [x] **Buffer diff**: Iterator que solo retorna celdas modificadas, reduce I/O dramáticamente -- [x] **Cell.eql()**: Comparación eficiente de celdas para el diff -- [x] **Buffer.resize()**: Redimensiona preservando contenido existente -- [x] **writeSymbol()**: Escribe UTF-8 directo sin conversión de codepoint - -### Pendientes (v1.2+) -- [ ] Lazy rendering para widgets grandes -- [ ] Pooling de memoria para cells -- [ ] SIMD para operaciones de buffer masivas - -### Funcionalidades Adicionales -- [ ] Input handling (keyboard events) -- [ ] Mouse support -- [ ] Clipboard integration -- [ ] Animaciones - -### Documentación -- [ ] Ejemplos completos -- [ ] Tutorial paso a paso -- [ ] API reference generada - ---- - ## Historial de Desarrollo +### 2025-12-08 - v1.3 (Widgets avanzados + Extras) +**Widgets nuevos:** +- Input: Readline-style con cursor, word nav, kill/yank, history, Unicode +- Popup: Overlay flotante con backdrop dimming +- Modal: Diálogo con título, mensaje, botones navegables +- Menu: Dropdown menu con shortcuts +- MenuBar: Barra horizontal con dropdowns + +**Sistemas nuevos:** +- Animation: Easing functions, Animation, AnimationGroup, Timer +- Clipboard: OSC 52 copy/paste support + +**Ejemplos nuevos:** +- list_demo.zig, table_demo.zig, dashboard.zig +- input_demo.zig, animation_demo.zig +- clipboard_demo.zig, menu_demo.zig + +**Estudio:** +- Análisis completo del sistema LEGO panels de simifactu-fyne + ### 2025-12-08 - v1.2 (Eventos - crossterm-style) - Sistema de eventos integrado (teclado + ratón) - Event, KeyEvent, MouseEvent, KeyCode types @@ -471,7 +545,6 @@ zig build test --summary all # Tests con detalles - Cursor control (shapes, blinking, save/restore) - Terminal integrado: pollEvent(), enableMouseCapture(), enableFocusChange() - Ejemplo interactivo: events_demo.zig -- Tests: 47 tests (29 nuevos para eventos) ### 2025-12-08 - v1.1 (Performance) - Symbol: tipo compacto UTF-8 (4 bytes max) @@ -479,7 +552,6 @@ zig build test --summary all # Tests con detalles - Cell.eql(): comparación optimizada - Buffer.resize(): redimensionado con preservación - writeSymbol(): output UTF-8 directo -- Tests: 18 tests (9 nuevos para optimizaciones) ### 2025-12-08 - v1.0 (Implementación Completa) - Implementados todos los widgets de ratatui (13 widgets)