zcatgui/docs/research/IMMEDIATE_MODE_LIBS.md
reugenio c4ea6422dc style: Use consistent lowercase naming (zcatgui, not zCatGui)
Apply TEAM_STANDARDS Norma #25: project names use lowercase
everywhere - repo, directory, module, documentation, imports.

No CamelCase in project names. Consistency = less cognitive friction.

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

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

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

  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:

// 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

  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


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)

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


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

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

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

  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):
nk_foreach(cmd, &ctx->draw_list) {
    switch (cmd->type) {
        case NK_COMMAND_RECT: ...
        case NK_COMMAND_TEXT: ...
    }
}
  1. 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

  1. Styling extenso: Sistema de propiedades muy configurable
  2. Memory model: Fixed memory para embedded
  3. 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

  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


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


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

// 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

Software Rendering

Zig Bindings Existentes