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}