radicle_term/
hstack.rs

1use crate::{Constraint, Element, Line, Size};
2
3/// Horizontal stack of [`Element`] objects that implements [`Element`].
4#[derive(Default, Debug)]
5pub struct HStack<'a> {
6    elems: Vec<Box<dyn Element + 'a>>,
7}
8
9impl<'a> HStack<'a> {
10    /// Add an element to the stack.
11    pub fn child(mut self, child: impl Element + 'a) -> Self {
12        self.push(child);
13        self
14    }
15
16    pub fn push(&mut self, child: impl Element + 'a) {
17        self.elems.push(Box::new(child));
18    }
19}
20
21impl Element for HStack<'_> {
22    fn size(&self, parent: Constraint) -> Size {
23        let width = self.elems.iter().map(|c| c.columns(parent)).sum();
24        let height = self.elems.iter().map(|c| c.rows(parent)).max().unwrap_or(0);
25
26        Size::new(width, height)
27    }
28
29    fn render(&self, parent: Constraint) -> Vec<Line> {
30        fn rearrange(input: Vec<Vec<Line>>) -> Vec<Line> {
31            let max_len = input.iter().map(|v| v.len()).max().unwrap_or(0);
32
33            (0..max_len)
34                .map(|i| {
35                    Line::default().extend(
36                        input
37                            .iter()
38                            .filter_map(move |v| v.get(i))
39                            .flat_map(|l| l.clone()),
40                    )
41                })
42                .collect()
43        }
44        rearrange(self.elems.iter().map(|e| e.render(parent)).collect())
45    }
46}