vtui_core/
layout.rs

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}