Nuevas fuentes bitmap 8x16 (altura VGA estándar, mejor legibilidad): - font_8x16: ASCII básico (95 caracteres) - font_8x16_latin1: Latin-1 completo (224 caracteres) Sistema FontSize para selección por categoría: - getFontForSize(.small) → 8x8 Latin-1 (compacto) - getFontForSize(.medium) → 8x16 Latin-1 (estándar UI) - getFontForSizeAscii() variantes para menor memoria Soporte completo español/europeo: ñ, Ñ, á, é, í, ó, ú, ü, ¿, ¡, ç, ß Documentación actualizada en REFERENCE.md con tabla de fuentes y ejemplos de uso. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
35 KiB
zcatgui Reference Manual
Version: 0.15.0 Language: Zig 0.15.2 Paradigm: Immediate Mode GUI Lines of Code: ~35,000 across 81 source files
Table of Contents
- Overview
- Installation & Setup
- Quick Start
- Architecture
- Core Modules
- Widgets (37 total)
- Rendering System
- Animation & Effects
- Backend System
- Macro System
- Panel System
- Performance Utilities
- Theme System
- Accessibility
- Gesture Recognition
- API Reference
Overview
zcatgui is an immediate-mode GUI library for Zig featuring:
- Software Rendering: Works on any computer without GPU (SSH compatible)
- Cross-Platform: Linux, Windows, macOS, Web (WASM), Android, iOS
- Macro System: Record and replay user actions (cornerstone feature)
- 37 Widgets: From basic labels to complex tables and charts
- Zero External Dependencies: Only SDL2 for desktop windowing
Design Philosophy
"Maximum compatibility, minimum dependencies, total user control"
- Immediate mode = explicit state, no callbacks, no threading hell
- Software rendering first, GPU optional later
- Macro system integrated from the design phase
- Works on old laptops, new workstations, and via SSH
Installation & Setup
Requirements
- Zig 0.15.2
- SDL2 (for desktop builds only)
Build Commands
# Build library and examples
zig build
# Run tests
zig build test
# Run examples
zig build hello # Hello world
zig build widgets-demo # Widget showcase
zig build table-demo # Table with split panels
zig build macro-demo # Macro recording demo
# Platform-specific builds
zig build wasm # Web (WASM) - outputs to web/
zig build android # Android ARM64
zig build android-x86 # Android x86_64 (emulator)
zig build ios # iOS ARM64 (device)
zig build ios-sim # iOS ARM64 (simulator)
Project Integration
Add to your build.zig.zon:
.dependencies = .{
.zcatgui = .{
.path = "../path/to/zcatgui",
},
},
Quick Start
const zcatgui = @import("zcatgui");
const Context = zcatgui.Context;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
// Initialize context
var ctx = try Context.init(allocator);
defer ctx.deinit();
// Main loop
while (ctx.running) {
ctx.beginFrame();
// Draw a button
if (zcatgui.button(&ctx, "Click me!")) {
// Handle click
}
// Draw a label
zcatgui.label(&ctx, "Hello, zcatgui!");
ctx.endFrame();
}
}
Architecture
Layer Diagram
┌─────────────────────────────────────────────────────────────┐
│ Layer 4: Widgets (37 widgets) │
│ Button, Table, Tree, Chart, Modal, etc. │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: Macro System + Panels │
│ MacroRecorder, MacroPlayer, AutonomousPanel, Composites │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: Core UI │
│ Context, Layout, Style, Input, Command, DragDrop, Gesture │
├─────────────────────────────────────────────────────────────┤
│ Layer 1: Rendering │
│ SoftwareRenderer, Framebuffer, Font, TTF, Animation │
├─────────────────────────────────────────────────────────────┤
│ Layer 0: Backends │
│ SDL2, WASM, Android, iOS │
└─────────────────────────────────────────────────────────────┘
File Structure
zcatgui/
├── src/
│ ├── zcatgui.zig # Main entry point, re-exports
│ ├── core/ # Core modules
│ │ ├── context.zig # UI context, frame management
│ │ ├── layout.zig # Rect, Constraint, Layout
│ │ ├── style.zig # Color, Theme, ThemeManager
│ │ ├── input.zig # Key, Mouse, InputState
│ │ ├── command.zig # DrawCommand list
│ │ ├── clipboard.zig # Clipboard operations
│ │ ├── dragdrop.zig # Drag and drop system
│ │ ├── shortcuts.zig # Keyboard shortcuts
│ │ ├── focus_group.zig # Focus navigation
│ │ ├── accessibility.zig # A11y roles and states
│ │ └── gesture.zig # Touch gesture recognition
│ ├── widgets/ # 37 widgets
│ │ └── widgets.zig # Re-exports all widgets
│ ├── render/ # Rendering
│ │ ├── framebuffer.zig # Pixel buffer
│ │ ├── software.zig # Software rasterizer
│ │ ├── font.zig # Bitmap fonts
│ │ ├── ttf.zig # TrueType fonts
│ │ ├── animation.zig # Easing, Animation, Spring
│ │ ├── effects.zig # Shadow, Gradient, Blur
│ │ └── antialiasing.zig # AA drawing functions
│ ├── backend/ # Platform backends
│ │ ├── backend.zig # Abstract interface
│ │ ├── sdl2.zig # SDL2 (desktop)
│ │ ├── wasm.zig # WebAssembly
│ │ ├── android.zig # Android NDK
│ │ └── ios.zig # iOS UIKit
│ ├── macro/ # Macro system
│ │ └── macro.zig # Recorder, Player, Storage
│ ├── panels/ # Panel architecture
│ │ ├── panels.zig # Re-exports
│ │ ├── panel.zig # AutonomousPanel
│ │ ├── composite.zig # Composite patterns
│ │ └── data_manager.zig # Observer pattern
│ └── utils/ # Utilities
│ ├── utils.zig # Re-exports
│ ├── arena.zig # FrameArena, ScopedArena
│ ├── pool.zig # ObjectPool, CommandPool
│ ├── benchmark.zig # Timer, Benchmark
│ └── testing.zig # TestRunner, Assertions
├── examples/ # Example applications
├── web/ # WASM build output
├── ios/ # iOS bridge files
└── docs/ # Documentation
Core Modules
Context (src/core/context.zig)
The UI context manages frame lifecycle, command queue, and dirty regions.
const Context = zcatgui.Context;
// Create context
var ctx = try Context.init(allocator);
defer ctx.deinit();
// Frame lifecycle
ctx.beginFrame();
// ... draw widgets ...
ctx.endFrame();
// Access components
ctx.layout // LayoutState
ctx.input // InputState
ctx.commands // Command list
ctx.frame_arena // Per-frame allocator
// Dirty rectangle tracking
ctx.invalidateRect(rect);
ctx.needsRedraw();
ctx.getDirtyRects();
Key Types:
Context- Main UI contextFrameStats- Performance statistics
Layout (src/core/layout.zig)
Rectangle and constraint-based layout system.
const Layout = zcatgui.Layout;
const Rect = zcatgui.Rect;
const Constraint = zcatgui.Constraint;
// Create rectangles
const rect = Rect.init(x, y, width, height);
// Rectangle operations
rect.contains(point_x, point_y)
rect.intersection(other_rect)
rect.union_rect(other_rect)
rect.isEmpty()
rect.left(), rect.right(), rect.top(), rect.bottom()
rect.center()
rect.inset(amount)
rect.expand(amount)
// Constraints
const constraint = Constraint{
.min_width = 100,
.max_width = 500,
.min_height = 50,
.max_height = 200,
};
Style (src/core/style.zig)
Colors and theming system.
const Style = zcatgui.Style;
const Color = zcatgui.Color;
const Theme = zcatgui.Theme;
// Color creation
const red = Color.rgb(255, 0, 0);
const semi_transparent = Color.rgba(255, 0, 0, 128);
// Predefined colors
Color.white, Color.black, Color.red, Color.green, Color.blue
Color.primary, Color.secondary, Color.success, Color.warning, Color.danger
// Color operations
color.toABGR() // For framebuffer
color.blend(background) // Alpha blending
color.withAlpha(128) // New alpha value
// Theme system
const theme = zcatgui.currentTheme();
theme.colors.primary
theme.colors.background
theme.colors.text
Built-in Themes: dark, light, high_contrast, nord, dracula
Input (src/core/input.zig)
Keyboard and mouse input handling.
const Input = zcatgui.Input;
const InputState = Input.InputState;
// In your frame loop
const input = &ctx.input;
// Keyboard
input.keyPressed(.enter) // Just pressed this frame
input.keyReleased(.escape) // Just released
input.keyDown(.left_shift) // Currently held
input.getChar() // Text input character
// Mouse
input.mousePressed(.left)
input.mouseReleased(.right)
input.mouseDown(.middle)
const pos = input.mousePos(); // {x, y}
input.mouseDelta() // Movement since last frame
input.scrollDelta() // Scroll wheel
// Modifiers
input.keyDown(.left_ctrl) or input.keyDown(.right_ctrl)
input.keyDown(.left_shift) or input.keyDown(.right_shift)
input.keyDown(.left_alt) or input.keyDown(.right_alt)
Key Enum: 130+ keys including .a-.z, .F1-.F12, .space, .enter, .tab, .escape, arrow keys, numpad, etc.
Command (src/core/command.zig)
Draw command system for batched rendering.
const Command = zcatgui.Command;
// Command types
Command.rect(x, y, w, h, color) // Filled rectangle
Command.rectOutline(x, y, w, h, color, thickness)
Command.text(x, y, text, color, font) // Text rendering
Command.line(x1, y1, x2, y2, color) // Line
Command.clip(x, y, w, h) // Push clip region
Command.clipEnd() // Pop clip region
Command.nop // No operation
Widgets
Basic Widgets
| Widget | File | Description |
|---|---|---|
| Label | widgets/label.zig |
Static text display |
| Button | widgets/button.zig |
Clickable button with importance levels |
| TextInput | widgets/text_input.zig |
Single-line text entry |
| TextArea | widgets/textarea.zig |
Multi-line text editor |
| Checkbox | widgets/checkbox.zig |
Boolean toggle |
| Radio | widgets/radio.zig |
Radio button groups |
| Switch | widgets/switch.zig |
Toggle switch (iOS style) |
Selection Widgets
| Widget | File | Description |
|---|---|---|
| Select | widgets/select.zig |
Dropdown selection |
| List | widgets/list.zig |
Scrollable list |
| AutoComplete | widgets/autocomplete.zig |
ComboBox with filtering |
| Menu | widgets/menu.zig |
Dropdown/context menus |
| Tabs | widgets/tabs.zig |
Tab container |
Data Widgets
| Widget | File | Description |
|---|---|---|
| Table | widgets/table.zig |
Editable data table with sorting |
| Tree | widgets/tree.zig |
Hierarchical tree view |
| VirtualScroll | widgets/virtual_scroll.zig |
Virtualized list for large data |
Input Widgets
| Widget | File | Description |
|---|---|---|
| Slider | widgets/slider.zig |
Range selection |
| NumberEntry | widgets/numberentry.zig |
Numeric input with validation |
| ColorPicker | widgets/colorpicker.zig |
Color selection |
| DatePicker | widgets/datepicker.zig |
Date selection calendar |
Feedback Widgets
| Widget | File | Description |
|---|---|---|
| Progress | widgets/progress.zig |
Bar, circle, and spinner |
| Tooltip | widgets/tooltip.zig |
Hover tooltips |
| Toast | widgets/toast.zig |
Non-blocking notifications |
| Badge | widgets/badge.zig |
Status labels and tags |
| Loader | widgets/loader.zig |
Loading indicators |
Layout Widgets
| Widget | File | Description |
|---|---|---|
| Split | widgets/split.zig |
HSplit/VSplit draggable panels |
| Panel | widgets/panel.zig |
Container with title bar |
| Modal | widgets/modal.zig |
Dialog windows |
| ScrollArea | widgets/scroll.zig |
Scrollable content region |
| Surface | widgets/surface.zig |
Elevated container (material) |
| Grid | widgets/grid.zig |
Grid layout container |
| Resize | widgets/resize.zig |
Resizable container |
| Divider | widgets/divider.zig |
Visual separator |
Navigation Widgets
| Widget | File | Description |
|---|---|---|
| AppBar | widgets/appbar.zig |
Top app bar |
| NavDrawer | widgets/navdrawer.zig |
Side navigation |
| Sheet | widgets/sheet.zig |
Bottom/side sheets |
| Breadcrumb | widgets/breadcrumb.zig |
Navigation breadcrumbs |
| Discloser | widgets/discloser.zig |
Expand/collapse sections |
Visual Widgets
| Widget | File | Description |
|---|---|---|
| Icon | widgets/icon.zig |
Icon display |
| IconButton | widgets/iconbutton.zig |
Icon-only button |
| Image | widgets/image.zig |
Image display with caching |
| RichText | widgets/richtext.zig |
Styled text spans |
| Canvas | widgets/canvas.zig |
Custom drawing area |
| Chart | widgets/chart.zig |
Line, bar, pie charts |
Interactive Widgets
| Widget | File | Description |
|---|---|---|
| Reorderable | widgets/reorderable.zig |
Drag-to-reorder list |
| Selectable | widgets/selectable.zig |
Selection container |
Widget Usage Examples
Button
// Simple button
if (zcatgui.button(&ctx, "Click me")) {
// Handle click
}
// Button with importance
if (zcatgui.buttonPrimary(&ctx, "Submit")) { ... }
if (zcatgui.buttonDanger(&ctx, "Delete")) { ... }
// Full configuration
const result = zcatgui.widgets.button.buttonEx(&ctx, "Save", .{
.importance = .primary,
.disabled = false,
.width = 120,
}, .{});
TextInput
var text_state = zcatgui.TextInputState{};
var buffer: [256]u8 = undefined;
const result = zcatgui.textInput(&ctx, &text_state, &buffer);
if (result.changed) {
// Text was modified
}
if (result.submitted) {
// Enter was pressed
}
Table
const columns = [_]zcatgui.widgets.Column{
.{ .name = "Name", .width = 150 },
.{ .name = "Age", .width = 80, .column_type = .number },
.{ .name = "Email", .width = 200 },
};
var table_state = zcatgui.widgets.TableState{};
const result = zcatgui.widgets.table.table(
&ctx,
&table_state,
&columns,
data,
row_count,
);
if (result.cell_edited) {
// Handle cell edit
}
if (result.row_added) {
// Add new row
}
Slider
var slider_state = zcatgui.widgets.SliderState{};
slider_state.setValue(50, 0, 100); // Initial value
const result = zcatgui.widgets.slider.slider(&ctx, &slider_state);
if (result.changed) {
const value = slider_state.getValueInt(0, 100);
}
Modal
var show_modal = false;
if (zcatgui.button(&ctx, "Open Modal")) {
show_modal = true;
}
if (show_modal) {
const result = zcatgui.widgets.modal.alert(
&ctx,
"Confirmation",
"Are you sure?",
);
if (result.confirmed or result.cancelled) {
show_modal = false;
}
}
Rendering System
Framebuffer (src/render/framebuffer.zig)
Software pixel buffer.
const Framebuffer = zcatgui.render.Framebuffer;
var fb = try Framebuffer.init(allocator, 800, 600);
defer fb.deinit();
// Operations
fb.clear(Color.black);
fb.setPixel(x, y, color);
fb.getPixel(x, y);
fb.fillRect(x, y, w, h, color);
fb.drawRect(x, y, w, h, color); // Outline
fb.drawLine(x1, y1, x2, y2, color);
fb.drawHLine(x, y, w, color);
fb.drawVLine(x, y, h, color);
// For blitting to backend
fb.getData() // []const u32
fb.getPitch() // Bytes per row
SoftwareRenderer (src/render/software.zig)
Executes draw commands on framebuffer.
const SoftwareRenderer = zcatgui.render.SoftwareRenderer;
var renderer = SoftwareRenderer.init(&framebuffer);
renderer.setDefaultFont(&font);
// Execute commands
renderer.execute(command);
renderer.executeAll(command_slice);
// Clipping
renderer.getClip(); // Current clip rect
Font System
zcatgui provides multiple bitmap fonts for different use cases:
| Font | Size | Characters | Use Case |
|---|---|---|---|
default_font |
8x8 | ASCII | Compact displays, terminals |
default_font_latin1 |
8x8 | Latin-1 | Compact + Spanish/European |
font_8x16 |
8x16 | ASCII | Standard UI, good readability |
font_8x16_latin1 |
8x16 | Latin-1 | Standard UI + Spanish/European |
Latin-1 Character Support: ñ, Ñ, á, é, í, ó, ú, ü, ¿, ¡, ç, ß, and all Western European accented characters.
Bitmap Fonts (src/render/font.zig):
const render = zcatgui.render;
// Direct font access
const font = render.default_font_latin1; // 8x8 with Spanish support
const font_tall = render.font_8x16_latin1; // 8x16 taller, more readable
// Font by size category (recommended)
const small_font = render.getFontForSize(.small); // 8x8 Latin-1
const medium_font = render.getFontForSize(.medium); // 8x16 Latin-1
// ASCII-only variants (smaller memory)
const ascii_font = render.getFontForSizeAscii(.medium);
// Font operations
font.charWidth() // 8
font.charHeight() // 8 or 16
font.textWidth("Hello") // width in pixels
font.drawChar(fb, x, y, 'A', color, clip);
font.drawText(fb, x, y, "¿Hola, España!", color, clip);
Setting Default Font in Renderer:
var renderer = SoftwareRenderer.init(&framebuffer);
// Use 8x16 Latin-1 for better readability and Spanish support
renderer.setDefaultFont(@constCast(&render.font_8x16_latin1));
TrueType Fonts (src/render/ttf.zig):
const TtfFont = zcatgui.render.TtfFont;
var ttf = try TtfFont.loadFromFile(allocator, "font.ttf");
defer ttf.deinit();
ttf.setSize(16); // Set render size
const metrics = ttf.getGlyphMetrics('A');
ttf.textWidth("Hello");
Note
(bezier curve rendering) is planned for future releases. For production use, prefer the bitmap fonts which have complete glyph rendering.
Animation & Effects
Animation (src/render/animation.zig)
Easing Functions:
const Easing = zcatgui.Easing;
Easing.linear(t)
Easing.easeInQuad(t), Easing.easeOutQuad(t), Easing.easeInOutQuad(t)
Easing.easeInCubic(t), Easing.easeOutCubic(t), Easing.easeInOutCubic(t)
Easing.easeInSine(t), Easing.easeOutSine(t), Easing.easeInOutSine(t)
Easing.easeInExpo(t), Easing.easeOutExpo(t), Easing.easeInOutExpo(t)
Easing.easeInElastic(t), Easing.easeOutElastic(t)
Easing.easeInBounce(t), Easing.easeOutBounce(t), Easing.easeInOutBounce(t)
Easing.easeInBack(t), Easing.easeOutBack(t), Easing.easeInOutBack(t)
Animation:
const Animation = zcatgui.Animation;
var anim = Animation.create(0, 100, 1000, Easing.easeOutCubic);
anim.start(current_time_ms);
// In frame loop
const value = anim.getValue(current_time_ms);
if (anim.isComplete(current_time_ms)) {
// Animation done
}
Spring Physics:
const Spring = zcatgui.Spring;
const SpringConfig = zcatgui.SpringConfig;
var spring = Spring.create(0, 100, .{
.stiffness = 100,
.damping = 10,
.mass = 1,
});
// Each frame
spring.update(dt_seconds);
const value = spring.getValue();
if (spring.isSettled()) { ... }
AnimationManager:
const AnimationManager = zcatgui.AnimationManager;
var manager = AnimationManager.init();
manager.startAnimation(id, animation, time);
manager.getValue(id, time);
manager.stopAnimation(id);
manager.update(time);
Effects (src/render/effects.zig)
Shadows:
const Shadow = zcatgui.Shadow;
const shadow = Shadow{
.offset_x = 4,
.offset_y = 4,
.blur_radius = 8,
.color = Color.rgba(0, 0, 0, 128),
};
// Presets
Shadow.soft() // Subtle shadow
Shadow.hard() // No blur
Shadow.drop(offset, blur)
zcatgui.applyShadow(framebuffer, rect, shadow);
Gradients:
const Gradient = zcatgui.Gradient;
// Types
Gradient.horizontal(start_color, end_color)
Gradient.vertical(start_color, end_color)
Gradient.diagonal(start_color, end_color)
const gradient = Gradient{
.start_color = Color.rgb(255, 0, 0),
.end_color = Color.rgb(0, 0, 255),
.direction = .radial,
};
zcatgui.applyGradient(framebuffer, rect, gradient);
Color Operations:
zcatgui.interpolateColor(color_a, color_b, t) // Blend
zcatgui.applyOpacity(color, 0.5) // Reduce alpha
zcatgui.highlight(color, 50) // Lighter
zcatgui.lowlight(color, 50) // Darker
zcatgui.applyBlur(framebuffer, rect, radius) // Box blur
Anti-aliasing (src/render/antialiasing.zig)
const AA = zcatgui.render.antialiasing;
// Quality levels
AAQuality.none, AAQuality.low, AAQuality.medium, AAQuality.high
// AA drawing functions
zcatgui.drawLineAA(fb, x1, y1, x2, y2, color, quality)
zcatgui.drawCircleAA(fb, cx, cy, radius, color, quality)
zcatgui.drawRoundedRectAA(fb, rect, corner_radius, color, quality)
zcatgui.drawEllipseAA(fb, rect, color, quality)
zcatgui.drawPolygonAA(fb, points, color, quality)
Backend System
Abstract Interface (src/backend/backend.zig)
const Backend = zcatgui.backend.Backend;
// VTable interface
backend.pollEvent() // ?Event
backend.present(fb) // Display framebuffer
backend.getSize() // {width, height}
backend.deinit() // Cleanup
Event Types:
const Event = zcatgui.backend.Event;
event.key // KeyEvent
event.mouse // MouseEvent
event.resize // {width, height}
event.quit // Window close
event.text_input // Unicode text
SDL2 Backend (src/backend/sdl2.zig)
Desktop platform (Linux, Windows, macOS).
const Sdl2Backend = zcatgui.backend.Sdl2Backend;
var backend = try Sdl2Backend.init(allocator, "My App", 800, 600);
defer backend.deinit();
while (backend.pollEvent()) |event| {
// Handle events
}
backend.present(&framebuffer);
WASM Backend (src/backend/wasm.zig)
Browser via WebAssembly.
// Zig side - exports these functions
export fn wasm_main() void { ... }
export fn wasm_frame(time: f64) void { ... }
export fn wasm_resize(w: u32, h: u32) void { ... }
export fn wasm_mouse_move(x: i32, y: i32) void { ... }
export fn wasm_mouse_button(btn: u8, down: bool) void { ... }
export fn wasm_key_event(code: u16, down: bool) void { ... }
JavaScript integration (web/zcatgui.js):
// Load and initialize
const app = await ZcatguiApp.create('canvas-id', 'zcatgui-demo.wasm');
app.start();
Build: zig build wasm outputs to web/zcatgui-demo.wasm (18KB)
Android Backend (src/backend/android.zig)
Native Android via NDK.
// Exports for JNI
export fn ANativeActivity_onCreate(...) void { ... }
// Logging
zcatgui.backend.android.log("Message: {}", .{value});
Build: zig build android (ARM64), zig build android-x86 (emulator)
iOS Backend (src/backend/ios.zig)
iOS via UIKit bridge.
Zig side:
// Extern C functions called from Objective-C
extern fn ios_view_init(w: u32, h: u32) void;
extern fn ios_view_present(pixels: [*]const u32, w: u32, h: u32) void;
extern fn ios_poll_event(buffer: [*]u8) u32;
Objective-C bridge (ios/ZcatguiBridge.m):
ZcatguiView: UIView subclass for framebuffer displayZcatguiViewController: View controller with CADisplayLink render loop- Touch event handling with queue
Build: zig build ios (device), zig build ios-sim (simulator)
Macro System
The macro system is a cornerstone feature of zcatgui, enabling recording and playback of user actions.
Design Philosophy
Raw keys, not semantic commands:
- Simpler (less code = less bugs)
- Like Vim (proven to work)
- Minimal memory usage
MacroRecorder (src/macro/macro.zig)
const MacroRecorder = zcatgui.MacroRecorder;
var recorder = MacroRecorder.init(allocator);
defer recorder.deinit();
// Record
recorder.start();
recorder.record(key_event); // Call for each key event
const events = recorder.stop();
// Save/Load
try recorder.save("macro.zcm");
try recorder.load("macro.zcm");
// Convert to named macro
const macro = try recorder.toMacro("my_macro");
MacroPlayer
const MacroPlayer = zcatgui.MacroPlayer;
// Injection function
fn injectKey(event: KeyEvent) void {
// Add to input queue
}
// Playback
MacroPlayer.play(events, injectKey);
MacroPlayer.playWithDelay(events, injectKey, 50); // 50ms between keys
MacroStorage
const MacroStorage = zcatgui.macro.MacroStorage;
var storage = MacroStorage.init(allocator);
defer storage.deinit();
try storage.store(macro);
const m = storage.get("macro_name");
storage.remove("macro_name");
const names = storage.list();
File Format
ZCATGUI_MACRO_V1
<key_code>,<modifiers>,<char>,<pressed>
...
Panel System
Lego-style composable panels based on Simifactu architecture.
AutonomousPanel (src/panels/panel.zig)
Self-contained UI component with own state, UI, and logic.
const AutonomousPanel = zcatgui.panels.AutonomousPanel;
const panel = AutonomousPanel{
.id = "my_panel",
.panel_type = .content,
.state = .active,
.build_fn = myBuildFn,
.refresh_fn = myRefreshFn,
.data_change_fn = myDataChangeFn,
};
Composite Patterns (src/panels/composite.zig)
const composite = zcatgui.panels.composite;
// Vertical stack
var vstack = composite.VerticalComposite.init();
vstack.add(panel1);
vstack.add(panel2);
// Horizontal stack
var hstack = composite.HorizontalComposite.init();
// Split with draggable divider
var split = composite.SplitComposite.init(.horizontal, 0.5);
// Tabs
var tabs = composite.TabComposite.init();
tabs.addTab("Tab 1", panel1);
tabs.addTab("Tab 2", panel2);
// Grid layout
var grid = composite.GridComposite.init(3, 2); // 3 columns, 2 rows
DataManager (src/panels/data_manager.zig)
Observer pattern for panel communication.
const DataManager = zcatgui.panels.DataManager;
var manager = DataManager.init(allocator);
defer manager.deinit();
// Subscribe to changes
manager.subscribe("data_key", myCallback);
// Notify changes
manager.notify(.{
.key = "data_key",
.change_type = .modified,
.data = payload,
});
// Global access
zcatgui.panels.setDataManager(&manager);
const dm = zcatgui.panels.getDataManager();
Performance Utilities
FrameArena (src/utils/arena.zig)
Per-frame allocator with O(1) reset.
const FrameArena = zcatgui.FrameArena;
var arena = try FrameArena.init(allocator, 1024 * 1024);
defer arena.deinit();
// Each frame
arena.reset();
const temp = arena.alloc(u8, 100);
// No need to free - reset clears everything
ObjectPool (src/utils/pool.zig)
Generic object pool for frequently reused objects.
const ObjectPool = zcatgui.ObjectPool;
var pool = ObjectPool(MyType).init(allocator, 100);
defer pool.deinit();
const obj = pool.acquire();
// Use obj...
pool.release(obj);
CommandPool
Specialized pool for draw commands.
const CommandPool = zcatgui.CommandPool;
var pool = CommandPool.init(allocator);
defer pool.deinit();
const cmd = pool.acquire();
pool.releaseAll();
Benchmark (src/utils/benchmark.zig)
const Timer = zcatgui.Timer;
const Benchmark = zcatgui.Benchmark;
const FrameTimer = zcatgui.FrameTimer;
// Simple timing
var timer = Timer.start();
// ... work ...
const elapsed_ns = timer.elapsed();
// Statistics
var bench = Benchmark.init();
for (iterations) |_| {
timer = Timer.start();
// ... work ...
bench.addSample(timer.elapsed());
}
bench.average();
bench.min();
bench.max();
bench.stddev();
bench.median();
// Frame timing
var frame_timer = FrameTimer.init();
// Each frame
frame_timer.tick();
frame_timer.fps();
frame_timer.frameTimeMs();
AllocationTracker
const AllocationTracker = zcatgui.AllocationTracker;
var tracker = AllocationTracker.init();
tracker.trackAlloc(size);
tracker.trackFree(size);
tracker.currentBytes();
tracker.peakBytes();
tracker.totalAllocations();
Theme System
Built-in Themes
const ThemeManager = zcatgui.ThemeManager;
// Get global manager
var manager = zcatgui.getThemeManager();
// Switch themes
manager.setTheme(.dark);
manager.setTheme(.light);
manager.setTheme(.high_contrast);
manager.setTheme(.nord);
manager.setTheme(.dracula);
// Get current theme
const theme = zcatgui.currentTheme();
theme.colors.primary
theme.colors.secondary
theme.colors.background
theme.colors.surface
theme.colors.text
theme.colors.text_secondary
theme.colors.border
theme.colors.success
theme.colors.warning
theme.colors.danger
Custom Themes
const custom_theme = Theme{
.name = "custom",
.colors = .{
.primary = Color.rgb(100, 150, 200),
.background = Color.rgb(30, 30, 30),
// ... etc
},
};
manager.registerTheme("custom", custom_theme);
Accessibility
Roles (src/core/accessibility.zig)
const A11yRole = zcatgui.A11yRole;
A11yRole.button
A11yRole.checkbox
A11yRole.radio
A11yRole.textbox
A11yRole.slider
A11yRole.progressbar
A11yRole.listbox
A11yRole.tree
A11yRole.table
A11yRole.dialog
// ... and more
States
const A11yState = zcatgui.A11yState;
const state = A11yState{
.disabled = false,
.focused = true,
.selected = false,
.checked = true,
.expanded = false,
};
Info
const A11yInfo = zcatgui.A11yInfo;
// Create info for widgets
A11yInfo.button("Submit")
A11yInfo.checkbox("Accept terms", is_checked)
A11yInfo.slider("Volume", 0, 100, current_value)
A11yInfo.progressBar("Loading", progress)
A11yInfo.listItem("Item 1", position, total)
// Announce for screen readers
var buf: [256]u8 = undefined;
const announcement = info.announce(&buf);
Manager
const A11yManager = zcatgui.A11yManager;
var manager = A11yManager.init(allocator);
defer manager.deinit();
manager.register(widget_id, a11y_info);
manager.setFocus(widget_id);
manager.queueAnnouncement("File saved", .polite);
Gesture Recognition
GestureRecognizer (src/core/gesture.zig)
const GestureRecognizer = zcatgui.GestureRecognizer;
const GestureType = zcatgui.GestureType;
var recognizer = GestureRecognizer.init(.{
.double_tap_time_ms = 300,
.long_press_time_ms = 500,
.swipe_min_distance = 50,
.swipe_min_velocity = 200,
});
// Each frame
const result = recognizer.update(&input_state, current_time_ms);
// Check gestures
if (recognizer.detected(.tap)) { ... }
if (recognizer.detected(.double_tap)) { ... }
if (recognizer.detected(.long_press)) { ... }
if (recognizer.detected(.swipe_left)) { ... }
if (recognizer.isDragging()) {
const delta = recognizer.dragDelta();
}
Gesture Types:
.tap- Single tap.double_tap- Double tap.long_press- Press and hold.drag- Press and move.swipe_left,.swipe_right,.swipe_up,.swipe_down.pinch,.rotate(future touch support)
API Reference
Main Module Exports (src/zcatgui.zig)
// Core
pub const Context
pub const Layout
pub const Style
pub const Input
pub const Command
pub const clipboard
pub const dragdrop
pub const shortcuts
pub const focus_group
pub const accessibility
pub const gesture
// Rendering
pub const render.Framebuffer
pub const render.SoftwareRenderer
pub const render.Font
pub const render.TtfFont
pub const render.animation
pub const render.effects
pub const render.antialiasing
// Animation (re-exports)
pub const Animation
pub const AnimationManager
pub const Easing
pub const Spring
pub const SpringConfig
pub const lerp
pub const lerpInt
// Effects (re-exports)
pub const Shadow
pub const Gradient
pub const applyShadow
pub const applyGradient
pub const applyBlur
pub const interpolateColor
pub const highlight
pub const lowlight
// Backend
pub const backend.Backend
pub const backend.Sdl2Backend // Desktop only
pub const backend.wasm // WASM only
pub const backend.android // Android only
pub const backend.ios // iOS only
// Macro
pub const macro
pub const MacroRecorder
pub const MacroPlayer
pub const KeyEvent
// Widgets (37 total)
pub const widgets
// Widget shortcuts
pub const label, labelEx, labelColored, labelCentered
pub const button, buttonEx, buttonPrimary, buttonDanger
pub const textInput, textInputEx, TextInputState
pub const checkbox, checkboxEx
pub const select, selectEx, SelectState
pub const list, listEx, ListState
pub const FocusManager, FocusRing
// Panels
pub const panels
// Utils
pub const utils
pub const FrameArena
pub const ScopedArena
pub const ObjectPool
pub const CommandPool
pub const RingBuffer
pub const Benchmark
pub const Timer
pub const FrameTimer
pub const AllocationTracker
// Types
pub const Color
pub const Rect
pub const Constraint
pub const Theme
pub const ThemeManager
Version History
| Version | Date | Changes |
|---|---|---|
| 0.15.0 | 2025-12-09 | Mobile/Web backends (WASM, Android, iOS) |
| 0.14.1 | 2025-12-09 | Gio parity phase - 12 widgets + gesture system |
| 0.1.0 | 2025-12-09 | Initial release - core + macros + basic widgets |
License
MIT License
Related Projects
- zcatui: TUI library for terminal interfaces (sibling project)
- microui: Inspiration for minimal architecture
- DVUI: Reference Zig immediate-mode implementation
- Gio: Go immediate-mode GUI (feature parity target)
Generated: 2025-12-09