Skip to main content

Module table_view

Module table_view 

Source
Expand description

TableView<T> — generic, virtualized, accessible tabular widget.

Built atop the ListModel<T> / ListDataSource data layer in teksilo-data and the teksilo-core TableStyle. Mirrors Qt’s QTableView, SwiftUI’s Table, and JavaFX’s TableView. The core skeleton: single body pane, row-virtualized with alternating backgrounds, grid lines, Role::Table > Role::Row > Role::Cell accessibility, multi-row selection, and an empty-state slot. Headers, sort, filter, resize, reorder, pinning, cell selection, and editing are also included. Row heights come in three modes: uniform (row_height, the default fast path), exact per-row callback (row_height_fn), and auto-measured (auto_row_height — rows grow to their tallest cell, height-for-width). See docs/table-view.md “Row heights”.

The header strip is a TableHeader over the columns’ ColumnSpecs, which this view and TreeTableView both compose and which works on its own over rows an application lays out itself.

§Column state an application owns

The sort, the column widths, the column order and the filters live in four signals the table publishes (sort_signal(), column_widths_signal(), column_order_signal(), filters_signal()). By default the table creates them. bind_sort, bind_column_widths, bind_column_order and bind_filters make the table adopt signals the application already holds instead, so several views, or a view-model, share one state without mirroring it.

  • Adopting writes nothing. The table never seeds an adopted signal: not when it is built, mounted, laid out or rebuilt. What the signal holds is what the table shows; an empty map, an empty list or None means the declared defaults. The table writes only for a user gesture (a header click, a resize drag, a reorder drop, the filter popover, an AccessKit increment) or an imperative setter (set_sort, set_column_widths, …).
  • Ids the table does not declare are ignored when read and kept when written. A width, a filter or an order entry for a column this table lacks changes nothing here, and a reorder in this table moves the dragged column and leaves every other entry where it was. A column with no width entry takes its declared ColumnWidth.
  • A resize writes one width into an adopted map. The Flex columns before the grip keep their widths, so the divider follows the pointer, but in this table only: the widths they had here are not the widths they have in a view of another size sharing the map. A table on its own map writes them into it, so the map it persists matches what it shows.
  • No feedback loop. A view reacts to a change by relaying out or rebuilding, never by writing back, so two views bound to the same signals follow each other’s edits and settle after one pass.
  • Bind before any imperative setter. A setter called earlier in the builder chain wrote the table’s own signal, which the bind replaces.
ⓘ
use teksilo_data::ListModel;
use teksilo_widgets::table_view::{Column, ColumnWidth, TableView};
use teksilo_i18n::lit;

struct Person { name: String, age: u32 }

let model: ListModel<Person> = ListModel::new();
let _table = TableView::new(model)
    .add_column(Column::new("name", ColumnWidth::Flex(1.0))
        .label(lit!("Name"))
        .cell(|p: &Person, _cx| Box::new(
            teksilo_widgets::primitives::TextWidget::new(
                teksilo_i18n::lit!(p.name.clone())
            )
        )))
    .add_column(Column::new("age", ColumnWidth::Fixed(60.0))
        .label(lit!("Age"))
        .cell(|p: &Person, _cx| Box::new(
            teksilo_widgets::primitives::TextWidget::new(
                teksilo_i18n::lit!(p.age.to_string())
            )
        )))
    .alternating_rows(true)
    .row_height(32.0);

§Scrolling to a row

handle returns a TableViewHandle, a cheap Clone taken before the table is added and usable from any handler afterwards. Its scroll_to_row and ensure_row_visible are applied at the next layout pass, after row measurement and scroll anchoring, so they may follow a model change in the same turn, or be called before mount:

let table = TableView::new(model.clone());
let handle = table.handle();
// … add the columns, `ctx.add(table)`; then, from a handler:
model.insert(0, "Fresh".into());
handle.ensure_row_visible(0);

The builder-value methods of the same names compute the offset when they are called, against the last layout pass. See docs/table-view.md, “Scrolling to a row”.

§Pan to scroll

The view installs common::scrollable::ScrollableBehavior, which gives it the shared wheel arithmetic, a finger’s pan and the PanClaim that puts it on a pan’s claimant chain. A pan scrolls it, the release coasts, and a pan it cannot absorb hands the whole event to the container outside — never a residual. A pan that starts on a row scrolls rather than activating it or collapsing a multi-selection onto it. Both axes are claimed. Shift+wheel still scrolls the columns, and a finger’s pan is never remapped by a held Shift: the remap is a wheel convention, and turning a drag sideways is not what the hand asked for.

Re-exports§

pub use self::column::Alignment;
pub use self::column::CellContext;
pub use self::column::Column;
pub use self::column::ColumnContext;
pub use self::column::ColumnResizePolicy;
pub use self::column::ColumnSpec;
pub use self::column::ColumnWidth;
pub use self::column::EditTriggers;
pub use self::column::GridLines;
pub use self::column::PinnedSide;
pub use self::column::TabTraversal;
pub use self::column::TruncationPolicy;
pub use self::selection::CellSelectionModel;
pub use self::selection::TableSelectionMode;
pub use self::table_header::TableHeader;

Modules§

a11y
Accessibility wrappers for TableView / TreeTableView.
body
Per-row container widget — Role::Row, lays its cells horizontally using a shared column-width handle owned by the parent table.
body_pane
BodyPane<T> — the virtualized row pane underneath the header.
column
Column descriptor + supporting enums for TableView and TreeTableView.
filter
Per-column filter popover UI.
header
Per-column header cells.
imperative
Imperative-API helpers shared by TableView and TreeTableView.
keyboard
Shared keyboard handler for TableView and TreeTableView.
layout
Column-width resolution + per-pane horizontal layout.
row_navigator
Trait abstracting per-row navigation for TableView and TreeTableView.
selection
Selection types for TableView and TreeTableView.
table_header
TableHeader — the column header strip of TableView and TreeTableView, and a widget of its own for an application that lays out its own rows under columns: a section list with full-width group rows, an album card beside its tracks.

Structs§

TableView
Generic, virtualized, accessible table with sortable / filterable / resizable columns.
TableViewHandle
A handle on a mounted TableView, to scroll it to a row from outside the widget — a view-model reacting to a search hit, a “go to row” command.

Enums§

SortDirection
Sort direction emitted by TableView / TreeTableView headers and consumed by sort projections.