1use std::rc::Rc;
2
3use taffy::AlignSelf;
4
5use crate::{Color, PointerEvent, Size};
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, Default)]
15pub struct Modifier {
16 pub padding: Option<f32>,
17 pub size: Option<Size>,
18 pub fill_max: bool,
19 pub background: Option<Color>,
20 pub border: Option<Border>,
21 pub flex_grow: Option<f32>,
22 pub flex_shrink: Option<f32>,
23 pub flex_basis: Option<f32>,
24 pub align_self: Option<AlignSelf>,
25 pub aspect_ratio: Option<f32>, pub position_type: Option<PositionType>,
27 pub offset_left: Option<f32>,
28 pub offset_right: Option<f32>,
29 pub offset_top: Option<f32>,
30 pub offset_bottom: Option<f32>,
31 pub grid: Option<GridConfig>,
32 pub grid_col_span: Option<u16>,
33 pub grid_row_span: Option<u16>,
34 pub click: bool,
35 pub semantics_label: Option<String>,
36 pub z_index: f32,
37 pub clip_rounded: Option<f32>,
38 pub on_pointer_down: Option<Rc<dyn Fn(PointerEvent)>>,
40 pub on_pointer_move: Option<Rc<dyn Fn(PointerEvent)>>,
41 pub on_pointer_up: Option<Rc<dyn Fn(PointerEvent)>>,
42 pub on_pointer_enter: Option<Rc<dyn Fn(PointerEvent)>>,
43 pub on_pointer_leave: Option<Rc<dyn Fn(PointerEvent)>>,
44}
45
46#[derive(Clone, Copy, Debug)]
47pub enum PositionType {
48 Relative,
49 Absolute,
50}
51
52#[derive(Clone, Copy, Debug)]
53pub struct GridConfig {
54 pub columns: usize, pub row_gap: f32,
56 pub column_gap: f32,
57}
58
59impl Default for Border {
60 fn default() -> Self {
61 Border {
62 width: 1.0,
63 color: Color::WHITE,
64 radius: 0.0,
65 }
66 }
67}
68
69impl std::fmt::Debug for Modifier {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.debug_struct("Modifier")
72 .field("padding", &self.padding)
73 .field("size", &self.size)
74 .field("fill_max", &self.fill_max)
75 .field("background", &self.background)
76 .field("border", &self.border)
77 .field("click", &self.click)
78 .field("semantics_label", &self.semantics_label)
79 .field("z_index", &self.z_index)
80 .field("clip_rounded", &self.clip_rounded)
81 .finish()
82 }
83}
84
85impl Modifier {
86 pub fn new() -> Self {
87 Self::default()
88 }
89 pub fn padding(mut self, px: f32) -> Self {
90 self.padding = Some(px);
91 self
92 }
93 pub fn size(mut self, w: f32, h: f32) -> Self {
94 self.size = Some(Size {
95 width: w,
96 height: h,
97 });
98 self
99 }
100 pub fn fill_max_size(mut self) -> Self {
101 self.fill_max = true;
102 self
103 }
104 pub fn background(mut self, color: Color) -> Self {
105 self.background = Some(color);
106 self
107 }
108 pub fn border(mut self, width: f32, color: Color, radius: f32) -> Self {
109 self.border = Some(Border {
110 width,
111 color,
112 radius,
113 });
114 self
115 }
116 pub fn clickable(mut self) -> Self {
117 self.click = true;
118 self
119 }
120 pub fn semantics(mut self, label: impl Into<String>) -> Self {
121 self.semantics_label = Some(label.into());
122 self
123 }
124 pub fn z_index(mut self, z: f32) -> Self {
125 self.z_index = z;
126 self
127 }
128 pub fn clip_rounded(mut self, r: f32) -> Self {
129 self.clip_rounded = Some(r);
130 self
131 }
132
133 pub fn on_pointer_down(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
134 self.on_pointer_down = Some(Rc::new(f));
135 self
136 }
137 pub fn on_pointer_move(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
138 self.on_pointer_move = Some(Rc::new(f));
139 self
140 }
141 pub fn on_pointer_up(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
142 self.on_pointer_up = Some(Rc::new(f));
143 self
144 }
145 pub fn on_pointer_enter(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
146 self.on_pointer_enter = Some(Rc::new(f));
147 self
148 }
149 pub fn on_pointer_leave(mut self, f: impl Fn(PointerEvent) + 'static) -> Self {
150 self.on_pointer_leave = Some(Rc::new(f));
151 self
152 }
153 pub fn flex_grow(mut self, g: f32) -> Self {
154 self.flex_grow = Some(g);
155 self
156 }
157 pub fn flex_shrink(mut self, s: f32) -> Self {
158 self.flex_shrink = Some(s);
159 self
160 }
161 pub fn flex_basis(mut self, px: f32) -> Self {
162 self.flex_basis = Some(px);
163 self
164 }
165 pub fn align_self_baseline(mut self) -> Self {
166 self.align_self = Some(taffy::style::AlignSelf::Baseline);
167 self
168 }
169 pub fn align_self_center(mut self) -> Self {
170 self.align_self = Some(taffy::style::AlignSelf::Center);
171 self
172 }
173 pub fn aspect_ratio(mut self, ratio: f32) -> Self {
174 self.aspect_ratio = Some(ratio.max(0.0));
175 self
176 }
177 pub fn absolute(mut self) -> Self {
178 self.position_type = Some(PositionType::Absolute);
179 self
180 }
181 pub fn offset(
182 mut self,
183 left: Option<f32>,
184 top: Option<f32>,
185 right: Option<f32>,
186 bottom: Option<f32>,
187 ) -> Self {
188 self.offset_left = left;
189 self.offset_top = top;
190 self.offset_right = right;
191 self.offset_bottom = bottom;
192 self
193 }
194 pub fn grid(mut self, columns: usize, row_gap: f32, column_gap: f32) -> Self {
195 self.grid = Some(GridConfig {
196 columns: columns.max(1),
197 row_gap,
198 column_gap,
199 });
200 self
201 }
202 pub fn grid_span(mut self, col_span: u16, row_span: u16) -> Self {
203 self.grid_col_span = Some(col_span.max(1));
204 self.grid_row_span = Some(row_span.max(1));
205 self
206 }
207}