docs: REFERENCE.md - Documentación completa AdvancedTable
- Añadido AdvancedTable a lista de Data Widgets - Sección completa de uso (~200 líneas): - Basic usage con schema - Column types - Lookup & Auto-fill (Fase 7) - DataStore interface - Callbacks + Debounce (Fase 8) - Keyboard navigation - Row states - Result fields - Actualizado Version History (v0.18.0 → v0.20.0) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
6287231cee
commit
964523b883
1 changed files with 192 additions and 0 deletions
192
REFERENCE.md
192
REFERENCE.md
|
|
@ -390,6 +390,7 @@ Command.nop // No operation
|
||||||
| Widget | File | Description |
|
| Widget | File | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| **Table** | `widgets/table.zig` | Editable data table with sorting |
|
| **Table** | `widgets/table.zig` | Editable data table with sorting |
|
||||||
|
| **AdvancedTable** | `widgets/advanced_table/` | Schema-driven table with CRUD, lookup, callbacks |
|
||||||
| **Tree** | `widgets/tree.zig` | Hierarchical tree view |
|
| **Tree** | `widgets/tree.zig` | Hierarchical tree view |
|
||||||
| **VirtualScroll** | `widgets/virtual_scroll.zig` | Virtualized list for large data |
|
| **VirtualScroll** | `widgets/virtual_scroll.zig` | Virtualized list for large data |
|
||||||
|
|
||||||
|
|
@ -519,6 +520,194 @@ if (result.row_added) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### AdvancedTable (Schema-Driven)
|
||||||
|
|
||||||
|
AdvancedTable is a full-featured table widget with schema-driven configuration, auto-CRUD detection, lookup & auto-fill, and hierarchical callbacks.
|
||||||
|
|
||||||
|
**Basic Usage:**
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const advanced_table = zcatgui.widgets.advanced_table;
|
||||||
|
const AdvancedTableState = advanced_table.AdvancedTableState;
|
||||||
|
const TableSchema = advanced_table.TableSchema;
|
||||||
|
const ColumnDef = advanced_table.ColumnDef;
|
||||||
|
|
||||||
|
// Define columns
|
||||||
|
const columns = [_]ColumnDef{
|
||||||
|
.{ .name = "id", .title = "ID", .width = 60, .editable = false },
|
||||||
|
.{ .name = "name", .title = "Name", .width = 150 },
|
||||||
|
.{ .name = "email", .title = "Email", .width = 200 },
|
||||||
|
.{ .name = "active", .title = "Active", .width = 80, .column_type = .boolean },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define schema
|
||||||
|
const schema = TableSchema{
|
||||||
|
.table_name = "users",
|
||||||
|
.columns = &columns,
|
||||||
|
.config = .{
|
||||||
|
.allow_edit = true,
|
||||||
|
.allow_sorting = true,
|
||||||
|
.auto_crud_enabled = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create state
|
||||||
|
var state = AdvancedTableState.init(allocator);
|
||||||
|
defer state.deinit();
|
||||||
|
|
||||||
|
// In frame loop
|
||||||
|
const result = advanced_table.advancedTable(&ctx, &state, &schema);
|
||||||
|
|
||||||
|
if (result.cell_edited) {
|
||||||
|
// Cell was modified
|
||||||
|
}
|
||||||
|
if (result.crud_action) |action| {
|
||||||
|
switch (action) {
|
||||||
|
.create => { /* New row needs INSERT */ },
|
||||||
|
.update => { /* Row needs UPDATE */ },
|
||||||
|
.delete => { /* Row needs DELETE */ },
|
||||||
|
.none => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Column Types:**
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const ColumnType = enum {
|
||||||
|
string, // Text (default)
|
||||||
|
integer, // Whole numbers
|
||||||
|
float, // Decimal numbers
|
||||||
|
money, // Currency
|
||||||
|
boolean, // Yes/No
|
||||||
|
date, // Date
|
||||||
|
select, // Dropdown with options
|
||||||
|
lookup, // Lookup in related table
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Lookup & Auto-fill (Phase 7):**
|
||||||
|
|
||||||
|
Configure columns to lookup values in related tables and auto-fill other columns:
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const columns = [_]ColumnDef{
|
||||||
|
.{ .name = "nif", .title = "NIF", .width = 100 },
|
||||||
|
.{
|
||||||
|
.name = "cliente_id",
|
||||||
|
.title = "Cliente",
|
||||||
|
.width = 150,
|
||||||
|
.enable_lookup = true,
|
||||||
|
.lookup_table = "clientes",
|
||||||
|
.lookup_key_column = "nif",
|
||||||
|
.auto_fill_columns = &[_]AutoFillMapping{
|
||||||
|
.{ .source_field = "nombre", .target_column = "cliente_nombre" },
|
||||||
|
.{ .source_field = "direccion", .target_column = "cliente_dir" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.{ .name = "cliente_nombre", .title = "Nombre", .width = 200, .editable = false },
|
||||||
|
.{ .name = "cliente_dir", .title = "Dirección", .width = 200, .editable = false },
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
When user edits `cliente_id` and presses Tab/Enter:
|
||||||
|
1. Table calls `DataStore.lookup("clientes", "nif", entered_value)`
|
||||||
|
2. If found, auto-fills `cliente_nombre` and `cliente_dir` from result
|
||||||
|
3. `result.lookup_success` indicates if lookup succeeded
|
||||||
|
|
||||||
|
**DataStore Interface:**
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const DataStore = struct {
|
||||||
|
ptr: *anyopaque,
|
||||||
|
vtable: *const VTable,
|
||||||
|
|
||||||
|
pub const VTable = struct {
|
||||||
|
load: *const fn (ptr: *anyopaque, allocator: Allocator) anyerror!ArrayList(Row),
|
||||||
|
save: *const fn (ptr: *anyopaque, row: *Row) anyerror!void,
|
||||||
|
delete: *const fn (ptr: *anyopaque, row: *Row) anyerror!void,
|
||||||
|
lookup: *const fn (ptr: *anyopaque, table: []const u8, key_column: []const u8, key_value: CellValue, allocator: Allocator) anyerror!?Row,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Callbacks (Phase 8):**
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const schema = TableSchema{
|
||||||
|
.table_name = "users",
|
||||||
|
.columns = &columns,
|
||||||
|
.config = .{
|
||||||
|
.callback_debounce_ms = 150, // Debounce interval
|
||||||
|
},
|
||||||
|
|
||||||
|
// Called when selection changes (debounced)
|
||||||
|
.on_row_selected = struct {
|
||||||
|
fn callback(row_index: usize, row: *const Row) void {
|
||||||
|
// Handle row selection
|
||||||
|
}
|
||||||
|
}.callback,
|
||||||
|
|
||||||
|
// Called when cell value changes
|
||||||
|
.on_cell_changed = struct {
|
||||||
|
fn callback(row_idx: usize, col_idx: usize, old: CellValue, new: CellValue) void {
|
||||||
|
// Handle cell change
|
||||||
|
}
|
||||||
|
}.callback,
|
||||||
|
|
||||||
|
// Called when moving to different row (for loading detail panels)
|
||||||
|
.on_active_row_changed = struct {
|
||||||
|
fn callback(old_row: ?usize, new_row: usize, row: *const Row) void {
|
||||||
|
// Load detail panel for new row
|
||||||
|
}
|
||||||
|
}.callback,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Keyboard Navigation:**
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| ↑↓←→ | Navigate cells |
|
||||||
|
| Tab / Shift+Tab | Move to next/prev cell (wraps rows) |
|
||||||
|
| Enter / F2 | Start editing |
|
||||||
|
| Escape (1st) | Revert to original value |
|
||||||
|
| Escape (2nd) | Cancel edit |
|
||||||
|
| PageUp/Down | Navigate by page |
|
||||||
|
| Home/End | First/last column |
|
||||||
|
| Ctrl+Home/End | First/last row |
|
||||||
|
| Ctrl+N | Insert new row |
|
||||||
|
| Ctrl+Delete | Delete row |
|
||||||
|
|
||||||
|
**Row States:**
|
||||||
|
|
||||||
|
| State | Visual | Meaning |
|
||||||
|
|-------|--------|---------|
|
||||||
|
| `normal` | Default | No changes |
|
||||||
|
| `modified` | Yellow indicator | Edited, pending save |
|
||||||
|
| `new` | Green indicator | New row, not in DB |
|
||||||
|
| `deleted` | Red indicator | Marked for deletion |
|
||||||
|
| `error` | Red background | Validation error |
|
||||||
|
|
||||||
|
**Result Fields:**
|
||||||
|
|
||||||
|
```zig
|
||||||
|
const AdvancedTableResult = struct {
|
||||||
|
selection_changed: bool, // Selection moved
|
||||||
|
selected_row: ?usize, // Current row
|
||||||
|
selected_col: ?usize, // Current column
|
||||||
|
edit_started: bool, // Editing began
|
||||||
|
edit_ended: bool, // Editing finished
|
||||||
|
cell_edited: bool, // Value was changed
|
||||||
|
sort_changed: bool, // Sort column/direction changed
|
||||||
|
row_inserted: bool, // New row added
|
||||||
|
row_deleted: bool, // Row removed
|
||||||
|
crud_action: ?CRUDAction, // Auto-CRUD action detected
|
||||||
|
lookup_success: ?bool, // Lookup result (null=no lookup)
|
||||||
|
clicked: bool, // Table was clicked
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
#### Slider
|
#### Slider
|
||||||
|
|
||||||
```zig
|
```zig
|
||||||
|
|
@ -1453,6 +1642,9 @@ pub const ThemeManager
|
||||||
|
|
||||||
| Version | Date | Changes |
|
| Version | Date | Changes |
|
||||||
|---------|------|---------|
|
|---------|------|---------|
|
||||||
|
| 0.20.0 | 2025-12-17 | AdvancedTable Phases 7-8: Lookup & Auto-fill, Callbacks + Debounce |
|
||||||
|
| 0.19.0 | 2025-12-17 | AdvancedTable Phases 1-6: Schema-driven, CRUD, sorting, editing |
|
||||||
|
| 0.18.0 | 2025-12-17 | Visual Parity Phase 3: Shadows multi-layer, Gradients suaves |
|
||||||
| 0.15.0 | 2025-12-09 | Mobile/Web backends (WASM, Android, iOS) |
|
| 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.14.1 | 2025-12-09 | Gio parity phase - 12 widgets + gesture system |
|
||||||
| 0.1.0 | 2025-12-09 | Initial release - core + macros + basic widgets |
|
| 0.1.0 | 2025-12-09 | Initial release - core + macros + basic widgets |
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue