docs: Documentar refactorización modular (autocomplete, icon)

This commit is contained in:
reugenio 2025-12-29 11:52:19 +01:00
parent 1ae07812bd
commit ea388facb2
2 changed files with 270 additions and 0 deletions

View file

@ -204,6 +204,14 @@ zcatgui/
│ ├── zcatgui.zig # Entry point, re-exports
│ ├── core/ # Context, Layout, Style, Input, Command, etc.
│ ├── widgets/ # 37 widgets implementados
│ │ ├── autocomplete/ # Modular: state, types, filtering
│ │ ├── icon/ # Modular: types, drawing_helpers
│ │ ├── textarea/ # Modular: state, render, types
│ │ ├── progress/ # Modular: bar, circle, spinner
│ │ ├── table/ # Tabla simple
│ │ ├── advanced_table/ # Tabla avanzada con CRUD
│ │ ├── virtual_advanced_table/ # Tabla virtual con paginación
│ │ └── ... # Widgets simples (archivos individuales)
│ ├── render/ # Software renderer, fonts, animation, effects
│ ├── backend/ # SDL2, WASM, Android, iOS
│ ├── macro/ # MacroRecorder, MacroPlayer
@ -257,6 +265,12 @@ zcatgui/
## HITOS RECIENTES
### Refactorización Modular ✅ (2025-12-29)
Archivos grandes modularizados en carpetas:
- `autocomplete/` (910→571 LOC hub, -37%): state, types, filtering
- `icon/` (805→515 LOC hub, -36%): types, drawing_helpers
→ Detalle: `docs/REFACTORING_MODULAR_2025-12-29.md`
### AdvancedTable Color por Focus ✅ (2025-12-19)
Fila seleccionada cambia color según focus de la tabla:
- `selected_row`: color con focus (accent)

View file

@ -0,0 +1,256 @@
# Refactorización Modular 2025-12-29
> **Objetivo:** Reducir archivos monolíticos (>700 LOC) a estructuras modulares mantenibles.
---
## Resumen Ejecutivo
| Módulo | Antes | Hub | Reducción |
|--------|-------|-----|-----------|
| autocomplete | 910 LOC | 571 LOC | **-37%** |
| icon | 805 LOC | 515 LOC | **-36%** |
| textarea | Ya modular | 404 LOC | - |
| progress | Ya modular | ~300 LOC | - |
**Archivos residuales eliminados:** `textarea.zig`, `progress.zig` (duplicados de carpetas existentes)
---
## Patrón de Modularización
### Estructura Estándar
```
widget/
├── widget.zig # Hub: API pública, re-exports, lógica principal
├── types.zig # Tipos, enums, Config, Colors, Result
├── state.zig # Estado del widget (si es stateful)
└── helpers.zig # Funciones auxiliares específicas
```
### Principios
1. **Hub Mínimo**: El archivo principal solo contiene API pública y lógica core
2. **Tipos Separados**: Todos los `struct`, `enum`, `Config`, `Colors` van a `types.zig`
3. **Estado Aislado**: Estado mutable con sus métodos en `state.zig`
4. **Helpers Específicos**: Funciones de dibujo, filtrado, etc. en su propio archivo
5. **Re-exports**: El hub re-exporta todo para compatibilidad con código existente
---
## autocomplete/ (910 → 571 LOC, -37%)
### Estructura
```
src/widgets/autocomplete/
├── autocomplete.zig (571 LOC) - Hub con API y lógica principal
├── state.zig (200 LOC) - AutoCompleteState + buffer management
├── types.zig (89 LOC) - MatchMode, Config, Colors, Result
└── filtering.zig (106 LOC) - matchesFilter, matchesPrefix, matchesFuzzy
```
### Archivos Modificados
- `widgets.zig`: Import actualizado a `autocomplete/autocomplete.zig`
### Detalles de Extracción
**state.zig:**
```zig
pub const AutoCompleteState = struct {
buffer: [256]u8 = [_]u8{0} ** 256,
cursor: usize = 0,
// ... métodos de gestión de buffer
};
```
**types.zig:**
```zig
pub const MatchMode = enum { prefix, contains, fuzzy };
pub const AutoCompleteConfig = struct { ... };
pub const AutoCompleteColors = struct { ... };
pub const AutoCompleteResult = struct { ... };
```
**filtering.zig:**
```zig
pub fn matchesFilter(text: []const u8, filter: []const u8, mode: MatchMode) bool;
pub fn matchesPrefix(text: []const u8, prefix: []const u8) bool;
pub fn matchesContains(text: []const u8, needle: []const u8) bool;
pub fn matchesFuzzy(text: []const u8, pattern: []const u8) bool;
```
---
## icon/ (805 → 515 LOC, -36%)
### Estructura
```
src/widgets/icon/
├── icon.zig (515 LOC) - Hub con API y switch de ~50 iconos
├── types.zig (146 LOC) - Size, IconType, Config, Colors
└── drawing_helpers.zig (93 LOC) - drawLine, fillCircle, strokeCircle
```
### Archivos Modificados
- `widgets.zig`: Import actualizado a `icon/icon.zig`
- `iconbutton.zig`: Import actualizado
- `appbar.zig`: Import actualizado
- `navdrawer.zig`: Import actualizado
### Detalles de Extracción
**types.zig:**
```zig
pub const Size = enum {
small, // 12x12
medium, // 16x16
large, // 24x24
xlarge, // 32x32
pub fn pixels(self: Size) u32 { ... }
};
pub const IconType = enum {
// Navigation (~12)
arrow_up, arrow_down, arrow_left, arrow_right,
chevron_up, chevron_down, chevron_left, chevron_right,
home, menu, more_horizontal, more_vertical,
// Actions (~16)
check, close, plus, minus, edit, delete, refresh,
search, settings, filter, sort, copy, paste, cut, undo, redo,
// Files (~8)
file, folder, folder_open, document, image_file,
download, upload, save,
// Status (~9)
info, warning, error_icon, success, question,
star, star_filled, heart, heart_filled,
// UI elements (~10)
eye, eye_off, lock, unlock, user, users,
calendar, clock, bell, mail,
// Media (~5)
play, pause, stop, volume, volume_off,
// Misc (~8)
grip, drag, expand, collapse, maximize, minimize, external_link,
};
pub const Config = struct {
size: Size = .medium,
custom_size: ?u32 = null,
stroke_width: u32 = 2,
filled: bool = false,
};
pub const Colors = struct {
foreground: Style.Color = Style.Color.rgba(220, 220, 220, 255),
background: ?Style.Color = null,
pub fn fromTheme(theme: Style.Theme) Colors { ... }
};
```
**drawing_helpers.zig:**
```zig
/// Dibuja línea con grosor variable
pub fn drawLine(ctx: *Context, x1: i32, y1: i32, x2: i32, y2: i32,
thickness: u32, color: Style.Color) void;
/// Rellena círculo
pub fn fillCircle(ctx: *Context, cx: i32, cy: i32, radius: u32, color: Style.Color) void;
/// Dibuja contorno de círculo (Bresenham)
pub fn strokeCircle(ctx: *Context, cx: i32, cy: i32, radius: u32,
thickness: u32, color: Style.Color) void;
fn setPixelThick(ctx: *Context, x: i32, y: i32, thickness: u32, color: Style.Color) void;
```
---
## Limpieza de Archivos Residuales
### Problema Detectado
Existían archivos duplicados:
- `src/widgets/textarea.zig` (26KB) - archivo antiguo
- `src/widgets/textarea/` - carpeta con módulos
Lo mismo con `progress.zig` / `progress/`.
### Solución
```bash
rm src/widgets/textarea.zig
rm src/widgets/progress.zig
```
Los imports en `widgets.zig` ya apuntaban a las carpetas, por lo que los archivos sueltos eran código muerto.
---
## Módulos Ya Modulares (No Modificados)
### textarea/ (404 LOC hub)
```
src/widgets/textarea/
├── textarea.zig (404 LOC)
├── state.zig
├── render.zig
└── types.zig
```
### progress/ (~300 LOC hub)
```
src/widgets/progress/
├── progress.zig
├── bar.zig
├── circle.zig
└── spinner.zig
```
---
## Beneficios de la Modularización
1. **Mantenibilidad**: Archivos <600 LOC son más fáciles de navegar
2. **Compilación**: Cambios en types.zig no recompilan lógica principal
3. **Testing**: Módulos aislados son más fáciles de testear
4. **Colaboración**: Menos conflictos de merge en archivos grandes
5. **Documentación**: Estructura refleja responsabilidades
---
## Candidatos Futuros
| Archivo | LOC | Prioridad |
|---------|-----|-----------|
| font_data.zig | 1157 | Baja (datos estáticos) |
| style.zig | 858 | Media |
| table.zig | ~750 | Media |
---
## Commits
```
chore: Eliminar archivos residuales textarea.zig y progress.zig
refactor(autocomplete): Modularizar en carpeta (910→571 LOC hub, -37%)
refactor(icon): Modularizar en carpeta (805→515 LOC hub, -36%)
```
---
*Fecha: 2025-12-29*
*Autor: Claude (Opus 4.5) + R.Eugenio*