class TUI::ArrayTableSource(T)

Overview

Generic TableDataSource over an in-memory Array(T) — a substring filter on one derived string per row, plus symbol-keyed sort comparators, covers every hand-written array-backed TableDataSource this library's own examples needed. Anything needing a richer filter (multi-field, fuzzy) or a data source backed by something other than a plain in-memory Array should still hand-write its own TableDataSource — this covers the common case, not every case.

#sort_keys maps a Symbol to a (T, T) -> Int32 comparator rather than a key-extractor (T -> _), since Crystal can't compare two values pulled from a Hash whose value type is a union across heterogeneous field types (e.g. String for one sort key, Float64 for another) — a two-argument comparator sidesteps that entirely.

Defined in:

tui/data_sources/array_table_source.cr
tui/data_sources/array_table_source_define.cr

Constructors

Macro Summary

Instance Method Summary

Instance methods inherited from class TUI::TableDataSource

columns : Array(TableColumn) columns, row(index : Int32) : TableRow row

Instance methods inherited from class TUI::ListDataSource

reload(filter : String, sort : Symbol) : Nil reload, size : Int32 size, sort_keys : Array(Symbol) sort_keys, title(filter : String, sort_key : Symbol) : String title

Constructor Detail

def self.new(all : Array(T), title : String, columns : Array(TableColumn), filter_text : T -> String, row : T -> TableRow, sort_keys : Hash(Symbol, T, T -> Int32) = {} of Symbol => (T, T -> Int32)) #

[View source]

Macro Detail

macro define(name, model_type, &block) #

Block-DSL sugar over ArrayTableSource(T) construction. Unlike Form.define, this macro does NOT auto-assign a constant to the built source — Crystal disallows declaring a class inside a def body ("can't define class inside def"), so a caller wanting a fresh ArrayTableSource per call (e.g. one per page, so Table view and Split window don't share filter/sort state) must call this macro once at the top level to declare a named builder class, then call that class's own .build(all) from a plain function whenever it needs a new instance:

TUI::ArrayTableSource.define(PackageSourceBuilder, Package) do title "Packages" filter_by :name column :name, "Name", width: 10..20, expand: true column :size_mb, "Size (MB)", width: 6..10, align: :right, sort: true end

def build_package_source : TUI::ArrayTableSource(Package) PackageSourceBuilder.build(FAKE_PACKAGES) end

Column cell styling avoids macro-time type introspection (Crystal's instance_vars reflection only works inside a def body, not at macro-expansion time of a single column call) by generating a runtime value.class.name.downcase lookup instead — e.g. Float64.name.downcase == "float64", matching TypeStyle's own case-when keys exactly. sort: true still generates a two-argument comparator (a.prop <=> b.prop || 0), not a key-extractor, per ArrayTableSource(T)'s own comparator-based sort_keys contract.


[View source]

Instance Method Detail

def columns : Array(TableColumn) #

[View source]
def item_at(index : Int32) : T #

The currently-filtered row's underlying model — the generic replacement for a hand-written source's own xxx_at(index).


[View source]
def reload(filter : String, sort : Symbol) : Nil #

[View source]
def row(index : Int32) : TableRow #

[View source]
def size : Int32 #

[View source]
def sort_keys : Array(Symbol) #

[View source]
def title(filter : String, sort_key : Symbol) : String #

[View source]