1use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*};
4
5fn main() {
6 App::new()
7 .add_plugins(DefaultPlugins)
8 .add_systems(Startup, setup)
9 .run();
10}
11
12fn setup(mut commands: Commands) {
13 commands.spawn(Camera2d);
14
15 let border_labels = [
17 "None",
18 "All",
19 "Left",
20 "Right",
21 "Top",
22 "Bottom",
23 "Horizontal",
24 "Vertical",
25 "Top Left",
26 "Bottom Left",
27 "Top Right",
28 "Bottom Right",
29 "Top Bottom Right",
30 "Top Bottom Left",
31 "Top Left Right",
32 "Bottom Left Right",
33 ];
34
35 let borders = [
38 UiRect::default(),
39 UiRect::all(px(10)),
40 UiRect::left(px(10)),
41 UiRect::right(px(10)),
42 UiRect::top(px(10)),
43 UiRect::bottom(px(10)),
44 UiRect::horizontal(px(10)),
45 UiRect::vertical(px(10)),
46 UiRect {
47 left: px(20),
48 top: px(10),
49 ..default()
50 },
51 UiRect {
52 left: px(10),
53 bottom: px(20),
54 ..default()
55 },
56 UiRect {
57 right: px(20),
58 top: px(10),
59 ..default()
60 },
61 UiRect {
62 right: px(10),
63 bottom: px(10),
64 ..default()
65 },
66 UiRect {
67 right: px(10),
68 top: px(20),
69 bottom: px(10),
70 ..default()
71 },
72 UiRect {
73 left: px(10),
74 top: px(10),
75 bottom: px(10),
76 ..default()
77 },
78 UiRect {
79 left: px(20),
80 right: px(10),
81 top: px(10),
82 ..default()
83 },
84 UiRect {
85 left: px(10),
86 right: px(10),
87 bottom: px(20),
88 ..default()
89 },
90 ];
91
92 let borders_examples = (
93 Node {
94 margin: px(25).all(),
95 flex_wrap: FlexWrap::Wrap,
96 ..default()
97 },
98 Children::spawn(SpawnIter(border_labels.into_iter().zip(borders).map(
99 |(label, border)| {
100 (
101 Node {
102 flex_direction: FlexDirection::Column,
103 align_items: AlignItems::Center,
104 ..default()
105 },
106 children![
107 (
108 Node {
109 width: px(50),
110 height: px(50),
111 border,
112 margin: px(20).all(),
113 align_items: AlignItems::Center,
114 justify_content: JustifyContent::Center,
115 ..default()
116 },
117 BackgroundColor(MAROON.into()),
118 BorderColor {
119 top: RED.into(),
120 bottom: YELLOW.into(),
121 left: GREEN.into(),
122 right: BLUE.into(),
123 },
124 Outline {
125 width: px(6),
126 offset: px(6),
127 color: Color::WHITE,
128 },
129 children![(
130 Node {
131 width: px(10),
132 height: px(10),
133 ..default()
134 },
135 BackgroundColor(YELLOW.into()),
136 )]
137 ),
138 (Text::new(label), TextFont::from_font_size(9.0))
139 ],
140 )
141 },
142 ))),
143 );
144
145 let non_zero = |x, y| x != px(0) && y != px(0);
146 let border_size = move |x, y| {
147 if non_zero(x, y) {
148 f32::MAX
149 } else {
150 0.
151 }
152 };
153
154 let rounded_border_radii = borders.map(|border| {
155 BorderRadius::px(
156 border_size(border.left, border.top),
157 border_size(border.right, border.top),
158 border_size(border.right, border.bottom),
159 border_size(border.left, border.bottom),
160 )
161 });
162
163 let elliptical_border_labels = [
164 "Ellipse Wide",
165 "Ellipse Tall",
166 "Ellipse Mixed",
167 "Ellipse Percent",
168 ];
169 let elliptical_borders = [
170 UiRect::all(px(10)),
171 UiRect::all(px(10)),
172 UiRect::all(px(10)),
173 UiRect::all(px(10)),
174 ];
175 let elliptical_border_radii = [
176 BorderRadius {
177 top_left: CornerRadius {
178 x: px(25),
179 y: px(8),
180 },
181 top_right: CornerRadius {
182 x: px(25),
183 y: px(8),
184 },
185 bottom_right: CornerRadius {
186 x: px(25),
187 y: px(8),
188 },
189 bottom_left: CornerRadius {
190 x: px(25),
191 y: px(8),
192 },
193 },
194 BorderRadius {
195 top_left: (px(8), px(25)).into(),
196 top_right: (px(8), px(25)).into(),
197 bottom_right: [px(8), px(25)].into(),
198 bottom_left: [px(8), px(25)].into(),
199 },
200 BorderRadius {
201 top_left: CornerRadius {
202 x: px(25),
203 y: px(12),
204 },
205 top_right: CornerRadius {
206 x: px(12),
207 y: px(25),
208 },
209 bottom_right: CornerRadius {
210 x: px(25),
211 y: px(12),
212 },
213 bottom_left: CornerRadius {
214 x: px(12),
215 y: px(25),
216 },
217 },
218 BorderRadius {
219 top_left: CornerRadius {
220 x: percent(50),
221 y: percent(20),
222 },
223 top_right: CornerRadius {
224 x: percent(20),
225 y: percent(50),
226 },
227 bottom_right: CornerRadius {
228 x: percent(50),
229 y: percent(20),
230 },
231 bottom_left: CornerRadius {
232 x: percent(20),
233 y: percent(50),
234 },
235 },
236 ];
237
238 let borders_examples_rounded = (
239 Node {
240 margin: px(25).all(),
241 flex_wrap: FlexWrap::Wrap,
242 ..default()
243 },
244 Children::spawn(SpawnIter(
245 border_labels
246 .into_iter()
247 .zip(borders)
248 .zip(rounded_border_radii)
249 .map(|((label, border), border_radius)| (label, border, border_radius))
250 .chain(
251 elliptical_border_labels
252 .into_iter()
253 .zip(elliptical_borders)
254 .zip(elliptical_border_radii)
255 .map(|((label, border), border_radius)| (label, border, border_radius)),
256 )
257 .map(move |(label, border, border_radius)| {
258 (
259 Node {
260 flex_direction: FlexDirection::Column,
261 align_items: AlignItems::Center,
262 ..default()
263 },
264 children![
265 (
266 Node {
267 width: px(50),
268 height: px(50),
269 border,
270 margin: px(20).all(),
271 align_items: AlignItems::Center,
272 justify_content: JustifyContent::Center,
273 border_radius,
274 ..default()
275 },
276 BackgroundColor(MAROON.into()),
277 BorderColor {
278 top: RED.into(),
279 bottom: YELLOW.into(),
280 left: GREEN.into(),
281 right: BLUE.into(),
282 },
283 Outline {
284 width: px(6),
285 offset: px(6),
286 color: Color::WHITE,
287 },
288 children![(
289 Node {
290 width: px(10),
291 height: px(10),
292 border_radius: BorderRadius::MAX,
293 ..default()
294 },
295 BackgroundColor(YELLOW.into()),
296 )],
297 ),
298 (Text::new(label), TextFont::from_font_size(9.0))
299 ],
300 )
301 }),
302 )),
303 );
304
305 commands.spawn((
306 Node {
307 margin: px(25).all(),
308 flex_direction: FlexDirection::Column,
309 align_self: AlignSelf::Stretch,
310 justify_self: JustifySelf::Stretch,
311 ..default()
312 },
313 BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
314 children![
315 label("Borders"),
316 borders_examples,
317 label("Borders Rounded"),
318 borders_examples_rounded
319 ],
320 ));
321}
322
323fn label(text: &str) -> impl Bundle {
326 (
327 Node {
328 margin: px(25).all(),
329 ..default()
330 },
331 children![(Text::new(text), TextFont::from_font_size(20.0))],
332 )
333}