TableView

TableView<T> β generic, virtualized, accessible tabular widget.
Built atop the ListModel<T> /
ListDataSource data layer in
teksilo-data and the teksilo-tokens 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".
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);
Builder methods at a glance
from_source, from_source_keyed, enabled, overscroll_behavior, smooth_scrolling, type_ahead_label, type_ahead_timeout, smooth_scroll_duration, scroll_bar_style, add_column, columns, row_height, row_height_fn, auto_row_height, header_height, show_header, column_resize_policy, tab_traversal, edit_triggers, on_cell_edit_request, on_cell_edit_dismissed, on_row_activate, reorderable, reorderable_rows, exportable, export_external, on_rows_transferred_out, accept_foreign_rows, on_rows_received, activate_on, selection_mode, selection, cell_selection, alternating_rows, grid_lines, a11y_label, show_internal_scrollbars, empty_view, scroll_y_signal, max_scroll_y_signal, viewport_ratio_y_signal, scroll_x_signal, max_scroll_x_signal, viewport_ratio_x_signal, sort_signal, column_widths_signal, column_order_signal, column_pinning_signal, focused_cell_signal, set_focused_cell, clear_focused_cell, editing_cell_signal, begin_edit, end_edit, filters_signal, set_filter, clear_filters, scroll_to_row, set_sort, clear_sort, set_column_width, set_column_widths, set_column_order, set_column_pinning, ensure_row_visible
API reference
π Full rustdoc API for this module
pub struct TableView
Generic, virtualized, accessible table with sortable / filterable / resizable columns.
Construct with TableView::new (from a ListModel<T>)
or TableView::from_source (any ListDataSource), then chain builder methods
to configure columns, row heights, selection, and so on. See module docs for the full
feature list and row-height modes.
#![allow(unused)] fn main() { pub struct TableView<T: 'static> { /* fields */ } }
Methods
pub fn new(model: ListModel<T>) -> Self
Wrap a ListModel<T>.
pub fn from_source<S: ListDataSource<Item = T>>(source: S) -> Self
Wrap any ListDataSource<Item = T> (e.g. a
SortFilterListModel<T>).
The source owns DnD validation (can_accept / accept_drop) and
lazy windowing (row_state / request_window / fetch_more); a
read-only source leaves the defaults inert.
pub fn from_source_keyed<S: ListDataSource<Item = T>>( source: S, keyed: KeyedSelectionModel<S::Key>, ) -> Self where S::Key: ItemKey,
Wrap any ListDataSource<Item = T> with keyed row selection. The
KeyedSelectionModel<S::Key> tracks selection by source identity, so it
survives reorders / filters / lazy window-slides and stays consistent
across two views of the same source. The view stays TableView<T> β the
indexβkey mapping is captured from the concrete source here. Equivalent
to from_source(..) plus an identity-based replacement for
selection.
pub fn enabled(mut self, enabled: impl Into<Prop<bool>>) -> Self
Enable or disable the whole view. A disabled view greys out and stops accepting focus / selection / keyboard input (arena-gated).
pub fn overscroll_behavior(mut self, behavior: OverscrollBehavior) -> Self
Set the scroll-chaining behavior at the boundary (default
OverscrollBehavior::Chain; Contain
disables chaining to an ancestor scrollable).
pub fn smooth_scrolling(mut self, enabled: bool) -> Self
Enable or disable animated wheel scrolling (enabled by default). When disabled, wheel events snap immediately to the new offset.
pub fn type_ahead_label(mut self, label: impl Fn(&T) -> String + 'static) -> Self
Enable type-ahead ("type to jump"): typing a printable character
while the table has keyboard focus jumps the focused row to the next
row whose label starts with the accumulated search term, wrapping
around (Qt keyboardSearch / macOS & Windows type-select).
label(&item) yields the searchable text for a row; matching is
ASCII-case-insensitive. A pause longer than the
type_ahead_timeout starts a fresh term.
On an editable column whose EditTriggers is type-to-edit, typing
starts an edit instead β type-ahead applies on non-editable columns
(or when no type-to-edit trigger is configured).
pub fn type_ahead_timeout(mut self, timeout: Duration) -> Self
Reset window between keystrokes before the type-ahead search term clears (default 500 ms). A zero duration disables type-ahead.
pub fn smooth_scroll_duration(mut self, duration: Duration) -> Self
Duration of the smooth scroll animation (default 150 ms).
pub fn scroll_bar_style(mut self, style: ScrollBarMode) -> Self
How the scroll bar is displayed (default Permanent). Overlay
and Thin float the bar over the content instead of reserving a
layout column for it, mirroring ScrollArea::scroll_bar_style.
pub fn add_column(mut self, col: Column<T>) -> Self
Append a single Column<T> definition to the table.
pub fn columns(mut self, cols: impl IntoIterator<Item = Column<T>>) -> Self
Append multiple Column<T> definitions from an iterator.
pub fn row_height(mut self, height: f32) -> Self
Fixed row height (default: the table style's 28 px) β the
uniform fast path. Mutually exclusive with
row_height_fn and
auto_row_height; the last mode setter
wins.
pub fn row_height_fn(mut self, f: impl Fn(usize) -> f32 + 'static) -> Self
Per-row heights from a callback over the visible row index. The
callback must be pure (same index + same data β same height); it
is re-swept from the first changed index on every model change
(a SortFilterListModel source reports that index through
first_changed_index, so sort/filter/append keep the valid
prefix). No measurement pass runs.
pub fn auto_row_height(mut self, estimated: f32) -> Self
Auto-measured row heights: each realized row reports the height
of its tallest cell measured at the cell's column width
(height-for-width), unrealized rows assume estimated. Scroll
anchoring keeps content above the viewport stationary as
estimates are corrected; the scrollbar settles one frame after a
measurement change.
pub fn header_height(mut self, height: f32) -> Self
Override the column header row height in logical pixels. Default: the table style's HEADER_HEIGHT.
pub fn show_header(mut self, visible: bool) -> Self
Show or hide the column header row. Default: visible.
pub fn column_resize_policy(mut self, policy: ColumnResizePolicy) -> Self
Set how column widths are redistributed when columns are
added, resized, or the table's own width changes. See
ColumnResizePolicy.
pub fn tab_traversal(mut self, mode: TabTraversal) -> Self
Control how Tab / Shift+Tab navigate between cells. See
TabTraversal.
pub fn edit_triggers(mut self, trigger: EditTriggers) -> Self
Set which user action opens a cell editor. See EditTriggers.
pub fn on_cell_edit_request( mut self, f: impl Fn(usize, &str, &mut teksilo_core::widget::EventContext) + 'static, ) -> Self
Hook fired by the keyboard handler when an edit trigger fires
on the focused cell. Receives (row_index, col_id, ctx).
pub fn on_cell_edit_dismissed( mut self, f: impl Fn(usize, &str, &mut teksilo_core::widget::EventContext) + 'static, ) -> Self
Callback invoked when an open cell editor should end because the pointer went somewhere else: a press that lands on any cell other than the one being edited. Receives the editing cell's flat row index and column id, so the owner can commit (or discard) whatever is in its buffer, then clear its own editing state.
The counterpart of on_cell_edit_request,
and the view cannot do it alone: the framework owns which cell is being
edited, but only the owner knows what an ended edit means β commit,
discard, or refuse a value that will not parse.
Why a press and not a focus change. "The editor lost focus" is the obvious signal and it cannot be used: a body pane rebuilds constantly β selection, filtering, scroll, a reload from elsewhere β and every rebuild destroys and re-creates the open editor, so focus leaves it many times during an edit the writer never interrupted. A press on another cell is unambiguous and happens exactly once.
pub fn on_row_activate( mut self, f: impl Fn(usize, &mut teksilo_core::widget::EventContext) + 'static, ) -> Self
Hook fired when the user presses Enter on the focused row.
pub fn reorderable(mut self, enabled: bool) -> Self
Enable drag-to-reorder of rows (pointer drag + keyboard
Alt+ArrowUp/Down). Distinct from
Column::reorderable, which reorders
columns and defaults to true; this defaults to false.
The move is routed through the backing source's accept_drop: a
ListModel reorders in place, an external source routes the move to
its store. Per-hover the source's can_accept decides whether the
drop is allowed β a forbidden position shows no insertion line and
the drop is refused. A row may also be forbidden from dragging at
all (the source's drag gate). Cross-table / external drops arrive
at accept_drop as DragSource::Foreign; a bare ListModel
rejects them, an external source decides.
pub fn reorderable_rows(self, enabled: bool) -> Self
Renamed to reorderable, matching ListView,
GridView, TreeView and TreeTableView β this was the only view in
the family spelling it differently.
pub fn exportable(mut self, mode: DragTransferMode) -> Self where T: Clone,
Make rows droppable outside this view β on a
DropTarget, another data view, or the OS.
A dragged row (or the whole selection, when the pressed row is part of a
multi-selection) carries clones of its items in a public
RowDragData<T>, so a foreign receiver can pull
them out with payload.get_typed::<RowDragData<T>>() /
DropTarget::on_drop_typed::<RowDragData<T>>() β no serialization. This
also makes rows a drag source even without reorderable.
mode chooses what happens to the origin rows once a foreign target
accepts them: DragTransferMode::Move removes them (via the source's
on_drag_out, or on_rows_transferred_out),
DragTransferMode::Copy leaves them. A same-view reorder is never a
transfer, so mode never affects it. Requires T: Clone.
pub fn export_external(mut self, f: impl Fn(&[T]) -> Vec<(String, Vec<u8>)> + 'static) -> Self where T: Clone,
Additionally advertise the dragged rows as MIME data so they can be
dropped on a DropZone or exported to another
application / window via the OS. f maps the dragged items to
(mime_type, bytes) pairs (e.g. text/plain, text/uri-list, an
app-specific application/x-β¦). Implies exportable
(defaulting to DragTransferMode::Move if not already set). Requires
T: Clone.
pub fn on_rows_transferred_out( mut self, f: impl Fn(&[usize], &mut teksilo_core::widget::EventContext) + 'static, ) -> Self
Override how rows moved out to a foreign target are removed from this
view. Receives the dragged rows' indices (descending-safe) and the live
context. Without this, an exportable
Move drag removes them through the source's
on_drag_out (works out of the box for a ListModel).
pub fn accept_foreign_rows(mut self, accept: bool) -> Self
Accept exported rows dropped from a different view or source without
writing a custom ListDataSource. Pair with
on_rows_received, which is handed the dropped
items and the insertion index. (Same-view reorder is
reorderable; a custom ListDataSource can still
accept foreign drops through its can_accept/accept_drop instead.)
pub fn on_rows_received( mut self, f: impl Fn(Vec<T>, usize, &mut teksilo_core::widget::EventContext) + 'static, ) -> Self
Handler for rows accepted via accept_foreign_rows:
(items, insertion_index, ctx). Insert them into your model at the
index.
pub fn activate_on(mut self, mode: crate::data_views::ActivateOn) -> Self
Choose single- vs double-click activation for on_row_activate (default
ActivateOn::DoubleClick). Enter/Space activates in
either mode.
pub fn selection_mode(mut self, mode: TableSelectionMode) -> Self
Choose the row-selection granularity (None / Single / Multi).
See TableSelectionMode.
pub fn selection(mut self, sel: SelectionModel) -> Self
Set the index-based row selection model (positions). For identity-based
selection that survives reorder / filter / window-slide, build the view
with from_source_keyed instead.
pub fn cell_selection(mut self, sel: CellSelectionModel) -> Self
Install an independent cell-selection model on top of row selection.
See CellSelectionModel.
pub fn alternating_rows(mut self, enabled: bool) -> Self
Paint every other row with a tinted background. Default: off.
pub fn grid_lines(mut self, kind: GridLines) -> Self
Draw horizontal and/or vertical grid lines between cells.
See GridLines.
pub fn a11y_label(mut self, label: impl Into<LocalizedString>) -> Self
Provide an accessible label for the table (aria-label). Required
when the page hosts more than one table so screen readers can
distinguish them.
pub fn show_internal_scrollbars(mut self, show: bool) -> Self
Show or hide the built-in vertical scroll bar. Default: visible. Set to
false when an external scroll bar is wired to scroll_y_signal.
pub fn empty_view(mut self, f: impl Fn() -> Box<dyn Widget> + 'static) -> Self
Widget shown when the source is empty.
pub fn scroll_y_signal(&self) -> &Signal<f32>
Current vertical scroll offset in logical pixels.
pub fn max_scroll_y_signal(&self) -> &Signal<f32>
Maximum vertical scroll offset β total_content_height β viewport_height.
pub fn viewport_ratio_y_signal(&self) -> &Signal<f32>
Viewport-to-content height ratio, used by external scroll bar thumbs.
pub fn scroll_x_signal(&self) -> &Signal<f32>
Current horizontal scroll offset of the Middle (unpinned) pane, in
logical pixels. Leading/Trailing-pinned columns are unaffected β
see Column::pinned.
pub fn max_scroll_x_signal(&self) -> &Signal<f32>
Maximum horizontal scroll offset β middle_content_width β middle_viewport_width.
pub fn viewport_ratio_x_signal(&self) -> &Signal<f32>
Middle-pane viewport-to-content width ratio, used by external horizontal scroll bar thumbs.
pub fn sort_signal(&self) -> &Signal<Option<(String, SortDirection)>>
Active sort: Some((col_id, dir)) or None when unsorted.
Mutated by header clicks (cycle: None β Asc β Desc β None) and by
set_sort / clear_sort.
Bind a SortFilterListModel to
drive a re-sort of the underlying data:
let proxy = SortFilterListModel::new(model)
.with_comparator("name", |a, b| a.name.cmp(&b.name));
proxy.sort_signal(table.sort_signal().clone());
pub fn column_widths_signal(&self) -> &Signal<HashMap<String, f32>>
Map of column id β user-overridden width. A column id appears in this map only after the user resizes that column; missing keys mean "use the declared width policy".
pub fn column_order_signal(&self) -> &Signal<Vec<String>>
Column ids in display order. Updated when the user drags a
header to reorder, or imperatively via
set_column_order. When empty, the
declared order applies. Pinned-side groups (Leading / None /
Trailing) are always honored β the entries inside this signal
only re-sort within each group.
pub fn column_pinning_signal(&self) -> &Signal<HashMap<String, PinnedSide>>
Per-id pinning override map. A key here pins the column to that
side; missing keys fall back to the declared Column::pinned.
Updated when the user drags a column across a pane boundary.
pub fn focused_cell_signal(&self) -> &Signal<Option<(usize, usize)>>
Currently keyboard-focused cell, as (row_index, display_col),
or None when no cell is focused. Mutated by the keyboard
handler (Arrow keys / Tab / Home / End / PgUp / PgDn /
Ctrl-Home / Ctrl-End / Escape) and by direct
set_focused_cell /
clear_focused_cell calls.
pub fn set_focused_cell(&self, row: usize, col: usize)
Move the focused cell. Out-of-range values are silently clamped when the next layout runs.
pub fn clear_focused_cell(&self)
Remove keyboard focus from any cell (equivalent to pressing Escape).
pub fn editing_cell_signal(&self) -> &Signal<Option<(usize, usize)>>
Cell currently in edit mode, or None when no editor is open.
Cell delegates inspect this via CellContext::is_editing and
swap in an editor widget when matched.
pub fn begin_edit(&self, row: usize, col_id: &str)
Begin editing the cell (row, col_id). Silently no-ops if col_id
isn't a currently-displayed column, or if row is outside the visible
range β an out-of-range target would otherwise strand editing_cell on
a row nothing can match.
Callable before the view is mounted, which is the only point at
which a consumer can seed a freshly constructed view with an edit
target it already holds. display_indices is a cache build() fills,
so a pre-mount call finds it empty; the order is recomputed on demand
in that case rather than resolving against nothing and no-opping for a
third, undocumented reason.
pub fn end_edit(&self)
Close the active cell editor without committing (the field's on_blur still fires).
pub fn filters_signal(&self) -> &Signal<HashMap<String, String>>
Per-column filter text. Updated by filter affordances in
header cells and by
set_filter / clear_filters.
Bind a SortFilterListModel<T> to drive the upstream data:
let proxy = SortFilterListModel::new(model)
.with_predicate("name", |t| {
let needle = t.to_string();
Box::new(move |r: &Row| r.name.contains(&needle))
});
proxy.filters_signal(table.filters_signal().clone());
pub fn set_filter(&self, col_id: &str, text: &str)
Set or clear the filter text for a single column. An empty text removes
the entry for col_id (same as clearing the filter for that column).
pub fn clear_filters(&self)
Remove all active column filters.
pub fn scroll_to_row(&self, row: usize)
Scroll so that row is aligned to the top of the viewport. A no-op
before the first layout pass.
pub fn set_sort(&self, col_id: Option<&str>, dir: SortDirection)
Set the active sort imperatively. Equivalent to writing to
sort_signal directly, except that an unchanged
value neither writes nor notifies β see
set_column_widths.
pub fn clear_sort(&self)
Clear the active sort.
pub fn set_column_width(&self, col_id: &str, width: f32)
Set or remove a single column's user-resized width override.
A non-positive width removes the entry (the column reverts to
its declared width policy).
pub fn set_column_widths(&self, widths: HashMap<String, f32>)
Replace the full width-override map (typically used to restore a persisted layout).
A no-op when the map is unchanged, so the documented
settings-round-trip wiring (see docs/table-view.md, "Persistence")
terminates instead of recursing: Signal::set has no equality check of
its own, and a live resize writes a width on every pointer move.
pub fn set_column_order(&self, order: Vec<String>)
Replace the column-order list. Ids not declared on this table are silently dropped on the next layout pass.
pub fn set_column_pinning(&self, col_id: &str, side: PinnedSide)
Pin or unpin a single column.
pub fn ensure_row_visible(&self, row: usize)
Scroll the minimum distance needed to make row visible. A no-op
before the first layout pass, when the viewport height is not yet known.
pub enum ColumnWidth
How a column's width is determined during layout.
#![allow(unused)] fn main() { pub enum ColumnWidth { /* variants */ } }
Variants
Fixedβ Exact pixel width. Clamped bymin_width/max_width.Flexβ Share of the leftover space proportional to the flex factor β behaves like CSSflex-grow. The factor must be> 0.0.Autoβ Intrinsic content width (currently approximated by the table'smin_column_width_defaulttoken; refined to probe the header label and visible cells).
pub enum PinnedSide
Whether a column is pinned to one side of the table.
#![allow(unused)] fn main() { pub enum PinnedSide { /* variants */ } }
Variants
Leadingβ Pinned against the leading edge β stays visible during horizontal scroll.Noneβ Not pinned β scrolls horizontally with the body.Trailingβ Pinned against the trailing edge.
pub enum Alignment
Horizontal alignment of a cell's content within its column.
#![allow(unused)] fn main() { pub enum Alignment { /* variants */ } }
Variants
LeadingCenterTrailing
pub enum TruncationPolicy
Strategy when a cell's text overflows its column.
#![allow(unused)] fn main() { pub enum TruncationPolicy { /* variants */ } }
Variants
Ellipsisββ¦-elide the trailing portion. Default.Noneβ Don't truncate; let the cell content draw beyond the column edge (the body pane's clip will hide it).Fadeβ Fade the trailing portion β gradient mask.
pub enum GridLines
Whether the table draws grid lines between rows / columns.
#![allow(unused)] fn main() { pub enum GridLines { /* variants */ } }
Variants
NoneHorizontalVerticalBoth
pub enum ColumnResizePolicy
Whether column resize commits the new width on every drag tick (Live)
or only on Ended (OnRelease).
#![allow(unused)] fn main() { pub enum ColumnResizePolicy { /* variants */ } }
Variants
LiveOnRelease
pub struct EditTriggers
Which gestures open a cell editor β a set, composed with |, after
Qt's QAbstractItemView::EditTriggers.
A set rather than an enum of named combinations, because the combinations
are the caller's to choose: "one click" and "F2 or one click" are ordinary
requests that a closed enum of F2 / F2OrType / F2OrTypeOrDoubleClick / DoubleClick / None could not express at all.
Set table-wide with TableView::edit_triggers
/ TreeTableView::edit_triggers, and
per column with Column::edit_triggers β the column wins where it sets
one. Only cells of an editable column ever open an
editor, whatever the triggers say; the two are the same split Qt makes
between a view's editTriggers and an item's ItemIsEditable.
SINGLE_CLICK claims the press. A cell that edits on one click does not
also select its row β the same trade any interactive cell content already
makes, and the reason it is per column: put it on the columns that are
nothing but a value, and leave the row's own column alone.
#![allow(unused)] fn main() { pub struct EditTriggers(u8); }
Methods
pub const NONE: Self = Self(0);
Editing is never opened by the view. Cells of an editable column still
render normally; nothing reaches on_cell_edit_request.
pub const F2: Self = Self(1 << 0);
F2 on the focused cell.
pub const ANY_KEY: Self = Self(1 << 1);
Any printable character typed on the focused cell. Note that the keystroke that opens the editor is not delivered into it β the editor does not exist until the next build β so this reads as "F2 with an extra key", and it shadows type-ahead on every editable column.
pub const SINGLE_CLICK: Self = Self(1 << 2);
A single click on the cell. Claims the press, so that cell no longer selects its row.
pub const DOUBLE_CLICK: Self = Self(1 << 3);
A double click on the cell. It takes the gesture from row activation on this column β a column that edits on double-click must not also open its row on the same click β while every other column still activates.
pub const ALL: Self = Self(0b0000_1111);
Every trigger at once.
pub const fn contains(self, other: Self) -> bool
true when every trigger in other is present.
pub const fn is_empty(self) -> bool
true when nothing opens an editor.
pub const fn union(self, other: Self) -> Self
pub const fn intersection(self, other: Self) -> Self
pub enum TabTraversal
Tab / Shift-Tab traversal policy across cells of a row.
Regardless of the policy, Ctrl+Tab / Ctrl+Shift+Tab always move focus
out of the table to the next / previous focusable widget β the reliable
escape from CellsThenRows, so keyboard focus is never trapped.
#![allow(unused)] fn main() { pub enum TabTraversal { /* variants */ } }
Variants
CellsThenRowsβ Tab moves to the next cell within the row, then wraps to the first cell of the next row. Default. (Ctrl+Tab leaves the table.)OutOfTableβ Tab leaves the table once the focused cell is reached at the row boundary; the focus owner is whatever follows the table in tab order.
pub struct CellContext
Per-cell context handed to a column's cell delegate during build.
#![allow(unused)] fn main() { pub struct CellContext { /* fields */ } }
pub struct ColumnContext
Per-column-header context handed to a column's header delegate.
#![allow(unused)] fn main() { pub struct ColumnContext { /* fields */ } }
pub struct Column
Single column declaration. Column ids must be stable, unique strings β they're the persistence key for sort, filter, width, and ordering.
#![allow(unused)] fn main() { pub struct Column<T: 'static> { /* fields */ } }
Methods
pub fn new( id: impl Into<String>, header: impl Into<LocalizedString>, cell: impl Fn(&T, &CellContext) -> Box<dyn Widget> + 'static, ) -> Self
Create a column with a stable id, a localized header label, and a
cell builder that takes &T plus a CellContext and returns a
boxed widget.
pub fn width(mut self, w: ColumnWidth) -> Self
pub fn min_width(mut self, px: f32) -> Self
pub fn max_width(mut self, px: f32) -> Self
pub fn alignment(mut self, a: Alignment) -> Self
pub fn resizable(mut self, b: bool) -> Self
pub fn reorderable(mut self, b: bool) -> Self
pub fn sortable(mut self, b: bool) -> Self
pub fn filterable(mut self, b: bool) -> Self
pub fn editable(mut self, b: bool) -> Self
Mark the column as editable. Default false. F2 / type-to-edit
only enter edit mode on cells of editable columns; the
on_cell_edit_request hook also fires only for these. Cells of
non-editable columns continue to render their static delegate
regardless of editing_cell.
pub fn edit_triggers(mut self, triggers: EditTriggers) -> Self
Override the view's EditTriggers for this column alone.
The reason the set is not only table-wide: a table's columns rarely want the same gesture. A tree column has to keep click-to-select and double-click-to-open, while the plain value columns beside it are exactly where one click to edit belongs. Unset columns inherit the view's set.
pub fn effective_edit_triggers(&self, view: EditTriggers) -> EditTriggers
The triggers in force for this column, given the view's set β the question the body pane and the key handler both ask, and the one an application's own tests want to ask about their column set.
A non-editable column never opens an editor, whatever either says.
pub fn pinned(mut self, side: PinnedSide) -> Self
pub fn truncation(mut self, p: TruncationPolicy) -> Self
pub fn header_override( mut self, f: impl Fn(&ColumnContext) -> Box<dyn Widget> + 'static, ) -> Self
Override the default header rendering (label + sort/filter
indicators). The closure receives a ColumnContext reflecting
the current sort/filter state.
pub fn id(&self) -> &str
Stable column id (the persistence key for sort, filter, width, and ordering signals).
pub enum TableSelectionMode
Selection mode for a TableView or TreeTableView.
#![allow(unused)] fn main() { pub enum TableSelectionMode { /* variants */ } }
Variants
Noneβ No selection allowed.SingleRowβ At most one row selected at a time.MultiRowβ Multiple rows selectable; Ctrl-click toggles, Shift-click extends. Default.SingleCellβ Excel-style: at most one cell selected at a time.MultiCellβ Excel-style: rectangular cell selection.
Methods
pub fn is_cell_mode(self) -> bool
Whether the mode operates on cells rather than entire rows.
pub fn is_multi(self) -> bool
Whether the mode allows more than one entry to be selected.
pub struct CellSelectionModel
Cell-level selection state for TableSelectionMode::SingleCell /
MultiCell. Tracks (row, col) pairs in visible-index space.
Mirrors teksilo_data::SelectionModel's API surface (signal-backed,
auto-adjustable on data mutations) but keyed by (row, col) instead of
row alone.
#![allow(unused)] fn main() { pub struct CellSelectionModel { /* fields */ } }
Methods
pub fn new(mode: TableSelectionMode) -> Self
Construct a model. Panics if mode is not a cell mode β
callers in row mode should use teksilo_data::SelectionModel.
pub fn mode(&self) -> TableSelectionMode
pub fn selection_signal(&self) -> Signal<BTreeSet<(usize, usize)>>
pub fn is_selected(&self, row: usize, col: usize) -> bool
pub fn count(&self) -> usize
pub fn select(&self, row: usize, col: usize)
Replace the selection with the single cell (row, col) and set
the anchor.
pub fn toggle(&self, row: usize, col: usize)
Toggle the cell (row, col) (Ctrl-click). In SingleCell mode
this behaves like select.
pub fn extend_to(&self, row: usize, col: usize)
Extend the selection to include the rectangular range from the
anchor to (row, col). In SingleCell mode this falls back to
select.
pub fn select_all(&self, row_count: usize, col_count: usize)
Select every cell in 0..row_count Γ 0..col_count.
pub fn clear(&self)
pub fn adjust_for_row_insert(&self, at_row: usize, count: usize)
Adjust selection after count rows are inserted starting at
at_row. Existing selections at indices >= at_row shift up.
pub fn adjust_for_row_remove(&self, at_row: usize, count: usize)
Adjust selection after count rows starting at at_row are
removed. Selections within the removed range are dropped; later
rows shift down.
pub fn adjust_for_row_move(&self, from: usize, to: usize, count: usize)
Adjust selection after a block of count rows moved from from to
to (a post-removal index, matching ListModel::move_item). Selected
cells follow their rows; columns are untouched.
pub fn adjust_for_column_insert(&self, at_col: usize, count: usize)
Adjust selection after count columns are inserted at at_col.
Reserved for future dynamic-column support. TableView/TreeTableView
columns are declared once via .add_column()/.columns() and are
static for the widget's lifetime β there is no runtime insert/remove
API today, so nothing calls this. A column reorder or pin-toggle
permutes positions instead (see remap_columns),
which is what the current views actually use. Kept (not removed) as
public API in case a future dynamic-column feature needs the
offset-shift semantics this and adjust_for_column_remove
already implement and test.
pub fn adjust_for_column_remove(&self, at_col: usize, count: usize)
Adjust selection after count columns starting at at_col are
removed.
Reserved for future dynamic-column support β see the doc comment on
adjust_for_column_insert; nothing
calls this today for the same reason.