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>
13 KiB
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
- Tamaño perfecto: 1,100 LOC se puede estudiar completo en una tarde
- C puro: Trivial de entender para quien escribe Zig
- Software rendering natural: Output son comandos primitivos (rect, text)
- Zero dependencies: ANSI C puro
- Diseño brillante: Máximo valor en mínimo espacio
Arquitectura
Input → mu_Context → Widgets → Command List → Render
Command List Approach:
// 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
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
- Command list es suficiente - No necesitamos vertex buffers
- ~1000 LOC para MVP - Es alcanzable
- State pool - Técnica para tracking de IDs
- Layout simple -
mu_layout_row()es todo lo que necesitas inicialmente
Recursos
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.
- Idiomático Zig: Patterns que podemos copiar directamente
- Moderno: Low framerate support (no redibuja innecesariamente)
- Backend abstraction: VTable pattern para SDL3, Raylib, Web, DirectX11
- 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)
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
- Backend VTable: Abstracción limpia para múltiples backends
- Event processing: Cómo manejar eventos en Zig
- Widget patterns: Cómo estructurar widgets en Zig
- Memory management: Allocators idiomáticos
Recursos
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.
- Battle-tested: Usado en millones de aplicaciones
- API excelente: Muy ergonómica y bien diseñada
- Documentación: FAQ, wiki, ejemplos abundantes
- Software renderer existe: 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
- ID system: Hash de string/pointer para tracking
- State caching: ImGuiStorage para estado persistente
- Table API: Referencia para nuestra tabla
- Backend separation: Muy limpia
Bindings Zig Existentes
- cimgui.zig
- dinau/imguinz - ImGui 1.91.8
- SpexGuy/Zig-ImGui
Recursos
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
- Single header: nuklear.h contiene todo
- Renderer-agnostic: Command iteration o vertex buffers
- Zero dependencies: ANSI C puro
- Memoria fija: Diseñado para embedded
Arquitectura
Dos modos de rendering:
- Command iteration (similar a microui):
nk_foreach(cmd, &ctx->draw_list) {
switch (cmd->type) {
case NK_COMMAND_RECT: ...
case NK_COMMAND_TEXT: ...
}
}
- Vertex buffer (similar a ImGui):
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
- Styling extenso: Sistema de propiedades muy configurable
- Memory model: Fixed memory para embedded
- Dual rendering: Command list Y vertex buffer
Recursos
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
- API ergonómica: Closures, builder pattern idiomático
- Web + Native: Diseñado para ambos desde el inicio
- 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
- Response pattern: Widgets retornan Response con interacciones
- Context memory: Retiene mínimo estado entre frames
- 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
6. raygui (C) ⭐⭐⭐
Información General
| Campo | Valor |
|---|---|
| Repositorio | https://github.com/raysan5/raygui |
| Lenguaje | C |
| LOC | ~8,000 |
| Dependencia | raylib |
Características
- Integrado con raylib: Dibuja directamente
- Tools-focused: Diseñado para editores
- Ya tiene bindings Zig: via raylib-zig
Por qué Menos Relevante
- Acoplado a raylib
- Menos features que ImGui/Nuklear
- No standalone
Recursos
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):
- Más simple de implementar
- Suficiente para nuestros casos de uso
- Software rendering natural
- ~1000 LOC para renderer
Software Rendering: Análisis
¿Qué necesita un software renderer?
- Framebuffer: Array 2D de pixels (u32 RGBA)
- Primitive rasterizer:
drawRect(x, y, w, h, color)drawLine(x1, y1, x2, y2, color)- Opcional:
drawTriangle()para anti-aliasing
- Text rasterizer:
- Font atlas (bitmap)
drawText(x, y, string, font, color)
- Clipping: Restringir dibujo a región
- Output: Blit framebuffer a ventana (SDL_UpdateTexture)
Librerías con Mejor Soporte Software
- microui: IDEAL - output son rects/text directos
- imgui_software_renderer: Rasteriza triangles de ImGui en CPU
- 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
- microui (1-2 días): Código completo, fundamentos
- DVUI (2-3 días): Patterns Zig, backend abstraction
- Dear ImGui (1 semana): API design (no portar, solo estudiar)
Arquitectura Propuesta
// 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
- Retained vs Immediate Mode - Microsoft
- microui v2 Implementation Overview