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}