Skip to main content

borders/
borders.rs

1//! Example demonstrating bordered UI nodes
2
3use 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    // labels for the different border edges
16    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    // all the different combinations of border edges
36    // these correspond to the labels above
37    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 borders_examples_rounded = (
155        Node {
156            margin: px(25).all(),
157            flex_wrap: FlexWrap::Wrap,
158            ..default()
159        },
160        Children::spawn(SpawnIter(border_labels.into_iter().zip(borders).map(
161            move |(label, border)| {
162                (
163                    Node {
164                        flex_direction: FlexDirection::Column,
165                        align_items: AlignItems::Center,
166                        ..default()
167                    },
168                    children![
169                        (
170                            Node {
171                                width: px(50),
172                                height: px(50),
173                                border,
174                                margin: px(20).all(),
175                                align_items: AlignItems::Center,
176                                justify_content: JustifyContent::Center,
177                                border_radius: BorderRadius::px(
178                                    border_size(border.left, border.top),
179                                    border_size(border.right, border.top),
180                                    border_size(border.right, border.bottom,),
181                                    border_size(border.left, border.bottom),
182                                ),
183                                ..default()
184                            },
185                            BackgroundColor(MAROON.into()),
186                            BorderColor {
187                                top: RED.into(),
188                                bottom: YELLOW.into(),
189                                left: GREEN.into(),
190                                right: BLUE.into(),
191                            },
192                            Outline {
193                                width: px(6),
194                                offset: px(6),
195                                color: Color::WHITE,
196                            },
197                            children![(
198                                Node {
199                                    width: px(10),
200                                    height: px(10),
201                                    border_radius: BorderRadius::MAX,
202                                    ..default()
203                                },
204                                BackgroundColor(YELLOW.into()),
205                            )],
206                        ),
207                        (Text::new(label), TextFont::from_font_size(9.0))
208                    ],
209                )
210            },
211        ))),
212    );
213
214    commands.spawn((
215        Node {
216            margin: px(25).all(),
217            flex_direction: FlexDirection::Column,
218            align_self: AlignSelf::Stretch,
219            justify_self: JustifySelf::Stretch,
220            ..default()
221        },
222        BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
223        children![
224            label("Borders"),
225            borders_examples,
226            label("Borders Rounded"),
227            borders_examples_rounded
228        ],
229    ));
230}
231
232// A label widget that accepts a &str and returns
233// a Bundle that can be spawned
234fn label(text: &str) -> impl Bundle {
235    (
236        Node {
237            margin: px(25).all(),
238            ..default()
239        },
240        children![(Text::new(text), TextFont::from_font_size(20.0))],
241    )
242}