pub struct Table<S: RowSource, Msg = ()> {
pub page_size: usize,
pub zebra_striping: bool,
pub column_order: Vec<usize>,
pub column_widths: Vec<f32>,
pub column_filters: Vec<String>,
pub pinned_columns: usize,
pub row_background: Option<Box<dyn Fn(usize) -> Option<[u8; 4]> + Send + Sync>>,
/* private fields */
}Expand description
A virtualized table widget backed by a RowSource.
The optional second type parameter Msg (default ()) is the application’s
message type. When Msg is not (), use Table::on_message to attach a
handler that is called whenever the table emits an application-level message.
Only rows visible within the current scroll viewport (plus a configurable overscan region) are materialized, keeping CPU and memory usage constant regardless of the total row count.
Column attributes that the frozen ColumnDef struct
does not carry (per-column alignment, sortability, runtime width) are stored
on the table itself, keyed by column index.
Fields§
§page_size: usizeNumber of rows shown per pagination page. 0 means pagination is disabled.
zebra_striping: boolWhether to render alternate rows with a slightly different background color.
column_order: Vec<usize>Column render order: column_order[i] is the logical column index rendered
in position i. Defaults to the identity permutation.
column_widths: Vec<f32>Runtime column widths (logical pixels). Initialized from column_defs().width
and updated by Table::resize_column. Renderers should prefer this over
the source’s ColumnDef::width so that user resize drags are reflected.
column_filters: Vec<String>Per-column filter text strings (empty = no filter).
Indexed by logical column index. Update with Table::set_column_filter.
pinned_columns: usizeNumber of leftmost columns to pin (freeze) during horizontal scrolling.
row_background: Option<Box<dyn Fn(usize) -> Option<[u8; 4]> + Send + Sync>>Optional per-row background colour callback.
Called with the visible row index. Return Some([r, g, b, a]) to
paint a custom row background, or None to fall back to the default
(zebra striping or theme background).
Implementations§
Source§impl<S: RowSource> Table<S>
impl<S: RowSource> Table<S>
Sourcepub fn new(source: S) -> Self
pub fn new(source: S) -> Self
Create a new Table wrapping source with default settings.
Default row_height is 24.0 pixels; default overscan is 3 rows.
Pagination is disabled by default (page_size = 0), zebra striping is off,
and the column order is the identity permutation.
The message type Msg defaults to (). To use a different message
type, specify the Msg type parameter explicitly when constructing Table.
Source§impl<S: RowSource, Msg> Table<S, Msg>
impl<S: RowSource, Msg> Table<S, Msg>
Sourcepub fn with_page_size(self, size: usize) -> Self
pub fn with_page_size(self, size: usize) -> Self
Set the number of rows per pagination page. 0 disables pagination.
Sourcepub fn with_zebra_striping(self, enabled: bool) -> Self
pub fn with_zebra_striping(self, enabled: bool) -> Self
Enable or disable zebra row striping.
Sourcepub fn with_column_order(self, order: Vec<usize>) -> Self
pub fn with_column_order(self, order: Vec<usize>) -> Self
Override the column render order. Each element is a logical column index.
If order is shorter than the number of columns, trailing columns are
appended in their natural order.
Sourcepub fn with_row_height(self, h: f32) -> Self
pub fn with_row_height(self, h: f32) -> Self
Set a uniform height for all rows in logical pixels.
Also updates the CumulativeHeightCache so that
Table::cache_visible_range and Table::cache_row_at_offset reflect the new height.
Sourcepub fn with_row_heights(self, heights: Vec<f32>) -> Self
pub fn with_row_heights(self, heights: Vec<f32>) -> Self
Set per-row heights (variable-height rows) and update the cumulative height cache.
heights[i] is the height of row i in logical pixels. If heights is shorter
than row_count, missing rows fall back to whatever height was previously configured.
Sourcepub fn cache_row_at_offset(&mut self, y: f32) -> usize
pub fn cache_row_at_offset(&mut self, y: f32) -> usize
Return the row index whose vertical span contains scroll offset y,
using the CumulativeHeightCache for O(log n) lookup.
Sourcepub fn cache_visible_range(
&mut self,
viewport_y: f32,
viewport_h: f32,
) -> Range<usize>
pub fn cache_visible_range( &mut self, viewport_y: f32, viewport_h: f32, ) -> Range<usize>
Return the range of rows at least partially visible in the viewport
[viewport_y, viewport_y + viewport_h), using the cumulative height cache.
Sourcepub fn get_or_fetch_row(&mut self, idx: usize) -> Vec<Cell>
pub fn get_or_fetch_row(&mut self, idx: usize) -> Vec<Cell>
Fetch row idx from the cache if present, or materialise it from the
source, insert it into the cache, and return the cells.
Sourcepub fn invalidate_row_cache(&mut self)
pub fn invalidate_row_cache(&mut self)
Invalidate the row cache. Call after any mutation to the underlying source.
Sourcepub fn with_overscan(self, overscan: usize) -> Self
pub fn with_overscan(self, overscan: usize) -> Self
Set the overscan — extra rows to render beyond the visible viewport on each edge to avoid flash-of-empty-row when scrolling quickly.
Sourcepub fn with_sticky_headers(self, sticky: bool) -> Self
pub fn with_sticky_headers(self, sticky: bool) -> Self
Enable or disable sticky column headers.
When sticky is true, the header row is always rendered at the top of
the visible viewport (y = 0), regardless of the current vertical scroll
offset. Data rows are offset by Table::header_height so they begin
below the pinned header. Table::visible_range also subtracts the
header height from the effective viewport height to virtualize the correct
number of data rows.
Sourcepub fn with_header_height(self, h: f32) -> Self
pub fn with_header_height(self, h: f32) -> Self
Set the height of the header row in logical pixels.
Defaults to 32.0. Only used when Table::sticky_headers is true.
Sourcepub fn header_height(&self) -> f32
pub fn header_height(&self) -> f32
Return the configured header row height in logical pixels.
Sourcepub fn sticky_headers(&self) -> bool
pub fn sticky_headers(&self) -> bool
Return whether sticky column headers are enabled.
Sourcepub fn header_origin_y(&self, v_scroll: f32) -> f32
pub fn header_origin_y(&self, v_scroll: f32) -> f32
Compute the Y position at which the header row should be rendered.
When sticky headers are enabled, this always returns 0.0 so that the
header stays pinned to the top of the viewport. When disabled, the
header scrolls with the content: its position is -v_scroll (i.e. the
header is above the viewport when the user has scrolled down).
Sourcepub fn data_row_origin_y(&self, row: usize, v_scroll: f32) -> f32
pub fn data_row_origin_y(&self, row: usize, v_scroll: f32) -> f32
Compute the Y position at which the top of data row should be rendered.
When sticky headers are enabled, data rows are pushed down by
Table::header_height so they start below the pinned header. The
scroll offset is subtracted so that rows outside the viewport scroll out
of view.
Formula: header_offset + row * row_height - v_scroll, where
header_offset is header_height when sticky and 0.0 otherwise.
Sourcepub fn render_header(&self, origin_y: f32) -> Vec<RenderedCell>
pub fn render_header(&self, origin_y: f32) -> Vec<RenderedCell>
Produce a Vec of RenderedCell values representing the column
header row positioned at origin_y.
Columns are laid out left-to-right according to column_order, using
per-column widths from Table::effective_width. The text field of
each RenderedCell is the crate::ColumnDef::name of the column.
Pass origin_y = 0.0 for a sticky header that is always pinned to the
top of the viewport, or origin_y = self.header_origin_y(v_scroll) to
let the header scroll with the content.
Sourcepub fn with_column_align(self, column: usize, align: CellAlign) -> Self
pub fn with_column_align(self, column: usize, align: CellAlign) -> Self
Set the alignment for column. Columns without an explicit alignment
use the per-cell default (CellAlign::default_for).
Sourcepub fn with_column_sortable(self, column: usize, sortable: bool) -> Self
pub fn with_column_sortable(self, column: usize, sortable: bool) -> Self
Mark whether column may be sorted by clicking its header.
Sourcepub fn with_pinned_columns(self, n: usize) -> Self
pub fn with_pinned_columns(self, n: usize) -> Self
Set the number of leftmost columns to pin (freeze) during horizontal scrolling.
Sourcepub fn with_row_background<F>(self, f: F) -> Self
pub fn with_row_background<F>(self, f: F) -> Self
Attach a per-row background colour callback.
f(vis_row) should return Some([r, g, b, a]) for rows that need a custom
background, or None to fall back to the default (zebra / theme) colour.
Sourcepub fn column_align(&self, column: usize, cell: &Cell) -> CellAlign
pub fn column_align(&self, column: usize, cell: &Cell) -> CellAlign
Resolve the alignment for a cell in column: the explicit override if
set, otherwise the cell’s natural default.
Sourcepub fn is_column_sortable(&self, column: usize) -> bool
pub fn is_column_sortable(&self, column: usize) -> bool
Returns true if column is sortable (default true).
Sourcepub fn sort_state(&self) -> Option<SortState>
pub fn sort_state(&self) -> Option<SortState>
The current sort state, if any.
Sourcepub fn toggle_sort(&mut self, column: usize) -> Option<SortState>
pub fn toggle_sort(&mut self, column: usize) -> Option<SortState>
Toggle sorting on column, cycling None→Asc→Desc→None. Sorting a
different column resets to ascending. No-op if the column is not
sortable. Returns the resulting SortState (or None when cleared).
Sourcepub fn sorted_indices(&self) -> Vec<usize>
pub fn sorted_indices(&self) -> Vec<usize>
Compute the current row-index ordering, applying the active sort if any. Returns the identity order when unsorted.
Sourcepub fn filtered_sorted_indices(&self) -> Vec<usize>
pub fn filtered_sorted_indices(&self) -> Vec<usize>
Apply the per-column filters to sorted_indices and return the
matching subset. An empty column_filters entry is treated as
“no filter” (matches all rows).
Returns the full sorted index when no filter is active.
Sourcepub fn set_column_filter(&mut self, col: usize, text: String)
pub fn set_column_filter(&mut self, col: usize, text: String)
Update the per-column filter text for col.
An empty string clears the filter for that column. No-op if col is
out of range.
Sourcepub fn resize_column(&mut self, col: usize, delta_px: f32) -> Option<f32>
pub fn resize_column(&mut self, col: usize, delta_px: f32) -> Option<f32>
Apply a resize delta delta_px to col, clamping to the column’s
min_width / max_width / resizable constraints.
Returns the new effective width, or None if:
colis out of range forcolumn_widths, or- the column’s
ColumnDefmarks it non-resizable.
Sourcepub fn effective_width(&self, col: usize) -> f32
pub fn effective_width(&self, col: usize) -> f32
Return the effective runtime width for col (logical pixels).
Falls back to the source’s ColumnDef::width if col is outside
column_widths.
Sourcepub fn row_bg(&self, vis_row: usize) -> Option<[u8; 4]>
pub fn row_bg(&self, vis_row: usize) -> Option<[u8; 4]>
Return the background colour for vis_row, or None for the default.
Consults row_background if set; otherwise returns None. Renderers
apply zebra striping independently from this callback.
Sourcepub fn row_height(&self) -> f32
pub fn row_height(&self) -> f32
Return the configured row height in logical pixels.
Sourcepub fn visible_range(
&self,
viewport_height: f32,
scroll_offset: f32,
) -> Range<usize>
pub fn visible_range( &self, viewport_height: f32, scroll_offset: f32, ) -> Range<usize>
Calculate which rows are visible for a viewport of height viewport_height
starting at scroll_offset pixels from the top.
The returned range is clamped to 0..row_count().
When Table::sticky_headers is true, the effective viewport height
for data rows is reduced by Table::header_height (the header occupies
the top portion of the viewport). The scroll offset is not adjusted —
it still refers to the position within the data content.
Sourcepub fn materialize_visible(
&self,
viewport_height: f32,
scroll_offset: f32,
) -> Vec<Vec<Cell>>
pub fn materialize_visible( &self, viewport_height: f32, scroll_offset: f32, ) -> Vec<Vec<Cell>>
Materialize only the visible rows for the given viewport parameters.
Each returned inner Vec<Cell> corresponds to one row. Rows outside the
visible range are never fetched from the source.
Sourcepub fn to_csv_all(&self, filters: &[ColumnFilter]) -> String
pub fn to_csv_all(&self, filters: &[ColumnFilter]) -> String
Export all rows (after optional filter+sort, ignoring pagination) to CSV.
Pass a non-empty filters slice to restrict to matching rows; pass an
empty slice to export every row. The output uses ',' as the delimiter
and follows RFC-4180 quoting.
Sourcepub fn to_csv_visible(
&self,
page: &PaginationState,
filters: &[ColumnFilter],
) -> String
pub fn to_csv_visible( &self, page: &PaginationState, filters: &[ColumnFilter], ) -> String
Export visible rows (after filter+sort+pagination) to CSV.
page is the PaginationState governing which page is visible.
filters may be empty (no filtering).
Source§impl<S: RowSource, Msg> Table<S, Msg>
impl<S: RowSource, Msg> Table<S, Msg>
Sourcepub fn visible_column_range(
&self,
h_scroll: f32,
viewport_width: f32,
) -> Range<usize>
pub fn visible_column_range( &self, h_scroll: f32, viewport_width: f32, ) -> Range<usize>
Compute the range of column indices that are at least partially visible within a horizontal viewport.
h_scroll is the current horizontal scroll offset (logical pixels from
the left edge of the first column). viewport_width is the visible
width in logical pixels.
The returned range is suitable for slicing column_order or iterating
directly: range.start..range.end gives the first and one-past-last
column render position whose pixel span overlaps [h_scroll, h_scroll + viewport_width).
Columns widths are read from column_widths
via effective_width, so user resize deltas
are reflected correctly.
Returns an empty range (n..n) when:
- There are no columns.
h_scrollis beyond the total column extent.
Source§impl<S: RowSource, Msg> Table<S, Msg>
impl<S: RowSource, Msg> Table<S, Msg>
Sourcepub fn on_message<F: FnMut(Msg) + Send + 'static>(self, f: F) -> Self
pub fn on_message<F: FnMut(Msg) + Send + 'static>(self, f: F) -> Self
Attach an application-message handler.
f is called (via Table::dispatch_message) whenever the table
produces a Msg value. This is the escape hatch for integrating the
table into an Elm-style message-passing architecture without wrapping
every table event in a manual .map() call.
§Example
table.on_message(|msg: MyAppMsg| sender.send(msg).ok());Sourcepub fn dispatch_message(&mut self, msg: Msg)
pub fn dispatch_message(&mut self, msg: Msg)
Dispatch a Msg value to the registered handler, if any.
No-op when no handler has been attached via Table::on_message.
Trait Implementations§
Auto Trait Implementations§
impl<S, Msg = ()> !RefUnwindSafe for Table<S, Msg>
impl<S, Msg = ()> !Sync for Table<S, Msg>
impl<S, Msg = ()> !UnwindSafe for Table<S, Msg>
impl<S, Msg> Freeze for Table<S, Msg>where
S: Freeze,
impl<S, Msg> Send for Table<S, Msg>
impl<S, Msg> Unpin for Table<S, Msg>
impl<S, Msg> UnsafeUnpin for Table<S, Msg>where
S: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more