Widgets implementados (13): - Block, Paragraph, List, Table - Gauge, LineGauge, Tabs, Sparkline - Scrollbar, BarChart, Canvas, Chart - Calendar (Monthly), Clear Modulos: - src/text.zig: Span, Line, Text, Alignment - src/symbols/: line, border, block, bar, braille, half_block, scrollbar, marker - src/widgets/: todos los widgets con tests Documentacion: - docs/ARCHITECTURE.md: arquitectura tecnica - docs/WIDGETS.md: guia completa de widgets - docs/API.md: referencia rapida - CLAUDE.md: actualizado con estado v1.0 Tests: 103+ tests en widgets, todos pasan 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
886 lines
23 KiB
Markdown
886 lines
23 KiB
Markdown
# zcatui - Documentacion de Widgets
|
|
|
|
> Referencia completa de todos los widgets disponibles en zcatui
|
|
|
|
## Indice
|
|
|
|
1. [Block](#block) - Contenedor con bordes
|
|
2. [Paragraph](#paragraph) - Texto con wrapping
|
|
3. [List](#list) - Lista seleccionable
|
|
4. [Table](#table) - Tabla multi-columna
|
|
5. [Gauge](#gauge) - Barra de progreso
|
|
6. [LineGauge](#linegauge) - Progreso en linea
|
|
7. [Tabs](#tabs) - Navegacion por pestanas
|
|
8. [Sparkline](#sparkline) - Mini graficos
|
|
9. [Scrollbar](#scrollbar) - Indicador de scroll
|
|
10. [BarChart](#barchart) - Graficos de barras
|
|
11. [Canvas](#canvas) - Dibujo libre
|
|
12. [Chart](#chart) - Graficos con ejes
|
|
13. [Calendar](#calendar) - Calendario mensual
|
|
14. [Clear](#clear) - Limpiar area
|
|
|
|
---
|
|
|
|
## Block
|
|
|
|
Widget base que proporciona bordes, titulos y padding. Usado como contenedor para otros widgets.
|
|
|
|
### Archivo
|
|
`src/widgets/block.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const block = Block.init()
|
|
.title("Mi Titulo")
|
|
.borders(Borders.all)
|
|
.borderStyle(Style.default.fg(Color.blue));
|
|
|
|
block.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Block = struct {
|
|
// Constructores
|
|
pub fn init() Block;
|
|
pub fn bordered() Block; // Con bordes en todos los lados
|
|
|
|
// Configuracion
|
|
pub fn title(self: Block, t: []const u8) Block;
|
|
pub fn titleStyle(self: Block, style: Style) Block;
|
|
pub fn titleAlignment(self: Block, alignment: Alignment) Block;
|
|
pub fn borders(self: Block, b: Borders) Block;
|
|
pub fn borderStyle(self: Block, style: Style) Block;
|
|
pub fn borderSet(self: Block, set: BorderSet) Block;
|
|
pub fn style(self: Block, s: Style) Block;
|
|
pub fn padding(self: Block, p: Padding) Block;
|
|
|
|
// Utilidades
|
|
pub fn inner(self: Block, area: Rect) Rect;
|
|
pub fn horizontalSpace(self: Block) u16;
|
|
pub fn verticalSpace(self: Block) u16;
|
|
|
|
// Renderizado
|
|
pub fn render(self: Block, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const Borders = packed struct {
|
|
top: bool = false,
|
|
right: bool = false,
|
|
bottom: bool = false,
|
|
left: bool = false,
|
|
|
|
pub const none: Borders = .{};
|
|
pub const all: Borders = .{ .top = true, .right = true, .bottom = true, .left = true };
|
|
pub const top: Borders = .{ .top = true };
|
|
// etc.
|
|
};
|
|
```
|
|
|
|
### Border Sets Disponibles
|
|
|
|
| Set | Descripcion | Caracteres |
|
|
|-----|-------------|------------|
|
|
| `plain` | Lineas simples | `─ │ ┌ ┐ └ ┘` |
|
|
| `rounded` | Esquinas redondeadas | `─ │ ╭ ╮ ╰ ╯` |
|
|
| `double` | Lineas dobles | `═ ║ ╔ ╗ ╚ ╝` |
|
|
| `thick` | Lineas gruesas | `━ ┃ ┏ ┓ ┗ ┛` |
|
|
|
|
---
|
|
|
|
## Paragraph
|
|
|
|
Widget para mostrar texto con word-wrapping, alineacion y scroll.
|
|
|
|
### Archivo
|
|
`src/widgets/paragraph.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const text = Text.raw("Este es un texto largo que sera\nenvuelto automaticamente si es necesario.");
|
|
|
|
const para = Paragraph.init(text)
|
|
.setBlock(Block.bordered().title("Info"))
|
|
.setWrap(.{ .trim = true })
|
|
.setAlignment(.center);
|
|
|
|
para.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Paragraph = struct {
|
|
pub fn init(text: Text) Paragraph;
|
|
pub fn initWithSpans(spans: []const Span) Paragraph;
|
|
|
|
pub fn setBlock(self: Paragraph, block: Block) Paragraph;
|
|
pub fn setStyle(self: Paragraph, style: Style) Paragraph;
|
|
pub fn setWrap(self: Paragraph, wrap: Wrap) Paragraph;
|
|
pub fn setAlignment(self: Paragraph, alignment: Alignment) Paragraph;
|
|
pub fn setScroll(self: Paragraph, offset: struct { x: u16, y: u16 }) Paragraph;
|
|
|
|
pub fn render(self: Paragraph, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const Wrap = struct {
|
|
trim: bool = false, // Eliminar espacios extra
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## List
|
|
|
|
Lista seleccionable con soporte para scroll automatico y highlighting.
|
|
|
|
### Archivo
|
|
`src/widgets/list.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const items = [_]ListItem{
|
|
ListItem.init(Line.raw("Item 1")),
|
|
ListItem.init(Line.raw("Item 2")).setStyle(Style.default.fg(Color.red)),
|
|
ListItem.init(Line.raw("Item 3")),
|
|
};
|
|
|
|
var state = ListState.init();
|
|
state.select(1); // Seleccionar segundo item
|
|
|
|
const list = List.init(&items)
|
|
.setBlock(Block.bordered().title("Lista"))
|
|
.setHighlightStyle(Style.default.bg(Color.blue))
|
|
.setHighlightSymbol("> ");
|
|
|
|
list.renderStateful(area, buf, &state);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const List = struct {
|
|
pub fn init(items: []const ListItem) List;
|
|
|
|
pub fn setBlock(self: List, block: Block) List;
|
|
pub fn setStyle(self: List, style: Style) List;
|
|
pub fn setHighlightStyle(self: List, style: Style) List;
|
|
pub fn setHighlightSymbol(self: List, symbol: []const u8) List;
|
|
pub fn setHighlightSpacing(self: List, spacing: HighlightSpacing) List;
|
|
pub fn setDirection(self: List, direction: ListDirection) List;
|
|
pub fn setRepeatHighlightSymbol(self: List, repeat: bool) List;
|
|
|
|
pub fn render(self: List, area: Rect, buf: *Buffer) void;
|
|
pub fn renderStateful(self: List, area: Rect, buf: *Buffer, state: *ListState) void;
|
|
};
|
|
|
|
pub const ListState = struct {
|
|
selected: ?usize = null,
|
|
offset: usize = 0,
|
|
|
|
pub fn init() ListState;
|
|
pub fn select(self: *ListState, index: usize) void;
|
|
pub fn selectNext(self: *ListState, len: usize) void;
|
|
pub fn selectPrevious(self: *ListState) void;
|
|
};
|
|
|
|
pub const ListDirection = enum { top_to_bottom, bottom_to_top };
|
|
```
|
|
|
|
---
|
|
|
|
## Table
|
|
|
|
Tabla multi-columna con headers, footers y seleccion de filas.
|
|
|
|
### Archivo
|
|
`src/widgets/table.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const header = Row.init(&[_]Cell{
|
|
Cell.init(Line.raw("Nombre")),
|
|
Cell.init(Line.raw("Edad")),
|
|
Cell.init(Line.raw("Ciudad")),
|
|
}).setStyle(Style.default.bold());
|
|
|
|
const rows = [_]Row{
|
|
Row.init(&[_]Cell{
|
|
Cell.init(Line.raw("Ana")),
|
|
Cell.init(Line.raw("25")),
|
|
Cell.init(Line.raw("Madrid")),
|
|
}),
|
|
Row.init(&[_]Cell{
|
|
Cell.init(Line.raw("Juan")),
|
|
Cell.init(Line.raw("30")),
|
|
Cell.init(Line.raw("Barcelona")),
|
|
}),
|
|
};
|
|
|
|
const widths = [_]Constraint{
|
|
Constraint.percentage(40),
|
|
Constraint.length(10),
|
|
Constraint.fill(1),
|
|
};
|
|
|
|
var state = TableState.init();
|
|
state.select(0);
|
|
|
|
const table = Table.init(&rows, &widths)
|
|
.setHeader(header)
|
|
.setBlock(Block.bordered().title("Usuarios"))
|
|
.setHighlightStyle(Style.default.bg(Color.yellow));
|
|
|
|
table.renderStateful(area, buf, &state);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Table = struct {
|
|
pub fn init(rows: []const Row, widths: []const Constraint) Table;
|
|
|
|
pub fn setHeader(self: Table, header: Row) Table;
|
|
pub fn setFooter(self: Table, footer: Row) Table;
|
|
pub fn setBlock(self: Table, block: Block) Table;
|
|
pub fn setStyle(self: Table, style: Style) Table;
|
|
pub fn setHighlightStyle(self: Table, style: Style) Table;
|
|
pub fn setHighlightSymbol(self: Table, symbol: []const u8) Table;
|
|
pub fn setColumnSpacing(self: Table, spacing: u16) Table;
|
|
|
|
pub fn render(self: Table, area: Rect, buf: *Buffer) void;
|
|
pub fn renderStateful(self: Table, area: Rect, buf: *Buffer, state: *TableState) void;
|
|
};
|
|
|
|
pub const TableState = struct {
|
|
selected: ?usize = null,
|
|
offset: usize = 0;
|
|
|
|
pub fn init() TableState;
|
|
pub fn select(self: *TableState, index: usize) void;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Gauge
|
|
|
|
Barra de progreso usando caracteres de bloque.
|
|
|
|
### Archivo
|
|
`src/widgets/gauge.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const gauge = Gauge.init()
|
|
.setRatio(0.75)
|
|
.setLabel("75%")
|
|
.setBlock(Block.bordered().title("Progreso"))
|
|
.setGaugeStyle(Style.default.fg(Color.green).bg(Color.black));
|
|
|
|
gauge.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Gauge = struct {
|
|
pub fn init() Gauge;
|
|
|
|
pub fn setRatio(self: Gauge, ratio: f64) Gauge; // 0.0 - 1.0
|
|
pub fn setPercent(self: Gauge, percent: u16) Gauge; // 0 - 100
|
|
pub fn setLabel(self: Gauge, label: []const u8) Gauge;
|
|
pub fn setBlock(self: Gauge, block: Block) Gauge;
|
|
pub fn setStyle(self: Gauge, style: Style) Gauge;
|
|
pub fn setGaugeStyle(self: Gauge, style: Style) Gauge;
|
|
pub fn setUseUnicode(self: Gauge, use: bool) Gauge;
|
|
|
|
pub fn render(self: Gauge, area: Rect, buf: *Buffer) void;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## LineGauge
|
|
|
|
Barra de progreso en una sola linea.
|
|
|
|
### Archivo
|
|
`src/widgets/gauge.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const gauge = LineGauge.init()
|
|
.setRatio(0.5)
|
|
.setLabel("Loading...")
|
|
.setLineSet(symbols.line.NORMAL)
|
|
.setFilledStyle(Style.default.fg(Color.cyan))
|
|
.setUnfilledStyle(Style.default.fg(Color.white));
|
|
|
|
gauge.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const LineGauge = struct {
|
|
pub fn init() LineGauge;
|
|
|
|
pub fn setRatio(self: LineGauge, ratio: f64) LineGauge;
|
|
pub fn setLabel(self: LineGauge, label: []const u8) LineGauge;
|
|
pub fn setBlock(self: LineGauge, block: Block) LineGauge;
|
|
pub fn setStyle(self: LineGauge, style: Style) LineGauge;
|
|
pub fn setFilledStyle(self: LineGauge, style: Style) LineGauge;
|
|
pub fn setUnfilledStyle(self: LineGauge, style: Style) LineGauge;
|
|
pub fn setLineSet(self: LineGauge, set: symbols.line.Set) LineGauge;
|
|
|
|
pub fn render(self: LineGauge, area: Rect, buf: *Buffer) void;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Tabs
|
|
|
|
Widget de navegacion por pestanas.
|
|
|
|
### Archivo
|
|
`src/widgets/tabs.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const titles = [_]Line{
|
|
Line.raw("Tab 1"),
|
|
Line.raw("Tab 2"),
|
|
Line.raw("Tab 3"),
|
|
};
|
|
|
|
const tabs = Tabs.init(&titles)
|
|
.select(1)
|
|
.setBlock(Block.bordered())
|
|
.setHighlightStyle(Style.default.fg(Color.yellow).bold())
|
|
.setDivider(" | ");
|
|
|
|
tabs.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Tabs = struct {
|
|
pub fn init(titles: []const Line) Tabs;
|
|
|
|
pub fn select(self: Tabs, index: usize) Tabs;
|
|
pub fn setBlock(self: Tabs, block: Block) Tabs;
|
|
pub fn setStyle(self: Tabs, style: Style) Tabs;
|
|
pub fn setHighlightStyle(self: Tabs, style: Style) Tabs;
|
|
pub fn setDivider(self: Tabs, divider: []const u8) Tabs;
|
|
pub fn setPadding(self: Tabs, left: []const u8, right: []const u8) Tabs;
|
|
|
|
pub fn render(self: Tabs, area: Rect, buf: *Buffer) void;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Sparkline
|
|
|
|
Mini grafico de linea usando caracteres de bloque.
|
|
|
|
### Archivo
|
|
`src/widgets/sparkline.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const data = [_]u64{ 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4 };
|
|
|
|
const spark = Sparkline.init()
|
|
.setData(&data)
|
|
.setMax(5)
|
|
.setBlock(Block.bordered().title("CPU"))
|
|
.setStyle(Style.default.fg(Color.cyan))
|
|
.setDirection(.left_to_right);
|
|
|
|
spark.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Sparkline = struct {
|
|
pub fn init() Sparkline;
|
|
|
|
pub fn setData(self: Sparkline, data: []const u64) Sparkline;
|
|
pub fn setMax(self: Sparkline, max: u64) Sparkline;
|
|
pub fn setBlock(self: Sparkline, block: Block) Sparkline;
|
|
pub fn setStyle(self: Sparkline, style: Style) Sparkline;
|
|
pub fn setBarSet(self: Sparkline, set: symbols.bar.Set) Sparkline;
|
|
pub fn setDirection(self: Sparkline, direction: RenderDirection) Sparkline;
|
|
|
|
pub fn render(self: Sparkline, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const RenderDirection = enum { left_to_right, right_to_left };
|
|
```
|
|
|
|
---
|
|
|
|
## Scrollbar
|
|
|
|
Indicador visual de posicion de scroll.
|
|
|
|
### Archivo
|
|
`src/widgets/scrollbar.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
var state = ScrollbarState.init(100) // 100 items totales
|
|
.setPosition(25) // Posicion actual
|
|
.setViewportContentLength(20); // Items visibles
|
|
|
|
const scrollbar = Scrollbar.init(.vertical_right)
|
|
.setSymbols(.{ .track = "│", .thumb = "█" })
|
|
.setStyle(Style.default.fg(Color.white));
|
|
|
|
scrollbar.render(area, buf, &state);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Scrollbar = struct {
|
|
pub fn init(orientation: ScrollbarOrientation) Scrollbar;
|
|
|
|
pub fn setOrientation(self: Scrollbar, o: ScrollbarOrientation) Scrollbar;
|
|
pub fn setThumbSymbol(self: Scrollbar, symbol: []const u8) Scrollbar;
|
|
pub fn setTrackSymbol(self: Scrollbar, symbol: ?[]const u8) Scrollbar;
|
|
pub fn setBeginSymbol(self: Scrollbar, symbol: ?[]const u8) Scrollbar;
|
|
pub fn setEndSymbol(self: Scrollbar, symbol: ?[]const u8) Scrollbar;
|
|
pub fn setSymbols(self: Scrollbar, symbols: ScrollbarSymbols) Scrollbar;
|
|
pub fn setStyle(self: Scrollbar, style: Style) Scrollbar;
|
|
pub fn setThumbStyle(self: Scrollbar, style: Style) Scrollbar;
|
|
pub fn setTrackStyle(self: Scrollbar, style: Style) Scrollbar;
|
|
|
|
pub fn render(self: Scrollbar, area: Rect, buf: *Buffer, state: *ScrollbarState) void;
|
|
};
|
|
|
|
pub const ScrollbarState = struct {
|
|
pub fn init(content_length: usize) ScrollbarState;
|
|
pub fn setPosition(self: ScrollbarState, position: usize) ScrollbarState;
|
|
pub fn setViewportContentLength(self: ScrollbarState, length: usize) ScrollbarState;
|
|
};
|
|
|
|
pub const ScrollbarOrientation = enum {
|
|
vertical_right,
|
|
vertical_left,
|
|
horizontal_bottom,
|
|
horizontal_top,
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## BarChart
|
|
|
|
Graficos de barras con soporte para grupos.
|
|
|
|
### Archivo
|
|
`src/widgets/barchart.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const bars = [_]Bar{
|
|
Bar.init(50).setLabel("Ene").setStyle(Style.default.fg(Color.red)),
|
|
Bar.init(80).setLabel("Feb").setStyle(Style.default.fg(Color.green)),
|
|
Bar.init(65).setLabel("Mar").setStyle(Style.default.fg(Color.blue)),
|
|
};
|
|
|
|
const group = BarGroup.init(&bars).setLabel("Q1 2024");
|
|
|
|
const groups = [_]BarGroup{group};
|
|
|
|
const chart = BarChart.init()
|
|
.setData(&groups)
|
|
.setBarWidth(5)
|
|
.setBarGap(1)
|
|
.setGroupGap(2)
|
|
.setBlock(Block.bordered().title("Ventas"))
|
|
.setMax(100);
|
|
|
|
chart.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const BarChart = struct {
|
|
pub fn init() BarChart;
|
|
|
|
pub fn setData(self: BarChart, data: []const BarGroup) BarChart;
|
|
pub fn setBlock(self: BarChart, block: Block) BarChart;
|
|
pub fn setBarWidth(self: BarChart, width: u16) BarChart;
|
|
pub fn setBarGap(self: BarChart, gap: u16) BarChart;
|
|
pub fn setGroupGap(self: BarChart, gap: u16) BarChart;
|
|
pub fn setBarStyle(self: BarChart, style: Style) BarChart;
|
|
pub fn setLabelStyle(self: BarChart, style: Style) BarChart;
|
|
pub fn setValueStyle(self: BarChart, style: Style) BarChart;
|
|
pub fn setStyle(self: BarChart, style: Style) BarChart;
|
|
pub fn setMax(self: BarChart, max: u64) BarChart;
|
|
pub fn setDirection(self: BarChart, dir: Direction) BarChart;
|
|
|
|
pub fn render(self: BarChart, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const Bar = struct {
|
|
pub fn init(value: u64) Bar;
|
|
pub fn setLabel(self: Bar, label: []const u8) Bar;
|
|
pub fn setStyle(self: Bar, style: Style) Bar;
|
|
pub fn setValueStyle(self: Bar, style: Style) Bar;
|
|
pub fn setTextValue(self: Bar, text: []const u8) Bar;
|
|
};
|
|
|
|
pub const BarGroup = struct {
|
|
pub fn init(bars: []const Bar) BarGroup;
|
|
pub fn setLabel(self: BarGroup, label: []const u8) BarGroup;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Canvas
|
|
|
|
Widget para dibujo libre con diferentes tipos de marcadores.
|
|
|
|
### Archivo
|
|
`src/widgets/canvas.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const canvas = Canvas.init()
|
|
.setXBounds(-10.0, 10.0)
|
|
.setYBounds(-10.0, 10.0)
|
|
.setMarker(.braille)
|
|
.setBlock(Block.bordered().title("Canvas"))
|
|
.paint(struct {
|
|
pub fn draw(painter: *Painter) void {
|
|
// Dibujar una linea
|
|
painter.line(0, 0, 10, 10, Color.red);
|
|
|
|
// Dibujar un rectangulo
|
|
painter.rectangle(2, 2, 8, 8, Color.blue);
|
|
|
|
// Dibujar un circulo
|
|
painter.circle(5, 5, 3, Color.green);
|
|
|
|
// Dibujar puntos individuales
|
|
painter.point(0, 0, Color.yellow);
|
|
}
|
|
}.draw);
|
|
|
|
canvas.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Canvas = struct {
|
|
pub fn init() Canvas;
|
|
|
|
pub fn setXBounds(self: Canvas, min: f64, max: f64) Canvas;
|
|
pub fn setYBounds(self: Canvas, min: f64, max: f64) Canvas;
|
|
pub fn setMarker(self: Canvas, marker: Marker) Canvas;
|
|
pub fn setBlock(self: Canvas, block: Block) Canvas;
|
|
pub fn setBackgroundColor(self: Canvas, color: Color) Canvas;
|
|
pub fn paint(self: Canvas, painter_fn: *const fn(*Painter) void) Canvas;
|
|
|
|
pub fn render(self: Canvas, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const Marker = enum {
|
|
dot, // Punto simple
|
|
block, // Caracter bloque completo
|
|
bar, // Barras verticales
|
|
braille, // Patrones braille (2x4 por celda)
|
|
half_block, // Half-blocks (1x2 por celda)
|
|
};
|
|
|
|
pub const Painter = struct {
|
|
pub fn point(self: *Painter, x: f64, y: f64, color: Color) void;
|
|
pub fn line(self: *Painter, x1: f64, y1: f64, x2: f64, y2: f64, color: Color) void;
|
|
pub fn rectangle(self: *Painter, x: f64, y: f64, width: f64, height: f64, color: Color) void;
|
|
pub fn circle(self: *Painter, x: f64, y: f64, radius: f64, color: Color) void;
|
|
};
|
|
```
|
|
|
|
### Resoluciones por Marker
|
|
|
|
| Marker | Resolucion por celda | Uso recomendado |
|
|
|--------|---------------------|-----------------|
|
|
| `dot` | 1x1 | Simple, compatible |
|
|
| `block` | 1x1 | Relleno solido |
|
|
| `bar` | 8x1 | Barras horizontales |
|
|
| `braille` | 2x4 | Alta resolucion |
|
|
| `half_block` | 1x2 | Resolucion media |
|
|
|
|
---
|
|
|
|
## Chart
|
|
|
|
Graficos de linea, scatter y barras con ejes X/Y.
|
|
|
|
### Archivo
|
|
`src/widgets/chart.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
const data1 = [_][2]f64{
|
|
.{ 0, 0 }, .{ 1, 1 }, .{ 2, 4 }, .{ 3, 9 }, .{ 4, 16 },
|
|
};
|
|
|
|
const data2 = [_][2]f64{
|
|
.{ 0, 16 }, .{ 1, 9 }, .{ 2, 4 }, .{ 3, 1 }, .{ 4, 0 },
|
|
};
|
|
|
|
const datasets = [_]Dataset{
|
|
Dataset.init(&data1)
|
|
.setName("x^2")
|
|
.setMarker(.braille)
|
|
.setGraphType(.line)
|
|
.setStyle(Style.default.fg(Color.cyan)),
|
|
Dataset.init(&data2)
|
|
.setName("(4-x)^2")
|
|
.setMarker(.braille)
|
|
.setGraphType(.scatter)
|
|
.setStyle(Style.default.fg(Color.yellow)),
|
|
};
|
|
|
|
const x_axis = Axis.init()
|
|
.setTitle("X")
|
|
.setBounds(0, 4)
|
|
.setLabels(&[_][]const u8{ "0", "1", "2", "3", "4" });
|
|
|
|
const y_axis = Axis.init()
|
|
.setTitle("Y")
|
|
.setBounds(0, 16);
|
|
|
|
const chart = Chart.init(&datasets)
|
|
.setXAxis(x_axis)
|
|
.setYAxis(y_axis)
|
|
.setBlock(Block.bordered().title("Grafico"))
|
|
.setLegendPosition(.top_right);
|
|
|
|
chart.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Chart = struct {
|
|
pub fn init(datasets: []const Dataset) Chart;
|
|
|
|
pub fn setXAxis(self: Chart, axis: Axis) Chart;
|
|
pub fn setYAxis(self: Chart, axis: Axis) Chart;
|
|
pub fn setBlock(self: Chart, block: Block) Chart;
|
|
pub fn setStyle(self: Chart, style: Style) Chart;
|
|
pub fn setLegendPosition(self: Chart, pos: ?LegendPosition) Chart;
|
|
pub fn setHideLegendConstraint(self: Chart, constraint: Constraint) Chart;
|
|
|
|
pub fn render(self: Chart, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const Dataset = struct {
|
|
pub fn init(data: []const [2]f64) Dataset;
|
|
|
|
pub fn setName(self: Dataset, name: []const u8) Dataset;
|
|
pub fn setData(self: Dataset, data: []const [2]f64) Dataset;
|
|
pub fn setMarker(self: Dataset, marker: Marker) Dataset;
|
|
pub fn setGraphType(self: Dataset, graph_type: GraphType) Dataset;
|
|
pub fn setStyle(self: Dataset, style: Style) Dataset;
|
|
};
|
|
|
|
pub const Axis = struct {
|
|
pub fn init() Axis;
|
|
|
|
pub fn setTitle(self: Axis, title: []const u8) Axis;
|
|
pub fn setTitleStyle(self: Axis, style: Style) Axis;
|
|
pub fn setBounds(self: Axis, min: f64, max: f64) Axis;
|
|
pub fn setLabels(self: Axis, labels: []const []const u8) Axis;
|
|
pub fn setLabelsAlignment(self: Axis, alignment: Alignment) Axis;
|
|
pub fn setStyle(self: Axis, style: Style) Axis;
|
|
};
|
|
|
|
pub const GraphType = enum { scatter, line, bar };
|
|
pub const LegendPosition = enum { top_left, top_right, bottom_left, bottom_right };
|
|
```
|
|
|
|
---
|
|
|
|
## Calendar
|
|
|
|
Calendario mensual con soporte para eventos y estilos personalizados.
|
|
|
|
### Archivo
|
|
`src/widgets/calendar.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
// Crear eventos con estilos
|
|
var events = CalendarEventStore.init();
|
|
events.add(Date.init(2024, 12, 25), Style.default.fg(Color.red).bold());
|
|
events.add(Date.init(2024, 12, 31), Style.default.fg(Color.yellow));
|
|
|
|
const calendar = Monthly.init(Date.init(2024, 12, 1))
|
|
.withEvents(events)
|
|
.showMonthHeader(Style.default.fg(Color.blue).bold())
|
|
.showWeekdaysHeader(Style.default.fg(Color.cyan))
|
|
.showSurrounding(Style.default.fg(Color.white))
|
|
.setDefaultStyle(Style.default)
|
|
.setBlock(Block.bordered());
|
|
|
|
calendar.render(area, buf);
|
|
```
|
|
|
|
### Salida Visual
|
|
|
|
```
|
|
┌──────────────────────┐
|
|
│ December 2024 │
|
|
│ Su Mo Tu We Th Fr Sa │
|
|
│ 1 2 3 4 5 6 7 │
|
|
│ 8 9 10 11 12 13 14 │
|
|
│ 15 16 17 18 19 20 21 │
|
|
│ 22 23 24 25 26 27 28 │
|
|
│ 29 30 31 │
|
|
└──────────────────────┘
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Monthly = struct {
|
|
pub fn init(display_date: Date) Monthly;
|
|
pub fn withEvents(display_date: Date, events: CalendarEventStore) Monthly;
|
|
|
|
pub fn showSurrounding(self: Monthly, style: Style) Monthly;
|
|
pub fn showWeekdaysHeader(self: Monthly, style: Style) Monthly;
|
|
pub fn showMonthHeader(self: Monthly, style: Style) Monthly;
|
|
pub fn setDefaultStyle(self: Monthly, style: Style) Monthly;
|
|
pub fn setBlock(self: Monthly, block: Block) Monthly;
|
|
|
|
pub fn width(self: Monthly) u16; // Siempre 21 + bordes
|
|
pub fn height(self: Monthly) u16; // Variable segun mes
|
|
|
|
pub fn render(self: Monthly, area: Rect, buf: *Buffer) void;
|
|
};
|
|
|
|
pub const Date = struct {
|
|
year: i16,
|
|
month: u4, // 1-12
|
|
day: u5, // 1-31
|
|
|
|
pub fn init(year: i16, month: u4, day: u5) Date;
|
|
pub fn isLeapYear(self: Date) bool;
|
|
pub fn daysInMonth(self: Date) u5;
|
|
pub fn dayOfWeek(self: Date) u3; // 0=Sunday
|
|
pub fn monthName(self: Date) []const u8;
|
|
};
|
|
|
|
pub const CalendarEventStore = struct {
|
|
pub fn init() CalendarEventStore;
|
|
pub fn add(self: *CalendarEventStore, date: Date, style: Style) void;
|
|
pub fn getStyle(self: CalendarEventStore, date: Date) Style;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Clear
|
|
|
|
Widget simple que limpia/resetea un area de la pantalla.
|
|
|
|
### Archivo
|
|
`src/widgets/clear.zig`
|
|
|
|
### Ejemplo Basico
|
|
|
|
```zig
|
|
// Limpiar todo el area antes de renderizar otros widgets
|
|
Clear.init().render(area, buf);
|
|
|
|
// Ahora renderizar contenido fresco
|
|
my_widget.render(area, buf);
|
|
```
|
|
|
|
### API
|
|
|
|
```zig
|
|
pub const Clear = struct {
|
|
pub fn init() Clear;
|
|
pub fn render(self: Clear, area: Rect, buf: *Buffer) void;
|
|
};
|
|
```
|
|
|
|
### Uso Tipico
|
|
|
|
Clear es util cuando:
|
|
1. Necesitas borrar contenido previo antes de re-renderizar
|
|
2. Quieres resetear estilos de un area especifica
|
|
3. Implementas transiciones entre pantallas
|
|
|
|
---
|
|
|
|
## Patrones Comunes
|
|
|
|
### Composicion de Widgets
|
|
|
|
```zig
|
|
// Crear un layout dividido
|
|
const chunks = Layout.vertical(&[_]Constraint{
|
|
Constraint.length(3), // Header
|
|
Constraint.min(0), // Contenido
|
|
Constraint.length(1), // Footer
|
|
}).split(area);
|
|
|
|
// Renderizar widgets en cada area
|
|
Block.bordered().title("Header").render(chunks[0], buf);
|
|
list.renderStateful(chunks[1], buf, &list_state);
|
|
Paragraph.init("Status: OK").render(chunks[2], buf);
|
|
```
|
|
|
|
### Widgets Anidados
|
|
|
|
```zig
|
|
// List con block personalizado
|
|
const list = List.init(items)
|
|
.setBlock(
|
|
Block.bordered()
|
|
.title("Items")
|
|
.titleStyle(Style.default.bold())
|
|
.borderStyle(Style.default.fg(Color.cyan))
|
|
);
|
|
```
|
|
|
|
### Estilos Condicionales
|
|
|
|
```zig
|
|
const item_style = if (is_selected)
|
|
Style.default.bg(Color.blue).fg(Color.white)
|
|
else if (is_important)
|
|
Style.default.fg(Color.red).bold()
|
|
else
|
|
Style.default;
|
|
```
|