1pub struct MeasureLayout {
2 width: f32,
3 gap: f32,
4 total_flex: u8,
5 no_expand_count: u8,
6 no_expand_width: f32,
7}
8
9impl MeasureLayout {
10 pub fn new(width: f32, gap: f32) -> Self {
11 MeasureLayout {
12 width,
13 gap,
14 total_flex: 0,
15 no_expand_count: 0,
16 no_expand_width: 0.,
17 }
18 }
19
20 pub fn add_fixed(&mut self, width: f32) {
21 self.no_expand_count += 1;
22 self.no_expand_width += width;
23 }
24
25 pub fn add_expand(&mut self, fraction: u8) {
26 self.total_flex += fraction;
28 }
29
30 pub fn no_expand_width(&self) -> Option<f32> {
31 if self.no_expand_count == 0 {
32 None
33 } else {
34 Some(self.no_expand_width + self.gap * (self.no_expand_count - 1) as f32)
35 }
36 }
37
38 pub fn build(self) -> DrawLayout {
39 let remaining_width =
51 (self.width + self.gap - self.no_expand_width - self.gap * self.no_expand_count as f32)
52 .max(0.);
53
54 DrawLayout {
55 total_flex: self.total_flex,
56 gap: self.gap,
57 remaining_width,
58 }
59 }
60}
61
62#[derive(Copy, Clone)]
63pub struct DrawLayout {
64 total_flex: u8,
65 gap: f32,
66 remaining_width: f32,
67}
68
69impl DrawLayout {
70 pub fn expand_width(&self, fraction: u8) -> f32 {
71 (self.remaining_width * fraction as f32 / self.total_flex as f32 - self.gap).max(0.)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_alignment() {
81 let mut layout = MeasureLayout::new(15., 2.);
82 layout.add_expand(1);
83 layout.add_fixed(3.);
84 layout.add_expand(1);
85
86 let a = layout.build();
87
88 let mut layout = MeasureLayout::new(15., 2.);
89 layout.add_expand(1);
90 layout.add_expand(1);
91 layout.add_fixed(3.);
92 layout.add_expand(2);
93
94 let b = layout.build();
95
96 assert_eq!(
98 a.expand_width(1),
99 b.expand_width(1) + 2. + b.expand_width(1),
100 );
101 assert_eq!(a.expand_width(1), 4.,);
102
103 assert_eq!(a.expand_width(1) + 2. + 3. + 2. + a.expand_width(1), 15.);
105 assert_eq!(
106 b.expand_width(1) + 2. + b.expand_width(1) + 2. + 3. + 2. + b.expand_width(2),
107 15.
108 );
109 }
110
111 #[test]
112 fn test_total_width() {
113 {
114 let mut layout = MeasureLayout::new(100., 4.);
115 layout.add_expand(1);
116 layout.add_expand(1);
117 layout.add_expand(1);
118
119 let draw_layout = layout.build();
120
121 assert_eq!(
122 draw_layout.expand_width(1)
123 + draw_layout.expand_width(1)
124 + draw_layout.expand_width(1)
125 + 2. * 4.,
126 100.,
127 );
128 }
129
130 {
131 let mut layout = MeasureLayout::new(100., 4.);
132 layout.add_expand(1);
133 layout.add_fixed(50.);
134 layout.add_expand(1);
135
136 let draw_layout = layout.build();
137
138 assert_eq!(
139 draw_layout.expand_width(1) + 50. + draw_layout.expand_width(1) + 2. * 4.,
140 100.,
141 );
142
143 assert_eq!(draw_layout.expand_width(1), 21.);
144 }
145
146 {
147 let mut layout = MeasureLayout::new(100., 4.);
148 layout.add_expand(1);
149 layout.add_fixed(25.);
150 layout.add_expand(1);
151 layout.add_fixed(25.);
152
153 let draw_layout = layout.build();
154
155 assert_eq!(
156 draw_layout.expand_width(1) + 25. + draw_layout.expand_width(1) + 25. + 3. * 4.,
157 100.,
158 );
159
160 assert_eq!(draw_layout.expand_width(1), 19.);
161 }
162
163 {
164 let mut layout = MeasureLayout::new(100., 4.);
165 layout.add_fixed(25.);
166 layout.add_expand(1);
167 layout.add_fixed(25.);
168 layout.add_expand(1);
169 layout.add_fixed(25.);
170
171 let draw_layout = layout.build();
172
173 assert_eq!(
174 25. + draw_layout.expand_width(1)
175 + 25.
176 + draw_layout.expand_width(1)
177 + 25.
178 + 4. * 4.,
179 100.,
180 );
181 }
182
183 {
184 let mut layout = MeasureLayout::new(100., 3.);
185 layout.add_fixed(25.);
186 layout.add_expand(2);
187 layout.add_fixed(25.);
188 layout.add_expand(1);
189 layout.add_fixed(25.);
190
191 let draw_layout = layout.build();
192
193 assert_eq!(
194 25. + draw_layout.expand_width(2)
195 + 25.
196 + draw_layout.expand_width(1)
197 + 25.
198 + 3. * 4.,
199 100.,
200 );
201 }
202
203 {
204 let mut layout = MeasureLayout::new(100., 4.);
205 layout.add_fixed(25.);
206 layout.add_expand(2);
207 layout.add_fixed(25.);
208 layout.add_expand(1);
209 layout.add_fixed(25.);
210
211 let draw_layout = layout.build();
212
213 assert_eq!(
214 (25. + draw_layout.expand_width(2)
215 + 25.
216 + draw_layout.expand_width(1)
217 + 25.
218 + 4. * 4.),
219 100.,
220 );
221 }
222
223 {
224 let mut layout = MeasureLayout::new(22., 2.);
225 layout.add_expand(2);
226 layout.add_fixed(14.);
227 layout.add_expand(1);
228
229 let draw_layout = layout.build();
230
231 assert_eq!(
232 draw_layout.expand_width(2) + 14. + draw_layout.expand_width(1) + 2. * 2.,
233 22.,
234 );
235 }
236 }
237}