GridModel API

Definition

pub struct GridModel {
    pub columns: Vec<ColumnDef>,
    pub data: Box<dyn DataSource>,
    pub row_height: f64,
    pub header_height: f64,
    pub filter_row_height: f64,
    pub show_filter_row: bool,
    pub column_offsets: ColumnOffsets,
    pub patches: HashMap<(u64, String), String>,
    pub row_number_width: f64,
    pub sort_order: Vec<u64>,
    pub pinned_count: usize,
    pub filters: HashMap<String, FilterCondition>,
    pub value_filters: HashMap<String, HashSet<String>>,
    pub filtered_indices: Vec<u64>,
    pub mode: DataSourceMode,
    pub scrollbar_size: f64,
    pub editable: bool,
    pub selectable: bool,
    pub column_reorderable: bool,
    pub invalid_edit_mode: InvalidEditMode,
}

Fields

FieldTypeDefaultDescription
columnsVec<ColumnDef>Ordered column definitions
dataBox<dyn DataSource>Backing data provider
row_heightf64Height of data rows (logical px)
header_heightf64Height of header row (logical px)
filter_row_heightf6436.0Height of the floating filter row (logical px) — see Filtering
show_filter_rowboolfalseShow the floating filter row — a quick "contains" filter per column, and the only click path to the filter popup
column_offsetsColumnOffsetscomputedPrecomputed left-edge offsets
patchesHashMap<(u64, String), String>emptyCell value overrides
row_number_widthf64autoGutter width (auto from row count)
sort_orderVec<u64>emptyDisplay→physical row mapping
pinned_countusize0Number of pinned leading columns
filtersHashMap<String, FilterCondition>emptyPer-column filter conditions — see Filtering
value_filtersHashMap<String, HashSet<String>>emptyPer-column value-set restrictions (checklist filter), AND-combined with filters — see Filtering
filtered_indicesVec<u64>emptyFiltered physical row indices — only meaningful when is_filter_applied() is true
modeDataSourceModeClientSideClient or server-side data
scrollbar_sizef6414.0Scrollbar reserved space
editablebooltrueGlobal inline-edit toggle (per-column flag still applies)
selectablebooltrueGlobal selection toggle; clears selection when set to false
column_reorderablebooltrueAllow header drag-to-reorder. MoveColumn works regardless
invalid_edit_modeInvalidEditModeRevertPolicy applied when a CommitEdit fails validation — see Validation

Constructors

// In-memory data
pub fn new(columns: Vec<ColumnDef>, rows: Vec<RowRecord>, row_height: f64, header_height: f64) -> Self

// Custom data source
pub fn with_data_source(columns: Vec<ColumnDef>, data: Box<dyn DataSource>, row_height: f64, header_height: f64) -> Self

Methods

MethodSignatureDescription
get_cell(row: u64, col_key: &str) -> Option<String>Read cell (patches first, then data source)
set_cell(row: u64, col_key: &str, value: String)Write cell to data source
logical_to_physical(logical: u64) -> u64Map display row to data row
display_row_count() -> u64Visible row count (respects filters)
total_width() -> f64Sum of column widths
total_height() -> f64row_count × row_height + data_top()
pinned_width() -> f64Total width of pinned columns
compute_row_number_width(row_count: u64) -> f64Auto-compute gutter width
effective_header_height() -> f64header_height (0 if show_header is false)
effective_filter_row_height() -> f64filter_row_height (0 if show_filter_row is false)
data_top() -> f64effective_header_height() + effective_filter_row_height() — where scrollable data starts
column_screen_x(col_idx: usize, scroll_x: f64) -> Option<f64>On-screen X of a column's left edge, pinned-aware
is_filter_applied() -> boolWhether filtered_indices should be trusted as-is, including when empty (zero rows match) — vs. being empty because no filter is active
unique_values(col_key: &str, cap: usize) -> UniqueValuesDistinct values for a column (sorted), up to cap — backs the checklist filter UI

GridModelBuilder

An ergonomic builder for constructing a GridModel with sensible defaults:

pub struct GridModelBuilder { /* ... */ }

impl GridModelBuilder {
    pub fn new(
        columns: Vec<ColumnDef>,
        data: Box<dyn DataSource>,
    ) -> Self;

    pub fn row_height(self, h: f64) -> Self;       // default 30.0
    pub fn header_height(self, h: f64) -> Self;     // default 40.0
    pub fn filter_row_height(self, h: f64) -> Self; // default 36.0
    pub fn show_filter_row(self, v: bool) -> Self;  // default false
    pub fn pinned_count(self, n: usize) -> Self;    // default 0
    pub fn mode(self, m: DataSourceMode) -> Self;   // default ClientSide
    pub fn scrollbar_size(self, s: f64) -> Self;    // default 14.0
    pub fn editable(self, v: bool) -> Self;         // default true
    pub fn selectable(self, v: bool) -> Self;       // default true
    pub fn column_reorderable(self, v: bool) -> Self; // default true
    pub fn invalid_edit_mode(self, m: InvalidEditMode) -> Self; // default Revert
    pub fn build(self) -> GridModel;
}

Example

let model = GridModelBuilder::new(columns, Box::new(data))
    .row_height(40.0)
    .pinned_count(2)
    .build();

pinned_count is clamped to the number of columns if it exceeds columns.len().

The existing constructors GridModel::new() and GridModel::with_data_source() remain available.

DataSourceMode

pub enum DataSourceMode {
    ClientSide,  // sort/filter done locally (default)
    ServerSide,  // sort/filter delegated to server
}

InvalidEditMode

pub enum InvalidEditMode {
    Revert,  // drop the edit session, revert the cell (default)
    Block,   // keep the edit session open with the error attached
}

Toggle at runtime with GridCommand::SetInvalidEditMode. See Validation for the full behaviour.