# Plan Maestro de Desarrollo: zcatgui > **Versión**: 1.0 > **Fecha**: 2025-12-09 > **Objetivo**: Llevar zcatgui a la perfección - paridad completa con DVUI/Gio + features únicas > **Filosofía**: Calidad sobre velocidad. Código óptimo, mínima memoria, máximo rendimiento. --- ## COMPARATIVA DE PARIDAD ### vs DVUI (Target: 100%) | Categoría | DVUI | zcatgui actual | Falta | Post-Plan | |-----------|:----:|:--------------:|:-----:|:---------:| | Básicos (Label, Button, etc.) | 7 | 7 ✅ | 0 | 7 ✅ | | Contenedores (Panel, Split, etc.) | 6 | 6 ✅ | 0 | 6 ✅ | | Datos (List, Table, Tree) | 4 | 2 | 2 | 4 ✅ | | Input (Text, Number, Editor) | 5 | 3 | 2 | 5 ✅ | | Navegación (Menu, Tabs) | 4 | 4 ✅ | 0 | 4 ✅ | | Feedback (Tooltip, Toast) | 3 | 0 | 3 | 3 ✅ | | Especial (Image, Icon) | 4 | 0 | 4 | 4 ✅ | | Rendering (AA, Effects) | ✅ | Básico | ✅ | ✅ | | **TOTAL WIDGETS** | **35** | **17** | **18** | **35 ✅** | ### vs Gio (Target: ~60% - lo útil) | Feature | Gio | Implementamos | Razón si NO | |---------|:---:|:-------------:|-------------| | Widgets básicos | ✅ | ✅ | - | | Progress/Spinner | ✅ | ✅ | - | | Charts | ✅ | ✅ | - | | Clipboard | ✅ | ✅ | - | | Animaciones | ✅ | ✅ | - | | Material Design | ✅ | ❌ | No necesario, tenemos themes | | GPU Rendering | ✅ | Opcional | Software-first es objetivo | | HarfBuzz/BiDi | ✅ | ❌ | Overkill, no idiomas RTL | | System Fonts | ✅ | ❌ | TTF embebido suficiente | ### Features ÚNICAS de zcatgui (Ventaja Competitiva) | Feature | DVUI | Gio | zcatgui | Valor | |---------|:----:|:---:|:-------:|:-----:| | Sistema de Macros | ❌ | ❌ | ✅ | ⭐⭐⭐ | | Lego Panels + DataManager | ❌ | ❌ | ✅ | ⭐⭐⭐ | | Table Dirty Tracking | ❌ | ❌ | ✅ | ⭐⭐⭐ | | Table Validation | ❌ | ❌ | ✅ | ⭐⭐ | | Table Sorting | ❌ | ❌ | ✅ | ⭐⭐ | | Table Multi-select | ❌ | ❌ | ✅ | ⭐⭐ | | High Contrast Theme | ❌ | ❌ | ✅ | ⭐⭐ | | SSH-first Design | Parcial | ❌ | ✅ | ⭐⭐⭐ | ### Conclusión de Paridad ``` Post-Plan: vs DVUI: 100% paridad + features únicas SUPERIORES vs Gio: ~60% paridad (lo útil) + features únicas zcatgui será MEJOR que ambas para aplicaciones empresariales gracias a: Macros + Lego Panels + Table avanzada + SSH-first ``` --- ## ÍNDICE 1. [Estado Actual](#1-estado-actual) 2. [Objetivos de Perfección](#2-objetivos-de-perfección) 3. [Principios de Desarrollo](#3-principios-de-desarrollo) 4. [Plan por Fases](#4-plan-por-fases) 5. [Detalles de Implementación](#5-detalles-de-implementación) 6. [Métricas de Calidad](#6-métricas-de-calidad) 7. [Checklist Final](#7-checklist-final) --- ## 1. ESTADO ACTUAL ### 1.1 Inventario Completado (v0.5.0) | Categoría | Completado | Items | |-----------|:----------:|-------| | **Core** | ✅ 100% | Context, Layout, Style, Input, Command | | **Render** | ✅ 80% | Framebuffer, SoftwareRenderer, Font, TTF básico | | **Backend** | ✅ 100% | SDL2 | | **Macros** | ✅ 100% | Recorder, Player, Storage | | **Widgets** | ✅ 17/35 | Label, Button, TextInput, Checkbox, Select, List, Focus, Table, Split, Panel, Modal, AutoComplete, Slider, Scroll, Menu, Tabs, Radio | | **Panels** | ✅ 100% | AutonomousPanel, Composites, DataManager | | **Themes** | ✅ 100% | 5 themes, ThemeManager | ### 1.2 LOC Actual ``` Core: ~1,700 LOC Render: ~1,300 LOC Backend: ~400 LOC Macro: ~340 LOC Widgets: ~8,000 LOC Panels: ~350 LOC Entry: ~130 LOC ───────────────────── TOTAL: ~12,220 LOC ``` ### 1.3 Tests Actuales - **85+ tests** pasando - Cobertura: Core 90%, Widgets 60%, Panels 70% --- ## 2. OBJETIVOS DE PERFECCIÓN ### 2.1 Paridad de Widgets (Target: 35 widgets) ``` Actual: 17 widgets Objetivo: 35 widgets (+18) Paridad: 100% DVUI, 60% Gio ``` ### 2.2 Rendimiento Target | Métrica | Target | Razón | |---------|--------|-------| | **FPS** | 60+ estable | Fluidez visual | | **Startup** | <50ms | Percepción instantánea | | **Memoria base** | <10MB | Eficiencia | | **Memoria por widget** | <100 bytes | Escalabilidad | | **Latencia input** | <16ms | Respuesta inmediata | | **Redraw completo** | <5ms | 60fps con margen | ### 2.3 Calidad de Código | Métrica | Target | |---------|--------| | **LOC total** | <20,000 (eficiente) | | **Cobertura tests** | >90% | | **Complejidad ciclomática** | <10 por función | | **Funciones >50 LOC** | 0 | | **Comentarios/código** | 15-20% | | **Warnings** | 0 | | **Memory leaks** | 0 | --- ## 3. PRINCIPIOS DE DESARROLLO ### 3.1 Optimización de Memoria ```zig // ❌ MAL: Allocaciones innecesarias fn process(allocator: Allocator, items: []const Item) ![]Result { var results = try allocator.alloc(Result, items.len); // ... } // ✅ BIEN: Reutilizar buffers, stack allocation cuando sea posible fn process(items: []const Item, result_buf: []Result) []Result { const count = @min(items.len, result_buf.len); // ... return result_buf[0..count]; } ``` **Reglas:** 1. Preferir stack allocation sobre heap 2. Usar `comptime` para cálculos en tiempo de compilación 3. Reutilizar buffers entre frames 4. Evitar slices dinámicos cuando el tamaño es conocido 5. Usar `@memset` y `@memcpy` para operaciones bulk ### 3.2 Optimización de Rendimiento ```zig // ❌ MAL: Múltiples pasadas for (items) |item| { if (item.visible) count += 1; } for (items) |item| { if (item.visible) process(item); } // ✅ BIEN: Una sola pasada for (items) |item| { if (item.visible) { count += 1; process(item); } } ``` **Reglas:** 1. Minimizar iteraciones (single-pass cuando posible) 2. Early-exit en condiciones frecuentes 3. Cache locality: acceso secuencial a memoria 4. Evitar división (usar multiplicación por recíproco) 5. Usar SIMD implícito via `@Vector` cuando aplique ### 3.3 Inmediato y Determinista ```zig // ❌ MAL: Estado oculto, efectos secundarios var global_counter: u32 = 0; fn doSomething() void { global_counter += 1; } // ✅ BIEN: Estado explícito, función pura fn doSomething(state: *State) void { state.counter += 1; } ``` **Reglas:** 1. Sin globals mutables (excepto ThemeManager/DataManager controlados) 2. Funciones puras cuando posible 3. Estado explícito pasado como parámetro 4. Resultados predecibles dado el mismo input ### 3.4 API Consistente Todos los widgets siguen el patrón: ```zig // Variante simple (defaults) pub fn widget(ctx: *Context, ...) Result { ... } // Variante extendida (con config) pub fn widgetEx(ctx: *Context, ..., config: Config) Result { ... } // Variante con bounds explícitos pub fn widgetRect(ctx: *Context, bounds: Rect, ..., config: Config) Result { ... } ``` --- ## 4. PLAN POR FASES ### FASE 1: FUNDAMENTOS SÓLIDOS **Duración estimada**: 1 semana **Objetivo**: Optimizar y solidificar el core existente #### 1.1 Optimización del Core | Tarea | Prioridad | LOC Est. | Descripción | |-------|:---------:|:--------:|-------------| | Arena allocator para Context | ALTA | 150 | Pool de memoria por frame | | Object pooling para Commands | ALTA | 100 | Reutilizar command buffers | | Optimizar Rect operations | MEDIA | 50 | SIMD para intersecciones | | Benchmark suite | ALTA | 200 | Medir rendimiento base | #### 1.2 Optimización del Renderer | Tarea | Prioridad | LOC Est. | Descripción | |-------|:---------:|:--------:|-------------| | Dirty rectangles | ALTA | 200 | Solo redibujar lo cambiado | | Batch draw commands | ALTA | 150 | Agrupar rects del mismo color | | Clip optimization | MEDIA | 100 | Skip completo si fuera de clip | | Framebuffer double-buffering | MEDIA | 80 | Evitar tearing | #### 1.3 Tests y Benchmarks | Tarea | Prioridad | LOC Est. | Descripción | |-------|:---------:|:--------:|-------------| | Test coverage 90%+ | ALTA | 500 | Tests para todo el core | | Performance benchmarks | ALTA | 300 | Medir todas las operaciones | | Memory leak tests | ALTA | 100 | Verificar cero leaks | | Stress tests | MEDIA | 200 | 10K widgets, 1M commands | **Entregables Fase 1:** - [ ] Arena allocator funcionando - [ ] Dirty rectangles implementado - [ ] Benchmark suite con métricas base - [ ] 90%+ test coverage en core - [ ] 0 memory leaks verificado --- ### FASE 2: WIDGETS DE FEEDBACK **Duración estimada**: 1 semana **Objetivo**: Completar widgets de feedback visual #### 2.1 Tooltip ```zig pub const TooltipConfig = struct { delay_ms: u32 = 500, // Delay antes de mostrar max_width: u16 = 300, // Ancho máximo position: Position = .auto, // auto, above, below, left, right arrow: bool = true, // Mostrar flecha }; pub const TooltipState = struct { hover_start: i64 = 0, // Timestamp inicio hover visible: bool = false, target_rect: Rect = .{}, }; pub fn tooltip(ctx: *Context, state: *TooltipState, text: []const u8, config: TooltipConfig) void; pub fn tooltipArea(ctx: *Context, bounds: Rect, state: *TooltipState, text: []const u8) void; ``` **Características:** - Delay configurable antes de mostrar - Posicionamiento inteligente (evitar salir de pantalla) - Soporte multi-línea con wrapping - Flecha apuntando al elemento - Fade in/out suave **LOC estimadas**: 150 #### 2.2 ProgressBar ```zig pub const ProgressStyle = enum { bar, circle, dots }; pub const ProgressConfig = struct { style: ProgressStyle = .bar, show_percentage: bool = true, show_label: bool = false, label: []const u8 = "", animated: bool = true, // Animación de progreso indeterminate: bool = false, // Modo indeterminado (loading) }; pub const ProgressColors = struct { track: Color, fill: Color, text: Color, }; pub fn progressBar(ctx: *Context, progress: f32, config: ProgressConfig) void; pub fn progressCircle(ctx: *Context, progress: f32, config: ProgressConfig) void; ``` **Características:** - Barra horizontal/vertical - Círculo de progreso - Modo indeterminado (spinner) - Porcentaje y label opcional - Animación suave de transición **LOC estimadas**: 200 #### 2.3 Toast/Notification ```zig pub const ToastType = enum { info, success, warning, error }; pub const ToastPosition = enum { top, bottom, top_right, bottom_right }; pub const ToastConfig = struct { duration_ms: u32 = 3000, position: ToastPosition = .bottom_right, max_visible: u8 = 5, animation: bool = true, }; pub const ToastManager = struct { toasts: [MAX_TOASTS]Toast, count: usize, pub fn show(self: *ToastManager, message: []const u8, toast_type: ToastType) void; pub fn showWithAction(self: *ToastManager, message: []const u8, action: []const u8, callback: ActionFn) void; pub fn dismiss(self: *ToastManager, id: u32) void; pub fn dismissAll(self: *ToastManager) void; pub fn render(self: *ToastManager, ctx: *Context) void; }; ``` **Características:** - Múltiples tipos (info, success, warning, error) - Posicionamiento configurable - Auto-dismiss con timer - Botón de acción opcional - Stack de múltiples toasts - Animación slide in/out **LOC estimadas**: 250 #### 2.4 Spinner/Loader ```zig pub const SpinnerStyle = enum { circular, // Círculo girando dots, // Puntos pulsando bars, // Barras ecualizador ring, // Anillo con gap }; pub const SpinnerConfig = struct { style: SpinnerStyle = .circular, size: u16 = 24, speed: f32 = 1.0, // Multiplicador de velocidad label: ?[]const u8 = null, }; pub fn spinner(ctx: *Context, config: SpinnerConfig) void; pub fn spinnerOverlay(ctx: *Context, bounds: Rect, config: SpinnerConfig) void; ``` **Características:** - Múltiples estilos de animación - Tamaño configurable - Velocidad ajustable - Label opcional ("Loading...") - Overlay mode para cubrir contenido **LOC estimadas**: 150 **Entregables Fase 2:** - [ ] Tooltip con posicionamiento inteligente - [ ] ProgressBar (bar + circle + indeterminate) - [ ] Toast/Notification system - [ ] Spinner con 4 estilos - [ ] Tests para cada widget - [ ] Demo de feedback widgets --- ### FASE 3: WIDGETS ESPECIALIZADOS **Duración estimada**: 2 semanas **Objetivo**: Widgets avanzados para aplicaciones complejas #### 3.1 Tree View ```zig pub const TreeNode = struct { id: u64, label: []const u8, icon: ?Icon = null, children: []TreeNode = &.{}, expanded: bool = false, selected: bool = false, data: ?*anyopaque = null, }; pub const TreeConfig = struct { indent: u16 = 20, show_lines: bool = true, show_icons: bool = true, multi_select: bool = false, drag_drop: bool = false, lazy_load: bool = false, // Cargar hijos bajo demanda }; pub const TreeState = struct { selected: std.ArrayList(u64), expanded: std.AutoHashMap(u64, bool), scroll_offset: i32, focused_id: ?u64, }; pub const TreeResult = struct { selection_changed: bool, expanded_changed: bool, activated: bool, // Double-click o Enter activated_node: ?*TreeNode, drag_started: bool, drop_target: ?*TreeNode, }; pub fn tree(ctx: *Context, bounds: Rect, state: *TreeState, root: *TreeNode, config: TreeConfig) TreeResult; ``` **Características:** - Expand/collapse con animación - Selección simple y múltiple - Keyboard navigation completo - Drag & drop entre nodos - Lazy loading para árboles grandes - Iconos por tipo de nodo - Líneas de conexión opcionales - Virtual scrolling para árboles enormes **LOC estimadas**: 400 #### 3.2 Image Widget ```zig pub const ImageFormat = enum { rgba, rgb, grayscale, indexed }; pub const ImageFit = enum { none, contain, cover, fill, scale_down }; pub const ImageData = struct { pixels: []const u8, width: u32, height: u32, format: ImageFormat, stride: ?u32 = null, }; pub const ImageConfig = struct { fit: ImageFit = .contain, alignment: Alignment = .center, border_radius: u8 = 0, placeholder: ?Color = null, // Color mientras carga error_placeholder: ?[]const u8 = null, }; pub const ImageCache = struct { entries: std.AutoHashMap(u64, CachedImage), max_size: usize, current_size: usize, pub fn get(self: *ImageCache, id: u64) ?*CachedImage; pub fn put(self: *ImageCache, id: u64, image: ImageData) !void; pub fn evict(self: *ImageCache, bytes: usize) void; }; pub fn image(ctx: *Context, bounds: Rect, data: ImageData, config: ImageConfig) void; pub fn imageFromCache(ctx: *Context, bounds: Rect, cache: *ImageCache, id: u64, config: ImageConfig) void; ``` **Características:** - Soporte RGBA, RGB, grayscale - Múltiples modos de fit - Caché de imágenes con LRU eviction - Border radius para esquinas redondeadas - Placeholder mientras carga - Lazy loading desde archivo - Resize eficiente (nearest/bilinear) **LOC estimadas**: 350 #### 3.3 ReorderableList ```zig pub const ReorderableConfig = struct { item_height: u16 = 32, drag_handle: bool = true, // Mostrar handle de arrastre allow_remove: bool = true, // Permitir eliminar items allow_add: bool = true, // Permitir añadir items animation: bool = true, // Animar reordenamiento }; pub const ReorderableState = struct { dragging_index: ?usize, drag_offset: i32, target_index: ?usize, items_order: []usize, // Índices en orden actual }; pub const ReorderableResult = struct { reordered: bool, removed_index: ?usize, add_requested: bool, new_order: []const usize, }; pub fn reorderableList( ctx: *Context, bounds: Rect, state: *ReorderableState, items: []const []const u8, config: ReorderableConfig, ) ReorderableResult; ``` **Características:** - Drag & drop para reordenar - Handle visual de arrastre - Animación suave de reposicionamiento - Botón eliminar por item - Botón añadir al final - Keyboard reorder (Ctrl+Up/Down) - Callback on change **LOC estimadas**: 300 #### 3.4 ColorPicker ```zig pub const ColorPickerMode = enum { rgb, hsl, hex, palette }; pub const ColorPickerConfig = struct { mode: ColorPickerMode = .rgb, show_alpha: bool = true, show_preview: bool = true, palette: ?[]const Color = null, // Colores predefinidos recent_colors: bool = true, }; pub const ColorPickerState = struct { current: Color, mode: ColorPickerMode, hue: f32, saturation: f32, lightness: f32, recent: [8]Color, }; pub fn colorPicker(ctx: *Context, bounds: Rect, state: *ColorPickerState, config: ColorPickerConfig) bool; pub fn colorPickerPopup(ctx: *Context, anchor: Rect, state: *ColorPickerState, config: ColorPickerConfig) bool; ``` **Características:** - Selector visual (cuadrado SL + barra H) - Inputs RGB/HSL/Hex - Slider de alpha - Paleta de colores predefinidos - Historial de colores recientes - Preview comparativo (nuevo vs actual) - Eyedropper (futuro) **LOC estimadas**: 350 #### 3.5 DatePicker/Calendar ```zig pub const DatePickerConfig = struct { min_date: ?Date = null, max_date: ?Date = null, disabled_dates: ?[]const Date = null, first_day_of_week: u8 = 1, // 0=Sunday, 1=Monday show_week_numbers: bool = false, range_selection: bool = false, }; pub const DatePickerState = struct { selected_date: ?Date, range_start: ?Date, range_end: ?Date, view_month: u8, view_year: u16, open: bool, }; pub const DatePickerResult = struct { changed: bool, date: ?Date, range: ?struct { start: Date, end: Date }, }; pub fn datePicker(ctx: *Context, state: *DatePickerState, config: DatePickerConfig) DatePickerResult; pub fn calendar(ctx: *Context, bounds: Rect, state: *DatePickerState, config: DatePickerConfig) DatePickerResult; ``` **Características:** - Vista de mes con navegación - Selección de fecha única o rango - Fechas deshabilitadas - Límites min/max - Números de semana opcionales - Navegación por teclado - Dropdown integrado **LOC estimadas**: 400 **Entregables Fase 3:** - [ ] Tree View con lazy loading - [ ] Image widget con cache - [ ] ReorderableList con drag & drop - [ ] ColorPicker completo - [ ] DatePicker/Calendar - [ ] Tests exhaustivos - [ ] Demo de widgets especializados --- ### FASE 4: TEXTO AVANZADO **Duración estimada**: 2 semanas **Objetivo**: Sistema de texto profesional #### 4.1 MultilineText Editor ```zig pub const EditorConfig = struct { read_only: bool = false, word_wrap: bool = true, show_line_numbers: bool = false, tab_size: u8 = 4, max_lines: ?u32 = null, placeholder: ?[]const u8 = null, }; pub const EditorState = struct { lines: std.ArrayList([]u8), cursor_line: usize, cursor_col: usize, selection_start: ?Position, selection_end: ?Position, scroll_offset: i32, undo_stack: UndoStack, redo_stack: UndoStack, }; pub const EditorResult = struct { text_changed: bool, cursor_moved: bool, selection_changed: bool, }; pub fn editor(ctx: *Context, bounds: Rect, state: *EditorState, config: EditorConfig) EditorResult; ``` **Características:** - Múltiples líneas con scroll - Selección de texto (mouse y teclado) - Copy/Cut/Paste (clipboard) - Undo/Redo con stack - Word wrap opcional - Line numbers opcional - Tab handling - Find & Replace (básico) **LOC estimadas**: 600 #### 4.2 NumberEntry ```zig pub const NumberType = enum { integer, float, currency }; pub const NumberConfig = struct { number_type: NumberType = .integer, min: ?f64 = null, max: ?f64 = null, step: f64 = 1.0, precision: u8 = 2, // Decimales para float/currency prefix: ?[]const u8 = null, // "$", "€" suffix: ?[]const u8 = null, // "%", "kg" thousand_separator: bool = true, allow_negative: bool = true, spinner: bool = true, // Botones +/- }; pub const NumberState = struct { value: f64, text_buf: [64]u8, text_len: usize, editing: bool, cursor: usize, }; pub const NumberResult = struct { changed: bool, value: f64, valid: bool, }; pub fn numberEntry(ctx: *Context, state: *NumberState, config: NumberConfig) NumberResult; ``` **Características:** - Validación en tiempo real - Formateo automático (separadores miles) - Spinner buttons (+/-) - Arrastrar para cambiar valor - Límites min/max - Precisión configurable - Prefijo/sufijo (moneda, unidades) **LOC estimadas**: 250 #### 4.3 Font Atlas y Rendering Mejorado ```zig pub const FontAtlas = struct { texture: []u8, width: u32, height: u32, glyphs: std.AutoHashMap(GlyphKey, GlyphInfo), pub fn getGlyph(self: *FontAtlas, codepoint: u32, size: u16) ?GlyphInfo; pub fn renderGlyph(self: *FontAtlas, codepoint: u32, size: u16) !GlyphInfo; }; pub const GlyphInfo = struct { atlas_x: u16, atlas_y: u16, width: u16, height: u16, bearing_x: i16, bearing_y: i16, advance: u16, }; pub const TextRenderer = struct { atlas: *FontAtlas, pub fn measureText(self: *TextRenderer, text: []const u8, size: u16) struct { width: u32, height: u32 }; pub fn renderText(self: *TextRenderer, fb: *Framebuffer, x: i32, y: i32, text: []const u8, size: u16, color: Color) void; pub fn renderTextWrapped(self: *TextRenderer, fb: *Framebuffer, bounds: Rect, text: []const u8, size: u16, color: Color, align: Alignment) void; }; ``` **Características:** - Font atlas dinámico - Caché de glyphs renderizados - Múltiples tamaños de fuente - Text measurement preciso - Word wrapping correcto - Kerning básico - Subpixel rendering (opcional) **LOC estimadas**: 500 #### 4.4 Rich Text (básico) ```zig pub const TextSpan = struct { text: []const u8, style: TextStyle, }; pub const TextStyle = struct { color: ?Color = null, bold: bool = false, italic: bool = false, underline: bool = false, strikethrough: bool = false, size: ?u16 = null, link: ?[]const u8 = null, }; pub fn richText(ctx: *Context, bounds: Rect, spans: []const TextSpan) void; pub fn richTextInteractive(ctx: *Context, bounds: Rect, spans: []const TextSpan) ?[]const u8; // Returns clicked link ``` **Características:** - Múltiples estilos en un texto - Bold, italic, underline - Links clickables - Colores por span - Tamaños mixtos **LOC estimadas**: 300 **Entregables Fase 4:** - [ ] Editor multilinea completo - [ ] NumberEntry con validación - [ ] Font Atlas funcionando - [ ] Rich Text básico - [ ] Clipboard integration - [ ] Tests de texto - [ ] Demo de editores --- ### FASE 5: SISTEMA DE ICONOS Y GRÁFICOS **Duración estimada**: 1 semana **Objetivo**: Iconos vectoriales y gráficos básicos #### 5.1 Icon System ```zig pub const IconSet = enum { material, // Material Design icons feather, // Feather icons custom, // User-defined }; pub const Icon = struct { data: []const u8, // Path data o bitmap width: u16, height: u16, pub fn render(self: Icon, fb: *Framebuffer, x: i32, y: i32, size: u16, color: Color) void; }; pub const IconLibrary = struct { icons: std.StringHashMap(Icon), pub fn get(self: *IconLibrary, name: []const u8) ?Icon; pub fn loadFromSvg(self: *IconLibrary, name: []const u8, svg_data: []const u8) !void; }; // Built-in icons pub const icons = struct { pub const check: Icon = ...; pub const close: Icon = ...; pub const arrow_left: Icon = ...; pub const arrow_right: Icon = ...; pub const arrow_up: Icon = ...; pub const arrow_down: Icon = ...; pub const menu: Icon = ...; pub const search: Icon = ...; pub const settings: Icon = ...; pub const user: Icon = ...; pub const folder: Icon = ...; pub const file: Icon = ...; pub const edit: Icon = ...; pub const delete: Icon = ...; pub const add: Icon = ...; pub const remove: Icon = ...; // ... 50+ iconos básicos }; ``` **LOC estimadas**: 400 #### 5.2 Canvas/Drawing Primitives ```zig pub const Canvas = struct { fb: *Framebuffer, clip: Rect, transform: Transform, // Primitivas básicas pub fn drawLine(self: *Canvas, x1: i32, y1: i32, x2: i32, y2: i32, color: Color, thickness: u8) void; pub fn drawRect(self: *Canvas, rect: Rect, color: Color) void; pub fn drawRectOutline(self: *Canvas, rect: Rect, color: Color, thickness: u8) void; pub fn drawRoundedRect(self: *Canvas, rect: Rect, radius: u8, color: Color) void; pub fn drawCircle(self: *Canvas, cx: i32, cy: i32, radius: u16, color: Color) void; pub fn drawCircleOutline(self: *Canvas, cx: i32, cy: i32, radius: u16, color: Color, thickness: u8) void; pub fn drawArc(self: *Canvas, cx: i32, cy: i32, radius: u16, start_angle: f32, end_angle: f32, color: Color) void; pub fn drawPolygon(self: *Canvas, points: []const Point, color: Color) void; // Path-based drawing pub fn beginPath(self: *Canvas) void; pub fn moveTo(self: *Canvas, x: i32, y: i32) void; pub fn lineTo(self: *Canvas, x: i32, y: i32) void; pub fn quadraticTo(self: *Canvas, cx: i32, cy: i32, x: i32, y: i32) void; pub fn closePath(self: *Canvas) void; pub fn fill(self: *Canvas, color: Color) void; pub fn stroke(self: *Canvas, color: Color, thickness: u8) void; }; ``` **LOC estimadas**: 500 #### 5.3 Charts (básicos) ```zig pub const ChartType = enum { line, bar, pie, donut }; pub const ChartData = struct { labels: []const []const u8, series: []const Series, }; pub const Series = struct { name: []const u8, values: []const f64, color: Color, }; pub const ChartConfig = struct { chart_type: ChartType, show_legend: bool = true, show_grid: bool = true, show_values: bool = false, animated: bool = true, }; pub fn chart(ctx: *Context, bounds: Rect, data: ChartData, config: ChartConfig) void; pub fn lineChart(ctx: *Context, bounds: Rect, data: ChartData) void; pub fn barChart(ctx: *Context, bounds: Rect, data: ChartData) void; pub fn pieChart(ctx: *Context, bounds: Rect, data: ChartData) void; ``` **LOC estimadas**: 400 **Entregables Fase 5:** - [ ] 50+ iconos built-in - [ ] Canvas con primitivas - [ ] Rounded rectangles - [ ] Charts básicos (line, bar, pie) - [ ] Documentación de iconos - [ ] Demo de gráficos --- ### FASE 6: INPUT AVANZADO **Duración estimada**: 1 semana **Objetivo**: Clipboard, drag & drop, gestures #### 6.1 Clipboard Integration ```zig pub const Clipboard = struct { pub fn getText(allocator: Allocator) !?[]u8; pub fn setText(text: []const u8) !void; pub fn hasText() bool; pub fn clear() void; // Formatos adicionales (futuro) pub fn getImage() ?ImageData; pub fn setImage(data: ImageData) !void; }; ``` **LOC estimadas**: 150 (SDL2 clipboard) #### 6.2 Drag & Drop System ```zig pub const DragData = struct { source_id: u64, data_type: []const u8, data: ?*anyopaque, preview: ?DragPreview, }; pub const DropZone = struct { accepts: []const []const u8, // Tipos aceptados highlight_on_hover: bool, }; pub const DragDropManager = struct { current_drag: ?DragData, drop_zones: std.ArrayList(DropZone), pub fn startDrag(self: *DragDropManager, data: DragData) void; pub fn endDrag(self: *DragDropManager) ?DragData; pub fn isDragging(self: DragDropManager) bool; pub fn registerDropZone(self: *DragDropManager, bounds: Rect, zone: DropZone) void; pub fn getHoveredDropZone(self: DragDropManager) ?*DropZone; }; pub fn draggable(ctx: *Context, bounds: Rect, id: u64, data_type: []const u8) bool; pub fn dropZone(ctx: *Context, bounds: Rect, accepts: []const []const u8) ?DragData; ``` **LOC estimadas**: 300 #### 6.3 Keyboard Shortcuts System ```zig pub const Shortcut = struct { key: Key, modifiers: KeyModifiers, action: []const u8, }; pub const ShortcutManager = struct { shortcuts: std.ArrayList(Shortcut), pub fn register(self: *ShortcutManager, shortcut: Shortcut) void; pub fn unregister(self: *ShortcutManager, action: []const u8) void; pub fn check(self: *ShortcutManager, input: *InputState) ?[]const u8; pub fn getShortcutText(shortcut: Shortcut) []const u8; // "Ctrl+S" }; ``` **LOC estimadas**: 150 #### 6.4 Focus Groups ```zig pub const FocusGroup = struct { id: u64, widgets: [MAX_GROUP_SIZE]u64, count: usize, wrap: bool, pub fn add(self: *FocusGroup, widget_id: u64) void; pub fn focusNext(self: *FocusGroup, current: u64) ?u64; pub fn focusPrev(self: *FocusGroup, current: u64) ?u64; }; pub const FocusManagerEx = struct { current_focus: ?u64, groups: std.AutoHashMap(u64, FocusGroup), pub fn createGroup(self: *FocusManagerEx) u64; pub fn addToGroup(self: *FocusManagerEx, group_id: u64, widget_id: u64) void; pub fn handleNavigation(self: *FocusManagerEx, input: *InputState) void; }; ``` **LOC estimadas**: 200 **Entregables Fase 6:** - [ ] Clipboard texto funcionando - [ ] Drag & drop básico - [ ] Sistema de shortcuts - [ ] Focus groups - [ ] Tests de input - [ ] Demo de drag & drop --- ### FASE 7: RENDERIZADO AVANZADO **Duración estimada**: 2 semanas **Objetivo**: Anti-aliasing, efectos visuales, rendimiento #### 7.1 Anti-aliasing ```zig pub const AAMode = enum { none, // Sin AA fast, // 2x supersampling quality, // 4x supersampling }; pub const AARenderer = struct { mode: AAMode, pub fn drawLineAA(self: *AARenderer, fb: *Framebuffer, x1: f32, y1: f32, x2: f32, y2: f32, color: Color) void; pub fn drawCircleAA(self: *AARenderer, fb: *Framebuffer, cx: f32, cy: f32, radius: f32, color: Color) void; }; ``` **LOC estimadas**: 300 #### 7.2 Efectos Visuales ```zig pub const Effect = union(enum) { shadow: ShadowEffect, blur: BlurEffect, gradient: GradientEffect, opacity: f32, }; pub const ShadowEffect = struct { offset_x: i8, offset_y: i8, blur_radius: u8, color: Color, }; pub const GradientEffect = struct { start_color: Color, end_color: Color, direction: GradientDirection, }; pub fn applyShadow(fb: *Framebuffer, rect: Rect, shadow: ShadowEffect) void; pub fn applyGradient(fb: *Framebuffer, rect: Rect, gradient: GradientEffect) void; pub fn applyBlur(fb: *Framebuffer, rect: Rect, radius: u8) void; ``` **LOC estimadas**: 400 #### 7.3 Animaciones ```zig pub const EasingFn = *const fn(f32) f32; pub const Easing = struct { pub fn linear(t: f32) f32; pub fn easeInQuad(t: f32) f32; pub fn easeOutQuad(t: f32) f32; pub fn easeInOutQuad(t: f32) f32; pub fn easeInCubic(t: f32) f32; pub fn easeOutCubic(t: f32) f32; pub fn easeInOutCubic(t: f32) f32; pub fn easeInElastic(t: f32) f32; pub fn easeOutElastic(t: f32) f32; pub fn easeInBounce(t: f32) f32; pub fn easeOutBounce(t: f32) f32; }; pub const Animation = struct { start_value: f32, end_value: f32, duration_ms: u32, easing: EasingFn, start_time: i64, pub fn getValue(self: Animation, current_time: i64) f32; pub fn isComplete(self: Animation, current_time: i64) bool; }; pub const AnimationManager = struct { animations: std.AutoHashMap(u64, Animation), pub fn start(self: *AnimationManager, id: u64, anim: Animation) void; pub fn stop(self: *AnimationManager, id: u64) void; pub fn getValue(self: *AnimationManager, id: u64) ?f32; pub fn update(self: *AnimationManager, current_time: i64) void; }; ``` **LOC estimadas**: 300 #### 7.4 Virtual Scrolling ```zig pub const VirtualScroller = struct { total_items: usize, item_height: u16, viewport_height: u32, scroll_offset: i32, pub fn getVisibleRange(self: VirtualScroller) struct { start: usize, end: usize }; pub fn getItemY(self: VirtualScroller, index: usize) i32; pub fn scrollToItem(self: *VirtualScroller, index: usize) void; pub fn handleScroll(self: *VirtualScroller, delta: i32) void; }; ``` **LOC estimadas**: 150 #### 7.5 GPU Renderer (Opcional) ```zig pub const GpuBackend = enum { opengl, vulkan, metal, d3d11 }; pub const GpuRenderer = struct { backend: GpuBackend, pub fn init(backend: GpuBackend) !GpuRenderer; pub fn deinit(self: *GpuRenderer) void; pub fn beginFrame(self: *GpuRenderer) void; pub fn endFrame(self: *GpuRenderer) void; pub fn execute(self: *GpuRenderer, commands: []const DrawCommand) void; }; ``` **LOC estimadas**: 800 (solo OpenGL básico) **Entregables Fase 7:** - [ ] Anti-aliasing para líneas y círculos - [ ] Sombras (drop shadow) - [ ] Gradientes lineales - [ ] Sistema de animaciones con easing - [ ] Virtual scrolling para listas - [ ] GPU renderer básico (opcional) - [ ] Benchmarks de rendimiento --- ### FASE 8: ACCESIBILIDAD Y TESTING **Duración estimada**: 1 semana **Objetivo**: Accesibilidad, testing automatizado, documentación #### 8.1 Accesibilidad ```zig pub const AccessibilityRole = enum { button, checkbox, radio, slider, textbox, listbox, tree, menu, dialog, // ... }; pub const AccessibilityInfo = struct { role: AccessibilityRole, label: []const u8, description: ?[]const u8, value: ?[]const u8, state: AccessibilityState, }; pub const AccessibilityState = packed struct { disabled: bool = false, expanded: bool = false, selected: bool = false, checked: bool = false, focused: bool = false, }; // Cada widget expone su info de accesibilidad pub fn getAccessibilityInfo(widget_id: u64) ?AccessibilityInfo; ``` **LOC estimadas**: 200 #### 8.2 Testing Framework ```zig pub const TestRunner = struct { ctx: *Context, input: *InputState, pub fn click(self: *TestRunner, x: i32, y: i32) void; pub fn typeText(self: *TestRunner, text: []const u8) void; pub fn pressKey(self: *TestRunner, key: Key, modifiers: KeyModifiers) void; pub fn waitFrames(self: *TestRunner, count: u32) void; pub fn findWidget(self: *TestRunner, label: []const u8) ?WidgetInfo; pub fn assertVisible(self: *TestRunner, label: []const u8) !void; pub fn assertText(self: *TestRunner, label: []const u8, expected: []const u8) !void; pub fn assertEnabled(self: *TestRunner, label: []const u8) !void; }; pub const SnapshotTest = struct { pub fn capture(fb: *Framebuffer, name: []const u8) !void; pub fn compare(fb: *Framebuffer, name: []const u8) !bool; }; ``` **LOC estimadas**: 400 #### 8.3 Documentación - API Reference generada automáticamente - Ejemplos para cada widget - Tutorial de inicio rápido - Guía de arquitectura - Guía de contribución **Entregables Fase 8:** - [ ] Roles de accesibilidad para todos los widgets - [ ] Framework de testing - [ ] Snapshot testing - [ ] Documentación completa - [ ] 10+ ejemplos funcionando --- ### FASE 9: INTEGRACIÓN Y POLISH **Duración estimada**: 1 semana **Objetivo**: Integración final, pulido, release #### 9.1 Integración Completa - Verificar que todos los widgets funcionan juntos - Verificar rendimiento con UI compleja - Verificar uso de memoria en escenarios reales - Verificar funcionamiento SSH/X11 #### 9.2 Polish - Revisar API consistency - Optimizar hot paths - Eliminar código muerto - Reducir allocaciones innecesarias #### 9.3 Release Preparation - Versión 1.0.0 - Changelog completo - Package en zig package manager - Anuncio **Entregables Fase 9:** - [ ] Integración completa verificada - [ ] Rendimiento optimizado - [ ] 0 warnings, 0 leaks - [ ] v1.0.0 release - [ ] Documentación publicada --- ### FASE 10: MOBILE & WEB BACKENDS ✅ COMPLETADA **Fecha completada**: 2025-12-09 **Objetivo**: Soporte multiplataforma - Web (WASM), Android, iOS #### 10.1 WASM Backend (Navegador) ✅ | Componente | Archivo | Estado | |------------|---------|--------| | Backend Zig | `src/backend/wasm.zig` | ✅ Completo | | Glue JS | `web/zcatgui.js` | ✅ Completo | | Demo HTML | `web/index.html` | ✅ Completo | | Ejemplo | `examples/wasm_demo.zig` | ✅ Completo | **Características:** - Compilación a WebAssembly (wasm32-freestanding) - Canvas 2D API para rendering - Event queue para teclado/ratón/touch - Funciona en cualquier navegador moderno - ~18KB de tamaño compilado **Build:** `zig build wasm` #### 10.2 Android Backend ✅ | Componente | Archivo | Estado | |------------|---------|--------| | Backend Zig | `src/backend/android.zig` | ✅ Completo | | Ejemplo | `examples/android_demo.zig` | ✅ Completo | **Características:** - ANativeActivity para lifecycle - ANativeWindow para rendering directo - AInputQueue para eventos touch/key - Touch → Mouse mapping - Back button → Quit event - Soporte ARM64 y x86_64 (emulador) **Build:** `zig build android` (ARM64) o `zig build android-x86` **Requisitos:** Android NDK #### 10.3 iOS Backend ✅ | Componente | Archivo | Estado | |------------|---------|--------| | Backend Zig | `src/backend/ios.zig` | ✅ Completo | | Bridge Header | `ios/ZcatguiBridge.h` | ✅ Completo | | Bridge Impl | `ios/ZcatguiBridge.m` | ✅ Completo | **Características:** - UIView custom para rendering - CGBitmapContext para framebuffer - Touch events mapping - CADisplayLink para render loop - Soporte device y simulator **Build:** `zig build ios` (device) o `zig build ios-sim` (simulator) **Requisitos:** macOS con Xcode #### 10.4 Arquitectura Multi-backend ``` src/zcatgui.zig ├── backend.Sdl2Backend (desktop: Linux/Win/Mac) ├── backend.wasm (navegador: WASM) ├── backend.android (Android) └── backend.ios (iOS) Compilación condicional basada en: - builtin.cpu.arch (wasm32/wasm64) - builtin.os.tag (ios, linux) - builtin.abi (android) ``` **Entregables Fase 10:** - [x] WASM backend completo y funcional - [x] Android backend completo (requiere NDK) - [x] iOS backend completo (requiere Xcode) - [x] Build targets en build.zig - [x] Documentación en `docs/MOBILE_WEB_BACKENDS.md` - [x] Compilación condicional correcta **Impacto:** - zcatgui ahora soporta 5 plataformas: Linux, Windows, macOS, Web, Android, iOS - Código de aplicación idéntico en todas las plataformas - Software rendering funciona en todos los backends --- ## 5. DETALLES DE IMPLEMENTACIÓN ### 5.1 Estructura Final de Archivos ``` zcatgui/ ├── src/ │ ├── zcatgui.zig # Entry point │ │ │ ├── core/ │ │ ├── context.zig # Context + Arena │ │ ├── layout.zig # Constraints │ │ ├── style.zig # Colors, Themes │ │ ├── input.zig # Input state │ │ ├── command.zig # Draw commands │ │ └── animation.zig # Animation system │ │ │ ├── widgets/ │ │ ├── basic/ │ │ │ ├── label.zig │ │ │ ├── button.zig │ │ │ ├── checkbox.zig │ │ │ ├── radio.zig │ │ │ └── slider.zig │ │ ├── input/ │ │ │ ├── text_input.zig │ │ │ ├── number_entry.zig │ │ │ ├── editor.zig # Multiline │ │ │ ├── select.zig │ │ │ └── autocomplete.zig │ │ ├── data/ │ │ │ ├── list.zig │ │ │ ├── table.zig │ │ │ ├── tree.zig │ │ │ └── reorderable.zig │ │ ├── navigation/ │ │ │ ├── menu.zig │ │ │ ├── tabs.zig │ │ │ └── breadcrumb.zig │ │ ├── container/ │ │ │ ├── panel.zig │ │ │ ├── split.zig │ │ │ ├── modal.zig │ │ │ └── scroll.zig │ │ ├── feedback/ │ │ │ ├── tooltip.zig │ │ │ ├── progress.zig │ │ │ ├── toast.zig │ │ │ └── spinner.zig │ │ ├── special/ │ │ │ ├── image.zig │ │ │ ├── color_picker.zig │ │ │ ├── date_picker.zig │ │ │ └── chart.zig │ │ ├── focus.zig │ │ └── widgets.zig # Re-exports │ │ │ ├── panels/ │ │ ├── panel.zig │ │ ├── composite.zig │ │ ├── data_manager.zig │ │ └── panels.zig │ │ │ ├── render/ │ │ ├── framebuffer.zig │ │ ├── software.zig │ │ ├── gpu.zig # Optional GPU │ │ ├── font.zig │ │ ├── font_atlas.zig │ │ ├── ttf.zig │ │ ├── canvas.zig │ │ ├── effects.zig │ │ └── aa.zig # Anti-aliasing │ │ │ ├── backend/ │ │ ├── backend.zig │ │ ├── sdl2.zig │ │ └── clipboard.zig │ │ │ ├── macro/ │ │ └── macro.zig │ │ │ ├── icons/ │ │ ├── icons.zig │ │ └── material.zig │ │ │ └── utils/ │ ├── pool.zig # Object pools │ ├── arena.zig # Arena allocator │ └── virtual_scroll.zig │ ├── examples/ │ ├── hello.zig │ ├── widgets_demo.zig │ ├── table_demo.zig │ ├── editor_demo.zig │ ├── tree_demo.zig │ ├── charts_demo.zig │ └── full_app_demo.zig │ ├── tests/ │ ├── core_tests.zig │ ├── widget_tests.zig │ ├── render_tests.zig │ └── integration_tests.zig │ ├── docs/ │ ├── ARCHITECTURE.md │ ├── DEVELOPMENT_PLAN.md │ ├── API_REFERENCE.md │ ├── TUTORIAL.md │ └── research/ │ ├── build.zig ├── build.zig.zon ├── CLAUDE.md └── README.md ``` ### 5.2 Estimación Total de LOC | Módulo | LOC Actual | LOC Final Est. | |--------|:----------:|:--------------:| | Core | 1,700 | 2,500 | | Render | 1,300 | 3,000 | | Backend | 400 | 600 | | Macro | 340 | 400 | | Widgets | 8,000 | 12,000 | | Panels | 350 | 500 | | Icons | 0 | 500 | | Utils | 0 | 500 | | Tests | 500 | 2,000 | | **TOTAL** | **12,590** | **~22,000** | --- ## 6. MÉTRICAS DE CALIDAD ### 6.1 Performance Benchmarks | Operación | Target | |-----------|--------| | Widget simple (button) | <50μs | | Widget complejo (table 100 rows) | <500μs | | Full frame (50 widgets) | <5ms | | Text rendering (1000 chars) | <1ms | | Command execution (1000 cmds) | <2ms | ### 6.2 Memory Benchmarks | Escenario | Target | |-----------|--------| | Startup (empty) | <5MB | | 100 widgets | <15MB | | 1000 widgets | <50MB | | Table 10K rows | <100MB | ### 6.3 Code Quality | Métrica | Target | |---------|--------| | Test coverage | >90% | | Functions >50 LOC | 0 | | Cyclomatic complexity | <10 | | Duplicate code | <5% | | TODO/FIXME | 0 (at release) | --- ## 7. CHECKLIST FINAL ### Pre-Release Checklist - ✅ COMPLETADO v0.14.0 #### Core - [x] Arena allocator implementado (FrameArena) - [x] Object pooling funcionando (ObjectPool, CommandPool) - [x] Dirty rectangles optimizado - [x] 0 memory leaks #### Widgets (35 total) - ✅ TODOS COMPLETADOS - [x] Label - [x] Button - [x] Checkbox - [x] Radio - [x] Slider - [x] TextInput - [x] NumberEntry - [x] TextArea (multiline editor) - [x] Select - [x] AutoComplete - [x] List - [x] Table - [x] Tree - [x] ReorderableList - [x] Menu - [x] Tabs - [x] Breadcrumb - [x] Panel - [x] Split - [x] Modal - [x] Scroll - [x] Tooltip - [x] Progress (bar, circle, spinner) - [x] Toast - [x] Image - [x] ColorPicker - [x] DatePicker - [x] Chart (line, bar, pie) - [x] Focus - [x] Canvas - [x] Icon (60+ icons) - [x] RichText - [x] Badge/TagGroup - [x] VirtualScroll #### Rendering - [x] TTF Font support (stb_truetype) - [x] Anti-aliasing (Xiaolin Wu lines, circles, ellipses) - [x] Shadows (soft, hard, blur) - [x] Gradients (horizontal, vertical, diagonal, radial) - [x] Virtual scrolling - [ ] GPU renderer (opcional - no implementado, software-first design) #### Input - [x] Clipboard (SDL2 integration) - [x] Drag & Drop (DragDropManager) - [x] Shortcuts system (ShortcutManager) - [x] Focus groups (FocusGroupManager) #### Sistema - [x] Animations (20+ easing functions, AnimationManager) - [x] Accessibility info (roles, states, announcements) - [x] Testing framework (TestRunner, Assertions) - [x] Snapshot tests (SnapshotTester) #### Documentación - [x] CLAUDE.md (project guide) - [x] DEVELOPMENT_PLAN.md (this file) - [x] ARCHITECTURE.md - [x] Research docs (WIDGET_COMPARISON, etc.) - [ ] API Reference (auto-generated - pending) - [ ] Tutorial (pending) #### Calidad - [x] 274 tests pasando - [x] 0 warnings - [x] 0 memory leaks - [x] Performance targets met - [x] Memory targets met --- ## RESUMEN | Fase | Duración | Widgets | LOC | |------|:--------:|:-------:|:---:| | 1. Fundamentos | 1 sem | 0 | +1,500 | | 2. Feedback | 1 sem | +4 | +750 | | 3. Especializados | 2 sem | +5 | +1,800 | | 4. Texto | 2 sem | +2 | +1,650 | | 5. Iconos/Gráficos | 1 sem | +4 | +1,300 | | 6. Input | 1 sem | 0 | +800 | | 7. Render | 2 sem | 0 | +1,950 | | 8. Testing | 1 sem | 0 | +600 | | 9. Polish | 1 sem | 0 | +100 | | **TOTAL** | **12 sem** | **+18** | **+10,450** | **Resultado final:** - **35 widgets** (paridad DVUI) - **~22,000 LOC** (eficiente) - **Performance óptimo** (60fps, <16ms latencia) - **Memoria mínima** (<50MB típico) - **Código perfecto** (0 warnings, 0 leaks, 90%+ coverage) --- > **Nota**: Este plan prioriza calidad sobre velocidad. Cada fase debe completarse con todos los tests pasando y métricas cumplidas antes de avanzar a la siguiente.