Skip to main content

ansiq_widgets/
block.rs

1use ansiq_core::{
2    Alignment, BlockFrame, BlockProps, BlockTitle, BorderType, Borders, Element, ElementKind,
3    Layout, Length, Line, Padding, Rect, Style, TitlePosition,
4};
5
6pub struct Block<Message = ()> {
7    element: Element<Message>,
8}
9
10impl<Message> Block<Message> {
11    pub fn new() -> Self {
12        Self {
13            element: Element::new(ElementKind::Block(BlockProps {
14                titles: Vec::new(),
15                title_alignment: Alignment::Left,
16                title_position: TitlePosition::Top,
17                borders: Borders::NONE,
18                border_type: BorderType::Plain,
19                border_set: None,
20                padding: Padding::zero(),
21                border_style: Style::default(),
22                title_style: Style::default(),
23            }))
24            .with_layout(Layout {
25                width: Length::Fill,
26                height: Length::Auto,
27            }),
28        }
29    }
30
31    pub fn bordered() -> Self {
32        let mut block = Self::new();
33        if let ElementKind::Block(props) = &mut block.element.kind {
34            props.borders = Borders::ALL;
35        }
36        block
37    }
38
39    pub fn title<T>(mut self, title: T) -> Self
40    where
41        T: Into<Line>,
42    {
43        if let ElementKind::Block(props) = &mut self.element.kind {
44            props.titles.push(BlockTitle::new(title));
45        }
46        self
47    }
48
49    pub fn title_top<T>(mut self, title: T) -> Self
50    where
51        T: Into<Line>,
52    {
53        if let ElementKind::Block(props) = &mut self.element.kind {
54            props.titles.push(BlockTitle::top(title));
55        }
56        self
57    }
58
59    pub fn title_bottom<T>(mut self, title: T) -> Self
60    where
61        T: Into<Line>,
62    {
63        if let ElementKind::Block(props) = &mut self.element.kind {
64            props.titles.push(BlockTitle::bottom(title));
65        }
66        self
67    }
68
69    pub fn title_alignment(mut self, alignment: Alignment) -> Self {
70        if let ElementKind::Block(props) = &mut self.element.kind {
71            props.title_alignment = alignment;
72        }
73        self
74    }
75
76    pub fn title_position(mut self, position: TitlePosition) -> Self {
77        if let ElementKind::Block(props) = &mut self.element.kind {
78            props.title_position = position;
79        }
80        self
81    }
82
83    pub fn bordered_flag(mut self, bordered: bool) -> Self {
84        if let ElementKind::Block(props) = &mut self.element.kind {
85            props.borders = if bordered {
86                Borders::ALL
87            } else {
88                Borders::NONE
89            };
90        }
91        self
92    }
93
94    pub fn borders(mut self, borders: Borders) -> Self {
95        if let ElementKind::Block(props) = &mut self.element.kind {
96            props.borders = borders;
97        }
98        self
99    }
100
101    pub fn border_type(mut self, border_type: BorderType) -> Self {
102        if let ElementKind::Block(props) = &mut self.element.kind {
103            props.border_type = border_type;
104        }
105        self
106    }
107
108    pub fn border_set(mut self, border_set: ansiq_core::symbols::border::Set) -> Self {
109        if let ElementKind::Block(props) = &mut self.element.kind {
110            props.border_set = Some(border_set);
111        }
112        self
113    }
114
115    pub fn padding(mut self, padding: Padding) -> Self {
116        if let ElementKind::Block(props) = &mut self.element.kind {
117            props.padding = padding;
118        }
119        self
120    }
121
122    pub fn border_style<S: Into<Style>>(mut self, style: S) -> Self {
123        if let ElementKind::Block(props) = &mut self.element.kind {
124            props.border_style = style.into();
125        }
126        self
127    }
128
129    pub fn title_style<S: Into<Style>>(mut self, style: S) -> Self {
130        if let ElementKind::Block(props) = &mut self.element.kind {
131            props.title_style = style.into();
132        }
133        self
134    }
135
136    pub fn child(mut self, child: Element<Message>) -> Self {
137        self.element.children.push(child);
138        self
139    }
140
141    pub fn children<I>(mut self, children: I) -> Self
142    where
143        I: IntoIterator<Item = Element<Message>>,
144    {
145        self.element.children.extend(children);
146        self
147    }
148
149    pub fn layout(mut self, layout: Layout) -> Self {
150        self.element.layout = layout;
151        self
152    }
153
154    pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
155        self.element.style = style.into();
156        self
157    }
158
159    pub fn build(self) -> Element<Message> {
160        self.element
161    }
162
163    pub fn inner(&self, rect: Rect) -> Rect {
164        let ElementKind::Block(props) = &self.element.kind else {
165            unreachable!("Block widgets always store Block props")
166        };
167
168        props.inner(rect)
169    }
170
171    pub fn into_frame(self) -> BlockFrame {
172        let style = self.element.style;
173        let ElementKind::Block(props) = self.element.kind else {
174            unreachable!("Block widgets always store Block props")
175        };
176
177        BlockFrame { props, style }
178    }
179}