# zcatui v2.1 - Manual Técnico de Referencia > Referencia completa de todos los módulos, widgets y funcionalidades implementadas. --- ## Índice 1. [Arquitectura General](#arquitectura-general) 2. [Módulos Core](#módulos-core) 3. [Widgets](#widgets) 4. [Sistema de Eventos](#sistema-de-eventos) 5. [Layout y Posicionamiento](#layout-y-posicionamiento) 6. [Themes y Estilos](#themes-y-estilos) 7. [Innovaciones v2.1](#innovaciones-v21) 8. [Utilidades](#utilidades) --- ## Arquitectura General ``` ┌─────────────────────────────────────────────────────────────┐ │ Application │ ├─────────────────────────────────────────────────────────────┤ │ Widgets (34 tipos) │ Layout │ Events │ Animation │ ├─────────────────────────────────────────────────────────────┤ │ Buffer (diff) │ Style │ Text │ Symbols │ ├─────────────────────────────────────────────────────────────┤ │ Terminal Backend │ └─────────────────────────────────────────────────────────────┘ ``` ### Flujo de Renderizado 1. **Frame Start**: El usuario llama a `terminal.draw()` 2. **Widget Render**: Cada widget escribe al Buffer 3. **Diff**: Se calcula qué celdas cambiaron 4. **Output**: Solo los cambios van al terminal --- ## Módulos Core ### Buffer (`src/buffer.zig`) El buffer es la representación en memoria de la pantalla. ```zig const Buffer = @import("zcatui").Buffer; const Rect = @import("zcatui").Rect; // Crear buffer var buf = try Buffer.init(allocator, Rect.init(0, 0, 80, 24)); defer buf.deinit(); // Obtener celda if (buf.get(x, y)) |cell| { // cell.symbol, cell.style } // Limpiar buf.clear(); // Redimensionar try buf.resize(new_rect); ``` **Tipos importantes:** - `Cell`: Una celda con símbolo y estilo - `Rect`: Rectángulo (x, y, width, height) - `Symbol`: Carácter Unicode (hasta 7 bytes inline) ### Style (`src/style.zig`) Sistema de estilos con colores y modificadores. ```zig const Style = @import("zcatui").Style; const Color = @import("zcatui").Color; // Crear estilo const style = Style.init() .fg(Color.red) .bg(Color.black) .bold() .italic() .underline(); // Colores disponibles Color.reset // Terminal default Color.black // ANSI 0 Color.red // ANSI 1 Color.green // ANSI 2 Color.yellow // ANSI 3 Color.blue // ANSI 4 Color.magenta // ANSI 5 Color.cyan // ANSI 6 Color.white // ANSI 7 Color.indexed(n) // 256-color palette Color.rgb(r,g,b) // True color ``` ### Text (`src/text.zig`) Texto con estilos inline. ```zig const Text = @import("zcatui").Text; const Line = @import("zcatui").Line; const Span = @import("zcatui").Span; // Texto simple const text = Text.raw("Hello, World!"); // Con estilos const styled = Text.fromSpans(&.{ Span.styled("Error: ", Style.init().fg(Color.red).bold()), Span.raw("file not found"), }); // Alineación text.alignment(.center); ``` --- ## Widgets ### Widgets Básicos #### Block (`src/widgets/block.zig`) Contenedor con bordes y títulos. ```zig const Block = @import("zcatui").widgets.Block; const block = Block.init() .title("Mi Panel") .borders(.all) .borderType(.rounded) .style(Style.init().fg(Color.blue)); block.render(area, buf); ``` #### Paragraph (`src/widgets/paragraph.zig`) Texto con word-wrap. ```zig const Paragraph = @import("zcatui").widgets.Paragraph; const para = Paragraph.init(text) .block(block) .alignment(.center) .wrap(.word); para.render(area, buf); ``` #### List (`src/widgets/list.zig`) Lista seleccionable. ```zig const List = @import("zcatui").widgets.List; const ListState = @import("zcatui").widgets.ListState; var state = ListState{}; state.select(0); const list = List.init(&items) .block(block) .highlightStyle(Style.init().bg(Color.blue)) .highlightSymbol("> "); list.render(area, buf, &state); // Navegación state.selectNext(items.len); state.selectPrevious(items.len); ``` #### Table (`src/widgets/table.zig`) Tabla multi-columna. ```zig const Table = @import("zcatui").widgets.Table; const TableState = @import("zcatui").widgets.TableState; var state = TableState{}; const table = Table.init(&rows) .header(header_row) .widths(&.{ .{ .percentage = 30 }, .{ .percentage = 70 }, }) .highlightStyle(highlight); table.render(area, buf, &state); ``` ### Widgets de Progreso #### Gauge (`src/widgets/gauge.zig`) Barra de progreso simple. ```zig const Gauge = @import("zcatui").widgets.Gauge; const gauge = Gauge.init() .percent(75) .label("75%") .gaugeStyle(Style.init().fg(Color.green)); gauge.render(area, buf); ``` #### Progress (`src/widgets/progress.zig`) - **NUEVO v2.1** Barra de progreso con ETA y velocidad. ```zig const Progress = @import("zcatui").widgets.Progress; var progress = Progress.init(100); // 100 items total progress.start(); // En cada iteración progress.tick(); // o progress.set(n); // Obtener métricas const eta = progress.etaSeconds(); const speed = progress.itemsPerSecond(); const elapsed = progress.elapsedSeconds(); progress.render(area, buf); ``` **Formatos:** - `.bar`: Barra simple - `.bar_with_percent`: Barra + porcentaje - `.bar_with_eta`: Barra + ETA - `.full`: Barra + porcentaje + ETA + velocidad #### Spinner (`src/widgets/spinner.zig`) - **NUEVO v2.1** Indicador de carga animado. ```zig const Spinner = @import("zcatui").widgets.Spinner; const SpinnerStyle = @import("zcatui").widgets.SpinnerStyle; var spinner = Spinner.init(.dots); // 17 estilos disponibles // En el loop de eventos spinner.tick(); spinner.render(area, buf); // Estilos disponibles: // .dots, .dots2, .dots3, .line, .line2 // .pipe, .simple_dots, .simple_dots_scrolling // .star, .star2, .flip, .hamburger // .grow_vertical, .grow_horizontal, .balloon // .noise, .bounce, .box_bounce ``` ### Widgets de Navegación #### Tabs (`src/widgets/tabs.zig`) Pestañas de navegación. ```zig const Tabs = @import("zcatui").widgets.Tabs; const tabs = Tabs.init(&.{"Home", "Settings", "Help"}) .select(0) .highlightStyle(Style.init().bold()); tabs.render(area, buf); ``` #### Menu (`src/widgets/menu.zig`) Menús desplegables. ```zig const Menu = @import("zcatui").widgets.Menu; const MenuItem = @import("zcatui").widgets.MenuItem; const MenuBar = @import("zcatui").widgets.MenuBar; // Menú simple const menu = Menu.init(&items) .title("File") .width(20); // Barra de menú const menubar = MenuBar.init(&.{ MenuBarItem.init("File", &file_items), MenuBarItem.init("Edit", &edit_items), }); ``` #### Tree (`src/widgets/tree.zig`) Vista de árbol. ```zig const Tree = @import("zcatui").widgets.Tree; const TreeItem = @import("zcatui").widgets.TreeItem; const TreeState = @import("zcatui").widgets.TreeState; var state = TreeState{}; const tree = Tree.init(&items) .block(block) .highlightStyle(highlight); tree.render(area, buf, &state); // Navegación state.toggle(); // Expandir/colapsar state.selectNext(); state.selectPrevious(); ``` #### DirectoryTree (`src/widgets/dirtree.zig`) - **NUEVO v2.1** Navegador de sistema de archivos. ```zig const DirectoryTree = @import("zcatui").widgets.DirectoryTree; var dirtree = try DirectoryTree.init(allocator, "/home/user"); defer dirtree.deinit(); // Cargar contenido try dirtree.loadRoot(); // Navegación dirtree.moveDown(); dirtree.moveUp(); dirtree.toggleExpand(); dirtree.goToParent(); dirtree.toggleHidden(); // Mostrar/ocultar archivos ocultos // Obtener selección actual if (dirtree.getSelected()) |node| { // node.path, node.name, node.kind } dirtree.render(area, buf); ``` ### Widgets de Entrada #### Input (`src/widgets/input.zig`) Campo de texto de una línea. ```zig const Input = @import("zcatui").widgets.Input; const InputState = @import("zcatui").widgets.InputState; var state = InputState.init(allocator); defer state.deinit(); const input = Input.init() .placeholder("Enter name...") .block(block); input.render(area, buf, &state); // Manejar eventos state.handleKey(key_event); const text = state.getText(); ``` #### TextArea (`src/widgets/textarea.zig`) Editor multi-línea. ```zig const TextArea = @import("zcatui").widgets.TextArea; var textarea = TextArea.init(allocator); defer textarea.deinit(); textarea.render(area, buf); textarea.handleKey(key_event); ``` #### Checkbox (`src/widgets/checkbox.zig`) Casillas de verificación. ```zig const Checkbox = @import("zcatui").widgets.Checkbox; const RadioGroup = @import("zcatui").widgets.RadioGroup; // Checkbox const checkbox = Checkbox.init("Accept terms") .checked(true); // Radio group var selected: usize = 0; const radio = RadioGroup.init(&.{"Option A", "Option B", "Option C"}, &selected); ``` #### Slider (`src/widgets/slider.zig`) Control deslizante. ```zig const Slider = @import("zcatui").widgets.Slider; var value: f32 = 0.5; const slider = Slider.init(&value) .min(0) .max(100) .step(1); slider.render(area, buf); ``` ### Widgets de Visualización #### Chart (`src/widgets/chart.zig`) Gráficos con ejes. ```zig const Chart = @import("zcatui").widgets.Chart; const Dataset = @import("zcatui").widgets.Dataset; const Axis = @import("zcatui").widgets.Axis; const chart = Chart.init(&.{ Dataset.init(&data_points) .name("Series 1") .graphType(.line) .style(Style.init().fg(Color.cyan)), }) .xAxis(Axis.init().title("Time")) .yAxis(Axis.init().title("Value").bounds(0, 100)); chart.render(area, buf); ``` #### BarChart (`src/widgets/barchart.zig`) Gráfico de barras. ```zig const BarChart = @import("zcatui").widgets.BarChart; const Bar = @import("zcatui").widgets.Bar; const barchart = BarChart.init(&.{ Bar.init(75).label("Mon"), Bar.init(90).label("Tue"), Bar.init(60).label("Wed"), }) .barWidth(5) .barGap(1); barchart.render(area, buf); ``` #### Sparkline (`src/widgets/sparkline.zig`) Mini-gráficos. ```zig const Sparkline = @import("zcatui").widgets.Sparkline; const spark = Sparkline.init(&data) .block(block) .style(Style.init().fg(Color.yellow)); spark.render(area, buf); ``` #### Calendar (`src/widgets/calendar.zig`) Calendario mensual. ```zig const Monthly = @import("zcatui").widgets.Monthly; const Date = @import("zcatui").widgets.Date; const calendar = Monthly.init(2024, 12) // Año, mes .showWeekNumbers(true) .highlightToday(true); calendar.render(area, buf); ``` #### Markdown (`src/widgets/markdown.zig`) - **NUEVO v2.1** Renderizado de Markdown. ```zig const Markdown = @import("zcatui").widgets.Markdown; const md = Markdown.init( \\# Título \\ \\Texto con **negrita** y *cursiva*. \\ \\- Item 1 \\- Item 2 \\ \\```zig \\const x = 42; \\``` ); md.render(area, buf); ``` **Soporta:** - Headers (# ## ###) - **Bold** y *Italic* - Listas (- y números) - Bloques de código - Citas (>) - Links [text](url) - Líneas horizontales (---) #### SyntaxHighlighter (`src/widgets/syntax.zig`) - **NUEVO v2.1** Resaltado de sintaxis. ```zig const SyntaxHighlighter = @import("zcatui").widgets.SyntaxHighlighter; const SyntaxLanguage = @import("zcatui").widgets.SyntaxLanguage; const highlighter = SyntaxHighlighter.init(.zig) .showLineNumbers(true) .highlightLine(5); // Resaltar línea 5 highlighter.render(code, area, buf); ``` **Lenguajes soportados:** - Zig, Rust, Go, C, C++ - Python, JavaScript, TypeScript - JSON, Bash ### Widgets de Overlay #### Popup (`src/widgets/popup.zig`) Ventanas emergentes y modales. ```zig const Popup = @import("zcatui").widgets.Popup; const Modal = @import("zcatui").widgets.Modal; // Popup simple const popup = Popup.init() .title("Info") .content("Message here") .percentSize(50, 30); popup.render(area, buf); // Modal con botones const modal = Modal.confirm("Delete file?", &on_confirm); modal.render(area, buf); // Helpers const confirm = confirmDialog("Sure?", &callback); const alert = alertDialog("Error!", &callback); ``` #### Tooltip (`src/widgets/tooltip.zig`) Tooltips posicionales. ```zig const Tooltip = @import("zcatui").widgets.Tooltip; const TooltipPosition = @import("zcatui").widgets.TooltipPosition; const tooltip = Tooltip.init("Help text") .position(.below) .style(Style.init().bg(Color.yellow)); tooltip.render(anchor_x, anchor_y, buf); ``` ### Widgets de Contenedor #### Viewport (`src/widgets/viewport.zig`) - **NUEVO v2.1** Contenido scrollable. ```zig const Viewport = @import("zcatui").widgets.Viewport; const ViewportState = @import("zcatui").widgets.ViewportState; var state = ViewportState{}; var viewport = try Viewport.init(allocator, 100, 500); // content width x height defer viewport.deinit(); // Renderizar contenido al buffer interno const content_buf = viewport.buffer(); // ... render widgets to content_buf ... // Scroll viewport.scrollDown(1); viewport.scrollUp(1); viewport.pageDown(area.height); viewport.pageUp(area.height); viewport.render(area, buf); ``` #### ScrollView (`src/widgets/scroll.zig`) Vista con scroll y virtualización. ```zig const ScrollView = @import("zcatui").widgets.ScrollView; const VirtualList = @import("zcatui").widgets.VirtualList; // Lista virtual (solo renderiza items visibles) const virtual = VirtualList.init(total_items, item_height, render_fn); virtual.render(area, buf, &scroll_state); ``` #### Panel (`src/widgets/panel.zig`) Paneles divididos. ```zig const Panel = @import("zcatui").widgets.Panel; const PanelSplit = @import("zcatui").widgets.PanelSplit; const TabbedPanel = @import("zcatui").widgets.TabbedPanel; // Panel split const split = PanelSplit.horizontal() .ratio(0.3) // 30% izquierda .gap(1); const areas = split.split(area); // areas[0] = izquierda, areas[1] = derecha // Tabbed panel const tabbed = TabbedPanel.init(&.{"Tab1", "Tab2"}); tabbed.render(area, buf, &state); ``` ### Widgets de Estado #### StatusBar (`src/widgets/statusbar.zig`) Barra de estado. ```zig const StatusBar = @import("zcatui").widgets.StatusBar; const StatusBarBuilder = @import("zcatui").widgets.StatusBarBuilder; const status = StatusBarBuilder.init() .left("NORMAL") .center("file.zig") .right("Ln 42, Col 8") .build(); status.render(area, buf); ``` #### Toast (`src/widgets/statusbar.zig`) Notificaciones temporales. ```zig const Toast = @import("zcatui").widgets.Toast; const ToastManager = @import("zcatui").widgets.ToastManager; var toasts = ToastManager.init(allocator); defer toasts.deinit(); try toasts.show("File saved!", .success, 3000); // 3 segundos try toasts.show("Error!", .err, 5000); toasts.render(area, buf); ``` #### Help (`src/widgets/help.zig`) - **NUEVO v2.1** Auto-genera ayuda de keybindings. ```zig const Help = @import("zcatui").widgets.Help; const KeyBinding = @import("zcatui").widgets.KeyBinding; const CommonBindings = @import("zcatui").widgets.CommonBindings; const help = Help.init(&.{ KeyBinding.init("q", "Quit"), KeyBinding.init("?", "Help"), KeyBinding.init("j/k", "Up/Down"), }) .mode(.compact) // .single_line, .multi_line, .full .separator(" | "); help.render(area, buf); // Bindings comunes predefinidos const common = CommonBindings.vim(); // o .emacs(), .arrows() ``` --- ## Sistema de Eventos ### EventReader (`src/event/reader.zig`) ```zig const EventReader = @import("zcatui").EventReader; const Event = @import("zcatui").Event; const KeyCode = @import("zcatui").KeyCode; var reader = try EventReader.init(); defer reader.deinit(); // Polling if (try reader.poll(100)) { // timeout ms const event = try reader.read(); switch (event) { .key => |k| { if (k.code == .char and k.getChar() == 'q') { // Quit } if (k.code == .enter) { // Enter pressed } if (k.isCtrl() and k.getChar() == 'c') { // Ctrl+C } }, .mouse => |m| { // m.column, m.row, m.kind, m.button }, .resize => |r| { // r.width, r.height }, .focus_gained, .focus_lost => {}, } } ``` ### KeyCode Values ```zig KeyCode.enter KeyCode.tab KeyCode.backspace KeyCode.escape KeyCode.left, .right, .up, .down KeyCode.home, .end KeyCode.page_up, .page_down KeyCode.insert, .delete KeyCode.f1 ... KeyCode.f12 KeyCode.char // con .getChar() ``` --- ## Layout y Posicionamiento ### Layout (`src/layout.zig`) ```zig const Layout = @import("zcatui").Layout; const Constraint = @import("zcatui").Constraint; const Direction = @import("zcatui").Direction; // Dividir área const chunks = Layout.init(.vertical) .constraints(&.{ Constraint.length(3), // 3 filas fijas Constraint.percentage(50), // 50% del resto Constraint.min(10), // Mínimo 10 Constraint.max(20), // Máximo 20 Constraint.ratio(1, 3), // 1/3 }) .split(area); ``` ### Flex Layout - **NUEVO v2.1** Layout CSS-like con justify y align. ```zig const Flex = @import("zcatui").Flex; const JustifyContent = @import("zcatui").JustifyContent; const AlignItems = @import("zcatui").AlignItems; const flex = Flex.horizontal() .setJustify(.space_between) // .start, .end, .center, .space_around, .space_evenly .setAlign(.center) // .start, .end, .center, .stretch .setGap(2) .setSizes(&.{20, 30, 20}); // Tamaños de items const rects = flex.layout(area); // rects[0], rects[1], rects[2]... ``` ### Helpers de Posicionamiento ```zig const centerRect = @import("zcatui").centerRect; const alignBottom = @import("zcatui").alignBottom; const alignRight = @import("zcatui").alignRight; const alignBottomRight = @import("zcatui").alignBottomRight; // Centrar un área de 40x10 dentro de parent const centered = centerRect(parent, 40, 10); // Alinear al fondo const bottom = alignBottom(parent, 3); // 3 filas de alto // Alinear a la derecha const right_area = alignRight(parent, 20); // 20 columnas de ancho ``` --- ## Themes y Estilos ### Theme (`src/theme.zig`) ```zig const Theme = @import("zcatui").Theme; const theme = Theme{ .background = Color.black, .foreground = Color.white, .primary = Color.blue, .secondary = Color.magenta, .success = Color.green, .warning = Color.yellow, .error_color = Color.red, .info = Color.cyan, .border = Color.indexed(240), // ... más colores }; // Usar theme para estilos const button_style = theme.buttonStyle(); const input_style = theme.inputStyle(); ``` ### ThemeLoader - **NUEVO v2.1** Hot-reload de themes desde archivos. ```zig const ThemeLoader = @import("zcatui").ThemeLoader; const ThemeWatcher = @import("zcatui").ThemeWatcher; // Cargar theme var loader = try ThemeLoader.init(allocator, "theme.json"); defer loader.deinit(); const theme = loader.getTheme(); // Watcher con auto-reload var watcher = try ThemeWatcher.init(allocator, "theme.json", 1000); // check cada 1s defer watcher.deinit(); // En el event loop if (watcher.poll()) { // Theme changed, re-render } ``` **Formato JSON:** ```json { "primary": "#3498db", "secondary": "#9b59b6", "success": "green", "warning": "#f1c40f", "error": "red" } ``` **Formato KV:** ``` # theme.conf primary = #3498db secondary = magenta success = green ``` --- ## Innovaciones v2.1 ### Testing Framework (`src/testing.zig`) Framework para tests de widgets. ```zig const testing = @import("zcatui").testing_framework; const WidgetHarness = @import("zcatui").WidgetHarness; const SimulatedInput = @import("zcatui").SimulatedInput; const Benchmark = @import("zcatui").Benchmark; test "widget renders correctly" { var harness = WidgetHarness.init(std.testing.allocator, 40, 10); defer harness.deinit(); // Renderizar widget const widget = MyWidget.init(); harness.render(widget); // Assertions try harness.expectText(0, 0, "Hello"); try harness.expectFg(0, 0, Color.red); try harness.expectNotEmpty(area); // Debug harness.debugPrint(); } test "keyboard input" { // Simular eventos const key = SimulatedInput.key(.enter); const char = SimulatedInput.char('a'); const click = SimulatedInput.click(10, 5, .left); const ctrl_c = SimulatedInput.keyWithMod(.{ .char = 'c' }, true, false, false); } test "benchmark" { var bench = Benchmark.start(); var i: u32 = 0; while (i < 1000) : (i += 1) { widget.render(area, buf); bench.lap(); } bench.report("Widget render"); // Imprime stats } ``` ### Serialization (`src/serialize.zig`) Guardar y restaurar estados de widgets. ```zig const serialize = @import("zcatui").serialize; const StateSnapshot = @import("zcatui").StateSnapshot; const UndoStack = @import("zcatui").UndoStack; const toJson = @import("zcatui").toJson; // Serializar a JSON const json = try toJson(allocator, my_state); defer allocator.free(json); // Snapshot de múltiples estados var snapshot = StateSnapshot.init(allocator); defer snapshot.deinit(); try snapshot.save("list", list_state); try snapshot.save("table", table_state); // Exportar todo const all_json = try snapshot.exportAll(); // Undo/Redo var undo = UndoStack(MyState).init(allocator, 50); // max 50 items defer undo.deinit(); try undo.push(current_state); if (undo.canUndo()) { const prev = undo.undo(); } if (undo.canRedo()) { const next = undo.redo(); } ``` ### Accessibility (`src/accessibility.zig`) Soporte para lectores de pantalla y preferencias. ```zig const a11y = @import("zcatui").accessibility; const AccessibleInfo = @import("zcatui").AccessibleInfo; const A11yRole = @import("zcatui").A11yRole; const Announcer = @import("zcatui").Announcer; // Verificar preferencias if (a11y.prefersReducedMotion()) { // Desactivar animaciones } if (a11y.prefersHighContrast()) { theme = a11y.high_contrast_theme; } // Información accesible para widget const info = AccessibleInfo{ .role = .button, .label = "Submit", .disabled = false, .shortcut = "Enter", }; // Anuncios para screen readers var announcer = Announcer.init(allocator); defer announcer.deinit(); try announcer.announce("Selection changed"); const output = try announcer.flush(); // Escribir output al terminal // Skip links para navegación var links = a11y.SkipLinks.init(allocator); try links.register("main", "Main content", 10); try links.register("footer", "Footer", 50); ``` --- ## Utilidades ### Unicode (`src/unicode.zig`) Cálculo de ancho de caracteres. ```zig const unicode = @import("zcatui").unicode; const width = unicode.charWidth('漢'); // 2 (full-width) const str_width = unicode.stringWidth("Hello 世界"); // 11 const truncated = unicode.truncateToWidth("Long text here", 10); // "Long text " ``` ### Terminal Capabilities (`src/termcap.zig`) Detección de capacidades del terminal. ```zig const termcap = @import("zcatui").termcap; const caps = termcap.detect(); if (caps.color_support == .true_color) { // Usar colores RGB } if (caps.unicode) { // Usar caracteres Unicode } if (caps.mouse) { // Habilitar mouse } ``` ### Animation (`src/animation.zig`) Sistema de animaciones. ```zig const Animation = @import("zcatui").Animation; const Easing = @import("zcatui").Easing; const Timer = @import("zcatui").Timer; var anim = Animation.init(0, 100, 1000, .ease_out); // from, to, duration_ms, easing // En cada frame anim.update(delta_ms); const current_value = anim.value(); if (anim.isFinished()) { // Done } // Timer var timer = Timer.init(5000); // 5 segundos timer.start(); if (timer.isExpired()) { // Timeout } ``` ### Clipboard (`src/clipboard.zig`) Acceso al portapapeles (OSC 52). ```zig const Clipboard = @import("zcatui").Clipboard; // Copiar const seq = Clipboard.copy("Hello"); // Escribir seq al terminal // Pegar (solicitar) const req = Clipboard.requestPaste(); // Escribir req, leer respuesta ``` ### Hyperlinks (`src/hyperlink.zig`) Links clickeables (OSC 8). ```zig const Hyperlink = @import("zcatui").Hyperlink; const link = Hyperlink.init("https://example.com", "Click here"); // link.start() ... text ... link.end() ``` ### Notifications (`src/notification.zig`) Notificaciones de escritorio (OSC 9/777). ```zig const Notification = @import("zcatui").Notification; const notif = Notification.init("Title", "Body text"); // Escribir notif.sequence() al terminal ``` ### Images (`src/image.zig`) Imágenes en terminal (Kitty/iTerm2). ```zig const Kitty = @import("zcatui").Kitty; const Iterm2 = @import("zcatui").Iterm2; // Kitty protocol const kitty = Kitty.init(image_data, width, height); kitty.render(buf); // iTerm2 protocol const iterm = Iterm2.init(image_data); iterm.render(buf); ``` --- ## Archivos del Proyecto ``` src/ ├── root.zig # Entry point, re-exports ├── buffer.zig # Buffer, Cell, Rect, Symbol ├── style.zig # Color, Style, Modifier ├── text.zig # Text, Line, Span ├── layout.zig # Layout, Constraint, Flex ├── terminal.zig # Terminal abstraction ├── event.zig # Event, KeyEvent, MouseEvent ├── event/ │ ├── reader.zig # EventReader │ └── parse.zig # Escape parser ├── focus.zig # FocusRing, FocusManager ├── theme.zig # Theme definitions ├── animation.zig # Animation, Easing, Timer ├── cursor.zig # Cursor control ├── clipboard.zig # OSC 52 ├── hyperlink.zig # OSC 8 ├── notification.zig # OSC 9/777 ├── image.zig # Kitty/iTerm2 images ├── lazy.zig # RenderCache, Throttle ├── unicode.zig # charWidth, stringWidth ├── termcap.zig # Terminal capabilities ├── testing.zig # Widget testing framework [NEW v2.1] ├── theme_loader.zig # Theme hot-reload [NEW v2.1] ├── serialize.zig # State serialization [NEW v2.1] ├── accessibility.zig # A11y support [NEW v2.1] ├── backend/ │ └── backend.zig # ANSI sequences ├── symbols/ # Line, border, block chars └── widgets/ ├── block.zig ├── paragraph.zig ├── list.zig ├── table.zig ├── gauge.zig ├── tabs.zig ├── sparkline.zig ├── scrollbar.zig ├── barchart.zig ├── canvas.zig ├── chart.zig ├── calendar.zig ├── clear.zig ├── input.zig ├── textarea.zig ├── popup.zig ├── menu.zig ├── tooltip.zig ├── tree.zig ├── filepicker.zig ├── scroll.zig ├── panel.zig ├── checkbox.zig ├── select.zig ├── slider.zig ├── statusbar.zig ├── spinner.zig [NEW v2.1] ├── help.zig [NEW v2.1] ├── viewport.zig [NEW v2.1] ├── progress.zig [NEW v2.1] ├── markdown.zig [NEW v2.1] ├── dirtree.zig [NEW v2.1] └── syntax.zig [NEW v2.1] ``` --- ## Estadísticas v2.1 | Métrica | Valor | |---------|-------| | Archivos fuente | 67 archivos .zig | | Widgets | 34 widgets | | Módulos core | 20 módulos | | Tests | 250+ tests | | Examples | 11 demos | | Nuevos en v2.1 | 11 módulos/widgets | --- ## Changelog v2.1 ### Nuevos Widgets - **Spinner**: Indicadores de carga animados (17 estilos) - **Help**: Auto-genera ayuda de keybindings - **Viewport**: Scroll genérico con buffer interno - **Progress**: Barras de progreso con ETA y velocidad - **Markdown**: Renderizado de Markdown styled - **DirectoryTree**: Navegador de archivos - **SyntaxHighlighter**: Resaltado de sintaxis (10 lenguajes) ### Nuevas Funcionalidades - **Flex Layout**: CSS-like justify/align - **Widget Testing Framework**: Harness, assertions, benchmarks - **Theme Hot-Reload**: Cargar themes desde archivos - **Widget Serialization**: JSON, undo/redo, snapshots - **Accessibility**: Roles ARIA, announcements, high contrast --- *Generado para zcatui v2.1 - Diciembre 2024*