1use crate::core::Rectangle;
2
3#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
5pub enum Axis {
6 Horizontal,
8 Vertical,
10}
11
12impl Axis {
13 pub fn split(
16 &self,
17 rectangle: &Rectangle,
18 ratio: f32,
19 spacing: f32,
20 ) -> (Rectangle, Rectangle) {
21 match self {
22 Axis::Horizontal => {
23 let height_top =
24 (rectangle.height * ratio - spacing / 2.0).round();
25 let height_bottom = rectangle.height - height_top - spacing;
26
27 (
28 Rectangle {
29 height: height_top,
30 ..*rectangle
31 },
32 Rectangle {
33 y: rectangle.y + height_top + spacing,
34 height: height_bottom,
35 ..*rectangle
36 },
37 )
38 }
39 Axis::Vertical => {
40 let width_left =
41 (rectangle.width * ratio - spacing / 2.0).round();
42 let width_right = rectangle.width - width_left - spacing;
43
44 (
45 Rectangle {
46 width: width_left,
47 ..*rectangle
48 },
49 Rectangle {
50 x: rectangle.x + width_left + spacing,
51 width: width_right,
52 ..*rectangle
53 },
54 )
55 }
56 }
57 }
58
59 pub fn split_line_bounds(
61 &self,
62 rectangle: Rectangle,
63 ratio: f32,
64 spacing: f32,
65 ) -> Rectangle {
66 match self {
67 Axis::Horizontal => Rectangle {
68 x: rectangle.x,
69 y: (rectangle.y + rectangle.height * ratio - spacing / 2.0)
70 .round(),
71 width: rectangle.width,
72 height: spacing,
73 },
74 Axis::Vertical => Rectangle {
75 x: (rectangle.x + rectangle.width * ratio - spacing / 2.0)
76 .round(),
77 y: rectangle.y,
78 width: spacing,
79 height: rectangle.height,
80 },
81 }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 enum Case {
90 Horizontal {
91 overall_height: f32,
92 spacing: f32,
93 top_height: f32,
94 bottom_y: f32,
95 bottom_height: f32,
96 },
97 Vertical {
98 overall_width: f32,
99 spacing: f32,
100 left_width: f32,
101 right_x: f32,
102 right_width: f32,
103 },
104 }
105
106 #[test]
107 fn split() {
108 let cases = vec![
109 Case::Horizontal {
111 overall_height: 10.0,
112 spacing: 2.0,
113 top_height: 4.0,
114 bottom_y: 6.0,
115 bottom_height: 4.0,
116 },
117 Case::Horizontal {
119 overall_height: 9.0,
120 spacing: 2.0,
121 top_height: 4.0,
122 bottom_y: 6.0,
123 bottom_height: 3.0,
124 },
125 Case::Horizontal {
127 overall_height: 10.0,
128 spacing: 1.0,
129 top_height: 5.0,
130 bottom_y: 6.0,
131 bottom_height: 4.0,
132 },
133 Case::Horizontal {
135 overall_height: 9.0,
136 spacing: 1.0,
137 top_height: 4.0,
138 bottom_y: 5.0,
139 bottom_height: 4.0,
140 },
141 Case::Vertical {
143 overall_width: 10.0,
144 spacing: 2.0,
145 left_width: 4.0,
146 right_x: 6.0,
147 right_width: 4.0,
148 },
149 Case::Vertical {
151 overall_width: 9.0,
152 spacing: 2.0,
153 left_width: 4.0,
154 right_x: 6.0,
155 right_width: 3.0,
156 },
157 Case::Vertical {
159 overall_width: 10.0,
160 spacing: 1.0,
161 left_width: 5.0,
162 right_x: 6.0,
163 right_width: 4.0,
164 },
165 Case::Vertical {
167 overall_width: 9.0,
168 spacing: 1.0,
169 left_width: 4.0,
170 right_x: 5.0,
171 right_width: 4.0,
172 },
173 ];
174 for case in cases {
175 match case {
176 Case::Horizontal {
177 overall_height,
178 spacing,
179 top_height,
180 bottom_y,
181 bottom_height,
182 } => {
183 let a = Axis::Horizontal;
184 let r = Rectangle {
185 x: 0.0,
186 y: 0.0,
187 width: 10.0,
188 height: overall_height,
189 };
190 let (top, bottom) = a.split(&r, 0.5, spacing);
191 assert_eq!(
192 top,
193 Rectangle {
194 height: top_height,
195 ..r
196 }
197 );
198 assert_eq!(
199 bottom,
200 Rectangle {
201 y: bottom_y,
202 height: bottom_height,
203 ..r
204 }
205 );
206 }
207 Case::Vertical {
208 overall_width,
209 spacing,
210 left_width,
211 right_x,
212 right_width,
213 } => {
214 let a = Axis::Vertical;
215 let r = Rectangle {
216 x: 0.0,
217 y: 0.0,
218 width: overall_width,
219 height: 10.0,
220 };
221 let (left, right) = a.split(&r, 0.5, spacing);
222 assert_eq!(
223 left,
224 Rectangle {
225 width: left_width,
226 ..r
227 }
228 );
229 assert_eq!(
230 right,
231 Rectangle {
232 x: right_x,
233 width: right_width,
234 ..r
235 }
236 );
237 }
238 }
239 }
240 }
241}