agg_gui/widgets/table/
config.rs1use std::sync::Arc;
7
8use crate::draw_ctx::DrawCtx;
9use crate::geometry::Rect;
10use crate::text::Font;
11use crate::theme::Visuals;
12
13#[derive(Clone, Copy, Debug)]
17pub enum ColumnSize {
18 Auto(f64),
19 Exact(f64),
20 Remainder { at_least: f64, clip: bool },
21}
22
23#[derive(Clone, Copy, Debug)]
24pub struct TableColumn {
25 pub size: ColumnSize,
26 pub resizable: bool,
27}
28
29impl TableColumn {
30 pub fn auto(initial: f64) -> Self {
31 Self {
32 size: ColumnSize::Auto(initial),
33 resizable: false,
34 }
35 }
36 pub fn exact(w: f64) -> Self {
37 Self {
38 size: ColumnSize::Exact(w),
39 resizable: false,
40 }
41 }
42 pub fn remainder() -> Self {
43 Self {
44 size: ColumnSize::Remainder {
45 at_least: 16.0,
46 clip: false,
47 },
48 resizable: false,
49 }
50 }
51 pub fn at_least(mut self, v: f64) -> Self {
52 if let ColumnSize::Remainder {
53 ref mut at_least, ..
54 } = self.size
55 {
56 *at_least = v;
57 }
58 self
59 }
60 pub fn clip(mut self, on: bool) -> Self {
61 if let ColumnSize::Remainder { ref mut clip, .. } = self.size {
62 *clip = on;
63 }
64 self
65 }
66 pub fn resizable(mut self, on: bool) -> Self {
67 self.resizable = on;
68 self
69 }
70}
71
72pub const MIN_COL_W: f64 = 16.0;
74pub const RESIZE_HIT_HALF: f64 = 4.0;
76
77pub fn distribute_widths(
84 columns: &[TableColumn],
85 total_w: f64,
86 overrides: &[Option<f64>],
87) -> Vec<f64> {
88 let n = columns.len();
89 let mut out = vec![0.0_f64; n];
90 let mut remainder_indices: Vec<usize> = Vec::new();
91 let mut remainder_min = 0.0_f64;
92 let mut fixed_total = 0.0_f64;
93 for (i, c) in columns.iter().enumerate() {
94 if let Some(w) = overrides.get(i).copied().flatten() {
95 out[i] = w.max(MIN_COL_W);
96 fixed_total += out[i];
97 continue;
98 }
99 match c.size {
100 ColumnSize::Auto(w) | ColumnSize::Exact(w) => {
101 out[i] = w;
102 fixed_total += w;
103 }
104 ColumnSize::Remainder { at_least, .. } => {
105 remainder_indices.push(i);
106 remainder_min += at_least;
107 }
108 }
109 }
110 let leftover = (total_w - fixed_total).max(remainder_min);
111 if !remainder_indices.is_empty() {
112 let each = leftover / remainder_indices.len() as f64;
113 for &i in &remainder_indices {
114 let at_least = match columns[i].size {
115 ColumnSize::Remainder { at_least, .. } => at_least,
116 _ => 0.0,
117 };
118 out[i] = each.max(at_least);
119 }
120 }
121 out
122}
123
124#[derive(Clone, Debug)]
126pub enum TableRows {
127 Homogeneous { count: usize, height: f64 },
128 Heterogeneous { heights: Vec<f64> },
129}
130
131impl TableRows {
132 pub fn count(&self) -> usize {
133 match self {
134 TableRows::Homogeneous { count, .. } => *count,
135 TableRows::Heterogeneous { heights } => heights.len(),
136 }
137 }
138 pub fn height_at(&self, i: usize) -> f64 {
139 match self {
140 TableRows::Homogeneous { height, .. } => *height,
141 TableRows::Heterogeneous { heights } => heights.get(i).copied().unwrap_or(0.0),
142 }
143 }
144 pub fn total_height(&self) -> f64 {
145 match self {
146 TableRows::Homogeneous { count, height } => *count as f64 * *height,
147 TableRows::Heterogeneous { heights } => heights.iter().copied().sum(),
148 }
149 }
150 pub fn top_down_y_at(&self, i: usize) -> f64 {
151 match self {
152 TableRows::Homogeneous { height, .. } => i as f64 * *height,
153 TableRows::Heterogeneous { heights } => {
154 let take = i.min(heights.len());
155 heights[..take].iter().copied().sum()
156 }
157 }
158 }
159}
160
161pub struct CellInfo<'a> {
164 pub row: usize,
165 pub col: usize,
166 pub rect: Rect,
169 pub selected: bool,
170 pub visuals: &'a Visuals,
171 pub font: &'a Arc<Font>,
172}
173
174pub struct HeaderInfo<'a> {
175 pub col: usize,
176 pub rect: Rect,
177 pub visuals: &'a Visuals,
178 pub font: &'a Arc<Font>,
179}
180
181pub type CellPainter = Box<dyn FnMut(&CellInfo, &mut dyn DrawCtx)>;
182pub type HeaderPainter = Box<dyn FnMut(&HeaderInfo, &mut dyn DrawCtx)>;
183pub type HeaderClick = Box<dyn FnMut(usize, f64, f64) -> crate::event::EventResult>;
186pub type RowPredicate = Box<dyn Fn(usize) -> bool>;
188pub type RowsProvider = Box<dyn Fn() -> TableRows>;