Arquitectura diseñada por Gemini:
- TODA la lógica de decisión en table_core.zig
- Widgets solo pasan eventos y reaccionan a flags
- Cualquier tabla nueva hereda automáticamente
Cambios:
- TableEventResult: struct con TODOS los flags de acciones
- processTableEvents(): función maestra que procesa teclado
- Soporta: navegación, CRUD (Ctrl+N/B/Del), ordenación (Ctrl+Shift+1-9), edición
- VirtualAdvancedTable refactorizado al patrón Brain-in-Core
- Nuevos campos result: insert_row_requested, delete_row_requested, sort_column_index
- Añadido dirty_row_id: ?i64 a DrawRowsConfig
- drawRowsWithDataSource aplica blendColor(state_modified, 0.25) si dirty
- VirtualAdvancedTable pasa row_edit_buffer.row_id cuando has_changes
- Añadido VerticalScrollbarParams y drawVerticalScrollbar
- Añadido HorizontalScrollbarParams y drawHorizontalScrollbar
- AdvancedTable y VirtualAdvancedTable ahora usan funciones unificadas
- Elimina duplicación de código de renderizado de scrollbars
- Añadir RowState enum a table_core.zig
- Añadir getRowState a TableDataSource.VTable (opcional)
- Añadir colores de estado a RowRenderColors
- Añadir draw_row_borders a DrawRowsConfig
- Añadir getRowState a MemoryDataSource
- Nueva función handleRowClicks() separando input de rendering
- AdvancedTable usa drawRowsWithDataSource (sin bucle for propio)
- Eliminar drawRow() y drawStateIndicator() locales (~160 líneas)
Objetivo cumplido: un solo bloque de código para renderizar filas
Add unified row rendering function to table_core.zig that uses
TableDataSource interface for data access.
Changes:
- Add ColumnRenderDef, RowRenderColors, DrawRowsConfig types
- Add drawRowsWithDataSource() unified rendering function
- Update VirtualAdvancedTable.drawRows to use unified function
with PagedDataSource
Note: AdvancedTable not yet integrated due to additional complexity
(state indicators, click handling interleaved with drawing).
See PLAN_REFACTOR_TABLES_CONTINUIDAD.md for details.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add MemoryDataSource for AdvancedTable (in-memory ArrayList) and
PagedDataSource for VirtualAdvancedTable (paged DB data).
Both implement TableDataSource interface from table_core.zig,
enabling unified rendering patterns while respecting memory ownership.
New files:
- advanced_table/datasource.zig - MemoryDataSource
- virtual_advanced_table/paged_datasource.zig - PagedDataSource
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- TableDataSource: vtable interface for data abstraction
- getCellValueInto: buffer-based pattern to avoid memory issues
- getRowCount, getRowId: basic data access methods
- isCellEditable, invalidate: optional methods
- makeTableDataSource: helper to create from concrete types
- isGhostRow: convenience method for new row detection
This interface enables unified rendering for both memory and
paginated tables while enforcing safe memory patterns.
FASE 2 del refactor de tablas:
- AdvancedTableState: Embed cell_edit, delegate editing methods
- VirtualAdvancedTableState: Embed cell_edit, replace editing_cell/edit_buffer
- Update advanced_table.zig to use isEditing() and cell_edit.*
- Update virtual_advanced_table.zig to use getEditingCell()
- Update cell_editor.zig to use cell_edit.*
Reduces code duplication, centralizes editing logic in table_core
- Check navigate_direction before setting tab_out in handleKeyboard
- Export NavigateDirection from virtual_advanced_table module
- Use cell_editor.NavigateDirection in VirtualAdvancedTableResult
This fixes the bug where Tab was processed twice: once by CellEditor
(for cell navigation) and again by handleKeyboard (for tab_out).
- Import and use table_core for keyboard handling
- Re-export NavigateDirection from table_core
- Map table_core.EditKeyboardResult to CellEditorResult
- Remove ~100 lines of duplicated keyboard handling code
- Add 'handled' field to CellEditorResult
- Add NavigateDirection enum (none, next_cell, prev_cell, next_row, prev_row)
- Replace navigate_next/navigate_prev bools with single navigate field
- Add 'handled' flag to prevent double processing of Tab
- Add Up/Down arrow handling for row navigation
- Use getKeyEvents() loop instead of keyPressed() for consistency
Norma #6: Abstract to library level
- Tab navigation with wrap now in library, not application
- AdvancedTableState.tabToNextCell/tabToPrevCell for in-memory data
- VirtualAdvancedTableState.tabToNextCell/tabToPrevCell for paginated data
- DRY: same logic available in both table widgets
- Tab/Shift+Tab with wrap navigation in editing mode
- tab_out/tab_shift result fields for application handling
- Cursor position, blinking, background color fixes
- markRowSaved() to clear dirty state after save
- last_edited_row only set when actual changes made
- New module: table_core.zig with common table rendering logic
- drawCellActiveIndicator(): visual indicator for selected cell
- detectDoubleClick(): timing-based double-click detection
- handleEditingKeyboard(): common keyboard handling for editing
- blendColor(), startsWithIgnoreCase(): utilities
VirtualAdvancedTable now uses table_core:
- Active cell indicator in drawRows (visible highlight on selected cell)
- Double-click detection in handleMouseClick
- Added state fields: last_click_time, last_click_row, last_click_col
AdvancedTable changes:
- Improved cell active indicator (alpha 0.35, double border)
- Added double-click fields to state
- Space starts editing with empty value
- Alphanumeric keys start editing in editable cells
- Replace manual temp variable swap with std.mem.swap (more explicit)
- Add documentation warning about pointer invalidation after sort/setRows
- Row contains StringHashMap with internal pointers - swap is safe but
pointers obtained via getRow() are invalidated after mutations
Based on INFORME_AUDITORIA_PROFUNDA_20251225.md §1.2
- Added footer_display_buf and footer_display_len to VirtualListState
- Fixes use-after-return bug: stack buffer passed to pushCommand() was
invalidated when function returned, causing corrupted display in
deferred rendering
- FilterBar chips con forma pill (border-radius completo)
- Esquinas redondeadas en TextInput del filtro
- Fix click offset: ahora cuenta filter_bar_h + header_h
- Corrección selección de fila por click
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Añadir borde alrededor de toda la lista (siempre visible)
- Mejorar centrado vertical del texto (y+4 → y+3)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- moveUp: Calcular screen position para scroll correcto
- footer_h: Reducir de 20 a 16 pixels para más filas visibles
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- moveDown: Calcular screen position antes de decidir scroll
- Scroll ahora ocurre cuando llega a última fila visible (no penúltima)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- drawRows: Calcular window_offset para dibujar desde scroll_offset
- handleMouseClick: Convertir screen_row a data_idx con offset
- Antes siempre dibujaba desde índice 0 del buffer
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cambiar de keyPressed() a navKeyPressed() permite que mantener
pulsada la flecha arriba/abajo mueva la selección continuamente.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- VirtualListConfig.Colors ahora usa Style.Color en vez de u32
- Reemplazar Command.fill() por Command.rect() (fill no existe)
- Corregir tipo bg_color en drawRows
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Nuevo módulo virtual_list para listas virtualizadas:
types.zig:
- RowData: datos genéricos de fila con ID persistente
- ColumnDef: definición de columnas (name, title, width)
- SortDirection: enum con toggle()
- CountInfo: conteo con estado (loading, partial, ready)
- VirtualListConfig: configuración con umbral configurable
data_provider.zig:
- DataProvider: interface vtable para fuentes de datos
- Métodos: fetchWindow, getTotalCount, setFilter, setSort
- MockProvider para tests
- Tests completos
state.zig:
- VirtualListState: estado de navegación y selección
- Selección por ID (no índice)
- Conversión global ↔ window index
- Navegación: moveUp/Down, pageUp/Down, goToStart/End
- Tests completos
virtual_list.zig:
- Re-exports de módulos
- Documentación de arquitectura
- VirtualListResult struct
- TODO: widget principal (Fase 3)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- CellValue.clone(): duplica strings en lugar de copiar punteros
- CellValue.deinit(): libera strings clonados
- Row.owns_data: flag para indicar propiedad de memoria
- Row.clone(): ahora hace deep copy completo
- Row.deinit(): libera strings si owns_data=true
Soluciona crash al guardar cliente sin población/provincia/país,
donde loadWhoList() liberaba strings que Row clonada seguía referenciando.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
OVERLAY SYSTEM:
- Context: nuevo campo overlay_commands para capa superior
- Context: nueva función pushOverlayCommand()
- mainloop: renderiza overlay_commands DESPUÉS de commands
- autocomplete: dropdown usa overlay (se dibuja encima de otros widgets)
MEJORAS AUTOCOMPLETE:
- Dropdown se abre inmediatamente al escribir (sin delay de 1 frame)
- Dropdown se abre al borrar con backspace/delete
- Click en flecha del dropdown hace toggle abrir/cerrar
- Área clicable de flecha: 20px
ESTADO: En progreso - funcionalidad básica operativa, pendiente:
- Keyboard handlers completos
- Más testing de casos edge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Altura del cursor: inner.h (toda la altura del campo, no 8px fijos)
- Posición Y: inner.y (no centrado en el texto)
- Parpadeo: usa CURSOR_BLINK_PERIOD_MS y CURSOR_IDLE_TIMEOUT_MS
- Lógica idéntica a TextInput para consistencia visual
Cambios de Gemini para estabilidad IMGUI:
- setText(): Sincroniza last_filter para evitar falsos text_changed
- clear(): Resetea last_filter_len
- autocompleteRect(): Cierra dropdown si options.len == 0
Parte de la solución para corrupción de memoria en cascade AutoComplete.
Eliminados std.debug.print con números mágicos 99999 y debug de
focus/colores añadidos durante investigación del bug.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bug crítico: Al dar focus a cualquier widget, TODO el fondo se pintaba
de azul semitransparente, no solo el borde de focus.
Causa: En drawRoundedRect() había código de una implementación anterior
que hacía fillRoundedRect() antes de dibujar el outline. Cuando focusRing
llamaba a drawRoundedRect con color azul, primero rellenaba todo el área.
Fix: Eliminadas 8 líneas de código obsoleto (comentarios de estrategia
abandonada + la llamada a fillRoundedRect).
También: Limpieza de código debug en advanced_table.zig.
Crédito: Bug encontrado por Gemini tras descripción del problema.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cambios:
- Añadir selected_row_unfocus a TableColors
- drawRow ahora recibe has_focus para elegir color
- Con focus: usa selected_row (color accent)
- Sin focus: usa selected_row_unfocus (gris sutil)
BasicColors ahora acepta selected_row y selected_row_unfocus
opcionales para permitir override desde PanelColorScheme.
Esto permite que el usuario vea claramente:
- Qué panel tiene focus (fila con color accent)
- Qué fila está seleccionada en panel sin focus (gris)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- BasicColors struct: background, foreground, accent, header_bg opcionales
- TableColors.fromBasic(): deriva 26 colores desde 3-4 básicos
- BasicColors.toColor(): convierte cualquier tipo con r,g,b a Style.Color
- Detecta automáticamente tema claro/oscuro para derivar colores
- Presets dark()/light() y withAccent() para personalización
Permite que las aplicaciones pasen colores configurables desde sus
sistemas de config propios (como zsimifactu con resolveColor()).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bug: Las flechas no movían la selección en AdvancedTable.
Causa raíz:
- handleKeyboard seteaba result.selection_changed = true
- PERO NO seteaba result.selected_row / result.selected_col
- zsimifactu sincroniza selección desde DataManager cada frame
- Sin esos valores, DataManager no se actualizaba
- Siguiente frame: selección se reseteaba al valor anterior
Solución:
- Añadir result.selected_row y result.selected_col a todas
las teclas de navegación (up, down, left, right, page_up,
page_down, home, end)
Cambios visuales:
- Celda seleccionada: borde + tinte sutil (15%) en lugar
de fondo sólido azul
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fase 7 - Lookup & Auto-fill:
- performLookupAndAutoFill() en commitEdit
- Busca en DataStore.lookup() al editar columna lookup
- Auto-rellena columnas según auto_fill_columns mapping
- Indicador visual "?" en header para columnas lookup
- Campo lookup_success en AdvancedTableResult
Fase 8 - Callbacks + Debounce:
- invokeCallbacks() con sistema de debounce (150ms default)
- on_row_selected: al cambiar selección
- on_cell_changed: al confirmar edición
- on_active_row_changed: al cambiar de fila (para paneles detalle)
- Campos last_callback_time_ms, last_notified_row en state
Tests: 373/373 (+3 nuevos)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Widgets actualizados:
- NumberEntry: esquinas redondeadas + focus ring
- Radio: esquinas redondeadas para círculos + focus ring en opción
- Slider: esquinas redondeadas en track/thumb + focus ring
- Tabs: esquinas redondeadas en tab seleccionado + focus ring
- Table: focus ring alrededor de toda la tabla
- TextArea: esquinas redondeadas + focus ring
Nuevos campos:
- TableColors.focus_ring para consistencia
Total: +135 LOC en 7 archivos
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Command helpers:
- focusRing(x, y, w, h, radius) - focus indicator con AA
- focusRingColor() - versión con color custom
Características:
- Dibuja 2px fuera del widget (offset)
- Color semi-transparente (primary alpha 180)
- Radio +2 para mantener proporciones
- Thickness 2px para visibilidad
- Anti-aliasing habilitado
Widgets actualizados:
- TextInput: focus ring cuando has_focus
- Select: focus ring cuando has_focus (no cuando dropdown abierto)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SelectState ahora incluye:
- hover: HoverTransition para transiciones suaves
- last_time_ms: tracking de tiempo para delta
El color de fondo del botón principal del Select ahora
transiciona suavemente entre normal y hover (lighten 5%).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sistema de rendering dual para zcatgui:
Core:
- RenderMode enum (simple/fancy) en style.zig
- global_render_mode con helpers: isFancy(), setRenderMode()
- fillRoundedRect con edge-fade AA en framebuffer.zig (~350 LOC)
- Nuevos comandos: rounded_rect, rounded_rect_outline
Widgets actualizados:
- Button: corner_radius=4, usa roundedRect en fancy mode
- Panel: corner_radius=6, show_shadow=true, sombra offset 4px
- TextInput: corner_radius=3
- Select: corner_radius=3
- Modal: corner_radius=8, show_shadow=true, sombra offset 6px
- Botones y input field del modal también redondeados
Técnica edge-fade (de DVUI):
- Anti-aliasing por gradiente alfa en bordes
- Sin supersampling, mínimo impacto en rendimiento
- Bordes suaves sin multisampling
+589 líneas, 9 archivos modificados
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Añadir sección PROTOCOLO DE DOCUMENTACIÓN (2025-12-16)
- Agenda = índice, detalles en hitos/
- Límite ~300 líneas por archivo
- Añadir sección TAREA ACTUAL: Fuentes TTF con Antialiasing
- Estado de ttf.zig y fases de implementación
- TextInput: añadir text_color/border_color para validación
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cambios:
- base.zig: Añadido x_offset a ActionButtonsOpts y NavButtonsOpts
- text_input.zig: char_height 8→16 para fuente 8x16
- table/render.zig: char_height 8→16 (header y celdas)
El centrado vertical del texto ahora funciona correctamente
con fuentes 8x16 (VGA standard).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1592 líneas eliminadas - archivo no usado.
widgets.zig importa table/table.zig (versión fragmentada).
Detectado durante auditoría de tamaños de archivo.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Archivos que estaban localmente pero no en el repo:
- src/core/focus_group.zig (416 líneas)
- src/widgets/focus.zig (272 líneas)
- src/widgets/progress.zig (806 líneas)
- src/widgets/table.zig (1592 líneas)
- src/widgets/textarea.zig (871 líneas)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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>
- 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>
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>
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>