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>
502 lines
13 KiB
Markdown
502 lines
13 KiB
Markdown
# Análisis Comparativo: Librerías GUI Immediate-Mode
|
|
|
|
> Investigación realizada: 2025-12-09
|
|
> Propósito: Identificar mejores referencias para implementar zCatGui
|
|
|
|
---
|
|
|
|
## Resumen Ejecutivo
|
|
|
|
Se analizaron las principales librerías GUI immediate-mode para identificar patrones, arquitecturas y código reutilizable para zCatGui.
|
|
|
|
### Ranking de Relevancia para zCatGui
|
|
|
|
| # | Librería | Relevancia | Por qué |
|
|
|---|----------|------------|---------|
|
|
| 1 | **microui** | ⭐⭐⭐⭐⭐ | 1,100 LOC, C puro, software rendering natural |
|
|
| 2 | **DVUI** | ⭐⭐⭐⭐⭐ | Único ejemplo Zig nativo |
|
|
| 3 | **Dear ImGui** | ⭐⭐⭐⭐ | Referencia API, muy maduro |
|
|
| 4 | **Nuklear** | ⭐⭐⭐⭐ | C puro, vertex buffer approach |
|
|
| 5 | **egui** | ⭐⭐⭐ | API ergonómica (Rust) |
|
|
| 6 | **raygui** | ⭐⭐⭐ | Ya tiene bindings Zig |
|
|
|
|
---
|
|
|
|
## 1. microui (C) ⭐⭐⭐⭐⭐
|
|
|
|
### Información General
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Repositorio** | https://github.com/rxi/microui |
|
|
| **Lenguaje** | ANSI C |
|
|
| **LOC** | ~1,100 (microui.h + microui.c) |
|
|
| **Licencia** | MIT |
|
|
|
|
### Por qué es la Mejor Referencia
|
|
|
|
1. **Tamaño perfecto**: 1,100 LOC se puede estudiar completo en una tarde
|
|
2. **C puro**: Trivial de entender para quien escribe Zig
|
|
3. **Software rendering natural**: Output son comandos primitivos (rect, text)
|
|
4. **Zero dependencies**: ANSI C puro
|
|
5. **Diseño brillante**: Máximo valor en mínimo espacio
|
|
|
|
### Arquitectura
|
|
|
|
```
|
|
Input → mu_Context → Widgets → Command List → Render
|
|
```
|
|
|
|
**Command List Approach:**
|
|
```c
|
|
// Output son comandos simples
|
|
enum { MU_COMMAND_RECT, MU_COMMAND_TEXT, MU_COMMAND_CLIP, ... };
|
|
|
|
// Fácil de renderizar con software
|
|
while (mu_next_command(ctx, &cmd)) {
|
|
switch (cmd->type) {
|
|
case MU_COMMAND_RECT: draw_rect(...);
|
|
case MU_COMMAND_TEXT: draw_text(...);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Widgets Incluidos (8)
|
|
|
|
- Window, Panel
|
|
- Button, Checkbox, Slider
|
|
- Textbox, Label
|
|
- (containers básicos)
|
|
|
|
### Código Ejemplo
|
|
|
|
```c
|
|
mu_begin_window(ctx, "My Window", mu_rect(10, 10, 300, 200));
|
|
mu_layout_row(ctx, 2, (int[]){100, -1}, 0);
|
|
mu_label(ctx, "Name:");
|
|
if (mu_textbox(ctx, name_buf, sizeof(name_buf)) & MU_RES_SUBMIT) {
|
|
submit_name();
|
|
}
|
|
if (mu_button(ctx, "Submit")) {
|
|
handle_submit();
|
|
}
|
|
mu_end_window(ctx);
|
|
```
|
|
|
|
### Lecciones para zCatGui
|
|
|
|
1. **Command list es suficiente** - No necesitamos vertex buffers
|
|
2. **~1000 LOC para MVP** - Es alcanzable
|
|
3. **State pool** - Técnica para tracking de IDs
|
|
4. **Layout simple** - `mu_layout_row()` es todo lo que necesitas inicialmente
|
|
|
|
### Recursos
|
|
|
|
- [microui GitHub](https://github.com/rxi/microui)
|
|
- [microui v2 Implementation Overview](https://rxi.github.io/microui_v2_an_implementation_overview.html)
|
|
|
|
---
|
|
|
|
## 2. DVUI (Zig) ⭐⭐⭐⭐⭐
|
|
|
|
### Información General
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Repositorio** | https://github.com/david-vanderson/dvui |
|
|
| **Lenguaje** | Zig |
|
|
| **LOC** | ~15,000 (estimado) |
|
|
| **Estado Zig** | 0.13-0.15 |
|
|
|
|
### Por qué es Crítico
|
|
|
|
**Es la ÚNICA GUI immediate-mode nativa en Zig.**
|
|
|
|
1. **Idiomático Zig**: Patterns que podemos copiar directamente
|
|
2. **Moderno**: Low framerate support (no redibuja innecesariamente)
|
|
3. **Backend abstraction**: VTable pattern para SDL3, Raylib, Web, DirectX11
|
|
4. **Activo**: Mantenido activamente (2022-presente)
|
|
|
|
### Arquitectura
|
|
|
|
```
|
|
Event → Widget Processing → Layout → Render
|
|
```
|
|
|
|
**Características especiales:**
|
|
- Procesa TODOS los eventos (no solo último)
|
|
- Funciona a bajo framerate
|
|
- Floating windows con Z-order correcto
|
|
|
|
### Widgets Incluidos (~30)
|
|
|
|
- Button, Checkbox, Radio
|
|
- TextInput, TextArea
|
|
- Slider, ScrollArea
|
|
- Menu, Dropdown
|
|
- TreeView, Table
|
|
- Modal, Popup
|
|
- y más...
|
|
|
|
### Código Ejemplo (Zig)
|
|
|
|
```zig
|
|
pub fn gui(dvui: *Dvui) !void {
|
|
if (dvui.button("Click me!")) {
|
|
count += 1;
|
|
}
|
|
|
|
dvui.text("Count: {}", .{count});
|
|
|
|
if (dvui.beginWindow("Settings")) {
|
|
defer dvui.endWindow();
|
|
|
|
_ = dvui.checkbox("Enable feature", &enabled);
|
|
_ = dvui.slider("Volume", &volume, 0, 100);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Lecciones para zCatGui
|
|
|
|
1. **Backend VTable**: Abstracción limpia para múltiples backends
|
|
2. **Event processing**: Cómo manejar eventos en Zig
|
|
3. **Widget patterns**: Cómo estructurar widgets en Zig
|
|
4. **Memory management**: Allocators idiomáticos
|
|
|
|
### Recursos
|
|
|
|
- [DVUI GitHub](https://github.com/david-vanderson/dvui)
|
|
- [DVUI Zig NEWS Article](https://zig.news/david_vanderson/dvui-immediate-zig-gui-for-apps-and-games-2a5h)
|
|
|
|
---
|
|
|
|
## 3. Dear ImGui (C++) ⭐⭐⭐⭐
|
|
|
|
### Información General
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Repositorio** | https://github.com/ocornut/imgui |
|
|
| **Lenguaje** | C++ |
|
|
| **LOC** | ~60,000 |
|
|
| **Licencia** | MIT |
|
|
|
|
### Por qué es Importante
|
|
|
|
**El estándar de facto para GUIs immediate-mode.**
|
|
|
|
1. **Battle-tested**: Usado en millones de aplicaciones
|
|
2. **API excelente**: Muy ergonómica y bien diseñada
|
|
3. **Documentación**: FAQ, wiki, ejemplos abundantes
|
|
4. **Software renderer existe**: [imgui_software_renderer](https://github.com/emilk/imgui_software_renderer)
|
|
|
|
### Arquitectura
|
|
|
|
```
|
|
Input → ImGuiContext → Widgets → Vertex Buffers → GPU/Software Raster
|
|
```
|
|
|
|
**Separación de concerns:**
|
|
- **Core**: imgui.cpp, imgui_widgets.cpp, imgui_tables.cpp, imgui_draw.cpp
|
|
- **Backends**: Plataforma (GLFW, SDL2/3, Win32) separados
|
|
- **Renderers**: OpenGL, DirectX, Vulkan, Metal, WebGPU
|
|
|
|
### Widgets Incluidos (50+)
|
|
|
|
- Window, Child, Popup, Modal
|
|
- Button, Checkbox, Radio, Slider, Drag
|
|
- Input (text, int, float, multiline)
|
|
- Combo, ListBox, Selectable
|
|
- TreeNode, CollapsingHeader
|
|
- Table (muy avanzada)
|
|
- Menu, MenuBar
|
|
- TabBar, Tabs
|
|
- ColorPicker, ColorEdit
|
|
- Plot, Histogram
|
|
- y muchos más...
|
|
|
|
### Lecciones para zCatGui
|
|
|
|
1. **ID system**: Hash de string/pointer para tracking
|
|
2. **State caching**: ImGuiStorage para estado persistente
|
|
3. **Table API**: Referencia para nuestra tabla
|
|
4. **Backend separation**: Muy limpia
|
|
|
|
### Bindings Zig Existentes
|
|
|
|
- [cimgui.zig](https://github.com/tiawl/cimgui.zig)
|
|
- [dinau/imguinz](https://github.com/dinau/imguinz) - ImGui 1.91.8
|
|
- [SpexGuy/Zig-ImGui](https://github.com/SpexGuy/Zig-ImGui)
|
|
|
|
### Recursos
|
|
|
|
- [Dear ImGui GitHub](https://github.com/ocornut/imgui)
|
|
- [Dear ImGui FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md)
|
|
- [imgui_software_renderer](https://github.com/emilk/imgui_software_renderer)
|
|
|
|
---
|
|
|
|
## 4. Nuklear (C) ⭐⭐⭐⭐
|
|
|
|
### Información General
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Repositorio** | https://github.com/Immediate-Mode-UI/Nuklear |
|
|
| **Lenguaje** | ANSI C |
|
|
| **LOC** | ~30,000 (single header) |
|
|
| **Licencia** | Public Domain |
|
|
|
|
### Características
|
|
|
|
1. **Single header**: nuklear.h contiene todo
|
|
2. **Renderer-agnostic**: Command iteration o vertex buffers
|
|
3. **Zero dependencies**: ANSI C puro
|
|
4. **Memoria fija**: Diseñado para embedded
|
|
|
|
### Arquitectura
|
|
|
|
**Dos modos de rendering:**
|
|
|
|
1. **Command iteration** (similar a microui):
|
|
```c
|
|
nk_foreach(cmd, &ctx->draw_list) {
|
|
switch (cmd->type) {
|
|
case NK_COMMAND_RECT: ...
|
|
case NK_COMMAND_TEXT: ...
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Vertex buffer** (similar a ImGui):
|
|
```c
|
|
nk_convert(&ctx, &cmds, &verts, &idx, &config);
|
|
// Renderizar con GPU
|
|
```
|
|
|
|
### Widgets Incluidos (~20)
|
|
|
|
- Window, Panel, Group
|
|
- Button, Checkbox, Radio, Slider
|
|
- Edit (text), Property
|
|
- Chart, Color picker
|
|
- Combo, Contextual, Menu, Tree
|
|
|
|
### Lecciones para zCatGui
|
|
|
|
1. **Styling extenso**: Sistema de propiedades muy configurable
|
|
2. **Memory model**: Fixed memory para embedded
|
|
3. **Dual rendering**: Command list Y vertex buffer
|
|
|
|
### Recursos
|
|
|
|
- [Nuklear GitHub](https://github.com/Immediate-Mode-UI/Nuklear)
|
|
|
|
---
|
|
|
|
## 5. egui (Rust) ⭐⭐⭐
|
|
|
|
### Información General
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Repositorio** | https://github.com/emilk/egui |
|
|
| **Lenguaje** | Rust |
|
|
| **LOC** | ~35,000 |
|
|
| **Licencia** | MIT / Apache 2.0 |
|
|
|
|
### Características
|
|
|
|
1. **API ergonómica**: Closures, builder pattern idiomático
|
|
2. **Web + Native**: Diseñado para ambos desde el inicio
|
|
3. **epaint**: Tessellator separado (shapes → meshes)
|
|
|
|
### Arquitectura
|
|
|
|
```
|
|
egui (core) → epaint (tessellation) → eframe (backend glue)
|
|
```
|
|
|
|
**epaint es interesante**: Convierte shapes vectoriales en triangle meshes.
|
|
|
|
### Lecciones para zCatGui
|
|
|
|
1. **Response pattern**: Widgets retornan Response con interacciones
|
|
2. **Context memory**: Retiene mínimo estado entre frames
|
|
3. **Tessellator separado**: epaint podría portarse
|
|
|
|
### Nota sobre Software Rendering
|
|
|
|
**No tiene software renderer oficial** - hay un issue abierto (#1129).
|
|
El autor (emilk) escribió uno para ImGui, podría adaptarse.
|
|
|
|
### Recursos
|
|
|
|
- [egui GitHub](https://github.com/emilk/egui)
|
|
- [egui.rs](https://www.egui.rs/)
|
|
|
|
---
|
|
|
|
## 6. raygui (C) ⭐⭐⭐
|
|
|
|
### Información General
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **Repositorio** | https://github.com/raysan5/raygui |
|
|
| **Lenguaje** | C |
|
|
| **LOC** | ~8,000 |
|
|
| **Dependencia** | raylib |
|
|
|
|
### Características
|
|
|
|
1. **Integrado con raylib**: Dibuja directamente
|
|
2. **Tools-focused**: Diseñado para editores
|
|
3. **Ya tiene bindings Zig**: via raylib-zig
|
|
|
|
### Por qué Menos Relevante
|
|
|
|
- Acoplado a raylib
|
|
- Menos features que ImGui/Nuklear
|
|
- No standalone
|
|
|
|
### Recursos
|
|
|
|
- [raygui GitHub](https://github.com/raysan5/raygui)
|
|
- [raylib-zig](https://github.com/raylib-zig/raylib-zig)
|
|
|
|
---
|
|
|
|
## Comparativa Técnica
|
|
|
|
| Librería | LOC | Lenguaje | Software Renderer | Complejidad | Porting a Zig |
|
|
|----------|-----|----------|-------------------|-------------|---------------|
|
|
| **microui** | 1,100 | C | ✅ Natural | Muy Baja | Trivial |
|
|
| **DVUI** | 15,000 | Zig | Via backend | Media | ✅ Nativo |
|
|
| **Dear ImGui** | 60,000 | C++ | ✅ (external) | Alta | Medio |
|
|
| **Nuklear** | 30,000 | C | ⚠️ Custom | Media | Fácil |
|
|
| **egui** | 35,000 | Rust | ❌ Planeado | Media | Medio |
|
|
| **raygui** | 8,000 | C | Via raylib | Baja | Ya existe |
|
|
|
|
---
|
|
|
|
## Arquitectura de Rendering: Comparativa
|
|
|
|
### Command List Approach (microui, nuestro approach)
|
|
|
|
```
|
|
Input → UI Logic → Commands (DrawRect, DrawText) → Direct Render
|
|
```
|
|
|
|
**Pros**: Simplicísimo, ideal software rendering
|
|
**Contras**: No batching, menos eficiente con muchos elementos
|
|
|
|
### Vertex Buffer Approach (ImGui, Nuklear, egui)
|
|
|
|
```
|
|
Input → UI Logic → Shapes → Tessellate → Vertex Buffers → GPU/Software Raster
|
|
```
|
|
|
|
**Pros**: Eficiente, batching, flexible
|
|
**Contras**: Necesita tessellator, más complejo
|
|
|
|
### Decisión para zCatGui
|
|
|
|
**Command List** (microui style):
|
|
1. Más simple de implementar
|
|
2. Suficiente para nuestros casos de uso
|
|
3. Software rendering natural
|
|
4. ~1000 LOC para renderer
|
|
|
|
---
|
|
|
|
## Software Rendering: Análisis
|
|
|
|
### ¿Qué necesita un software renderer?
|
|
|
|
1. **Framebuffer**: Array 2D de pixels (u32 RGBA)
|
|
2. **Primitive rasterizer**:
|
|
- `drawRect(x, y, w, h, color)`
|
|
- `drawLine(x1, y1, x2, y2, color)`
|
|
- Opcional: `drawTriangle()` para anti-aliasing
|
|
3. **Text rasterizer**:
|
|
- Font atlas (bitmap)
|
|
- `drawText(x, y, string, font, color)`
|
|
4. **Clipping**: Restringir dibujo a región
|
|
5. **Output**: Blit framebuffer a ventana (SDL_UpdateTexture)
|
|
|
|
### Librerías con Mejor Soporte Software
|
|
|
|
1. **microui**: IDEAL - output son rects/text directos
|
|
2. **imgui_software_renderer**: Rasteriza triangles de ImGui en CPU
|
|
3. **SDL software renderer**: Backend para ImGui/Nuklear
|
|
|
|
### Estimación para zCatGui
|
|
|
|
- **Rasterizer básico**: ~500 LOC
|
|
- **Font handling**: ~300 LOC
|
|
- **Clipping**: ~100 LOC
|
|
- **Total**: ~1000 LOC
|
|
|
|
---
|
|
|
|
## Recomendaciones para zCatGui
|
|
|
|
### Estudio Prioritario
|
|
|
|
1. **microui** (1-2 días): Código completo, fundamentos
|
|
2. **DVUI** (2-3 días): Patterns Zig, backend abstraction
|
|
3. **Dear ImGui** (1 semana): API design (no portar, solo estudiar)
|
|
|
|
### Arquitectura Propuesta
|
|
|
|
```zig
|
|
// Basado en microui + DVUI patterns
|
|
pub const Context = struct {
|
|
commands: ArrayList(DrawCommand),
|
|
state: StatePool,
|
|
input: InputState,
|
|
|
|
pub fn button(self: *Context, text: []const u8) bool {
|
|
const id = hashId(text);
|
|
const bounds = self.layout.nextRect();
|
|
const hovered = bounds.contains(self.input.mouse);
|
|
const clicked = hovered and self.input.mousePressed;
|
|
|
|
self.pushCommand(.{ .rect = .{ .bounds = bounds, ... }});
|
|
self.pushCommand(.{ .text = .{ .pos = bounds.center(), ... }});
|
|
|
|
return clicked;
|
|
}
|
|
};
|
|
```
|
|
|
|
### Roadmap Basado en Referencias
|
|
|
|
| Fase | LOC Estimado | Tiempo | Referencia Principal |
|
|
|------|--------------|--------|---------------------|
|
|
| MVP (button, label) | ~1000 | 1 semana | microui |
|
|
| Core widgets | ~3000 | 2 semanas | microui + DVUI |
|
|
| Table editable | ~1500 | 2 semanas | Dear ImGui |
|
|
| Total | ~5500 | 5 semanas | - |
|
|
|
|
---
|
|
|
|
## Recursos Clave
|
|
|
|
### Tutoriales y Teoría
|
|
|
|
- [Immediate Mode GUI Wikipedia](https://en.wikipedia.org/wiki/Immediate_mode_GUI)
|
|
- [Retained vs Immediate Mode - Microsoft](https://learn.microsoft.com/en-us/windows/win32/learnwin32/retained-mode-versus-immediate-mode)
|
|
- [microui v2 Implementation Overview](https://rxi.github.io/microui_v2_an_implementation_overview.html)
|
|
|
|
### Software Rendering
|
|
|
|
- [imgui_software_renderer](https://github.com/emilk/imgui_software_renderer)
|
|
- [Tiny CPU Rasterizer Tutorial](https://lisyarus.github.io/blog/posts/implementing-a-tiny-cpu-rasterizer-part-1.html)
|
|
|
|
### Zig Bindings Existentes
|
|
|
|
- [cimgui.zig](https://github.com/tiawl/cimgui.zig)
|
|
- [raylib-zig](https://github.com/raylib-zig/raylib-zig)
|