El clip se aplicaba solo al área de contenido (excluyendo header),
lo que permitía que el texto de los headers se extendiera fuera
de los límites de la tabla.
Ahora el clip abarca toda la tabla (bounds completos) antes de
dibujar headers y contenido.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Table clipping:
- Add clip region around table content area
- Prevents cell text from drawing outside table bounds
- Header and scrollbar render outside clip region
Cursor animation API:
- Add CURSOR_IDLE_TIMEOUT_MS (5s) and CURSOR_BLINK_PERIOD_MS (500ms) constants
- Add needsCursorAnimation() to check if cursor should blink
- Add getAnimationTimeout() for dynamic event loop timeout
- Update TextInput to use constants from Context
The application can now query ctx.getAnimationTimeout() to determine
if a short timeout is needed for cursor animation, or if it can wait
indefinitely for events.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Split large widget files for better maintainability (~500-600 lines per file):
textarea/ (was 882 lines):
- types.zig: TextAreaConfig, TextAreaColors, TextAreaResult
- state.zig: TextAreaState with cursor/selection methods
- render.zig: drawLineNumber, drawLineText, drawLineSelection
- textarea.zig: Main API with re-exports and tests
progress/ (was 806 lines):
- render.zig: Shared drawing helpers (stripes, gradients, arcs)
- bar.zig: ProgressBar widget
- circle.zig: ProgressCircle widget
- spinner.zig: Spinner widget with animation state
- progress.zig: Main API with re-exports and tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Split the 1770-line table.zig into a cleaner module structure:
src/widgets/table/
├── table.zig (~400 lines) - Public API + re-exports + tests
├── types.zig (~150 lines) - Enums, configs, column definitions
├── state.zig (~500 lines) - TableState, TableResult
├── keyboard.zig (~270 lines) - Keyboard handling, search
└── render.zig (~350 lines) - Drawing functions
Benefits:
- Each file is now manageable (<500 lines)
- Clearer separation of concerns
- Easier to navigate and modify
- Same public API (no breaking changes)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Commit de seguridad antes de dividir table.zig (1770 líneas) en
múltiples archivos más manejables.
Ver docs/TABLE_REFACTORING_PLAN.md para el plan completo.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1: Frame timing in Context
- Added current_time_ms and frame_delta_ms to Context
- Added setFrameTime() method for applications to provide timing
Phase 2: Centralized shortcuts system
- Added StandardShortcut enum with common shortcuts (copy, paste, etc.)
- Added isStandardActive() function for checking shortcuts
- Updated TextInput to use centralized shortcuts
Phase 3: Incremental search in table
- Added search_buffer, search_len, search_last_time to TableState
- Added addSearchChar(), getSearchTerm(), clearSearch() methods
- Typing in focused table searches first column (case-insensitive)
- 1 second timeout resets search buffer
Phase 4: Blinking cursor in TextInput
- Cursor blinks every 500ms when field is focused
- Uses current_time_ms from Context for timing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auditoría comparando con Gio, microui y DVUI identificó 4 problemas:
1. SDL_KEYDOWN y SDL_TEXTINPUT separados
2. Dos arrays para eventos de teclado
3. Sin timing en Context para animaciones
4. Shortcuts duplicados en cada widget
Plan de 4 fases aprobado (~7-11 horas total).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Actualizar FOCUS_TRANSITION_2025-12-11.md con patrón de integración
- Actualizar CLAUDE.md: sección SISTEMA DE FOCUS - RESUELTO
- Widgets adaptados a FocusSystem:
- numberentry.zig: registerFocusable, requestFocus, hasFocus
- textarea.zig: registerFocusable, requestFocus, hasFocus
- select.zig: campo focused, integración completa
- radio.zig: reemplazado focus manual por FocusSystem
- slider.zig: reemplazado focus manual por FocusSystem
- tabs.zig: navegación teclado solo cuando tiene focus
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cambios principales:
- Nuevo FocusSystem unificado en core/focus.zig
- Separación registration_group / active_group para multi-panel
- Focus implícito para primer widget del grupo activo
- Table inicializa selected_row/col a 0 cuando tiene datos
- Corregido test navKeyPressed (usaba setKeyState en vez de handleKeyEvent)
Bug resuelto: tabla no respondía a teclado sin clic previo
Causa: selected_col quedaba en -1, selectedCell() retornaba null
Documentación: docs/FOCUS_TRANSITION_2025-12-11.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PROBLEMA DETECTADO:
- Existían dos sistemas de focus paralelos que no se comunicaban
- FocusManager (widgets/focus.zig) usaba IDs u32
- FocusGroupManager (core/focus_group.zig) usaba IDs u64
- Esto causaba que Tab no funcionara y clics no cambiaran focus
SOLUCIÓN CONSENSUADA:
- Usar SOLO FocusGroupManager como fuente de verdad
- Integrar en Context con métodos públicos
- Widgets se auto-registran en el grupo activo al dibujarse
- Tab navega DENTRO del grupo activo
- F6 (u otro) cambia entre grupos/paneles
CAMBIOS:
- context.zig: Añadidos createFocusGroup(), setActiveFocusGroup(),
hasFocus(), requestFocus(), registerFocusable(), handleTabKey()
- text_input.zig: Usa @intFromPtr para ID único, se auto-registra
- table.zig: Ahora se registra como widget focusable
- widgets.zig/zcatgui.zig: Eliminadas referencias antiguas a FocusManager
- CLAUDE.md: Documentado el trabajo en progreso
ESTADO: EN PROGRESO - Compila pero requiere más testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add mainloop.zig section with feature status
- Note that patterns are tested via zsimifactu manual implementation
- Add to verification history
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add clearRect as verified feature
- Mark fillRect as improved with SIMD @memset
- Add historial entry: render 1.4ms → 1.0ms
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For solid colors (alpha=255), use @memset per row instead of
pixel-by-pixel loop. @memset is SIMD-optimized by the compiler
(uses SSE/AVX on x86-64).
Result: Render time 1.4ms → 1.0ms (28% faster in Release build)
Also cleaner code separation between solid color fast path
and alpha blending slow path.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Framebuffer:
- Add clearRect() for clearing specific rectangular regions
SoftwareRenderer:
- Add executeWithDirtyRegions() for optimized partial rendering
- Add clearRect() convenience method
- Add commandBounds() to extract bounding box from draw commands
- Add rectsIntersect() helper for intersection testing
This enables applications to:
1. Clear only dirty regions instead of full screen
2. Skip rendering commands outside dirty areas
3. Significantly reduce CPU when only small areas change
Usage: Pass dirty_regions from Context.getDirtyRects() to
executeWithDirtyRegions() instead of using clear()+executeAll().
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Mark waitEvent and waitEventTimeout as verified in sdl2.zig
- Add historial entry: CPU 92% → 1.9% with progressive sleep
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add waitEvent() and waitEventTimeout() to Backend abstract interface
- Implement SDL_WaitEvent and SDL_WaitEventTimeout in SDL2 backend
- Refactor translateEvent into shared function
- Optional vtable entries with fallback to pollEvent for compatibility
This enables progressive sleep patterns:
- Phase 1: Short sleep (8ms) for quick response
- Phase 2: Medium sleep (33ms) for moderate idle
- Phase 3: SDL_WaitEventTimeout for 0% CPU in deep idle
Result: CPU 92% → 1.9% in idle applications.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documento que distingue features realmente probadas en producción
vs solo tests unitarios. Incluye:
- 48 widgets con estado de verificación
- Core modules (context, input, layout, style)
- Render modules (framebuffer, font, software)
- Backends (SDL2, WASM, Android, iOS)
Verificado en zsimifactu:
- Table, TextInput, Split, Panel
- Font 8x16 Latin-1, UTF-8 rendering
- SDL2 backend completo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Early out para caracteres completamente fuera del clip
- Fast path para caracteres 100% visibles (caso común)
- Escritura directa al buffer de píxeles sin setPixel
- Loop optimizado para fuentes de 8px de ancho
- Unroll de los 8 bits del glyph byte
Resultados:
- Debug: 40ms → 32ms por frame
- Release: 40ms → 1.5ms por frame (~26x más rápido)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cambio de SDL_RENDERER_SOFTWARE a SDL_RENDERER_ACCELERATED | PRESENTVSYNC:
- VSync sincroniza con el refresco del monitor (~60Hz)
- SDL_RenderPresent() ahora bloquea hasta el próximo frame
- Elimina necesidad de sleep manual en aplicaciones
- CPU de ~70% a ~1-5% en idle
Fallback a software renderer si GPU no disponible.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
El widget TextInput ahora procesa internamente:
- Backspace/Delete: borrar caracteres
- Flechas izq/der: mover cursor
- Home/End: inicio/fin del texto
- Shift+movimiento: selección
- Ctrl+A: seleccionar todo
- Enter: submit
Esto hace que el widget sea auto-contenido y reutilizable,
sin requerir manejo de teclas en la aplicación.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- REFERENCE.md: Nueva sección "UTF-8 Text Rendering" explicando:
- Cómo funciona la decodificación UTF-8 → Latin-1
- Caracteres soportados (ASCII + Latin-1 Supplement)
- Por qué UTF-8 es el estándar correcto para BD/archivos
- Ejemplo de uso con texto español
- software.zig: Doc comments explicando el sistema UTF-8
El renderer ahora maneja texto UTF-8 automáticamente,
permitiendo mostrar correctamente: ñ, á, é, í, ó, ú, ¿, ¡, €, etc.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
El renderer iteraba byte por byte, causando que caracteres UTF-8
multi-byte (como ñ, á, é) se mostraran incorrectamente.
Cambios:
- Decodificación completa de UTF-8 (1-4 bytes)
- Mapeo de codepoints a Latin-1 para renderizado
- Caracteres fuera de Latin-1 se muestran como '?'
Esto permite mostrar correctamente texto en español y otros
idiomas europeos que usan caracteres Latin-1.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- build.zig.zon: .name = .zcatgui (enum literal, no string)
- examples/widgets_demo.zig: Añadido try en Context.init
- examples/table_demo.zig: Añadido try en Context.init
- ZIG_VERSION_NOTES.md: Referencia a sistema notas versiones
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add REFERENCE.md to documentation protocol (Step 3)
- Update widget count to 37
- Update LOC to ~35K
- Add REFERENCE.md to file structure
- Remove obsolete roadmap sections (now in DEVELOPMENT_PLAN.md)
- Simplify documentation section with table
- Clean up references section
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Project overview and features
- Quick start example
- Full widget list (35 widgets)
- Unique features documentation (Macros, Lego Panels, Table)
- Theme system
- Performance utilities
- Build instructions
- Comparison with DVUI/Dear ImGui
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated DEVELOPMENT_PLAN.md checklist:
- All 35 widgets marked complete
- All 9 development phases complete
- 274+ tests passing
- Ready for v1.0.0 release
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New Core Modules (4):
Clipboard - System clipboard integration
- getText()/setText() via SDL2 clipboard API
- hasText() and clear() utilities
- Cross-platform support
DragDrop - Drag and drop system
- DragData with typed data transfer
- DropZone registration with type filtering
- DragDropManager for coordinating operations
- Hover detection and drop results
- Helper functions: makeDraggable(), makeDropZone()
Shortcuts - Keyboard shortcuts system
- Shortcut struct with key + modifiers
- ShortcutManager for registration and checking
- Common shortcuts (Ctrl+C/V/X/Z, etc.)
- Human-readable formatting (formatShortcut)
- Enable/disable individual shortcuts
FocusGroup - Focus group management
- FocusGroup for widget tab order
- focusNext/Previous with wrap support
- FocusGroupManager for multiple groups
- Group switching (focusNextGroup)
- Tab/Shift+Tab navigation
All tests passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New Widgets:
- TextArea: Multi-line text editor with cursor navigation,
line numbers, selection, and scrolling support
- Tree: Hierarchical tree view with expand/collapse,
keyboard navigation, and selection
- Badge: Status labels with variants (primary, success,
warning, danger, info, outline), dismissible option
- TagGroup: Multiple badges in a row with wrapping
From previous session (v0.7.0):
- Progress: Bar (solid, striped, gradient, segmented),
Circle, Spinner (circular, dots, bars, ring)
- Tooltip: Hover tooltips with smart positioning
- Toast: Non-blocking notifications with auto-dismiss
Widget count: 23 widgets
Test count: 163 tests passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New Widgets (3):
- Progress: Bar, Circle, Spinner with multiple styles
- Bar styles: solid, striped, gradient, segmented
- Spinner styles: circular, dots, bars, ring
- Animated spinners with configurable speed
- Tooltip: Hover tooltips with smart positioning
- Auto-position to stay within screen bounds
- Arrow pointing to target element
- Multi-line text support with wrapping
- Configurable delay and styling
- Toast: Non-blocking notifications
- Types: info, success, warning, error
- Configurable position (6 positions)
- Auto-dismiss with countdown
- Action buttons support
- Stack multiple toasts
Widget count: 20 widgets
Test count: 140 tests passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply TEAM_STANDARDS Norma #25: project names use lowercase
everywhere - repo, directory, module, documentation, imports.
No CamelCase in project names. Consistency = less cognitive friction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>