zcatgui/docs/research/GIO_UI_ANALYSIS.md
reugenio 59c597fc18 feat: zCatGui v0.1.0 - Initial project setup
Immediate Mode GUI library for Zig with software rendering.

Core features:
- SDL2 backend for cross-platform window/events
- Software rasterizer (works everywhere, including SSH)
- Macro recording system (cornerstone feature, like Vim)
- Command-list rendering (DrawRect, DrawText, etc.)
- Layout system with constraints
- Color/Style system with themes

Project structure:
- src/core/: context, command, input, layout, style
- src/macro/: MacroRecorder, MacroPlayer, MacroStorage
- src/render/: Framebuffer, SoftwareRenderer, Font
- src/backend/: Backend interface, SDL2 implementation
- examples/: hello.zig, macro_demo.zig
- docs/: Architecture, research (Gio, immediate-mode libs, Simifactu)

Build: zig build (requires SDL2-devel)
Tests: 16 tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 01:30:05 +01:00

431 lines
12 KiB
Markdown

# Análisis Técnico: Gio UI (Go)
> Investigación realizada: 2025-12-09
> Propósito: Entender arquitectura de Gio como referencia para zCatGui
---
## Resumen Ejecutivo
**Gio UI** (gioui.org) es una librería de GUI immediate mode para Go que permite crear interfaces gráficas cross-platform nativas. Es comparable a Flutter en diseño pero implementado completamente en Go, sin dependencias externas más allá de las librerías de sistema para ventanas y GPU.
| Campo | Valor |
|-------|-------|
| **Repositorio** | https://git.sr.ht/~eliasnaur/gio |
| **Versión** | v0.9.0 (pre-1.0, API inestable) |
| **Licencia** | MIT / Unlicense |
| **Plataformas** | Android, iOS, macOS, Linux, Windows, FreeBSD, OpenBSD, WebAssembly |
---
## 1. Arquitectura General
### 1.1 Estructura de Capas
```
┌─────────────────────────────────────────┐
│ Material Design (widget/material) │ <- Widgets estilizados
├─────────────────────────────────────────┤
│ Widget State (widget) │ <- Estado de controles
├─────────────────────────────────────────┤
│ Layout System (layout) │ <- Sistema de layouts
├─────────────────────────────────────────┤
│ Operations (op, op/clip, op/paint) │ <- Comandos de dibujo
├─────────────────────────────────────────┤
│ Window Management (app) │ <- Manejo de ventanas
├─────────────────────────────────────────┤
│ GPU Rendering (gpu) │ <- Backends gráficos
├─────────────────────────────────────────┤
│ Platform Backend │ <- Win/macOS/Linux/etc.
└─────────────────────────────────────────┘
```
### 1.2 Módulos Principales
| Paquete | Propósito |
|---------|-----------|
| `gioui.org/app` | Window management, eventos del OS |
| `gioui.org/op` | Sistema de operaciones (comandos de dibujo) |
| `gioui.org/layout` | Layouts (Flex, Stack, List, Inset) |
| `gioui.org/widget` | Widgets con estado (Clickable, Editor, List, etc.) |
| `gioui.org/widget/material` | Material Design theme |
| `gioui.org/gpu` | Rendering GPU (OpenGL, Direct3D, Vulkan) |
| `gioui.org/io` | Input/output (pointer, keyboard, clipboard) |
| `gioui.org/text` | Text shaping, layout, glyphs |
| `gioui.org/font` | Font handling, OpenType |
| `gioui.org/gesture` | Gestures de alto nivel (Click, Drag, Scroll, Hover) |
| `gioui.org/x/component` | Componentes extendidos Material |
---
## 2. Sistema de Rendering
### 2.1 GPU Backends
Gio soporta múltiples backends GPU según la plataforma:
- **OpenGL ES** - Multiplataforma (Linux, Android, iOS, WebAssembly)
- **Direct3D 11** - Windows
- **Vulkan** - Linux, Android (opcional)
### 2.2 Vector Rendering Pipeline
Gio usa un **vector renderer basado en Pathfinder** (proyecto de Mozilla):
1. **Renderizado de outlines**: Las formas y texto se renderizan desde sus contornos vectoriales
2. **Sin pre-procesamiento CPU**: Los paths SVG se renderizan en GPU con mínimo trabajo en CPU
3. **Migración a piet-gpu**: Renderer basado en compute shaders para mayor eficiencia
### 2.3 CPU Fallback
**Importante para zCatGui**: Gio incluye un fallback CPU (`gioui.org/cpu`) con binarios pre-compilados de piet-gpu para arm, arm64, amd64, permitiendo renderizado software cuando no hay GPU disponible.
---
## 3. Sistema de Layout
### 3.1 Conceptos Fundamentales
```go
// Constraints = lo que el padre dice al hijo (límites de tamaño)
type Constraints struct {
Min, Max image.Point
}
// Dimensions = lo que el hijo devuelve al padre (tamaño usado)
type Dimensions struct {
Size image.Point
Baseline int
}
// Context = bundle de estado pasado a todos los widgets
type Context struct {
Constraints Constraints
Metric unit.Metric
Now time.Time
// ...
}
// Widget = función que calcula dimensions desde constraints
type Widget func(gtx layout.Context) layout.Dimensions
```
### 3.2 Layouts Principales
#### Flex - Distribución lineal con pesos
```go
layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D { return header.Layout(gtx) }),
layout.Flexed(1, func(gtx C) D { return content.Layout(gtx) }),
layout.Rigid(func(gtx C) D { return footer.Layout(gtx) }),
)
```
**Spacing modes:**
- `SpaceEnd` - Espacio al final
- `SpaceStart` - Espacio al inicio
- `SpaceSides` - Espacio en ambos lados
- `SpaceAround` - Espacio alrededor de children
- `SpaceBetween` - Espacio entre children
- `SpaceEvenly` - Distribución uniforme
#### Stack - Elementos apilados
```go
layout.Stack{}.Layout(gtx,
layout.Expanded(func(gtx C) D { return image.Layout(gtx) }),
layout.Stacked(func(gtx C) D { return button.Layout(gtx) }),
)
```
#### List - Lista scrollable virtualizada
```go
// Solo renderiza los elementos visibles
list.Layout(gtx, 1_000_000, func(gtx C, i int) D {
return material.Label(theme, unit.Sp(16), fmt.Sprintf("Item %d", i)).Layout(gtx)
})
```
#### Inset - Padding
```go
layout.UniformInset(10).Layout(gtx, func(gtx C) D {
return widget.Layout(gtx)
})
```
### 3.3 Sistema de Unidades
```go
type Px // Physical pixels (dependiente de dispositivo)
type Dp // Device-independent pixels (escala por densidad)
type Sp // Scaled points (incluye scaling de fuente del sistema)
```
---
## 4. Sistema de Eventos
### 4.1 Tipos de Eventos
```go
type pointer.Event // Mouse/touch (Press, Release, Move, Drag, Scroll)
type key.Event // Keyboard
type key.EditEvent // Edición de texto
type key.FocusEvent // Cambio de foco
```
### 4.2 Distribución de Eventos (Tag-based)
Gio usa un sistema **sin callbacks** basado en **tags**:
```go
// Declarar área clickable
pointer.InputOp{
Tag: &button, // Tag único
Types: pointer.Press | pointer.Release,
}.Add(ops)
// Consultar eventos
for {
ev, ok := gtx.Event(pointer.Filter{Target: &button, ...})
if !ok { break }
// Procesar evento
}
```
**Ventaja**: Elimina el overhead de callbacks y simplifica el manejo de estado.
### 4.3 Gestures de Alto Nivel
```go
type Click // Detecta clicks
type Drag // Detecta drags
type Hover // Detecta hover
type Scroll // Detecta scroll
```
---
## 5. Widgets Incluidos
### 5.1 Widget Pattern (Separación de Concerns)
Gio separa **estado** (stateful) y **presentación** (stateless):
```
widget.Clickable (state) → material.Button (presentation)
widget.Editor (state) → material.Editor (presentation)
widget.Bool (state) → material.CheckBox (presentation)
```
### 5.2 Widget State (`gioui.org/widget`)
| Widget | Propósito |
|--------|-----------|
| `Clickable` | Área clickable (botones, cards, etc.) |
| `Editor` | Editor de texto de una línea |
| `Selectable` | Texto seleccionable (no editable) |
| `Float` | Valor float para sliders |
| `Bool` | Valor booleano (checkboxes, switches) |
| `Enum` | Valor enum (radio buttons) |
| `List` | Estado de lista scrollable |
| `Scrollbar` | Estado de scrollbar |
| `Draggable` | Soporte drag & drop |
| `Decorations` | Decoraciones de ventana |
| `Icon` | Ícono vectorial |
### 5.3 Material Widgets (`gioui.org/widget/material`)
**Texto:** Label, H1-H6, Body1, Body2, Caption, Subtitle1, Subtitle2, Overline
**Botones:** Button, IconButton, ButtonLayout
**Input:** Editor, CheckBox, RadioButton, Switch, Slider
**Contenedores:** List, Scrollbar
**Indicadores:** ProgressBar, ProgressCircle, Loader (spinner)
**Ventanas:** Decorations
### 5.4 Extended Components (`gioui.org/x/component`)
- AppBar, NavDrawer, Menu, MenuItem, ContextArea
- Grid, Table, Sheet, Surface
- TextField (con label animada), Tooltip
- Discloser (expandible), Divider
- ModalLayer, Scrim
---
## 6. Theming y Styling
### 6.1 Sistema de Theme
```go
type Theme struct {
Shaper *text.Shaper
Palette Palette
TextSize unit.Sp
Face text.Face
FingerSize unit.Dp // Tamaño mínimo área touch (48dp)
}
type Palette struct {
Bg color.NRGBA
Fg color.NRGBA
ContrastBg color.NRGBA
ContrastFg color.NRGBA
}
```
### 6.2 Niveles de Customización
**Global (Theme-wide):**
```go
theme := material.NewTheme()
theme.Palette.Fg = color.NRGBA{R: 255, G: 255, B: 255, A: 255}
```
**Widget-local:**
```go
btn := material.Button(theme, button, "Click me!")
btn.Background = color.NRGBA{R: 0, G: 150, B: 0, A: 255}
```
---
## 7. Window Management
### 7.1 Creación de Ventana
```go
func main() {
go func() {
window := new(app.Window)
window.Option(app.Title("My App"))
window.Option(app.Size(unit.Dp(800), unit.Dp(600)))
if err := run(window); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
app.Main() // BLOQUEANTE en algunas plataformas
}
```
### 7.2 Event Loop
```go
func run(window *app.Window) error {
var ops op.Ops
for {
switch e := window.Event().(type) {
case app.DestroyEvent:
return e.Err
case app.FrameEvent:
ops.Reset()
gtx := app.NewContext(&ops, e)
drawUI(gtx)
e.Frame(gtx.Ops)
}
}
}
```
---
## 8. Paradigma Immediate Mode
### 8.1 Filosofía
```
while running:
eventos ← poll_events()
actualizar_estado(eventos)
ops.Reset()
dibujar_ui_completa(ops, estado) ← UI es función pura del estado
enviar_a_gpu(ops)
```
### 8.2 Ventajas Específicas de Gio
**Sin callbacks:**
```go
// NO HAY ESTO:
button.onClick(func() { ... })
// EN SU LUGAR:
for button.Clicked(gtx) {
count++
}
```
**Estado mínimo:**
```go
// El estado es tuyo, no del framework
type State struct {
count int
name string
}
// Widgets solo contienen estado UI mínimo
var button widget.Clickable
```
**UI como función pura:**
```go
func drawUI(gtx layout.Context, state *State) {
label := material.H1(theme, fmt.Sprintf("Count: %d", state.count))
label.Layout(gtx)
}
```
### 8.3 Zero-Allocation Design
```go
// Método tipado, sin interfaz → sin allocación
operation.Add(ops)
```
---
## 9. Lecciones para zCatGui
### 9.1 Qué Adoptar
1. **Separación estado/presentación**: Widget state vs widget render
2. **Sistema de constraints**: Constraints/Dimensions muy robusto
3. **Event tags**: Sin callbacks, consulta de eventos
4. **Zero-allocation**: Operaciones tipadas
5. **Spacing modes**: Flex con SpaceBetween, SpaceAround, etc.
### 9.2 Qué Adaptar
1. **Rendering**: Gio usa GPU, nosotros software renderer
2. **Operaciones**: Gio usa op.Ops (GPU), nosotros DrawCommand (CPU)
3. **Complejidad**: Gio es ~40K LOC, nosotros apuntamos a ~5-10K
### 9.3 Diferencias Clave
| Aspecto | Gio | zCatGui |
|---------|-----|---------|
| Lenguaje | Go | Zig |
| Rendering | GPU (Pathfinder) | Software (framebuffer) |
| Complejidad | Alta (~40K LOC) | Baja (target ~5K) |
| Macros | No tiene | Piedra angular |
| Fonts | HarfBuzz | Bitmap + stb_truetype |
---
## 10. Referencias
- [Gio UI Website](https://gioui.org/)
- [Architecture](https://gioui.org/doc/architecture)
- [Layout](https://gioui.org/doc/architecture/layout)
- [Widget](https://gioui.org/doc/architecture/widget)
- [Input](https://gioui.org/doc/architecture/input)
- [API Reference](https://pkg.go.dev/gioui.org)
- [Examples](https://github.com/gioui/gio-example)
- [Extended Components](https://github.com/gioui/gio-x)
- [GUI with Gio Tutorial](https://jonegil.github.io/gui-with-gio/)
- [Immediate Mode GUI Programming](https://eliasnaur.com/blog/immediate-mode-gui-programming)