Skip to main content

densa_grid/
model.rs

1use crate::{CellStyle, CellText, Column, Palette};
2
3/// Which way a column sorts.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[non_exhaustive]
6pub enum SortOrder {
7    /// Smallest first.
8    Ascending,
9    /// Largest first.
10    Descending,
11}
12
13impl SortOrder {
14    /// The other order.
15    #[must_use]
16    pub fn flipped(self) -> Self {
17        match self {
18            Self::Ascending => Self::Descending,
19            Self::Descending => Self::Ascending,
20        }
21    }
22}
23
24/// The data of a grid widget: its columns, its rows, and each cell's text and style, plus
25/// what the widget asks of it as the user works with it.
26///
27/// Rows are numbered from 0 in the order they are shown; the widget asks only for the rows
28/// on screen. [`cell`](Self::cell) runs for every visible cell every frame and formats into
29/// a stack buffer, so it must not allocate.
30pub trait GridModel {
31    /// The columns, left to right.
32    fn columns(&self) -> &[Column];
33
34    /// How many rows there are.
35    fn rows(&self) -> usize;
36
37    /// Writes the text of the cell at `row`, `column` into `text` (empty on entry) and
38    /// returns its style, in the grid's colors (`palette`, which follows the theme).
39    fn cell(&self, row: usize, column: usize, text: &mut CellText, palette: &Palette) -> CellStyle;
40
41    /// Brings the model up to date before the grid paints (taking in data that arrived, for
42    /// example). It may allocate when the data changed; it should not otherwise. It runs only
43    /// when the grid paints, not while it is hidden (an inactive tab): feed a model that
44    /// must keep up while hidden from the application, through
45    /// `DataGrid::model_mut`.
46    fn prepare(&mut self) {}
47
48    /// Sorts the rows by `column` (an index into [`columns`](Self::columns)) in `order`, when
49    /// the user asks for it (a click on its title); `false` if the model does not sort by
50    /// that column, which leaves the order alone.
51    fn sort(&mut self, column: usize, order: SortOrder) -> bool {
52        let _ = (column, order);
53        false
54    }
55
56    /// The column and order the rows are sorted by now, if the model knows (a model sorted
57    /// before the user clicked, or one that sorts itself); the grid shows it and reverses it
58    /// on the next click.
59    fn sort_state(&self) -> Option<(usize, SortOrder)> {
60        None
61    }
62
63    /// A value identifying the record at `row` while rows are added, removed or sorted (a
64    /// database key, an instrument id). With it, a selection follows its record; without
65    /// it (`None`, the default), a selection is a position and is cleared by sorting.
66    fn row_key(&self, row: usize) -> Option<u64> {
67        let _ = row;
68        None
69    }
70
71    /// Where the record [`row_key`](Self::row_key) gave `key` for is now, if it is still
72    /// shown. Asked once a frame while a row is selected: make it fast for large models.
73    /// `None` (the record was removed, or is filtered out) clears the selection.
74    fn row_of_key(&self, key: u64) -> Option<usize> {
75        let _ = key;
76        None
77    }
78
79    /// Changes whenever [`columns`](Self::columns) changes (another schema, new widths): the
80    /// grid then reads the columns again, dropping widths the user dragged. Checked each
81    /// frame after [`prepare`](Self::prepare).
82    fn columns_revision(&self) -> u64 {
83        0
84    }
85
86    /// Changes when the rows were replaced wholesale (another table), so that keys from
87    /// before mean nothing: the grid then clears its selection and scrolls to the top.
88    /// Checked each frame after [`prepare`](Self::prepare).
89    fn generation(&self) -> u64 {
90        0
91    }
92}