Skip to main content

anathema_default_widgets/stacks/
column.rs

1use std::ops::ControlFlow;
2
3use anathema_geometry::Size;
4use anathema_value_resolver::AttributeStorage;
5use anathema_widgets::error::Result;
6use anathema_widgets::layout::{Constraints, LayoutCtx, PositionCtx};
7use anathema_widgets::{LayoutChildren, PositionChildren, Widget, WidgetId};
8
9use crate::layout::Axis;
10use crate::stacks::Stack;
11
12pub struct Column(Stack);
13
14impl Default for Column {
15    fn default() -> Self {
16        Self(Stack(Axis::Vertical))
17    }
18}
19
20impl Widget for Column {
21    fn layout<'bp>(
22        &mut self,
23        children: LayoutChildren<'_, 'bp>,
24        constraints: Constraints,
25        id: WidgetId,
26        ctx: &mut LayoutCtx<'_, 'bp>,
27    ) -> Result<Size> {
28        self.0.layout(children, constraints, id, ctx)
29    }
30
31    fn position<'bp>(
32        &mut self,
33        mut children: PositionChildren<'_, 'bp>,
34        _: WidgetId,
35        attribute_storage: &AttributeStorage<'bp>,
36        mut ctx: PositionCtx,
37    ) {
38        let x_offset = (ctx.inner_size.width / 2) as i32;
39
40        _ = children.each(|child, children| {
41            let size = child.size();
42            let child_width = size.width as i32;
43            let x = x_offset - child_width / 2;
44
45            let mut pos = ctx.pos;
46            pos.x += x;
47
48            child.position(children, pos, attribute_storage, ctx.viewport);
49            ctx.pos.y += size.height as i32;
50            ControlFlow::Continue(())
51        });
52    }
53}
54
55#[cfg(test)]
56mod test {
57
58    use crate::testing::TestRunner;
59
60    #[test]
61    fn basic_column() {
62        let tpl = "
63            column
64                text 'a'
65                border
66                    text 'b'
67                text 'c'
68        ";
69
70        let expected = "
71            ╔═══╗
72            ║ a ║
73            ║┌─┐║
74            ║│b│║
75            ║└─┘║
76            ║ c ║
77            ╚═══╝
78        ";
79
80        TestRunner::new(tpl, (3, 5)).instance().render_assert(expected);
81    }
82}