repose_core/
modifier.rs

1use std::rc::Rc;
2
3use taffy::AlignSelf;
4
5use crate::{Color, PointerEvent, Size, Transform, Vec2};
6
7#[derive(Clone, Debug)]
8pub struct Border {
9    pub width: f32,
10    pub color: Color,
11    pub radius: f32,
12}
13
14#[derive(Clone, Copy, Debug, Default)]
15pub struct PaddingValues {
16    pub left: f32,
17    pub right: f32,
18    pub top: f32,
19    pub bottom: f32,
20}
21
22#[derive(Clone, Default)]
23pub struct Modifier {
24    pub padding: Option<f32>,
25    pub padding_values: Option<PaddingValues>,
26    pub size: Option<Size>,
27    pub fill_max: bool,
28    pub fill_max_w: bool,
29    pub fill_max_h: bool,
30    pub width: Option<f32>,
31    pub height: Option<f32>,
32    pub min_width: Option<f32>,
33    pub min_height: Option<f32>,
34    pub max_width: Option<f32>,
35    pub max_height: Option<f32>,
36    pub background: Option<Color>,
37    pub border: Option<Border>,
38    pub flex_grow: Option<f32>,
39    pub flex_shrink: Option<f32>,
40    pub flex_basis: Option<f32>,
41    pub align_self: Option<AlignSelf>,
42    pub aspect_ratio: Option<f32>, // width/height
43    pub position_type: Option<PositionType>,
44    pub offset_left: Option<f32>,
45    pub offset_right: Option<f32>,
46    pub offset_top: Option<f32>,
47    pub offset_bottom: Option<f32>,
48    pub grid: Option<GridConfig>,
49    pub grid_col_span: Option<u16>,
50    pub grid_row_span: Option<u16>,
51    pub click: bool,
52    pub semantics_label: Option<String>,
53    /// Works for hit-testing only, draw order is not changed.
54    pub z_index: f32,
55    pub clip_rounded: Option<f32>,
56    pub on_scroll: Option<Rc<dyn Fn(Vec2) -> Vec2>>,
57
58    // Pointer callbacks
59    pub on_pointer_down: Option<Rc<dyn Fn(PointerEvent)>>,
60    pub on_pointer_move: Option<Rc<dyn Fn(PointerEvent)>>,
61    pub on_pointer_up: Option<Rc<dyn Fn(PointerEvent)>>,
62    pub on_pointer_enter: Option<Rc<dyn Fn(PointerEvent)>>,
63    pub on_pointer_leave: Option<Rc<dyn Fn(PointerEvent)>>,
64
65    pub alpha: Option<f32>,
66    pub transform: Option<Transform>,
67
68    pub painter: Option<Rc<dyn Fn(&mut crate::Scene, crate::Rect)>>,
69}
70
71#[derive(Clone, Copy, Debug)]
72pub enum PositionType {
73    Relative,
74    Absolute,
75}
76
77#[derive(Clone, Copy, Debug)]
78pub struct GridConfig {
79    pub columns: usize, // e.g. 3 (auto 1fr tracks)
80    pub row_gap: f32,
81    pub column_gap: f32,
82}
83
84impl Default for Border {
85    fn default() -> Self {
86        Border {
87            width: 1.0,
88            color: Color::WHITE,
89            radius: 0.0,
90        }
91    }
92}
93
94impl std::fmt::Debug for Modifier {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        f.debug_struct("Modifier")
97            .field("padding", &self.padding)
98            .field("padding_values", &self.padding_values)
99            .field("size", &self.size)
100            .field("max_height", &self.max_height)
101            .field("max_width", &self.max_width)
102            .field("min_height", &self.min_height)
103            .field("min_width", &self.min_width)
104            .field("fill_max", &self.fill_max)
105            .field("background", &self.background)
106            .field("border", &self.border)
107            .field("click", &self.click)
108            .field("semantics_label", &self.semantics_label)
109            .field("z_index", &self.z_index)
110            .field("clip_rounded", &self.clip_rounded)
111            .field("alpha", &self.alpha)
112            .finish()
113    }
114}
115
116impl Modifier {
117    pub fn new() -> Self {
118        Self::default()
119    }
120    pub fn padding(mut self, px: f32) -> Self {
121        self.padding = Some(px);
122        self
123    }
124    pub fn padding_values(mut self, pv: PaddingValues) -> Self {
125        self.padding_values = Some(pv);
126        self
127    }
128    pub fn size(mut self, w: f32, h: f32) -> Self {
129        self.size = Some(Size {
130            width: w,
131            height: h,
132        });
133        self
134    }
135    pub fn fill_max_size(mut self) -> Self {
136        self.fill_max = true;
137        self
138    }
139    pub fn width(mut self, w: f32) -> Self {
140        self.width = Some(w);
141        self
142    }
143    pub fn height(mut self, h: f32) -> Self {
144        self.height = Some(h);
145        self
146    }
147    pub fn fill_max_width(mut self) -> Self {
148        self.fill_max_w = true;
149        self
150    }
151    pub fn fill_max_height(mut self) -> Self {
152        self.fill_max_h = true;
153        self
154    }
155    pub fn min_size(mut self, w: f32, h: f32) -> Self {
156        self.min_width = Some(w.max(0.0));
157        self.min_height = Some(h.max(0.0));
158        self
159    }
160    pub fn max_size(mut self, w: f32, h: f32) -> Self {
161        self.max_width = Some(w.max(0.0));
162        self.max_height = Some(h.max(0.0));
163        self
164    }
165    pub fn min_width(mut self, w: f32) -> Self {
166        self.min_width = Some(w.max(0.0));
167        self
168    }
169    pub fn min_height(mut self, h: f32) -> Self {
170        self.min_height = Some(h.max(0.0));
171        self
172    }
173    pub fn max_width(mut self, w: f32) -> Self {
174        self.max_width = Some(w.max(0.0));
175        self
176    }
177    pub fn max_height(mut self, h: f32) -> Self {
178        self.max_height = Some(h.max(0.0));
179        self
180    }
181    pub fn background(mut self, color: Color) -> Self {
182        self.background = Some(color);
183        self
184    }
185    pub fn border(mut self, width: f32, color: Color, radius: f32) -> Self {
186        self.border = Some(Border {
187            width,
188            color,
189            radius,
190        });
191        self
192    }
193    pub fn clickable(mut self) -> Self {
194        self.click = true;
195        self
196    }
197    pub fn semantics(mut self, label: impl Into<String>) -> Self {
198        self.semantics_label = Some(label.into());
199        self
200    }
201    pub fn z_index(mut self, z: f32) -> Self {
202        self.z_index = z;
203        self
204    }
205    pub fn clip_rounded(mut self, r: f32) -> Self {
206        self.clip_rounded = Some(r);
207        self
208    }
209
210    pub fn on_pointer_down(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
211        self.on_pointer_down = Some(Rc::new(f));
212        self
213    }
214    pub fn on_pointer_move(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
215        self.on_pointer_move = Some(Rc::new(f));
216        self
217    }
218    pub fn on_pointer_up(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
219        self.on_pointer_up = Some(Rc::new(f));
220        self
221    }
222    pub fn on_pointer_enter(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
223        self.on_pointer_enter = Some(Rc::new(f));
224        self
225    }
226    pub fn on_pointer_leave(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
227        self.on_pointer_leave = Some(Rc::new(f));
228        self
229    }
230    pub fn flex_grow(mut self, g: f32) -> Self {
231        self.flex_grow = Some(g);
232        self
233    }
234    pub fn flex_shrink(mut self, s: f32) -> Self {
235        self.flex_shrink = Some(s);
236        self
237    }
238    pub fn flex_basis(mut self, px: f32) -> Self {
239        self.flex_basis = Some(px);
240        self
241    }
242    pub fn align_self_baseline(mut self) -> Self {
243        self.align_self = Some(AlignSelf::Baseline);
244        self
245    }
246    pub fn align_self_center(mut self) -> Self {
247        self.align_self = Some(AlignSelf::Center);
248        self
249    }
250    pub fn align_self(mut self, align: AlignSelf) -> Self {
251        self.align_self = Some(align);
252        self
253    }
254    pub fn aspect_ratio(mut self, ratio: f32) -> Self {
255        self.aspect_ratio = Some(ratio.max(0.0));
256        self
257    }
258    pub fn absolute(mut self) -> Self {
259        self.position_type = Some(PositionType::Absolute);
260        self
261    }
262    pub fn offset(
263        mut self,
264        left: Option<f32>,
265        top: Option<f32>,
266        right: Option<f32>,
267        bottom: Option<f32>,
268    ) -> Self {
269        self.offset_left = left;
270        self.offset_top = top;
271        self.offset_right = right;
272        self.offset_bottom = bottom;
273        self
274    }
275    pub fn grid(mut self, columns: usize, row_gap: f32, column_gap: f32) -> Self {
276        self.grid = Some(GridConfig {
277            columns: columns.max(1),
278            row_gap,
279            column_gap,
280        });
281        self
282    }
283    pub fn grid_span(mut self, col_span: u16, row_span: u16) -> Self {
284        self.grid_col_span = Some(col_span.max(1));
285        self.grid_row_span = Some(row_span.max(1));
286        self
287    }
288
289    pub fn alpha(mut self, a: f32) -> Self {
290        self.alpha = Some(a.clamp(0.0, 1.0));
291        self
292    }
293    /// Broken currently?
294    pub fn translate(mut self, x: f32, y: f32) -> Self {
295        let t = self.transform.unwrap_or_else(Transform::identity);
296        self.transform = Some(t.combine(&Transform::translate(x, y)));
297        self
298    }
299    pub fn scale(mut self, s: f32) -> Self {
300        self.scale2(s, s)
301    }
302    pub fn scale2(mut self, sx: f32, sy: f32) -> Self {
303        let mut t = self.transform.unwrap_or_else(Transform::identity);
304        t.scale_x *= sx;
305        t.scale_y *= sy;
306        self.transform = Some(t);
307        self
308    }
309    pub fn rotate(mut self, radians: f32) -> Self {
310        let mut t = self.transform.unwrap_or_else(Transform::identity);
311        t.rotate += radians;
312        self.transform = Some(t);
313        self
314    }
315    pub fn on_scroll(mut self, f: impl Fn(Vec2) -> Vec2 + 'static) -> Self {
316        self.on_scroll = Some(Rc::new(f));
317        self
318    }
319
320    pub fn painter(mut self, f: impl Fn(&mut crate::Scene, crate::Rect) + 'static) -> Self {
321        self.painter = Some(Rc::new(f));
322        self
323    }
324}