1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Houses the [`Stack`] widget

use le::{
    layout::{Rect, Vec2},
    Layout, MinimumNatural,
};

use crate::{Widget, WidgetType};

/// A widget that stacks children on top
/// of each other.
#[derive(Default)]
pub struct Stack<'a> {
    /// The children to stack
    pub children: Vec<WidgetType<'a>>,
}

impl<'a> Stack<'a> {
    /// Creates a new [`Stack`]
    pub fn new() -> Self {
        Default::default()
    }

    /// Adds a child to this
    pub fn child<T: Widget + 'a>(mut self, child: T) -> Self {
        self.children.push(Box::new(child));
        self
    }
}

impl<'a> Layout for Stack<'a> {
    fn width_for_height(&self, height: usize) -> MinimumNatural<usize> {
        MinimumNatural {
            minimum: self
                .children
                .iter()
                .map(|x| x.width_for_height(height).minimum)
                .max()
                .unwrap_or(0),
            natural: self
                .children
                .iter()
                .map(|x| x.width_for_height(height).natural)
                .max()
                .unwrap_or(0),
        }
    }

    fn height_for_width(&self, width: usize) -> MinimumNatural<usize> {
        MinimumNatural {
            minimum: self
                .children
                .iter()
                .map(|x| x.height_for_width(width).minimum)
                .max()
                .unwrap_or(0),
            natural: self
                .children
                .iter()
                .map(|x| x.height_for_width(width).natural)
                .max()
                .unwrap_or(0),
        }
    }

    fn prefered_size(&self) -> MinimumNatural<Vec2> {
        let mut x_min = 0;
        let mut y_min = 0;
        let mut x_nat = 0;
        let mut y_nat = 0;
        for child in &self.children {
            let size = child.prefered_size();
            x_min = x_min.max(size.minimum.x);
            y_min = y_min.max(size.minimum.y);
            x_nat = x_nat.max(size.natural.x);
            y_nat = y_nat.max(size.natural.y);
        }
        MinimumNatural {
            minimum: Vec2::new(x_min, y_min),
            natural: Vec2::new(x_nat, y_nat),
        }
    }

    fn prefered_size_of_container(
        &self,
        container: Vec2,
    ) -> MinimumNatural<Vec2> {
        let mut x_min = 0;
        let mut y_min = 0;
        let mut x_nat = 0;
        let mut y_nat = 0;
        for child in &self.children {
            let size = child.prefered_size_of_container(container);
            x_min = x_min.max(size.minimum.x);
            y_min = y_min.max(size.minimum.y);
            x_nat = x_nat.max(size.natural.x);
            y_nat = y_nat.max(size.natural.y);
        }
        MinimumNatural {
            minimum: Vec2::new(x_min, y_min),
            natural: Vec2::new(x_nat, y_nat),
        }
    }
}

impl<'a> Widget for Stack<'a> {
    fn render(&self, rect: Rect, buffer: &mut crate::Buffer) {
        for child in &self.children {
            child.render(rect, buffer);
        }
    }
}