# zcatui - API Reference > Referencia rapida de la API publica de zcatui ## Importar la Libreria ```zig const zcatui = @import("zcatui"); // Core types const Color = zcatui.Color; const Style = zcatui.Style; const Modifier = zcatui.Modifier; const Cell = zcatui.Cell; const Buffer = zcatui.Buffer; const Rect = zcatui.Rect; const Span = zcatui.Span; const Line = zcatui.Line; const Text = zcatui.Text; const Alignment = zcatui.Alignment; // Layout const Layout = zcatui.Layout; const Constraint = zcatui.Constraint; const Direction = zcatui.Direction; // Terminal const Terminal = zcatui.Terminal; // Widgets const widgets = zcatui.widgets; const Block = widgets.Block; const Paragraph = widgets.Paragraph; const List = widgets.List; const ListState = widgets.ListState; // ... etc ``` --- ## Core Types ### Color ```zig pub const Color = union(enum) { // Reset reset, // Basic 16 colors black, red, green, yellow, blue, magenta, cyan, white, light_black, light_red, light_green, light_yellow, light_blue, light_magenta, light_cyan, light_white, // 256 color palette indexed: u8, // True color (24-bit) rgb: struct { r: u8, g: u8, b: u8 }, // Constructor helpers pub fn indexed(n: u8) Color; pub fn rgb(r: u8, g: u8, b: u8) Color; }; ``` **Ejemplos:** ```zig const red = Color.red; const gray = Color.indexed(240); const custom = Color.rgb(255, 128, 0); ``` ### Style ```zig pub const Style = struct { foreground: ?Color = null, background: ?Color = null, add_modifiers: Modifier = .{}, sub_modifiers: Modifier = .{}, pub const default: Style = .{}; // Fluent setters pub fn fg(self: Style, color: Color) Style; pub fn bg(self: Style, color: Color) Style; pub fn bold(self: Style) Style; pub fn dim(self: Style) Style; pub fn italic(self: Style) Style; pub fn underlined(self: Style) Style; pub fn slow_blink(self: Style) Style; pub fn rapid_blink(self: Style) Style; pub fn reversed(self: Style) Style; pub fn hidden(self: Style) Style; pub fn crossed_out(self: Style) Style; // Remove modifiers pub fn notBold(self: Style) Style; pub fn notDim(self: Style) Style; // ... etc // Combine styles pub fn patch(self: Style, other: Style) Style; }; ``` **Ejemplos:** ```zig const style1 = Style.default.fg(Color.red).bold(); const style2 = Style.default.bg(Color.blue).italic(); const combined = style1.patch(style2); // red fg, blue bg, bold+italic ``` ### Modifier ```zig pub const Modifier = packed struct { bold: bool = false, dim: bool = false, italic: bool = false, underlined: bool = false, slow_blink: bool = false, rapid_blink: bool = false, reversed: bool = false, hidden: bool = false, crossed_out: bool = false, pub const empty: Modifier = .{}; pub const all: Modifier = .{ .bold = true, ... }; pub fn contains(self: Modifier, other: Modifier) bool; pub fn insert(self: Modifier, other: Modifier) Modifier; pub fn remove(self: Modifier, other: Modifier) Modifier; }; ``` ### Rect ```zig pub const Rect = struct { x: u16, y: u16, width: u16, height: u16, pub fn init(x: u16, y: u16, width: u16, height: u16) Rect; // Getters pub fn left(self: Rect) u16; // x pub fn right(self: Rect) u16; // x + width pub fn top(self: Rect) u16; // y pub fn bottom(self: Rect) u16; // y + height pub fn area(self: Rect) u32; // width * height // Queries pub fn isEmpty(self: Rect) bool; pub fn contains(self: Rect, x: u16, y: u16) bool; // Transformations pub fn inner(self: Rect, margin: u16) Rect; pub fn innerMargins(self: Rect, top: u16, right: u16, bottom: u16, left_: u16) Rect; pub fn intersection(self: Rect, other: Rect) Rect; pub fn union_(self: Rect, other: Rect) Rect; }; ``` **Ejemplos:** ```zig const area = Rect.init(0, 0, 80, 24); const inner = area.inner(1); // Rect.init(1, 1, 78, 22) ``` ### Symbol Almacenamiento compacto UTF-8 (hasta 4 bytes). Optimizado para evitar conversiones en render. ```zig pub const Symbol = struct { data: [4]u8 = .{ ' ', 0, 0, 0 }, len: u3 = 1, pub const default_val: Symbol = .{}; pub const space: Symbol = .{}; // Constructores pub fn fromSlice(bytes: []const u8) Symbol; pub fn fromCodepoint(cp: u21) Symbol; // Acceso pub fn slice(self: Symbol) []const u8; // Para output directo pub fn eql(self: Symbol, other: Symbol) bool; }; ``` ### Cell ```zig pub const Cell = struct { symbol: Symbol = Symbol.space, fg: Color = .reset, bg: Color = .reset, modifiers: Modifier = .{}, pub const empty: Cell = .{}; // Constructores pub fn init(cp: u21) Cell; pub fn fromStr(s: []const u8) Cell; // Modificadores pub fn setStyle(self: *Cell, s: Style) void; pub fn setChar(self: *Cell, cp: u21) void; pub fn setSymbol(self: *Cell, s: []const u8) void; pub fn reset(self: *Cell) void; // Comparación (para diff) pub fn eql(self: Cell, other: Cell) bool; // Legacy accessor pub fn char(self: Cell) u21; // Decodifica symbol a codepoint }; ``` ### Buffer ```zig pub const Buffer = struct { area: Rect, cells: []Cell, allocator: Allocator, pub fn init(allocator: Allocator, area: Rect) !Buffer; pub fn deinit(self: *Buffer) void; // Cell access pub fn getPtr(self: *Buffer, x: u16, y: u16) ?*Cell; pub fn getCell(self: *Buffer, x: u16, y: u16) ?*Cell; // Alias pub fn get(self: *const Buffer, x: u16, y: u16) ?Cell; // Setting content pub fn setChar(self: *Buffer, x: u16, y: u16, cp: u21, s: Style) void; pub fn setString(self: *Buffer, x: u16, y: u16, text: []const u8, style: Style) u16; pub fn setStyle(self: *Buffer, area: Rect, style: Style) void; // Filling pub fn fill(self: *Buffer, rect: Rect, cp: u21, s: Style) void; pub fn clear(self: *Buffer) void; // Differential rendering (v1.1) pub fn diff(self: *const Buffer, other: *const Buffer) DiffIterator; pub fn resize(self: *Buffer, new_rect: Rect) !void; pub fn merge(self: *Buffer, other: *const Buffer) void; // Legacy (no-op, for compatibility) pub fn markDirty(self: *Buffer) void; pub fn markClean(self: *Buffer) void; }; // Iterator para renderizado diferencial pub const DiffIterator = struct { pub fn next(self: *DiffIterator) ?CellUpdate; pub fn countRemaining(self: *DiffIterator) usize; }; pub const CellUpdate = struct { x: u16, y: u16, cell: Cell, }; ``` **Ejemplos:** ```zig var buf = try Buffer.init(allocator, Rect.init(0, 0, 80, 24)); defer buf.deinit(); _ = buf.setString(10, 5, "Hello, World!", Style.default.fg(Color.green)); if (buf.getCell(10, 5)) |cell| { cell.setStyle(Style.default.bold()); } ``` --- ## Text Types ### Span ```zig pub const Span = struct { content: []const u8, style: Style, pub fn init(content: []const u8) Span; pub fn raw(content: []const u8) Span; pub fn styled(content: []const u8, style: Style) Span; pub fn setStyle(self: Span, style: Style) Span; pub fn width(self: Span) usize; }; ``` ### Line ```zig pub const Line = struct { spans: []const Span, alignment: Alignment, pub fn init(spans: []const Span) Line; pub fn raw(content: []const u8) Line; pub fn styled(content: []const u8, style: Style) Line; pub fn setStyle(self: Line, style: Style) Line; pub fn setAlignment(self: Line, alignment: Alignment) Line; pub fn width(self: Line) usize; }; ``` ### Text ```zig pub const Text = struct { lines: []const Line, alignment: Alignment, pub fn init(lines: []const Line) Text; pub fn raw(content: []const u8) Text; pub fn styled(content: []const u8, style: Style) Text; pub fn setStyle(self: Text, style: Style) Text; pub fn setAlignment(self: Text, alignment: Alignment) Text; pub fn width(self: Text) usize; pub fn height(self: Text) usize; }; ``` ### Alignment ```zig pub const Alignment = enum { left, center, right, }; ``` **Ejemplos:** ```zig // Simple text const span = Span.styled("Hello", Style.default.fg(Color.red)); const line = Line.raw("Simple line"); // Multi-span line const multi_line = Line.init(&[_]Span{ Span.styled("Error: ", Style.default.fg(Color.red).bold()), Span.raw("Something went wrong"), }); // Multi-line text const text = Text.raw("Line 1\nLine 2\nLine 3"); ``` --- ## Layout ### Layout ```zig pub const Layout = struct { direction: Direction, constraints: []const Constraint, pub fn horizontal(constraints: []const Constraint) Layout; pub fn vertical(constraints: []const Constraint) Layout; pub fn init(direction: Direction, constraints: []const Constraint) Layout; pub fn split(self: Layout, area: Rect, result: []Rect) void; }; ``` ### Constraint ```zig pub const Constraint = union(enum) { length: u16, // Exactly N cells min: u16, // At least N cells max: u16, // At most N cells percentage: u16, // N% of available space (0-100) ratio: struct { num: u32, den: u32 }, fill: u16, // Fill remaining space (weight) pub fn length(n: u16) Constraint; pub fn min(n: u16) Constraint; pub fn max(n: u16) Constraint; pub fn percentage(n: u16) Constraint; pub fn ratio(num: u32, den: u32) Constraint; pub fn fill(weight: u16) Constraint; }; ``` ### Direction ```zig pub const Direction = enum { horizontal, vertical, }; ``` **Ejemplos:** ```zig // Vertical layout: header (3 rows), content (rest), footer (1 row) const layout = Layout.vertical(&[_]Constraint{ Constraint.length(3), Constraint.min(0), Constraint.length(1), }); var chunks: [3]Rect = undefined; layout.split(area, &chunks); // Horizontal split: 30% | 70% const h_layout = Layout.horizontal(&[_]Constraint{ Constraint.percentage(30), Constraint.percentage(70), }); ``` --- ## Symbols ### Line Set ```zig pub const line = struct { pub const Set = struct { vertical: []const u8, horizontal: []const u8, top_right: []const u8, top_left: []const u8, bottom_right: []const u8, bottom_left: []const u8, vertical_left: []const u8, vertical_right: []const u8, horizontal_down: []const u8, horizontal_up: []const u8, cross: []const u8, }; pub const NORMAL: Set; // ─│┌┐└┘ pub const ROUNDED: Set; // ─│╭╮╰╯ pub const DOUBLE: Set; // ═║╔╗╚╝ pub const THICK: Set; // ━┃┏┓┗┛ }; ``` ### Border Set ```zig pub const border = struct { pub const Set = struct { top_left: []const u8, top_right: []const u8, bottom_left: []const u8, bottom_right: []const u8, horizontal: []const u8, vertical: []const u8, }; pub const PLAIN: Set; pub const ROUNDED: Set; pub const DOUBLE: Set; pub const THICK: Set; }; ``` ### Block Characters ```zig pub const block = struct { pub const FULL: []const u8 = "█"; pub const UPPER_HALF: []const u8 = "▀"; pub const LOWER_HALF: []const u8 = "▄"; pub const LEFT_HALF: []const u8 = "▌"; pub const RIGHT_HALF: []const u8 = "▐"; // ... }; ``` ### Bar Characters ```zig pub const bar = struct { pub const Set = struct { full: []const u8, seven_eighths: []const u8, three_quarters: []const u8, five_eighths: []const u8, half: []const u8, three_eighths: []const u8, one_quarter: []const u8, one_eighth: []const u8, empty: []const u8, }; pub const NINE_LEVELS: Set; pub const THREE_LEVELS: Set; }; ``` ### Braille ```zig pub const braille = struct { pub const BLANK: []const u8 = "⠀"; // U+2800 // Bit positions for 2x4 grid: // 0 3 // 1 4 // 2 5 // 6 7 pub const PATTERNS: [256][3]u8; // Pre-computed UTF-8 patterns pub fn fromPattern(pattern: u8) []const u8; }; ``` ### Marker ```zig pub const Marker = enum { dot, block, bar, braille, half_block, }; ``` --- ## Terminal ```zig pub const Terminal = struct { pub fn init(allocator: Allocator) !Terminal; pub fn deinit(self: *Terminal) void; pub fn size(self: Terminal) struct { width: u16, height: u16 }; pub fn area(self: Terminal) Rect; pub fn draw(self: *Terminal, render_fn: fn(area: Rect, buf: *Buffer) void) !void; pub fn clear(self: *Terminal) !void; pub fn flush(self: *Terminal) !void; pub fn hideCursor(self: *Terminal) !void; pub fn showCursor(self: *Terminal) !void; pub fn setCursorPosition(self: *Terminal, x: u16, y: u16) !void; pub fn enterAlternateScreen(self: *Terminal) !void; pub fn leaveAlternateScreen(self: *Terminal) !void; pub fn enableRawMode(self: *Terminal) !void; pub fn disableRawMode(self: *Terminal) !void; }; ``` **Ejemplo de uso:** ```zig pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); var term = try Terminal.init(allocator); defer term.deinit(); try term.enterAlternateScreen(); defer term.leaveAlternateScreen() catch {}; try term.hideCursor(); defer term.showCursor() catch {}; try term.draw(struct { pub fn render(area: Rect, buf: *Buffer) void { const block = Block.bordered().title("Hello zcatui!"); block.render(area, buf); } }.render); // Wait for input... } ``` --- ## Widgets Quick Reference | Widget | Constructor | Stateful | Key Methods | |--------|------------|----------|-------------| | Block | `Block.init()` | No | `title()`, `borders()`, `borderStyle()` | | Paragraph | `Paragraph.init(text)` | No | `setWrap()`, `setAlignment()`, `setScroll()` | | List | `List.init(items)` | Yes | `setHighlightStyle()`, `setHighlightSymbol()` | | Table | `Table.init(rows, widths)` | Yes | `setHeader()`, `setHighlightStyle()` | | Gauge | `Gauge.init()` | No | `setRatio()`, `setPercent()`, `setLabel()` | | LineGauge | `LineGauge.init()` | No | `setRatio()`, `setFilledStyle()` | | Tabs | `Tabs.init(titles)` | No | `select()`, `setDivider()` | | Sparkline | `Sparkline.init()` | No | `setData()`, `setMax()` | | Scrollbar | `Scrollbar.init(orientation)` | Yes | `setSymbols()`, `setStyle()` | | BarChart | `BarChart.init()` | No | `setData()`, `setBarWidth()` | | Canvas | `Canvas.init()` | No | `setXBounds()`, `setYBounds()`, `paint()` | | Chart | `Chart.init(datasets)` | No | `setXAxis()`, `setYAxis()` | | Monthly | `Monthly.init(date)` | No | `showMonthHeader()`, `showWeekdaysHeader()` | | Clear | `Clear.init()` | No | (none) | --- ## Error Handling zcatui usa el sistema de errores de Zig. Las funciones que pueden fallar retornan `!T`. ```zig // Errores comunes const TerminalError = error{ InitFailed, WriteFailed, FlushFailed, }; const BufferError = error{ OutOfMemory, }; // Manejo tipico var term = Terminal.init(allocator) catch |err| { std.debug.print("Failed to init terminal: {}\n", .{err}); return err; }; defer term.deinit(); ``` --- ## Patterns ### Builder Pattern ```zig const widget = SomeWidget.init() .setOption1(value1) .setOption2(value2) .setBlock(Block.bordered()); ``` ### Stateful Rendering ```zig var state = WidgetState.init(); // En el loop de renderizado: widget.renderStateful(area, buf, &state); // Actualizar estado basado en input: state.selectNext(items.len); ``` ### Layout Composition ```zig const outer = Layout.vertical(&[_]Constraint{ Constraint.length(3), Constraint.min(0), }); var outer_chunks: [2]Rect = undefined; outer.split(area, &outer_chunks); const inner = Layout.horizontal(&[_]Constraint{ Constraint.percentage(50), Constraint.percentage(50), }); var inner_chunks: [2]Rect = undefined; inner.split(outer_chunks[1], &inner_chunks); ```