1use crate::canvas::LogicalRect;
2
3#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4pub enum Flow {
5 Horizontal,
6 #[default]
7 Vertical,
8}
9
10#[derive(Clone, Copy, Debug)]
11pub enum Measure {
12 Exact(i32),
13 Percentage(f64),
14}
15
16impl Default for Measure {
17 fn default() -> Self {
18 Measure::Percentage(1.0)
19 }
20}
21
22#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
23pub(crate) struct Layer(i32);
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26struct Variable {
27 start: i32,
28 size: i32,
29}
30
31pub(crate) fn compute_split(
32 flow: Flow,
33 area: LogicalRect,
34 measures: &[Measure],
35) -> Vec<LogicalRect> {
36 match flow {
37 Flow::Horizontal => split_measures(area.x, area.width, measures)
38 .map(|v| LogicalRect {
39 x: v.start,
40 y: area.y,
41 width: v.size,
42 height: area.height,
43 })
44 .collect(),
45 Flow::Vertical => split_measures(area.y, area.height, measures)
46 .map(|v| LogicalRect {
47 x: area.x,
48 y: v.start,
49 width: area.width,
50 height: v.size,
51 })
52 .collect(),
53 }
54}
55
56fn split_measures(start: i32, viewport: i32, measures: &[Measure]) -> impl Iterator<Item = Variable> {
57 let mut cursor = start;
58
59 measures.iter().map(move |measure| {
60 let size = match measure {
61 Measure::Exact(size) => *size,
62 Measure::Percentage(percent) => (viewport as f64 * percent).round() as i32,
63 };
64
65 let v = Variable {
66 start: cursor,
67 size,
68 };
69 cursor += size;
70 v
71 })
72}