# 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)