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