1use gpui::prelude::*;
4use gpui::{div, px, AnyElement, App, IntoElement, Window};
5
6use super::{apply_alignment, apply_margin, apply_padding, Alignment, EdgeInsets};
7use crate::theme::Color;
8
9#[derive(IntoElement)]
12pub struct Container {
13 child: Option<AnyElement>,
14 width: Option<f32>,
15 height: Option<f32>,
16 padding: EdgeInsets,
17 margin: EdgeInsets,
18 color: Option<Color>,
19 radius: f32,
20 border: Option<(f32, Color)>,
21 alignment: Option<Alignment>,
22}
23
24impl Container {
25 pub fn new() -> Self {
26 Container {
27 child: None,
28 width: None,
29 height: None,
30 padding: EdgeInsets::default(),
31 margin: EdgeInsets::default(),
32 color: None,
33 radius: 0.0,
34 border: None,
35 alignment: None,
36 }
37 }
38
39 pub fn child(mut self, child: impl IntoElement) -> Self {
40 self.child = Some(child.into_any_element());
41 self
42 }
43
44 pub fn width(mut self, width: f32) -> Self {
45 self.width = Some(width);
46 self
47 }
48
49 pub fn height(mut self, height: f32) -> Self {
50 self.height = Some(height);
51 self
52 }
53
54 pub fn padding(mut self, padding: EdgeInsets) -> Self {
55 self.padding = padding;
56 self
57 }
58
59 pub fn margin(mut self, margin: EdgeInsets) -> Self {
60 self.margin = margin;
61 self
62 }
63
64 pub fn color(mut self, color: Color) -> Self {
65 self.color = Some(color);
66 self
67 }
68
69 pub fn radius(mut self, radius: f32) -> Self {
70 self.radius = radius;
71 self
72 }
73
74 pub fn border(mut self, width: f32, color: Color) -> Self {
75 self.border = Some((width, color));
76 self
77 }
78
79 pub fn alignment(mut self, alignment: Alignment) -> Self {
80 self.alignment = Some(alignment);
81 self
82 }
83}
84
85impl Default for Container {
86 fn default() -> Self {
87 Container::new()
88 }
89}
90
91impl RenderOnce for Container {
92 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
93 let mut el = div();
94 if let Some(w) = self.width {
95 el = el.w(px(w));
96 }
97 if let Some(h) = self.height {
98 el = el.h(px(h));
99 }
100 el = apply_padding(el, self.padding);
101 el = apply_margin(el, self.margin);
102 if let Some(color) = self.color {
103 el = el.bg(color.hsla());
104 }
105 if self.radius > 0.0 {
106 el = el.rounded(px(self.radius));
107 }
108 if let Some((width, color)) = self.border {
109 el = el.border(px(width)).border_color(color.hsla());
110 }
111 if let Some(alignment) = self.alignment {
112 el = apply_alignment(el.flex(), alignment);
113 }
114 if let Some(child) = self.child {
115 el = el.child(child);
116 }
117 el
118 }
119}
120
121#[derive(IntoElement)]
123pub struct Padding {
124 insets: EdgeInsets,
125 child: Option<AnyElement>,
126}
127
128impl Padding {
129 pub fn all(value: f32) -> Self {
130 Padding {
131 insets: EdgeInsets::all(value),
132 child: None,
133 }
134 }
135
136 pub fn symmetric(horizontal: f32, vertical: f32) -> Self {
137 Padding {
138 insets: EdgeInsets::symmetric(horizontal, vertical),
139 child: None,
140 }
141 }
142
143 pub fn only(insets: EdgeInsets) -> Self {
144 Padding {
145 insets,
146 child: None,
147 }
148 }
149
150 pub fn child(mut self, child: impl IntoElement) -> Self {
151 self.child = Some(child.into_any_element());
152 self
153 }
154}
155
156impl RenderOnce for Padding {
157 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
158 let mut el = apply_padding(div(), self.insets);
159 if let Some(child) = self.child {
160 el = el.child(child);
161 }
162 el
163 }
164}
165
166#[derive(IntoElement)]
168pub struct Align {
169 alignment: Alignment,
170 child: Option<AnyElement>,
171}
172
173impl Align {
174 pub fn new(alignment: Alignment) -> Self {
175 Align {
176 alignment,
177 child: None,
178 }
179 }
180
181 pub fn child(mut self, child: impl IntoElement) -> Self {
182 self.child = Some(child.into_any_element());
183 self
184 }
185}
186
187impl RenderOnce for Align {
188 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
189 let mut el = apply_alignment(div().flex().size_full(), self.alignment);
190 if let Some(child) = self.child {
191 el = el.child(child);
192 }
193 el
194 }
195}
196
197#[derive(IntoElement)]
199pub struct Center {
200 child: Option<AnyElement>,
201}
202
203impl Center {
204 pub fn new() -> Self {
205 Center { child: None }
206 }
207
208 pub fn child(mut self, child: impl IntoElement) -> Self {
209 self.child = Some(child.into_any_element());
210 self
211 }
212}
213
214impl Default for Center {
215 fn default() -> Self {
216 Center::new()
217 }
218}
219
220impl RenderOnce for Center {
221 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
222 let mut el = div().flex().size_full().items_center().justify_center();
223 if let Some(child) = self.child {
224 el = el.child(child);
225 }
226 el
227 }
228}