Skip to main content

UiRect

Struct UiRect 

Source
pub struct UiRect {
    pub left: Val,
    pub right: Val,
    pub top: Val,
    pub bottom: Val,
}
Expand description

A type which is commonly used to define margins, paddings and borders.

§Examples

§Margin

A margin is used to create space around UI elements, outside of any defined borders.

let margin = UiRect::all(Val::Auto); // Centers the UI element

§Padding

A padding is used to create space around UI elements, inside of any defined borders.

let padding = UiRect {
    left: Val::Px(10.0),
    right: Val::Px(20.0),
    top: Val::Px(30.0),
    bottom: Val::Px(40.0),
};

§Borders

A border is used to define the width of the border of a UI element.

let border = UiRect {
    left: Val::Px(10.0),
    right: Val::Px(20.0),
    top: Val::Px(30.0),
    bottom: Val::Px(40.0),
};

Fields§

§left: Val

The value corresponding to the left side of the UI rect.

§right: Val

The value corresponding to the right side of the UI rect.

§top: Val

The value corresponding to the top side of the UI rect.

§bottom: Val

The value corresponding to the bottom side of the UI rect.

Implementations§

Source§

impl UiRect

Source

pub const DEFAULT: UiRect

Source

pub const ZERO: UiRect

Source

pub const AUTO: UiRect

Source

pub const fn new(left: Val, right: Val, top: Val, bottom: Val) -> UiRect

Creates a new UiRect from the values specified.

§Example
let ui_rect = UiRect::new(
    Val::Px(10.0),
    Val::Px(20.0),
    Val::Px(30.0),
    Val::Px(40.0),
);

assert_eq!(ui_rect.left, Val::Px(10.0));
assert_eq!(ui_rect.right, Val::Px(20.0));
assert_eq!(ui_rect.top, Val::Px(30.0));
assert_eq!(ui_rect.bottom, Val::Px(40.0));
Source

pub const fn all(value: Val) -> UiRect

Creates a new UiRect where all sides have the same value.

§Example
let ui_rect = UiRect::all(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::Px(10.0));
assert_eq!(ui_rect.right, Val::Px(10.0));
assert_eq!(ui_rect.top, Val::Px(10.0));
assert_eq!(ui_rect.bottom, Val::Px(10.0));
Examples found in repository?
examples/3d/../helpers/widgets.rs (line 28)
28pub const BUTTON_BORDER: UiRect = UiRect::all(Val::Px(1.0));
More examples
Hide additional examples
examples/app/log_layers_ecs.rs (line 135)
127fn setup(mut commands: Commands) {
128    commands.spawn(Camera2d);
129
130    commands.spawn((
131        Node {
132            width: vw(100),
133            height: vh(100),
134            flex_direction: FlexDirection::Column,
135            padding: UiRect::all(px(12)),
136            ..default()
137        },
138        LogViewerRoot,
139    ));
140}
examples/usage/context_menu.rs (line 131)
125fn context_item(text: &str, col: Srgba) -> impl Bundle {
126    (
127        Name::new(format!("item-{text}")),
128        ContextMenuItem(col),
129        Button,
130        Node {
131            padding: UiRect::all(px(5)),
132            ..default()
133        },
134        children![(
135            Pickable::IGNORE,
136            Text::new(text),
137            TextFont {
138                font_size: FontSize::Px(24.0),
139                ..default()
140            },
141            TextColor(Color::WHITE),
142        )],
143    )
144}
145
146fn background_and_button() -> impl Bundle {
147    (
148        Name::new("background"),
149        Node {
150            width: percent(100),
151            height: percent(100),
152            align_items: AlignItems::Center,
153            justify_content: JustifyContent::Center,
154            ..default()
155        },
156        ZIndex(-10),
157        Children::spawn(SpawnWith(|parent: &mut RelatedSpawner<ChildOf>| {
158            parent
159                .spawn((
160                    Name::new("button"),
161                    Button,
162                    Node {
163                        width: px(250),
164                        height: px(65),
165                        border: UiRect::all(px(5)),
166                        justify_content: JustifyContent::Center,
167                        align_items: AlignItems::Center,
168                        border_radius: BorderRadius::MAX,
169                        ..default()
170                    },
171                    BorderColor::all(Color::BLACK),
172                    BackgroundColor(Color::BLACK),
173                    children![(
174                        Pickable::IGNORE,
175                        Text::new("Context Menu"),
176                        TextFont {
177                            font_size: FontSize::Px(28.0),
178                            ..default()
179                        },
180                        TextColor(Color::WHITE),
181                        TextShadow::default(),
182                    )],
183                ))
184                .observe(|mut event: On<Pointer<Press>>, mut commands: Commands| {
185                    // by default this event would bubble up further leading to the `CloseContextMenus`
186                    // event being triggered and undoing the opening of one here right away.
187                    event.propagate(false);
188
189                    debug!("click: {}", event.pointer_location.position);
190
191                    commands.trigger(OpenContextMenu {
192                        pos: event.pointer_location.position,
193                    });
194                });
195        })),
196    )
197}
examples/ui/layout/ghost_nodes.rs (line 78)
72fn create_button() -> impl Bundle {
73    (
74        Button,
75        Node {
76            width: px(150),
77            height: px(65),
78            border: UiRect::all(px(5)),
79            // horizontally center child text
80            justify_content: JustifyContent::Center,
81            // vertically center child text
82            align_items: AlignItems::Center,
83            border_radius: BorderRadius::MAX,
84            ..default()
85        },
86        BorderColor::all(Color::BLACK),
87        BackgroundColor(Color::srgb(0.15, 0.15, 0.15)),
88    )
89}
examples/3d/split_screen.rs (line 117)
107    fn buttons_panel() -> impl Bundle {
108        (
109            Node {
110                position_type: PositionType::Absolute,
111                width: percent(100),
112                height: percent(100),
113                display: Display::Flex,
114                flex_direction: FlexDirection::Row,
115                justify_content: JustifyContent::SpaceBetween,
116                align_items: AlignItems::Center,
117                padding: UiRect::all(px(20)),
118                ..default()
119            },
120            children![
121                rotate_button("<", Direction::Left),
122                rotate_button(">", Direction::Right),
123            ],
124        )
125    }
126
127    fn rotate_button(caption: &str, direction: Direction) -> impl Bundle {
128        (
129            RotateCamera(direction),
130            Button,
131            Node {
132                width: px(40),
133                height: px(40),
134                border: UiRect::all(px(2)),
135                justify_content: JustifyContent::Center,
136                align_items: AlignItems::Center,
137                ..default()
138            },
139            BorderColor::all(Color::WHITE),
140            BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
141            children![Text::new(caption)],
142        )
143    }
examples/ui/scroll_and_overflow/scrollbars.rs (line 32)
20fn setup_view_root(mut commands: Commands) {
21    let camera = commands.spawn((Camera::default(), Camera2d)).id();
22
23    commands.spawn((
24        Node {
25            display: Display::Flex,
26            flex_direction: FlexDirection::Column,
27            position_type: PositionType::Absolute,
28            left: px(0),
29            top: px(0),
30            right: px(0),
31            bottom: px(0),
32            padding: UiRect::all(px(3)),
33            row_gap: px(6),
34            ..Default::default()
35        },
36        BackgroundColor(Color::srgb(0.1, 0.1, 0.1)),
37        UiTargetCamera(camera),
38        TabGroup::default(),
39        Children::spawn((Spawn(Text::new("Scrolling")), Spawn(scroll_area_demo()))),
40    ));
41}
42
43/// Create a scrolling area.
44///
45/// The "scroll area" is a container that can be scrolled. It has a nested structure which is
46/// three levels deep:
47/// - The outermost node is a grid that contains the scroll area and the scrollbars.
48/// - The scroll area is a flex container that contains the scrollable content. This
49///   is the element that has the `overflow: scroll` property.
50/// - The scrollable content consists of the elements actually displayed in the scrolling area.
51fn scroll_area_demo() -> impl Bundle {
52    (
53        // Frame element which contains the scroll area and scrollbars.
54        Node {
55            display: Display::Grid,
56            width: px(200),
57            height: px(150),
58            grid_template_columns: vec![RepeatedGridTrack::flex(1, 1.), RepeatedGridTrack::auto(1)],
59            grid_template_rows: vec![RepeatedGridTrack::flex(1, 1.), RepeatedGridTrack::auto(1)],
60            row_gap: px(2),
61            column_gap: px(2),
62            ..default()
63        },
64        Children::spawn((SpawnWith(|parent: &mut RelatedSpawner<ChildOf>| {
65            // The actual scrolling area.
66            // Note that we're using `SpawnWith` here because we need to get the entity id of the
67            // scroll area in order to set the target of the scrollbars.
68            let scroll_area_id = parent
69                .spawn((
70                    Node {
71                        display: Display::Flex,
72                        flex_direction: FlexDirection::Column,
73                        padding: UiRect::all(px(4)),
74                        overflow: Overflow::scroll(),
75                        ..default()
76                    },
77                    BackgroundColor(colors::GRAY1.into()),
78                    ScrollPosition(Vec2::new(0.0, 10.0)),
79                    Children::spawn((
80                        // The actual content of the scrolling area
81                        Spawn(text_row("Alpha Wolf")),
82                        Spawn(text_row("Beta Blocker")),
83                        Spawn(text_row("Delta Sleep")),
84                        Spawn(text_row("Gamma Ray")),
85                        Spawn(text_row("Epsilon Eridani")),
86                        Spawn(text_row("Zeta Function")),
87                        Spawn(text_row("Lambda Calculus")),
88                        Spawn(text_row("Nu Metal")),
89                        Spawn(text_row("Pi Day")),
90                        Spawn(text_row("Chi Pants")),
91                        Spawn(text_row("Psi Powers")),
92                        Spawn(text_row("Omega Fatty Acid")),
93                    )),
94                ))
95                .id();
96
97            // Vertical scrollbar
98            parent.spawn((
99                Node {
100                    min_width: px(8),
101                    grid_row: GridPlacement::start(1),
102                    grid_column: GridPlacement::start(2),
103                    ..default()
104                },
105                Scrollbar {
106                    orientation: ControlOrientation::Vertical,
107                    target: scroll_area_id,
108                    min_thumb_length: 8.0,
109                },
110                Children::spawn(Spawn((
111                    Hovered::default(),
112                    BackgroundColor(colors::GRAY2.into()),
113                    BorderColor::all(colors::GRAY3),
114                    ScrollbarThumb {
115                        border_radius: BorderRadius::all(px(4)),
116                        border: px(1).all(),
117                    },
118                ))),
119            ));
120
121            // Horizontal scrollbar
122            parent.spawn((
123                Node {
124                    min_height: px(8),
125                    grid_row: GridPlacement::start(2),
126                    grid_column: GridPlacement::start(1),
127                    ..default()
128                },
129                Scrollbar {
130                    orientation: ControlOrientation::Horizontal,
131                    target: scroll_area_id,
132                    min_thumb_length: 8.0,
133                },
134                Children::spawn(Spawn((
135                    Hovered::default(),
136                    BackgroundColor(colors::GRAY2.into()),
137                    BorderColor::all(colors::GRAY3),
138                    ScrollbarThumb {
139                        border_radius: BorderRadius::all(px(4)),
140                        border: px(1).all(),
141                    },
142                ))),
143            ));
144        }),)),
145    )
146}
Source

pub const fn px(left: f32, right: f32, top: f32, bottom: f32) -> UiRect

Creates a new UiRect from the values specified in logical pixels.

This is a shortcut for UiRect::new(), applying Val::Px to all arguments.

§Example
let ui_rect = UiRect::px(10., 20., 30., 40.);
assert_eq!(ui_rect.left, Val::Px(10.));
assert_eq!(ui_rect.right, Val::Px(20.));
assert_eq!(ui_rect.top, Val::Px(30.));
assert_eq!(ui_rect.bottom, Val::Px(40.));
Source

pub const fn percent(left: f32, right: f32, top: f32, bottom: f32) -> UiRect

Creates a new UiRect from the values specified in percentages.

This is a shortcut for UiRect::new(), applying Val::Percent to all arguments.

§Example
let ui_rect = UiRect::percent(5., 10., 2., 1.);
assert_eq!(ui_rect.left, Val::Percent(5.));
assert_eq!(ui_rect.right, Val::Percent(10.));
assert_eq!(ui_rect.top, Val::Percent(2.));
assert_eq!(ui_rect.bottom, Val::Percent(1.));
Source

pub const fn horizontal(value: Val) -> UiRect

Creates a new UiRect where left and right take the given value, and top and bottom set to zero Val::ZERO.

§Example
let ui_rect = UiRect::horizontal(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::Px(10.0));
assert_eq!(ui_rect.right, Val::Px(10.0));
assert_eq!(ui_rect.top, Val::ZERO);
assert_eq!(ui_rect.bottom, Val::ZERO);
Examples found in repository?
examples/3d/ssr.rs (line 544)
511fn range_row(
512    title: &str,
513    start_value: f32,
514    end_value: f32,
515    start_marker: RangeValueText,
516    end_marker: RangeValueText,
517    start_dec: ExampleSetting,
518    start_inc: ExampleSetting,
519    end_dec: ExampleSetting,
520    end_inc: ExampleSetting,
521) -> impl Bundle {
522    (
523        Node {
524            align_items: AlignItems::Center,
525            ..default()
526        },
527        Children::spawn((
528            Spawn((
529                widgets::ui_text(title, Color::WHITE),
530                Node {
531                    width: px(150),
532                    ..default()
533                },
534            )),
535            Spawn(range_controls(
536                start_value,
537                start_marker,
538                start_dec,
539                start_inc,
540            )),
541            Spawn((
542                widgets::ui_text("to", Color::WHITE),
543                Node {
544                    margin: UiRect::horizontal(px(10)),
545                    ..default()
546                },
547            )),
548            Spawn(range_controls(end_value, end_marker, end_dec, end_inc)),
549        )),
550    )
551}
More examples
Hide additional examples
examples/ui/layout/size_constraints.rs (line 221)
206fn spawn_button(
207    parent: &mut ChildSpawnerCommands,
208    constraint: Constraint,
209    action: ButtonValue,
210    label: String,
211    text_style: (TextFont, TextColor),
212    active: bool,
213) {
214    parent
215        .spawn((
216            Button,
217            Node {
218                align_items: AlignItems::Center,
219                justify_content: JustifyContent::Center,
220                border: UiRect::all(px(2)),
221                margin: UiRect::horizontal(px(2)),
222                ..Default::default()
223            },
224            BorderColor::all(if active {
225                ACTIVE_BORDER_COLOR
226            } else {
227                INACTIVE_BORDER_COLOR
228            }),
229            constraint,
230            action,
231        ))
232        .with_children(|parent| {
233            parent
234                .spawn((
235                    Node {
236                        width: px(100),
237                        justify_content: JustifyContent::Center,
238                        ..default()
239                    },
240                    BackgroundColor(if active {
241                        ACTIVE_INNER_COLOR
242                    } else {
243                        INACTIVE_INNER_COLOR
244                    }),
245                ))
246                .with_child((
247                    Text::new(label),
248                    text_style.0,
249                    TextColor(if active {
250                        ACTIVE_TEXT_COLOR
251                    } else {
252                        UNHOVERED_TEXT_COLOR
253                    }),
254                    TextLayout::new_with_justify(Justify::Center),
255                ));
256        });
257}
examples/ui/layout/anchor_layout.rs (line 82)
19fn spawn_layout(mut commands: Commands, asset_server: Res<AssetServer>) {
20    let font = asset_server.load("fonts/FiraSans-Bold.ttf");
21    commands.spawn(Camera2d);
22
23    let rows = [
24        (
25            "left: 10px\ntop: 10px",
26            Node {
27                left: px(10),
28                top: px(10),
29                ..default()
30            },
31        ),
32        (
33            "center: 10px\ntop: 10px",
34            Node {
35                margin: auto().horizontal(),
36                top: px(10),
37                ..default()
38            },
39        ),
40        (
41            "right: 10px\ntop: 10px",
42            Node {
43                right: px(10),
44                top: px(10),
45                ..default()
46            },
47        ),
48        (
49            "left: 10px\ncenter: 10px",
50            Node {
51                left: px(10),
52                margin: UiRect::vertical(auto()),
53                ..default()
54            },
55        ),
56        (
57            "center: 10px\ncenter: 10px",
58            Node {
59                margin: UiRect::all(auto()),
60                ..default()
61            },
62        ),
63        (
64            "right: 10px\ncenter: 10px",
65            Node {
66                right: px(10),
67                margin: UiRect::vertical(auto()),
68                ..default()
69            },
70        ),
71        (
72            "left: 10px\nbottom: 10px",
73            Node {
74                left: px(10),
75                bottom: px(10),
76                ..default()
77            },
78        ),
79        (
80            "center: 10px\nbottom: 10px",
81            Node {
82                margin: UiRect::horizontal(auto()),
83                bottom: px(10),
84                ..default()
85            },
86        ),
87        (
88            "right: 10px\nbottom: 10px",
89            Node {
90                right: px(10),
91                bottom: px(10),
92                ..default()
93            },
94        ),
95    ];
96
97    // let font = font.clone();
98    commands.spawn((
99        Node {
100            // fill the entire window
101            width: percent(100),
102            height: percent(100),
103            padding: MARGIN.all(),
104            row_gap: MARGIN,
105            column_gap: MARGIN,
106            display: Display::Grid,
107            grid_template_columns: RepeatedGridTrack::fr(3, 1.),
108            grid_template_rows: RepeatedGridTrack::fr(3, 1.),
109            ..default()
110        },
111        BackgroundColor(Color::BLACK),
112        Children::spawn(SpawnIter(
113            rows.into_iter()
114                .map(move |v| anchored_node(font.clone(), v.1, v.0)),
115        )),
116    ));
117}
examples/ui/scroll_and_overflow/overflow.rs (line 42)
13fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
14    commands.spawn(Camera2d);
15
16    let text_style = TextFont::default();
17
18    let image = asset_server.load("branding/icon.png");
19
20    commands
21        .spawn((
22            Node {
23                width: percent(100),
24                height: percent(100),
25                align_items: AlignItems::Center,
26                justify_content: JustifyContent::Center,
27                ..Default::default()
28            },
29            BackgroundColor(ANTIQUE_WHITE.into()),
30        ))
31        .with_children(|parent| {
32            for overflow in [
33                Overflow::visible(),
34                Overflow::clip_x(),
35                Overflow::clip_y(),
36                Overflow::clip(),
37            ] {
38                parent
39                    .spawn(Node {
40                        flex_direction: FlexDirection::Column,
41                        align_items: AlignItems::Center,
42                        margin: UiRect::horizontal(px(25)),
43                        ..Default::default()
44                    })
45                    .with_children(|parent| {
46                        let label = format!("{overflow:#?}");
47                        parent
48                            .spawn((
49                                Node {
50                                    padding: UiRect::all(px(10)),
51                                    margin: UiRect::bottom(px(25)),
52                                    ..Default::default()
53                                },
54                                BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
55                            ))
56                            .with_children(|parent| {
57                                parent.spawn((Text::new(label), text_style.clone()));
58                            });
59                        parent
60                            .spawn((
61                                Node {
62                                    width: px(100),
63                                    height: px(100),
64                                    padding: UiRect {
65                                        left: px(25),
66                                        top: px(25),
67                                        ..Default::default()
68                                    },
69                                    border: UiRect::all(px(5)),
70                                    overflow,
71                                    ..default()
72                                },
73                                BorderColor::all(Color::BLACK),
74                                BackgroundColor(GRAY.into()),
75                            ))
76                            .with_children(|parent| {
77                                parent.spawn((
78                                    ImageNode::new(image.clone()),
79                                    Node {
80                                        min_width: px(100),
81                                        min_height: px(100),
82                                        ..default()
83                                    },
84                                    Interaction::default(),
85                                    Outline {
86                                        width: px(2),
87                                        offset: px(2),
88                                        color: Color::NONE,
89                                    },
90                                ));
91                            });
92                    });
93            }
94        });
95}
examples/ui/styling/box_shadow.rs (line 358)
290fn build_setting_row(
291    setting_type: SettingType,
292    dec: SettingsButton,
293    inc: SettingsButton,
294    value: f32,
295    asset_server: &Res<AssetServer>,
296) -> impl Bundle {
297    let value_text = match setting_type {
298        SettingType::Shape => SHAPES[value as usize % SHAPES.len()].0.to_string(),
299        SettingType::Count => format!("{}", value as usize),
300        _ => format!("{value:.1}"),
301    };
302
303    (
304        Node {
305            flex_direction: FlexDirection::Row,
306            align_items: AlignItems::Center,
307            height: px(32),
308            ..default()
309        },
310        children![
311            (
312                Node {
313                    width: px(80),
314                    justify_content: JustifyContent::FlexEnd,
315                    align_items: AlignItems::Center,
316                    ..default()
317                },
318                // Attach SettingType to the value label node, not the parent row
319                children![(
320                    Text::new(setting_type.label()),
321                    TextFont {
322                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
323                        font_size: FontSize::Px(16.0),
324                        ..default()
325                    },
326                )],
327            ),
328            (
329                Button,
330                Node {
331                    width: px(28),
332                    height: px(28),
333                    margin: UiRect::left(px(8)),
334                    justify_content: JustifyContent::Center,
335                    align_items: AlignItems::Center,
336                    border_radius: BorderRadius::all(px(6)),
337                    ..default()
338                },
339                BackgroundColor(Color::WHITE),
340                dec,
341                children![(
342                    Text::new(if setting_type == SettingType::Shape {
343                        "<"
344                    } else {
345                        "-"
346                    }),
347                    TextFont {
348                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
349                        font_size: FontSize::Px(18.0),
350                        ..default()
351                    },
352                )],
353            ),
354            (
355                Node {
356                    width: px(48),
357                    height: px(28),
358                    margin: UiRect::horizontal(px(8)),
359                    justify_content: JustifyContent::Center,
360                    align_items: AlignItems::Center,
361                    border_radius: BorderRadius::all(px(6)),
362                    ..default()
363                },
364                children![{
365                    (
366                        Text::new(value_text),
367                        TextFont {
368                            font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
369                            font_size: FontSize::Px(16.0),
370                            ..default()
371                        },
372                        setting_type,
373                    )
374                }],
375            ),
376            (
377                Button,
378                Node {
379                    width: px(28),
380                    height: px(28),
381                    justify_content: JustifyContent::Center,
382                    align_items: AlignItems::Center,
383                    border_radius: BorderRadius::all(px(6)),
384                    ..default()
385                },
386                BackgroundColor(Color::WHITE),
387                inc,
388                children![(
389                    Text::new(if setting_type == SettingType::Shape {
390                        ">"
391                    } else {
392                        "+"
393                    }),
394                    TextFont {
395                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
396                        font_size: FontSize::Px(18.0),
397                        ..default()
398                    },
399                )],
400            ),
401        ],
402    )
403}
examples/ui/styling/borders.rs (line 44)
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}
Source

pub const fn vertical(value: Val) -> UiRect

Creates a new UiRect where top and bottom take the given value, and left and right are set to Val::ZERO.

§Example
let ui_rect = UiRect::vertical(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::ZERO);
assert_eq!(ui_rect.right, Val::ZERO);
assert_eq!(ui_rect.top, Val::Px(10.0));
assert_eq!(ui_rect.bottom, Val::Px(10.0));
Examples found in repository?
examples/ui/layout/anchor_layout.rs (line 52)
19fn spawn_layout(mut commands: Commands, asset_server: Res<AssetServer>) {
20    let font = asset_server.load("fonts/FiraSans-Bold.ttf");
21    commands.spawn(Camera2d);
22
23    let rows = [
24        (
25            "left: 10px\ntop: 10px",
26            Node {
27                left: px(10),
28                top: px(10),
29                ..default()
30            },
31        ),
32        (
33            "center: 10px\ntop: 10px",
34            Node {
35                margin: auto().horizontal(),
36                top: px(10),
37                ..default()
38            },
39        ),
40        (
41            "right: 10px\ntop: 10px",
42            Node {
43                right: px(10),
44                top: px(10),
45                ..default()
46            },
47        ),
48        (
49            "left: 10px\ncenter: 10px",
50            Node {
51                left: px(10),
52                margin: UiRect::vertical(auto()),
53                ..default()
54            },
55        ),
56        (
57            "center: 10px\ncenter: 10px",
58            Node {
59                margin: UiRect::all(auto()),
60                ..default()
61            },
62        ),
63        (
64            "right: 10px\ncenter: 10px",
65            Node {
66                right: px(10),
67                margin: UiRect::vertical(auto()),
68                ..default()
69            },
70        ),
71        (
72            "left: 10px\nbottom: 10px",
73            Node {
74                left: px(10),
75                bottom: px(10),
76                ..default()
77            },
78        ),
79        (
80            "center: 10px\nbottom: 10px",
81            Node {
82                margin: UiRect::horizontal(auto()),
83                bottom: px(10),
84                ..default()
85            },
86        ),
87        (
88            "right: 10px\nbottom: 10px",
89            Node {
90                right: px(10),
91                bottom: px(10),
92                ..default()
93            },
94        ),
95    ];
96
97    // let font = font.clone();
98    commands.spawn((
99        Node {
100            // fill the entire window
101            width: percent(100),
102            height: percent(100),
103            padding: MARGIN.all(),
104            row_gap: MARGIN,
105            column_gap: MARGIN,
106            display: Display::Grid,
107            grid_template_columns: RepeatedGridTrack::fr(3, 1.),
108            grid_template_rows: RepeatedGridTrack::fr(3, 1.),
109            ..default()
110        },
111        BackgroundColor(Color::BLACK),
112        Children::spawn(SpawnIter(
113            rows.into_iter()
114                .map(move |v| anchored_node(font.clone(), v.1, v.0)),
115        )),
116    ));
117}
More examples
Hide additional examples
examples/testbed/ui.rs (line 717)
700    pub fn setup(mut commands: Commands) {
701        commands.spawn((Camera2d, DespawnOnExit(super::Scene::Borders)));
702        let root = commands
703            .spawn((
704                Node {
705                    flex_wrap: FlexWrap::Wrap,
706                    ..default()
707                },
708                DespawnOnExit(super::Scene::Borders),
709            ))
710            .id();
711
712        // all the different combinations of border edges
713        let borders = [
714            UiRect::default(),
715            UiRect::all(px(20)),
716            UiRect::left(px(20)),
717            UiRect::vertical(px(20)),
718            UiRect {
719                left: px(40),
720                top: px(20),
721                ..Default::default()
722            },
723            UiRect {
724                right: px(20),
725                bottom: px(30),
726                ..Default::default()
727            },
728            UiRect {
729                right: px(20),
730                top: px(40),
731                bottom: px(20),
732                ..Default::default()
733            },
734            UiRect {
735                left: px(20),
736                top: px(20),
737                bottom: px(20),
738                ..Default::default()
739            },
740            UiRect {
741                left: px(20),
742                right: px(20),
743                bottom: px(40),
744                ..Default::default()
745            },
746        ];
747
748        let non_zero = |x, y| x != px(0) && y != px(0);
749        let border_size = |x, y| if non_zero(x, y) { f32::MAX } else { 0. };
750
751        for border in borders {
752            for rounded in [true, false] {
753                let border_node = commands
754                    .spawn((
755                        Node {
756                            width: px(100),
757                            height: px(100),
758                            border,
759                            margin: UiRect::all(px(30)),
760                            align_items: AlignItems::Center,
761                            justify_content: JustifyContent::Center,
762                            border_radius: if rounded {
763                                BorderRadius::px(
764                                    border_size(border.left, border.top),
765                                    border_size(border.right, border.top),
766                                    border_size(border.right, border.bottom),
767                                    border_size(border.left, border.bottom),
768                                )
769                            } else {
770                                BorderRadius::ZERO
771                            },
772                            ..default()
773                        },
774                        BackgroundColor(MAROON.into()),
775                        BorderColor::all(RED),
776                        Outline {
777                            width: px(10),
778                            offset: px(10),
779                            color: Color::WHITE,
780                        },
781                    ))
782                    .id();
783
784                commands.entity(root).add_child(border_node);
785            }
786        }
787    }
examples/animation/animation_masks.rs (line 274)
229fn new_mask_group_control(label: &str, width: Val, mask_group_id: u32) -> impl Bundle {
230    let button_text_style = (
231        TextFont {
232            font_size: FontSize::Px(14.0),
233            ..default()
234        },
235        TextColor::WHITE,
236    );
237    let selected_button_text_style = (button_text_style.0.clone(), TextColor::BLACK);
238    let label_text_style = (
239        button_text_style.0.clone(),
240        TextColor(Color::Srgba(LIGHT_GRAY)),
241    );
242
243    let make_animation_label = {
244        let button_text_style = button_text_style.clone();
245        let selected_button_text_style = selected_button_text_style.clone();
246        move |first: bool, label: AnimationLabel| {
247            (
248                Button,
249                BackgroundColor(if !first { Color::BLACK } else { Color::WHITE }),
250                Node {
251                    flex_grow: 1.0,
252                    border: if !first {
253                        UiRect::left(px(1))
254                    } else {
255                        UiRect::ZERO
256                    },
257                    ..default()
258                },
259                BorderColor::all(Color::WHITE),
260                AnimationControl {
261                    group_id: mask_group_id,
262                    label,
263                },
264                children![(
265                    Text(format!("{label:?}")),
266                    if !first {
267                        button_text_style.clone()
268                    } else {
269                        selected_button_text_style.clone()
270                    },
271                    TextLayout::new_with_justify(Justify::Center),
272                    Node {
273                        flex_grow: 1.0,
274                        margin: UiRect::vertical(px(3)),
275                        ..default()
276                    },
277                )],
278            )
279        }
280    };
281
282    (
283        Node {
284            border: UiRect::all(px(1)),
285            width,
286            flex_direction: FlexDirection::Column,
287            justify_content: JustifyContent::Center,
288            align_items: AlignItems::Center,
289            padding: UiRect::ZERO,
290            margin: UiRect::ZERO,
291            border_radius: BorderRadius::all(px(3)),
292            ..default()
293        },
294        BorderColor::all(Color::WHITE),
295        BackgroundColor(Color::BLACK),
296        children![
297            (
298                Node {
299                    border: UiRect::ZERO,
300                    width: percent(100),
301                    justify_content: JustifyContent::Center,
302                    align_items: AlignItems::Center,
303                    padding: UiRect::ZERO,
304                    margin: UiRect::ZERO,
305                    ..default()
306                },
307                BackgroundColor(Color::BLACK),
308                children![(
309                    Text::new(label),
310                    label_text_style.clone(),
311                    Node {
312                        margin: UiRect::vertical(px(3)),
313                        ..default()
314                    },
315                )]
316            ),
317            (
318                Node {
319                    width: percent(100),
320                    flex_direction: FlexDirection::Row,
321                    justify_content: JustifyContent::Center,
322                    align_items: AlignItems::Center,
323                    border: UiRect::top(px(1)),
324                    ..default()
325                },
326                BorderColor::all(Color::WHITE),
327                children![
328                    make_animation_label(true, AnimationLabel::Run),
329                    make_animation_label(false, AnimationLabel::Walk),
330                    make_animation_label(false, AnimationLabel::Idle),
331                    make_animation_label(false, AnimationLabel::Off),
332                ]
333            )
334        ],
335    )
336}
examples/ui/styling/borders.rs (line 45)
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}
Source

pub const fn axes(horizontal: Val, vertical: Val) -> UiRect

Creates a new UiRect where both left and right take the value of horizontal, and both top and bottom take the value of vertical.

§Example
let ui_rect = UiRect::axes(Val::Px(10.0), Val::Percent(15.0));

assert_eq!(ui_rect.left, Val::Px(10.0));
assert_eq!(ui_rect.right, Val::Px(10.0));
assert_eq!(ui_rect.top, Val::Percent(15.0));
assert_eq!(ui_rect.bottom, Val::Percent(15.0));
Examples found in repository?
examples/3d/../helpers/widgets.rs (line 42)
42pub const BUTTON_PADDING: UiRect = UiRect::axes(Val::Px(12.0), Val::Px(6.0));
More examples
Hide additional examples
examples/ui/layout/flex_layout.rs (line 152)
141fn spawn_nested_text_bundle(
142    builder: &mut ChildSpawnerCommands,
143    font: Handle<Font>,
144    background_color: Color,
145    margin: UiRect,
146    text: &str,
147) {
148    builder
149        .spawn((
150            Node {
151                margin,
152                padding: UiRect::axes(px(5), px(1)),
153                ..default()
154            },
155            BackgroundColor(background_color),
156        ))
157        .with_children(|builder| {
158            builder.spawn((Text::new(text), TextFont::from(font), TextColor::BLACK));
159        });
160}
examples/ui/layout/display_and_visibility.rs (line 386)
376fn spawn_button<T>(parent: &mut ChildSpawnerCommands, text_font: TextFont, target: Entity)
377where
378    T: Default + std::fmt::Debug + Send + Sync + 'static,
379    Target<T>: TargetUpdate,
380{
381    parent
382        .spawn((
383            Button,
384            Node {
385                align_self: AlignSelf::FlexStart,
386                padding: UiRect::axes(px(5), px(1)),
387                ..default()
388            },
389            BackgroundColor(Color::BLACK.with_alpha(0.5)),
390            Target::<T>::new(target),
391        ))
392        .with_children(|builder| {
393            builder.spawn((
394                Text(format!("{}::{:?}", Target::<T>::NAME, T::default())),
395                text_font,
396                TextLayout::new_with_justify(Justify::Center),
397            ));
398        });
399}
examples/ui/layout/anchor_layout.rs (line 133)
119fn anchored_node(font: Handle<Font>, node: Node, label: &str) -> impl Bundle {
120    (
121        // outer gray box
122        Node {
123            grid_column: GridPlacement::span(1),
124            grid_row: GridPlacement::span(1),
125            ..default()
126        },
127        BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
128        children![
129            // inner label box
130            (
131                Node {
132                    display: Display::Block,
133                    padding: UiRect::axes(px(5), px(1)),
134                    position_type: PositionType::Absolute,
135                    ..node
136                },
137                BackgroundColor(Color::srgb(1., 0.066, 0.349)),
138                children![(Text::new(label), TextFont::from(font), TextColor::BLACK,)],
139            )
140        ],
141    )
142}
examples/ui/widgets/standard_widgets.rs (line 235)
222fn menu_button(asset_server: &AssetServer) -> impl Bundle {
223    (
224        Node { ..default() },
225        DemoMenuAnchor,
226        observe(on_menu_event),
227        children![(
228            Node {
229                width: px(200),
230                height: px(65),
231                border: UiRect::all(px(5)),
232                box_sizing: BoxSizing::BorderBox,
233                justify_content: JustifyContent::SpaceBetween,
234                align_items: AlignItems::Center,
235                padding: UiRect::axes(px(16), px(0)),
236                border_radius: BorderRadius::all(px(5)),
237                ..default()
238            },
239            DemoMenuButton,
240            MenuButton,
241            Hovered::default(),
242            TabIndex(0),
243            BorderColor::all(Color::BLACK),
244            BackgroundColor(NORMAL_BUTTON),
245            children![
246                (
247                    Text::new("Menu"),
248                    TextFont {
249                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
250                        font_size: FontSize::Px(33.0),
251                        ..default()
252                    },
253                    TextColor(Color::srgb(0.9, 0.9, 0.9)),
254                    TextShadow::default(),
255                ),
256                (
257                    Node {
258                        width: px(12),
259                        height: px(12),
260                        ..default()
261                    },
262                    BackgroundColor(GRAY.into()),
263                )
264            ],
265        )],
266    )
267}
268
269fn update_button_style(
270    mut buttons: Query<
271        (
272            Has<Pressed>,
273            &Hovered,
274            Has<InteractionDisabled>,
275            &mut BackgroundColor,
276            &mut BorderColor,
277            &Children,
278        ),
279        (
280            Or<(
281                Changed<Pressed>,
282                Changed<Hovered>,
283                Added<InteractionDisabled>,
284            )>,
285            With<DemoButton>,
286        ),
287    >,
288    mut text_query: Query<&mut Text>,
289) {
290    for (pressed, hovered, disabled, mut color, mut border_color, children) in &mut buttons {
291        let mut text = text_query.get_mut(children[0]).unwrap();
292        set_button_style(
293            disabled,
294            hovered.get(),
295            pressed,
296            &mut color,
297            &mut border_color,
298            &mut text,
299        );
300    }
301}
302
303/// Supplementary system to detect removed marker components
304fn update_button_style2(
305    mut buttons: Query<
306        (
307            Has<Pressed>,
308            &Hovered,
309            Has<InteractionDisabled>,
310            &mut BackgroundColor,
311            &mut BorderColor,
312            &Children,
313        ),
314        With<DemoButton>,
315    >,
316    mut removed_depressed: RemovedComponents<Pressed>,
317    mut removed_disabled: RemovedComponents<InteractionDisabled>,
318    mut text_query: Query<&mut Text>,
319) {
320    removed_depressed
321        .read()
322        .chain(removed_disabled.read())
323        .for_each(|entity| {
324            if let Ok((pressed, hovered, disabled, mut color, mut border_color, children)) =
325                buttons.get_mut(entity)
326            {
327                let mut text = text_query.get_mut(children[0]).unwrap();
328                set_button_style(
329                    disabled,
330                    hovered.get(),
331                    pressed,
332                    &mut color,
333                    &mut border_color,
334                    &mut text,
335                );
336            }
337        });
338}
339
340fn set_button_style(
341    disabled: bool,
342    hovered: bool,
343    pressed: bool,
344    color: &mut BackgroundColor,
345    border_color: &mut BorderColor,
346    text: &mut Text,
347) {
348    match (disabled, hovered, pressed) {
349        // Disabled button
350        (true, _, _) => {
351            **text = "Disabled".to_string();
352            *color = NORMAL_BUTTON.into();
353            border_color.set_all(GRAY);
354        }
355
356        // Pressed and hovered button
357        (false, true, true) => {
358            **text = "Press".to_string();
359            *color = PRESSED_BUTTON.into();
360            border_color.set_all(RED);
361        }
362
363        // Hovered, unpressed button
364        (false, true, false) => {
365            **text = "Hover".to_string();
366            *color = HOVERED_BUTTON.into();
367            border_color.set_all(WHITE);
368        }
369
370        // Unhovered button (either pressed or not).
371        (false, false, _) => {
372            **text = "Button".to_string();
373            *color = NORMAL_BUTTON.into();
374            border_color.set_all(BLACK);
375        }
376    }
377}
378
379/// Create a demo slider
380fn slider(min: f32, max: f32, value: f32) -> impl Bundle {
381    (
382        Node {
383            display: Display::Flex,
384            flex_direction: FlexDirection::Column,
385            justify_content: JustifyContent::Center,
386            align_items: AlignItems::Stretch,
387            justify_items: JustifyItems::Center,
388            column_gap: px(4),
389            height: px(12),
390            width: percent(30),
391            ..default()
392        },
393        Name::new("Slider"),
394        Hovered::default(),
395        DemoSlider,
396        Slider {
397            track_click: TrackClick::Snap,
398            ..Default::default()
399        },
400        SliderValue(value),
401        SliderRange::new(min, max),
402        TabIndex(0),
403        Children::spawn((
404            // Slider background rail
405            Spawn((
406                Node {
407                    height: px(6),
408                    border_radius: BorderRadius::all(px(3)),
409                    ..default()
410                },
411                BackgroundColor(SLIDER_TRACK), // Border color for the slider
412            )),
413            // Invisible track to allow absolute placement of thumb entity. This is narrower than
414            // the actual slider, which allows us to position the thumb entity using simple
415            // percentages, without having to measure the actual width of the slider thumb.
416            Spawn((
417                Node {
418                    display: Display::Flex,
419                    position_type: PositionType::Absolute,
420                    left: px(0),
421                    // Track is short by 12px to accommodate the thumb.
422                    right: px(12),
423                    top: px(0),
424                    bottom: px(0),
425                    ..default()
426                },
427                children![(
428                    // Thumb
429                    DemoSliderThumb,
430                    SliderThumb,
431                    Node {
432                        display: Display::Flex,
433                        width: px(12),
434                        height: px(12),
435                        position_type: PositionType::Absolute,
436                        left: percent(0), // This will be updated by the slider's value
437                        border_radius: BorderRadius::MAX,
438                        ..default()
439                    },
440                    BackgroundColor(SLIDER_THUMB),
441                )],
442            )),
443        )),
444    )
445}
446
447/// Update the visuals of the slider based on the slider state.
448fn update_slider_style(
449    sliders: Query<
450        (
451            Entity,
452            &SliderValue,
453            &SliderRange,
454            &Hovered,
455            &CoreSliderDragState,
456            Has<InteractionDisabled>,
457        ),
458        (
459            Or<(
460                Changed<SliderValue>,
461                Changed<SliderRange>,
462                Changed<Hovered>,
463                Changed<CoreSliderDragState>,
464                Added<InteractionDisabled>,
465            )>,
466            With<DemoSlider>,
467        ),
468    >,
469    children: Query<&Children>,
470    mut thumbs: Query<(&mut Node, &mut BackgroundColor, Has<DemoSliderThumb>), Without<DemoSlider>>,
471) {
472    for (slider_ent, value, range, hovered, drag_state, disabled) in sliders.iter() {
473        for child in children.iter_descendants(slider_ent) {
474            if let Ok((mut thumb_node, mut thumb_bg, is_thumb)) = thumbs.get_mut(child)
475                && is_thumb
476            {
477                thumb_node.left = percent(range.thumb_position(value.0) * 100.0);
478                thumb_bg.0 = thumb_color(disabled, hovered.0 | drag_state.dragging);
479            }
480        }
481    }
482}
483
484fn update_slider_style2(
485    sliders: Query<
486        (
487            Entity,
488            &Hovered,
489            &CoreSliderDragState,
490            Has<InteractionDisabled>,
491        ),
492        With<DemoSlider>,
493    >,
494    children: Query<&Children>,
495    mut thumbs: Query<(&mut BackgroundColor, Has<DemoSliderThumb>), Without<DemoSlider>>,
496    mut removed_disabled: RemovedComponents<InteractionDisabled>,
497) {
498    removed_disabled.read().for_each(|entity| {
499        if let Ok((slider_ent, hovered, drag_state, disabled)) = sliders.get(entity) {
500            for child in children.iter_descendants(slider_ent) {
501                if let Ok((mut thumb_bg, is_thumb)) = thumbs.get_mut(child)
502                    && is_thumb
503                {
504                    thumb_bg.0 = thumb_color(disabled, hovered.0 | drag_state.dragging);
505                }
506            }
507        }
508    });
509}
510
511fn thumb_color(disabled: bool, hovered: bool) -> Color {
512    match (disabled, hovered) {
513        (true, _) => ELEMENT_FILL_DISABLED,
514
515        (false, true) => SLIDER_THUMB.lighter(0.3),
516
517        _ => SLIDER_THUMB,
518    }
519}
520
521/// Create a demo checkbox
522fn checkbox(asset_server: &AssetServer, caption: &str) -> impl Bundle {
523    (
524        Node {
525            display: Display::Flex,
526            flex_direction: FlexDirection::Row,
527            justify_content: JustifyContent::FlexStart,
528            align_items: AlignItems::Center,
529            align_content: AlignContent::Center,
530            column_gap: px(4),
531            ..default()
532        },
533        Name::new("Checkbox"),
534        Hovered::default(),
535        DemoCheckbox,
536        Checkbox,
537        TabIndex(0),
538        Children::spawn((
539            Spawn((
540                // Checkbox outer
541                Node {
542                    display: Display::Flex,
543                    width: px(16),
544                    height: px(16),
545                    border: UiRect::all(px(2)),
546                    border_radius: BorderRadius::all(px(3)),
547                    ..default()
548                },
549                BorderColor::all(ELEMENT_OUTLINE), // Border color for the checkbox
550                children![
551                    // Checkbox inner
552                    (
553                        Node {
554                            display: Display::Flex,
555                            width: px(8),
556                            height: px(8),
557                            position_type: PositionType::Absolute,
558                            left: px(2),
559                            top: px(2),
560                            ..default()
561                        },
562                        BackgroundColor(ELEMENT_FILL),
563                    ),
564                ],
565            )),
566            Spawn((
567                Text::new(caption),
568                TextFont {
569                    font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
570                    font_size: FontSize::Px(20.0),
571                    ..default()
572                },
573            )),
574        )),
575    )
576}
577
578// Update the element's styles.
579fn update_checkbox_or_radio_style(
580    mut q_checkbox: Query<
581        (Has<Checked>, &Hovered, Has<InteractionDisabled>, &Children),
582        (
583            Or<(With<DemoCheckbox>, With<DemoRadio>)>,
584            Or<(
585                Added<DemoCheckbox>,
586                Changed<Hovered>,
587                Added<Checked>,
588                Added<InteractionDisabled>,
589            )>,
590        ),
591    >,
592    mut q_border_color: Query<
593        (&mut BorderColor, &mut Children),
594        (Without<DemoCheckbox>, Without<DemoRadio>),
595    >,
596    mut q_bg_color: Query<&mut BackgroundColor, (Without<DemoCheckbox>, Without<Children>)>,
597) {
598    for (checked, Hovered(is_hovering), is_disabled, children) in q_checkbox.iter_mut() {
599        let Some(border_id) = children.first() else {
600            continue;
601        };
602
603        let Ok((mut border_color, border_children)) = q_border_color.get_mut(*border_id) else {
604            continue;
605        };
606
607        let Some(mark_id) = border_children.first() else {
608            warn!("Checkbox does not have a mark entity.");
609            continue;
610        };
611
612        let Ok(mut mark_bg) = q_bg_color.get_mut(*mark_id) else {
613            warn!("Checkbox mark entity lacking a background color.");
614            continue;
615        };
616
617        set_checkbox_or_radio_style(
618            is_disabled,
619            *is_hovering,
620            checked,
621            &mut border_color,
622            &mut mark_bg,
623        );
624    }
625}
626
627fn update_checkbox_or_radio_style2(
628    mut q_checkbox: Query<
629        (Has<Checked>, &Hovered, Has<InteractionDisabled>, &Children),
630        Or<(With<DemoCheckbox>, With<DemoRadio>)>,
631    >,
632    mut q_border_color: Query<
633        (&mut BorderColor, &mut Children),
634        (Without<DemoCheckbox>, Without<DemoRadio>),
635    >,
636    mut q_bg_color: Query<
637        &mut BackgroundColor,
638        (Without<DemoCheckbox>, Without<DemoRadio>, Without<Children>),
639    >,
640    mut removed_checked: RemovedComponents<Checked>,
641    mut removed_disabled: RemovedComponents<InteractionDisabled>,
642) {
643    removed_checked
644        .read()
645        .chain(removed_disabled.read())
646        .for_each(|entity| {
647            if let Ok((checked, Hovered(is_hovering), is_disabled, children)) =
648                q_checkbox.get_mut(entity)
649            {
650                let Some(border_id) = children.first() else {
651                    return;
652                };
653
654                let Ok((mut border_color, border_children)) = q_border_color.get_mut(*border_id)
655                else {
656                    return;
657                };
658
659                let Some(mark_id) = border_children.first() else {
660                    warn!("Checkbox does not have a mark entity.");
661                    return;
662                };
663
664                let Ok(mut mark_bg) = q_bg_color.get_mut(*mark_id) else {
665                    warn!("Checkbox mark entity lacking a background color.");
666                    return;
667                };
668
669                set_checkbox_or_radio_style(
670                    is_disabled,
671                    *is_hovering,
672                    checked,
673                    &mut border_color,
674                    &mut mark_bg,
675                );
676            }
677        });
678}
679
680fn set_checkbox_or_radio_style(
681    disabled: bool,
682    hovering: bool,
683    checked: bool,
684    border_color: &mut BorderColor,
685    mark_bg: &mut BackgroundColor,
686) {
687    let color: Color = if disabled {
688        // If the element is disabled, use a lighter color
689        ELEMENT_OUTLINE.with_alpha(0.2)
690    } else if hovering {
691        // If hovering, use a lighter color
692        ELEMENT_OUTLINE.lighter(0.2)
693    } else {
694        // Default color for the element
695        ELEMENT_OUTLINE
696    };
697
698    // Update the background color of the element
699    border_color.set_all(color);
700
701    let mark_color: Color = match (disabled, checked) {
702        (true, true) => ELEMENT_FILL_DISABLED,
703        (false, true) => ELEMENT_FILL,
704        (_, false) => Srgba::NONE.into(),
705    };
706
707    if mark_bg.0 != mark_color {
708        // Update the color of the element
709        mark_bg.0 = mark_color;
710    }
711}
712
713/// Create a demo radio group
714fn radio_group(asset_server: &AssetServer) -> impl Bundle {
715    (
716        Node {
717            display: Display::Flex,
718            flex_direction: FlexDirection::Column,
719            align_items: AlignItems::Start,
720            column_gap: px(4),
721            ..default()
722        },
723        Name::new("RadioGroup"),
724        RadioGroup,
725        TabIndex::default(),
726        children![
727            (radio(asset_server, TrackClick::Drag, "Slider Drag"),),
728            (radio(asset_server, TrackClick::Step, "Slider Step"),),
729            (radio(asset_server, TrackClick::Snap, "Slider Snap"),)
730        ],
731    )
732}
733
734/// Create a demo radio button
735fn radio(asset_server: &AssetServer, value: TrackClick, caption: &str) -> impl Bundle {
736    (
737        Node {
738            display: Display::Flex,
739            flex_direction: FlexDirection::Row,
740            justify_content: JustifyContent::FlexStart,
741            align_items: AlignItems::Center,
742            align_content: AlignContent::Center,
743            column_gap: px(4),
744            ..default()
745        },
746        Name::new("RadioButton"),
747        Hovered::default(),
748        DemoRadio(value),
749        RadioButton,
750        Children::spawn((
751            Spawn((
752                // Radio outer
753                Node {
754                    display: Display::Flex,
755                    width: px(16),
756                    height: px(16),
757                    border: UiRect::all(px(2)),
758                    border_radius: BorderRadius::MAX,
759                    ..default()
760                },
761                BorderColor::all(ELEMENT_OUTLINE), // Border color for the radio button
762                children![
763                    // Radio inner
764                    (
765                        Node {
766                            display: Display::Flex,
767                            width: px(8),
768                            height: px(8),
769                            position_type: PositionType::Absolute,
770                            left: px(2),
771                            top: px(2),
772                            border_radius: BorderRadius::MAX,
773                            ..default()
774                        },
775                        BackgroundColor(ELEMENT_FILL),
776                    ),
777                ],
778            )),
779            Spawn((
780                Text::new(caption),
781                TextFont {
782                    font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
783                    font_size: FontSize::Px(20.0),
784                    ..default()
785                },
786            )),
787        )),
788    )
789}
790
791fn on_menu_event(
792    menu_event: On<MenuEvent>,
793    q_anchor: Single<(Entity, &Children), With<DemoMenuAnchor>>,
794    q_popup: Query<Entity, With<MenuPopup>>,
795    assets: Res<AssetServer>,
796    mut focus: ResMut<InputFocus>,
797    mut commands: Commands,
798) {
799    let (anchor, children) = q_anchor.into_inner();
800    let popup = children.iter().find_map(|c| q_popup.get(c).ok());
801    info!("Menu action: {:?}", menu_event.action);
802    match menu_event.action {
803        MenuAction::Open => {
804            if popup.is_none() {
805                spawn_menu(anchor, assets, commands);
806            }
807        }
808        MenuAction::Toggle => match popup {
809            Some(popup) => commands.entity(popup).despawn(),
810            None => spawn_menu(anchor, assets, commands),
811        },
812        MenuAction::Close | MenuAction::CloseAll => {
813            if let Some(popup) = popup {
814                commands.entity(popup).despawn();
815            }
816        }
817        MenuAction::FocusRoot => {
818            focus.0 = Some(anchor);
819        }
820    }
821}
822
823fn spawn_menu(anchor: Entity, assets: Res<AssetServer>, mut commands: Commands) {
824    let menu = commands
825        .spawn((
826            Node {
827                display: Display::Flex,
828                flex_direction: FlexDirection::Column,
829                min_height: px(10.),
830                min_width: percent(100),
831                border: UiRect::all(px(1)),
832                position_type: PositionType::Absolute,
833                ..default()
834            },
835            MenuPopup::default(),
836            BorderColor::all(GREEN),
837            BackgroundColor(GRAY.into()),
838            BoxShadow::new(
839                Srgba::BLACK.with_alpha(0.9).into(),
840                px(0),
841                px(0),
842                px(1),
843                px(4),
844            ),
845            GlobalZIndex(100),
846            Popover {
847                positions: vec![
848                    PopoverPlacement {
849                        side: PopoverSide::Bottom,
850                        align: PopoverAlign::Start,
851                        gap: 2.0,
852                    },
853                    PopoverPlacement {
854                        side: PopoverSide::Top,
855                        align: PopoverAlign::Start,
856                        gap: 2.0,
857                    },
858                ],
859                window_margin: 10.0,
860            },
861            OverrideClip,
862            children![
863                menu_item(&assets),
864                menu_item(&assets),
865                menu_item(&assets),
866                menu_item(&assets)
867            ],
868        ))
869        .id();
870    commands.entity(anchor).add_child(menu);
871}
872
873fn menu_item(asset_server: &AssetServer) -> impl Bundle {
874    (
875        Node {
876            padding: UiRect::axes(px(8), px(2)),
877            justify_content: JustifyContent::Center,
878            align_items: AlignItems::Start,
879            ..default()
880        },
881        DemoMenuItem,
882        MenuItem,
883        Hovered::default(),
884        TabIndex(0),
885        BackgroundColor(NORMAL_BUTTON),
886        children![(
887            Text::new("Menu Item"),
888            TextFont {
889                font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
890                font_size: FontSize::Px(33.0),
891                ..default()
892            },
893            TextColor(Color::srgb(0.9, 0.9, 0.9)),
894            TextShadow::default(),
895        )],
896    )
897}
examples/stress_tests/many_buttons.rs (line 276)
263fn spawn_button(
264    commands: &mut ChildSpawnerCommands,
265    background_color: Color,
266    buttons: f32,
267    column: usize,
268    row: usize,
269    spawn_text: bool,
270    border: UiRect,
271    border_color: BorderColor,
272    image: Option<Handle<Image>>,
273) {
274    let width = vw(90.0 / buttons);
275    let height = vh(90.0 / buttons);
276    let margin = UiRect::axes(width * 0.05, height * 0.05);
277    let mut builder = commands.spawn((
278        Button,
279        Node {
280            width,
281            height,
282            margin,
283            align_items: AlignItems::Center,
284            justify_content: JustifyContent::Center,
285            border,
286            ..default()
287        },
288        BackgroundColor(background_color),
289        border_color,
290        IdleColor(background_color),
291    ));
292
293    if let Some(image) = image {
294        builder.insert(ImageNode::new(image));
295    }
296
297    if spawn_text {
298        builder.with_children(|parent| {
299            // These labels are split to stress test multi-span text
300            parent
301                .spawn((
302                    Text(format!("{column}, ")),
303                    TextFont {
304                        font_size: FONT_SIZE,
305                        ..default()
306                    },
307                    TextColor(Color::srgb(0.5, 0.2, 0.2)),
308                ))
309                .with_child((
310                    TextSpan(format!("{row}")),
311                    TextFont {
312                        font_size: FONT_SIZE,
313                        ..default()
314                    },
315                    TextColor(Color::srgb(0.2, 0.2, 0.5)),
316                ));
317        });
318    }
319}
Source

pub const fn left(left: Val) -> UiRect

Creates a new UiRect where left takes the given value, and the other fields are set to Val::ZERO.

§Example
let ui_rect = UiRect::left(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::Px(10.0));
assert_eq!(ui_rect.right, Val::ZERO);
assert_eq!(ui_rect.top, Val::ZERO);
assert_eq!(ui_rect.bottom, Val::ZERO);
Examples found in repository?
examples/animation/animation_graph.rs (line 370)
346fn setup_node_lines(commands: &mut Commands) {
347    for line in &HORIZONTAL_LINES {
348        commands.spawn((
349            Node {
350                position_type: PositionType::Absolute,
351                bottom: px(line.bottom),
352                left: px(line.left),
353                height: px(0),
354                width: px(line.length),
355                border: UiRect::bottom(px(1)),
356                ..default()
357            },
358            BorderColor::all(WHITE),
359        ));
360    }
361
362    for line in &VERTICAL_LINES {
363        commands.spawn((
364            Node {
365                position_type: PositionType::Absolute,
366                bottom: px(line.bottom),
367                left: px(line.left),
368                height: px(line.length),
369                width: px(0),
370                border: UiRect::left(px(1)),
371                ..default()
372            },
373            BorderColor::all(WHITE),
374        ));
375    }
376}
More examples
Hide additional examples
examples/testbed/ui.rs (line 716)
700    pub fn setup(mut commands: Commands) {
701        commands.spawn((Camera2d, DespawnOnExit(super::Scene::Borders)));
702        let root = commands
703            .spawn((
704                Node {
705                    flex_wrap: FlexWrap::Wrap,
706                    ..default()
707                },
708                DespawnOnExit(super::Scene::Borders),
709            ))
710            .id();
711
712        // all the different combinations of border edges
713        let borders = [
714            UiRect::default(),
715            UiRect::all(px(20)),
716            UiRect::left(px(20)),
717            UiRect::vertical(px(20)),
718            UiRect {
719                left: px(40),
720                top: px(20),
721                ..Default::default()
722            },
723            UiRect {
724                right: px(20),
725                bottom: px(30),
726                ..Default::default()
727            },
728            UiRect {
729                right: px(20),
730                top: px(40),
731                bottom: px(20),
732                ..Default::default()
733            },
734            UiRect {
735                left: px(20),
736                top: px(20),
737                bottom: px(20),
738                ..Default::default()
739            },
740            UiRect {
741                left: px(20),
742                right: px(20),
743                bottom: px(40),
744                ..Default::default()
745            },
746        ];
747
748        let non_zero = |x, y| x != px(0) && y != px(0);
749        let border_size = |x, y| if non_zero(x, y) { f32::MAX } else { 0. };
750
751        for border in borders {
752            for rounded in [true, false] {
753                let border_node = commands
754                    .spawn((
755                        Node {
756                            width: px(100),
757                            height: px(100),
758                            border,
759                            margin: UiRect::all(px(30)),
760                            align_items: AlignItems::Center,
761                            justify_content: JustifyContent::Center,
762                            border_radius: if rounded {
763                                BorderRadius::px(
764                                    border_size(border.left, border.top),
765                                    border_size(border.right, border.top),
766                                    border_size(border.right, border.bottom),
767                                    border_size(border.left, border.bottom),
768                                )
769                            } else {
770                                BorderRadius::ZERO
771                            },
772                            ..default()
773                        },
774                        BackgroundColor(MAROON.into()),
775                        BorderColor::all(RED),
776                        Outline {
777                            width: px(10),
778                            offset: px(10),
779                            color: Color::WHITE,
780                        },
781                    ))
782                    .id();
783
784                commands.entity(root).add_child(border_node);
785            }
786        }
787    }
788}
789
790mod box_shadow {
791    use bevy::{color::palettes::css::*, prelude::*};
792
793    pub fn setup(mut commands: Commands) {
794        commands.spawn((Camera2d, DespawnOnExit(super::Scene::BoxShadow)));
795
796        commands
797            .spawn((
798                Node {
799                    width: percent(100),
800                    height: percent(100),
801                    padding: UiRect::all(px(30)),
802                    column_gap: px(200),
803                    flex_wrap: FlexWrap::Wrap,
804                    ..default()
805                },
806                BackgroundColor(GREEN.into()),
807                DespawnOnExit(super::Scene::BoxShadow),
808            ))
809            .with_children(|commands| {
810                let example_nodes = [
811                    (
812                        Vec2::splat(100.),
813                        Vec2::ZERO,
814                        10.,
815                        0.,
816                        BorderRadius::bottom_right(px(10)),
817                    ),
818                    (Vec2::new(200., 50.), Vec2::ZERO, 10., 0., BorderRadius::MAX),
819                    (
820                        Vec2::new(100., 50.),
821                        Vec2::ZERO,
822                        10.,
823                        10.,
824                        BorderRadius::ZERO,
825                    ),
826                    (
827                        Vec2::splat(100.),
828                        Vec2::splat(20.),
829                        10.,
830                        10.,
831                        BorderRadius::bottom_right(px(10)),
832                    ),
833                    (
834                        Vec2::splat(100.),
835                        Vec2::splat(50.),
836                        0.,
837                        10.,
838                        BorderRadius::ZERO,
839                    ),
840                    (
841                        Vec2::new(50., 100.),
842                        Vec2::splat(10.),
843                        0.,
844                        10.,
845                        BorderRadius::MAX,
846                    ),
847                ];
848
849                for (size, offset, spread, blur, border_radius) in example_nodes {
850                    commands.spawn((
851                        Node {
852                            width: px(size.x),
853                            height: px(size.y),
854                            border: UiRect::all(px(2)),
855                            border_radius,
856                            ..default()
857                        },
858                        BorderColor::all(WHITE),
859                        BackgroundColor(BLUE.into()),
860                        BoxShadow::new(
861                            Color::BLACK.with_alpha(0.9),
862                            percent(offset.x),
863                            percent(offset.y),
864                            percent(spread),
865                            px(blur),
866                        ),
867                    ));
868                }
869            });
870    }
871}
872
873mod text_wrap {
874    use bevy::prelude::*;
875
876    pub fn setup(mut commands: Commands) {
877        commands.spawn((Camera2d, DespawnOnExit(super::Scene::TextWrap)));
878
879        let root = commands
880            .spawn((
881                Node {
882                    flex_direction: FlexDirection::Column,
883                    width: px(200),
884                    height: percent(100),
885                    overflow: Overflow::clip_x(),
886                    ..default()
887                },
888                BackgroundColor(Color::BLACK),
889                DespawnOnExit(super::Scene::TextWrap),
890            ))
891            .id();
892
893        for linebreak in [
894            LineBreak::AnyCharacter,
895            LineBreak::WordBoundary,
896            LineBreak::WordOrCharacter,
897            LineBreak::NoWrap,
898        ] {
899            let messages = [
900                "Lorem ipsum dolor sit amet, consectetur adipiscing elit.".to_string(),
901                "pneumonoultramicroscopicsilicovolcanoconiosis".to_string(),
902            ];
903
904            for (j, message) in messages.into_iter().enumerate() {
905                commands.entity(root).with_child((
906                    Text(message.clone()),
907                    TextLayout::new(Justify::Left, linebreak),
908                    BackgroundColor(Color::srgb(0.8 - j as f32 * 0.3, 0., 0.)),
909                ));
910            }
911        }
912    }
913}
914
915mod overflow {
916    use bevy::{color::palettes::css::*, prelude::*};
917
918    pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
919        commands.spawn((Camera2d, DespawnOnExit(super::Scene::Overflow)));
920        let image = asset_server.load("branding/icon.png");
921
922        commands
923            .spawn((
924                Node {
925                    width: percent(100),
926                    height: percent(100),
927                    align_items: AlignItems::Center,
928                    justify_content: JustifyContent::SpaceAround,
929                    ..Default::default()
930                },
931                BackgroundColor(BLUE.into()),
932                DespawnOnExit(super::Scene::Overflow),
933            ))
934            .with_children(|parent| {
935                for overflow in [
936                    Overflow::visible(),
937                    Overflow::clip_x(),
938                    Overflow::clip_y(),
939                    Overflow::clip(),
940                ] {
941                    parent
942                        .spawn((
943                            Node {
944                                width: px(100),
945                                height: px(100),
946                                padding: UiRect {
947                                    left: px(25),
948                                    top: px(25),
949                                    ..Default::default()
950                                },
951                                border: UiRect::all(px(5)),
952                                overflow,
953                                ..default()
954                            },
955                            BorderColor::all(RED),
956                            BackgroundColor(Color::WHITE),
957                        ))
958                        .with_children(|parent| {
959                            parent.spawn((
960                                ImageNode::new(image.clone()),
961                                Node {
962                                    min_width: px(100),
963                                    min_height: px(100),
964                                    ..default()
965                                },
966                                Interaction::default(),
967                                Outline {
968                                    width: px(2),
969                                    offset: px(2),
970                                    color: Color::NONE,
971                                },
972                            ));
973                        });
974                }
975            });
976    }
977}
978
979mod slice {
980    use bevy::prelude::*;
981
982    pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
983        commands.spawn((Camera2d, DespawnOnExit(super::Scene::Slice)));
984        let image = asset_server.load("textures/fantasy_ui_borders/numbered_slices.png");
985
986        let slicer = TextureSlicer {
987            border: BorderRect::all(16.0),
988            center_scale_mode: SliceScaleMode::Tile { stretch_value: 1.0 },
989            sides_scale_mode: SliceScaleMode::Tile { stretch_value: 1.0 },
990            ..default()
991        };
992        commands
993            .spawn((
994                Node {
995                    width: percent(100),
996                    height: percent(100),
997                    align_items: AlignItems::Center,
998                    justify_content: JustifyContent::SpaceAround,
999                    ..default()
1000                },
1001                DespawnOnExit(super::Scene::Slice),
1002            ))
1003            .with_children(|parent| {
1004                for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] {
1005                    parent.spawn((
1006                        Button,
1007                        ImageNode {
1008                            image: image.clone(),
1009                            image_mode: NodeImageMode::Sliced(slicer.clone()),
1010                            ..default()
1011                        },
1012                        Node {
1013                            width: px(w),
1014                            height: px(h),
1015                            ..default()
1016                        },
1017                    ));
1018                }
1019
1020                parent.spawn((
1021                    ImageNode {
1022                        image: asset_server
1023                            .load("textures/fantasy_ui_borders/panel-border-010.png"),
1024                        image_mode: NodeImageMode::Sliced(TextureSlicer {
1025                            border: BorderRect::all(22.0),
1026                            center_scale_mode: SliceScaleMode::Stretch,
1027                            sides_scale_mode: SliceScaleMode::Stretch,
1028                            max_corner_scale: 1.0,
1029                        }),
1030                        ..Default::default()
1031                    },
1032                    Node {
1033                        width: px(100),
1034                        height: px(100),
1035                        ..default()
1036                    },
1037                    BackgroundColor(bevy::color::palettes::css::NAVY.into()),
1038                ));
1039            });
1040    }
1041}
1042
1043mod layout_rounding {
1044    use bevy::{color::palettes::css::*, prelude::*};
1045
1046    pub fn setup(mut commands: Commands) {
1047        commands.spawn((Camera2d, DespawnOnExit(super::Scene::LayoutRounding)));
1048
1049        commands
1050            .spawn((
1051                Node {
1052                    display: Display::Grid,
1053                    width: percent(100),
1054                    height: percent(100),
1055                    grid_template_rows: vec![RepeatedGridTrack::fr(10, 1.)],
1056                    ..Default::default()
1057                },
1058                BackgroundColor(Color::WHITE),
1059                DespawnOnExit(super::Scene::LayoutRounding),
1060            ))
1061            .with_children(|commands| {
1062                for i in 2..12 {
1063                    commands
1064                        .spawn(Node {
1065                            display: Display::Grid,
1066                            grid_template_columns: vec![RepeatedGridTrack::fr(i, 1.)],
1067                            ..Default::default()
1068                        })
1069                        .with_children(|commands| {
1070                            for _ in 0..i {
1071                                commands.spawn((
1072                                    Node {
1073                                        border: UiRect::all(px(5)),
1074                                        ..Default::default()
1075                                    },
1076                                    BackgroundColor(MAROON.into()),
1077                                    BorderColor::all(DARK_BLUE),
1078                                ));
1079                            }
1080                        });
1081                }
1082            });
1083    }
1084}
1085
1086mod linear_gradient {
1087    use bevy::camera::Camera2d;
1088    use bevy::color::palettes::css::BLUE;
1089    use bevy::color::palettes::css::LIME;
1090    use bevy::color::palettes::css::RED;
1091    use bevy::color::palettes::css::YELLOW;
1092    use bevy::color::Color;
1093    use bevy::ecs::prelude::*;
1094    use bevy::state::state_scoped::DespawnOnExit;
1095    use bevy::text::TextFont;
1096    use bevy::ui::AlignItems;
1097    use bevy::ui::BackgroundGradient;
1098    use bevy::ui::ColorStop;
1099    use bevy::ui::GridPlacement;
1100    use bevy::ui::InterpolationColorSpace;
1101    use bevy::ui::JustifyContent;
1102    use bevy::ui::LinearGradient;
1103    use bevy::ui::Node;
1104    use bevy::ui::PositionType;
1105    use bevy::utils::default;
1106
1107    pub fn setup(mut commands: Commands) {
1108        commands.spawn((Camera2d, DespawnOnExit(super::Scene::LinearGradient)));
1109        commands
1110            .spawn((
1111                Node {
1112                    flex_direction: bevy::ui::FlexDirection::Column,
1113                    width: bevy::ui::percent(100),
1114                    height: bevy::ui::percent(100),
1115                    justify_content: JustifyContent::Center,
1116                    align_items: AlignItems::Center,
1117                    row_gap: bevy::ui::px(5),
1118                    ..default()
1119                },
1120                DespawnOnExit(super::Scene::LinearGradient),
1121            ))
1122            .with_children(|commands| {
1123                let mut i = 0;
1124                commands
1125                    .spawn(Node {
1126                        display: bevy::ui::Display::Grid,
1127                        row_gap: bevy::ui::px(4),
1128                        column_gap: bevy::ui::px(4),
1129                        ..Default::default()
1130                    })
1131                    .with_children(|commands| {
1132                        for stops in [
1133                            vec![ColorStop::auto(RED), ColorStop::auto(YELLOW)],
1134                            vec![
1135                                ColorStop::auto(Color::BLACK),
1136                                ColorStop::auto(RED),
1137                                ColorStop::auto(Color::WHITE),
1138                            ],
1139                            vec![
1140                                Color::hsl(180.71191, 0.0, 0.3137255).into(),
1141                                Color::hsl(180.71191, 0.5, 0.3137255).into(),
1142                                Color::hsl(180.71191, 1.0, 0.3137255).into(),
1143                            ],
1144                            vec![
1145                                Color::hsl(180.71191, 0.825, 0.0).into(),
1146                                Color::hsl(180.71191, 0.825, 0.5).into(),
1147                                Color::hsl(180.71191, 0.825, 1.0).into(),
1148                            ],
1149                            vec![
1150                                Color::hsl(0.0 + 0.0001, 1.0, 0.5).into(),
1151                                Color::hsl(180.0, 1.0, 0.5).into(),
1152                                Color::hsl(360.0 - 0.0001, 1.0, 0.5).into(),
1153                            ],
1154                            vec![
1155                                Color::WHITE.into(),
1156                                RED.into(),
1157                                LIME.into(),
1158                                BLUE.into(),
1159                                Color::BLACK.into(),
1160                            ],
1161                        ] {
1162                            for color_space in [
1163                                InterpolationColorSpace::LinearRgba,
1164                                InterpolationColorSpace::Srgba,
1165                                InterpolationColorSpace::Oklaba,
1166                                InterpolationColorSpace::Oklcha,
1167                                InterpolationColorSpace::OklchaLong,
1168                                InterpolationColorSpace::Hsla,
1169                                InterpolationColorSpace::HslaLong,
1170                                InterpolationColorSpace::Hsva,
1171                                InterpolationColorSpace::HsvaLong,
1172                            ] {
1173                                let row = i % 18 + 1;
1174                                let column = i / 18 + 1;
1175                                i += 1;
1176
1177                                commands.spawn((
1178                                    Node {
1179                                        grid_row: GridPlacement::start(row as i16 + 1),
1180                                        grid_column: GridPlacement::start(column as i16 + 1),
1181                                        justify_content: JustifyContent::SpaceEvenly,
1182                                        ..Default::default()
1183                                    },
1184                                    children![(
1185                                        Node {
1186                                            height: bevy::ui::px(30),
1187                                            width: bevy::ui::px(300),
1188                                            justify_content: JustifyContent::Center,
1189                                            ..Default::default()
1190                                        },
1191                                        BackgroundGradient::from(LinearGradient {
1192                                            color_space,
1193                                            angle: LinearGradient::TO_RIGHT,
1194                                            stops: stops.clone(),
1195                                        }),
1196                                        children![
1197                                            Node {
1198                                                position_type: PositionType::Absolute,
1199                                                ..default()
1200                                            },
1201                                            TextFont::from_font_size(10.),
1202                                            bevy::ui::widget::Text(format!("{color_space:?}")),
1203                                        ]
1204                                    )],
1205                                ));
1206                            }
1207                        }
1208                    });
1209            });
1210    }
1211}
1212
1213mod radial_gradient {
1214    use bevy::color::palettes::css::RED;
1215    use bevy::color::palettes::tailwind::GRAY_700;
1216    use bevy::prelude::*;
1217    use bevy::ui::ColorStop;
1218
1219    const CELL_SIZE: f32 = 80.;
1220    const GAP: f32 = 10.;
1221
1222    pub fn setup(mut commands: Commands) {
1223        let color_stops = vec![
1224            ColorStop::new(Color::BLACK, px(5)),
1225            ColorStop::new(Color::WHITE, px(5)),
1226            ColorStop::new(Color::WHITE, percent(100)),
1227            ColorStop::auto(RED),
1228        ];
1229
1230        commands.spawn((Camera2d, DespawnOnExit(super::Scene::RadialGradient)));
1231        commands
1232            .spawn((
1233                Node {
1234                    width: percent(100),
1235                    height: percent(100),
1236                    display: Display::Grid,
1237                    align_items: AlignItems::Start,
1238                    grid_template_columns: vec![RepeatedGridTrack::px(
1239                        GridTrackRepetition::AutoFill,
1240                        CELL_SIZE,
1241                    )],
1242                    grid_auto_flow: GridAutoFlow::Row,
1243                    row_gap: px(GAP),
1244                    column_gap: px(GAP),
1245                    padding: UiRect::all(px(GAP)),
1246                    ..default()
1247                },
1248                DespawnOnExit(super::Scene::RadialGradient),
1249            ))
1250            .with_children(|commands| {
1251                for (shape, shape_label) in [
1252                    (RadialGradientShape::ClosestSide, "ClosestSide"),
1253                    (RadialGradientShape::FarthestSide, "FarthestSide"),
1254                    (RadialGradientShape::Circle(percent(55)), "Circle(55%)"),
1255                    (RadialGradientShape::FarthestCorner, "FarthestCorner"),
1256                ] {
1257                    for (position, position_label) in [
1258                        (UiPosition::TOP_LEFT, "TOP_LEFT"),
1259                        (UiPosition::LEFT, "LEFT"),
1260                        (UiPosition::BOTTOM_LEFT, "BOTTOM_LEFT"),
1261                        (UiPosition::TOP, "TOP"),
1262                        (UiPosition::CENTER, "CENTER"),
1263                        (UiPosition::BOTTOM, "BOTTOM"),
1264                        (UiPosition::TOP_RIGHT, "TOP_RIGHT"),
1265                        (UiPosition::RIGHT, "RIGHT"),
1266                        (UiPosition::BOTTOM_RIGHT, "BOTTOM_RIGHT"),
1267                    ] {
1268                        for (w, h) in [(CELL_SIZE, CELL_SIZE), (CELL_SIZE, CELL_SIZE / 2.)] {
1269                            commands
1270                                .spawn((
1271                                    BackgroundColor(GRAY_700.into()),
1272                                    Node {
1273                                        display: Display::Grid,
1274                                        width: px(CELL_SIZE),
1275                                        ..Default::default()
1276                                    },
1277                                ))
1278                                .with_children(|commands| {
1279                                    commands.spawn((
1280                                        Node {
1281                                            margin: UiRect::all(px(2)),
1282                                            ..default()
1283                                        },
1284                                        Text(format!("{shape_label}\n{position_label}")),
1285                                        TextFont::from_font_size(9.),
1286                                    ));
1287                                    commands.spawn((
1288                                        Node {
1289                                            width: px(w),
1290                                            height: px(h),
1291                                            ..default()
1292                                        },
1293                                        BackgroundGradient::from(RadialGradient {
1294                                            stops: color_stops.clone(),
1295                                            position,
1296                                            shape,
1297                                            ..default()
1298                                        }),
1299                                    ));
1300                                });
1301                        }
1302                    }
1303                }
1304            });
1305    }
1306}
1307
1308mod transformations {
1309    use bevy::{color::palettes::css::*, prelude::*};
1310
1311    pub fn setup(mut commands: Commands) {
1312        commands.spawn((Camera2d, DespawnOnExit(super::Scene::Transformations)));
1313        commands
1314            .spawn((
1315                Node {
1316                    width: percent(100),
1317                    height: percent(100),
1318                    display: Display::Block,
1319                    ..default()
1320                },
1321                DespawnOnExit(super::Scene::Transformations),
1322            ))
1323            .with_children(|parent| {
1324                for (transformation, label, background) in [
1325                    (
1326                        UiTransform::from_rotation(Rot2::degrees(45.)),
1327                        "Rotate 45 degrees",
1328                        RED,
1329                    ),
1330                    (
1331                        UiTransform::from_scale(Vec2::new(2., 0.5)),
1332                        "Scale 2.x 0.5y",
1333                        GREEN,
1334                    ),
1335                    (
1336                        UiTransform::from_translation(Val2::px(-50., 50.)),
1337                        "Translate -50px x +50px y",
1338                        BLUE,
1339                    ),
1340                    (
1341                        UiTransform {
1342                            translation: Val2::px(50., 0.),
1343                            scale: Vec2::new(-1., 1.),
1344                            rotation: Rot2::degrees(30.),
1345                        },
1346                        "T 50px x\nS -1.x (refl)\nR 30deg",
1347                        DARK_CYAN,
1348                    ),
1349                ] {
1350                    parent
1351                        .spawn((Node {
1352                            width: percent(100),
1353                            margin: UiRect {
1354                                top: px(50),
1355                                bottom: px(50),
1356                                ..default()
1357                            },
1358                            align_items: AlignItems::Center,
1359                            justify_content: JustifyContent::SpaceAround,
1360                            ..default()
1361                        },))
1362                        .with_children(|row| {
1363                            row.spawn((
1364                                Text::new("Before Tf"),
1365                                Node {
1366                                    width: px(100),
1367                                    height: px(100),
1368                                    border_radius: BorderRadius::bottom_right(px(25.)),
1369                                    ..default()
1370                                },
1371                                BackgroundColor(background.into()),
1372                                TextFont::default(),
1373                            ));
1374                            row.spawn((
1375                                Text::new(label),
1376                                Node {
1377                                    width: px(100),
1378                                    height: px(100),
1379                                    border_radius: BorderRadius::bottom_right(px(25.)),
1380                                    ..default()
1381                                },
1382                                BackgroundColor(background.into()),
1383                                transformation,
1384                                TextFont::default(),
1385                            ));
1386                        });
1387                }
1388            });
1389    }
1390}
1391
1392#[cfg(feature = "bevy_ui_debug")]
1393mod debug_outlines {
1394    use bevy::{
1395        color::palettes::css::{BLUE, GRAY, RED},
1396        prelude::*,
1397        ui_render::UiDebugOptions,
1398    };
1399
1400    pub fn setup(mut commands: Commands, mut debug_options: ResMut<GlobalUiDebugOptions>) {
1401        debug_options.enabled = true;
1402        debug_options.line_width = 5.;
1403        debug_options.line_color_override = Some(LinearRgba::GREEN);
1404        debug_options.show_hidden = true;
1405        debug_options.show_clipped = true;
1406
1407        let debug_options: UiDebugOptions = (*debug_options.as_ref()).into();
1408
1409        commands.spawn((Camera2d, DespawnOnExit(super::Scene::DebugOutlines)));
1410        commands
1411            .spawn((
1412                Node {
1413                    width: percent(100),
1414                    height: percent(50),
1415                    align_items: AlignItems::Center,
1416                    justify_content: JustifyContent::SpaceAround,
1417                    ..default()
1418                },
1419                DespawnOnExit(super::Scene::DebugOutlines),
1420            ))
1421            .with_children(|parent| {
1422                parent.spawn((
1423                    Node {
1424                        width: px(100),
1425                        height: px(100),
1426                        ..default()
1427                    },
1428                    BackgroundColor(GRAY.into()),
1429                    UiTransform::from_rotation(Rot2::degrees(45.)),
1430                ));
1431
1432                parent.spawn((Text::new("Regular Text"), TextFont::default()));
1433
1434                parent.spawn((
1435                    Node {
1436                        width: px(100),
1437                        height: px(100),
1438                        ..default()
1439                    },
1440                    Text::new("Invisible"),
1441                    BackgroundColor(GRAY.into()),
1442                    TextFont::default(),
1443                    Visibility::Hidden,
1444                ));
1445
1446                parent
1447                    .spawn((
1448                        Node {
1449                            width: px(100),
1450                            height: px(100),
1451                            padding: UiRect {
1452                                left: px(25),
1453                                top: px(25),
1454                                ..Default::default()
1455                            },
1456                            overflow: Overflow::clip(),
1457                            ..default()
1458                        },
1459                        BackgroundColor(RED.into()),
1460                    ))
1461                    .with_children(|child| {
1462                        child.spawn((
1463                            Node {
1464                                min_width: px(100),
1465                                min_height: px(100),
1466                                ..default()
1467                            },
1468                            BackgroundColor(BLUE.into()),
1469                        ));
1470                    });
1471            });
1472
1473        commands
1474            .spawn((
1475                Node {
1476                    width: percent(100),
1477                    height: percent(50),
1478                    top: percent(50),
1479                    align_items: AlignItems::Center,
1480                    justify_content: JustifyContent::SpaceAround,
1481                    ..default()
1482                },
1483                DespawnOnExit(super::Scene::DebugOutlines),
1484            ))
1485            .with_children(|parent| {
1486                parent.spawn((
1487                    Node {
1488                        width: px(200),
1489                        height: px(200),
1490                        border: UiRect {
1491                            top: px(10),
1492                            bottom: px(20),
1493                            left: px(30),
1494                            right: px(40),
1495                        },
1496                        border_radius: BorderRadius::bottom_right(px(10)),
1497                        padding: UiRect {
1498                            top: px(40),
1499                            bottom: px(30),
1500                            left: px(20),
1501                            right: px(10),
1502                        },
1503                        ..default()
1504                    },
1505                    children![(
1506                        Text::new("border padding content outlines"),
1507                        TextFont::default(),
1508                        UiDebugOptions {
1509                            enabled: false,
1510                            ..default()
1511                        }
1512                    )],
1513                    UiDebugOptions {
1514                        outline_border_box: true,
1515                        outline_padding_box: true,
1516                        outline_content_box: true,
1517                        ignore_border_radius: false,
1518                        ..debug_options
1519                    },
1520                ));
1521
1522                // Vertical scrollbar (non-functional)
1523                parent.spawn((
1524                    Node {
1525                        flex_direction: FlexDirection::Column,
1526                        width: px(90),
1527                        height: px(230),
1528                        overflow: Overflow::scroll_y(),
1529                        scrollbar_width: 20.,
1530                        ..default()
1531                    },
1532                    ScrollPosition(Vec2::new(180., 180.)),
1533                    UiDebugOptions {
1534                        line_width: 3.,
1535                        outline_scrollbars: true,
1536                        show_hidden: false,
1537                        show_clipped: false,
1538                        ..debug_options
1539                    },
1540                    Children::spawn(SpawnIter((0..20).map(move |i| {
1541                        (
1542                            Node::default(),
1543                            children![(
1544                                Text(format!("Item {i}")),
1545                                UiDebugOptions {
1546                                    enabled: false,
1547                                    ..default()
1548                                }
1549                            )],
1550                            UiDebugOptions {
1551                                enabled: false,
1552                                ..default()
1553                            },
1554                        )
1555                    }))),
1556                ));
1557
1558                // Horizontal scrollbar (non-functional)
1559                parent.spawn((
1560                    Node {
1561                        flex_direction: FlexDirection::Row,
1562                        width: px(156),
1563                        height: px(70),
1564                        overflow: Overflow::scroll_x(),
1565                        scrollbar_width: 10.,
1566                        ..default()
1567                    },
1568                    UiDebugOptions {
1569                        line_width: 3.,
1570                        outline_scrollbars: true,
1571                        show_hidden: false,
1572                        show_clipped: false,
1573                        ..debug_options
1574                    },
1575                    Children::spawn(SpawnIter((0..20).map(move |i| {
1576                        (
1577                            Node::default(),
1578                            children![(
1579                                Text(format!("Item {i}")),
1580                                UiDebugOptions {
1581                                    enabled: false,
1582                                    ..default()
1583                                }
1584                            )],
1585                            UiDebugOptions {
1586                                enabled: false,
1587                                ..default()
1588                            },
1589                        )
1590                    }))),
1591                ));
1592
1593                // bi-directional scrollbar (non-functional)
1594                parent.spawn((
1595                    Node {
1596                        flex_direction: FlexDirection::Column,
1597                        width: px(230),
1598                        height: px(125),
1599                        overflow: Overflow::scroll(),
1600                        scrollbar_width: 20.,
1601                        ..default()
1602                    },
1603                    ScrollPosition(Vec2::new(300., 0.)),
1604                    UiDebugOptions {
1605                        line_width: 3.,
1606                        outline_scrollbars: true,
1607                        show_hidden: false,
1608                        show_clipped: false,
1609                        ..debug_options
1610                    },
1611                    Children::spawn(SpawnIter((0..6).map(move |i| {
1612                        (
1613                            Node {
1614                                flex_direction: FlexDirection::Row,
1615                                ..default()
1616                            },
1617                            Children::spawn(SpawnIter((0..6).map({
1618                                move |j| {
1619                                    (
1620                                        Text(format!("Item {}", (i * 5) + j)),
1621                                        UiDebugOptions {
1622                                            enabled: false,
1623                                            ..default()
1624                                        },
1625                                    )
1626                                }
1627                            }))),
1628                            UiDebugOptions {
1629                                enabled: false,
1630                                ..default()
1631                            },
1632                        )
1633                    }))),
1634                ));
1635            });
1636    }
1637
1638    pub fn teardown(mut debug_options: ResMut<GlobalUiDebugOptions>) {
1639        *debug_options = GlobalUiDebugOptions::default();
1640    }
1641}
1642
1643mod viewport_coords {
1644    use bevy::{color::palettes::css::*, prelude::*};
1645
1646    const PALETTE: [Srgba; 9] = [RED, WHITE, BEIGE, AQUA, CRIMSON, NAVY, AZURE, LIME, BLACK];
1647
1648    pub fn setup(mut commands: Commands) {
1649        commands.spawn((Camera2d, DespawnOnExit(super::Scene::ViewportCoords)));
1650        commands
1651            .spawn((
1652                Node {
1653                    width: vw(100),
1654                    height: vh(100),
1655                    border: UiRect::axes(vw(5), vh(5)),
1656                    flex_wrap: FlexWrap::Wrap,
1657                    ..default()
1658                },
1659                BorderColor::all(PALETTE[0]),
1660                DespawnOnExit(super::Scene::ViewportCoords),
1661            ))
1662            .with_children(|builder| {
1663                builder.spawn((
1664                    Node {
1665                        width: vw(30),
1666                        height: vh(30),
1667                        border: UiRect::all(vmin(5)),
1668                        ..default()
1669                    },
1670                    BackgroundColor(PALETTE[1].into()),
1671                    BorderColor::all(PALETTE[8]),
1672                ));
1673
1674                builder.spawn((
1675                    Node {
1676                        width: vw(60),
1677                        height: vh(30),
1678                        ..default()
1679                    },
1680                    BackgroundColor(PALETTE[2].into()),
1681                ));
1682
1683                builder.spawn((
1684                    Node {
1685                        width: vw(45),
1686                        height: vh(30),
1687                        border: UiRect::left(vmax(45. / 2.)),
1688                        ..default()
1689                    },
1690                    BackgroundColor(PALETTE[3].into()),
1691                    BorderColor::all(PALETTE[7]),
1692                ));
1693
1694                builder.spawn((
1695                    Node {
1696                        width: vw(45),
1697                        height: vh(30),
1698                        border: UiRect::right(vmax(45. / 2.)),
1699                        ..default()
1700                    },
1701                    BackgroundColor(PALETTE[4].into()),
1702                    BorderColor::all(PALETTE[7]),
1703                ));
1704
1705                builder.spawn((
1706                    Node {
1707                        width: vw(60),
1708                        height: vh(30),
1709                        ..default()
1710                    },
1711                    BackgroundColor(PALETTE[5].into()),
1712                ));
1713
1714                builder.spawn((
1715                    Node {
1716                        width: vw(30),
1717                        height: vh(30),
1718                        border: UiRect::all(vmin(5)),
1719                        ..default()
1720                    },
1721                    BackgroundColor(PALETTE[6].into()),
1722                    BorderColor::all(PALETTE[8]),
1723                ));
1724            });
1725    }
1726}
1727
1728mod outer_color {
1729    use bevy::prelude::*;
1730
1731    pub fn setup(mut commands: Commands) {
1732        let radius = percent(33.);
1733        let width = px(10.);
1734
1735        commands.spawn((Camera2d, DespawnOnExit(super::Scene::OuterColor)));
1736        commands
1737            .spawn((
1738                Node {
1739                    display: Display::Grid,
1740                    grid_template_columns: RepeatedGridTrack::px(3, 200.),
1741                    grid_template_rows: RepeatedGridTrack::px(3, 200.),
1742                    margin: UiRect::AUTO,
1743                    ..default()
1744                },
1745                DespawnOnExit(super::Scene::OuterColor),
1746            ))
1747            .with_children(|builder| {
1748                for (border, border_radius, invert) in [
1749                    (UiRect::ZERO, BorderRadius::bottom_right(radius), true),
1750                    (UiRect::top(width), BorderRadius::top(radius), false),
1751                    (UiRect::ZERO, BorderRadius::bottom_left(radius), true),
1752                    (UiRect::left(width), BorderRadius::left(radius), false),
1753                    (UiRect::all(width), BorderRadius::all(radius), true),
1754                    (UiRect::right(width), BorderRadius::right(radius), false),
1755                    (UiRect::ZERO, BorderRadius::top_right(radius), true),
1756                    (UiRect::bottom(width), BorderRadius::bottom(radius), false),
1757                    (UiRect::ZERO, BorderRadius::top_left(radius), true),
1758                ] {
1759                    builder
1760                        .spawn((
1761                            Node {
1762                                width: px(200.),
1763                                height: px(200.),
1764                                border_radius,
1765                                border,
1766                                ..default()
1767                            },
1768                            BorderColor::all(bevy::color::palettes::css::RED),
1769                        ))
1770                        .insert_if(BackgroundColor(Color::WHITE), || !invert)
1771                        .insert_if(OuterColor(Color::WHITE), || invert);
1772                }
1773            });
1774    }
examples/animation/animation_masks.rs (line 253)
229fn new_mask_group_control(label: &str, width: Val, mask_group_id: u32) -> impl Bundle {
230    let button_text_style = (
231        TextFont {
232            font_size: FontSize::Px(14.0),
233            ..default()
234        },
235        TextColor::WHITE,
236    );
237    let selected_button_text_style = (button_text_style.0.clone(), TextColor::BLACK);
238    let label_text_style = (
239        button_text_style.0.clone(),
240        TextColor(Color::Srgba(LIGHT_GRAY)),
241    );
242
243    let make_animation_label = {
244        let button_text_style = button_text_style.clone();
245        let selected_button_text_style = selected_button_text_style.clone();
246        move |first: bool, label: AnimationLabel| {
247            (
248                Button,
249                BackgroundColor(if !first { Color::BLACK } else { Color::WHITE }),
250                Node {
251                    flex_grow: 1.0,
252                    border: if !first {
253                        UiRect::left(px(1))
254                    } else {
255                        UiRect::ZERO
256                    },
257                    ..default()
258                },
259                BorderColor::all(Color::WHITE),
260                AnimationControl {
261                    group_id: mask_group_id,
262                    label,
263                },
264                children![(
265                    Text(format!("{label:?}")),
266                    if !first {
267                        button_text_style.clone()
268                    } else {
269                        selected_button_text_style.clone()
270                    },
271                    TextLayout::new_with_justify(Justify::Center),
272                    Node {
273                        flex_grow: 1.0,
274                        margin: UiRect::vertical(px(3)),
275                        ..default()
276                    },
277                )],
278            )
279        }
280    };
281
282    (
283        Node {
284            border: UiRect::all(px(1)),
285            width,
286            flex_direction: FlexDirection::Column,
287            justify_content: JustifyContent::Center,
288            align_items: AlignItems::Center,
289            padding: UiRect::ZERO,
290            margin: UiRect::ZERO,
291            border_radius: BorderRadius::all(px(3)),
292            ..default()
293        },
294        BorderColor::all(Color::WHITE),
295        BackgroundColor(Color::BLACK),
296        children![
297            (
298                Node {
299                    border: UiRect::ZERO,
300                    width: percent(100),
301                    justify_content: JustifyContent::Center,
302                    align_items: AlignItems::Center,
303                    padding: UiRect::ZERO,
304                    margin: UiRect::ZERO,
305                    ..default()
306                },
307                BackgroundColor(Color::BLACK),
308                children![(
309                    Text::new(label),
310                    label_text_style.clone(),
311                    Node {
312                        margin: UiRect::vertical(px(3)),
313                        ..default()
314                    },
315                )]
316            ),
317            (
318                Node {
319                    width: percent(100),
320                    flex_direction: FlexDirection::Row,
321                    justify_content: JustifyContent::Center,
322                    align_items: AlignItems::Center,
323                    border: UiRect::top(px(1)),
324                    ..default()
325                },
326                BorderColor::all(Color::WHITE),
327                children![
328                    make_animation_label(true, AnimationLabel::Run),
329                    make_animation_label(false, AnimationLabel::Walk),
330                    make_animation_label(false, AnimationLabel::Idle),
331                    make_animation_label(false, AnimationLabel::Off),
332                ]
333            )
334        ],
335    )
336}
examples/ui/styling/box_shadow.rs (line 333)
290fn build_setting_row(
291    setting_type: SettingType,
292    dec: SettingsButton,
293    inc: SettingsButton,
294    value: f32,
295    asset_server: &Res<AssetServer>,
296) -> impl Bundle {
297    let value_text = match setting_type {
298        SettingType::Shape => SHAPES[value as usize % SHAPES.len()].0.to_string(),
299        SettingType::Count => format!("{}", value as usize),
300        _ => format!("{value:.1}"),
301    };
302
303    (
304        Node {
305            flex_direction: FlexDirection::Row,
306            align_items: AlignItems::Center,
307            height: px(32),
308            ..default()
309        },
310        children![
311            (
312                Node {
313                    width: px(80),
314                    justify_content: JustifyContent::FlexEnd,
315                    align_items: AlignItems::Center,
316                    ..default()
317                },
318                // Attach SettingType to the value label node, not the parent row
319                children![(
320                    Text::new(setting_type.label()),
321                    TextFont {
322                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
323                        font_size: FontSize::Px(16.0),
324                        ..default()
325                    },
326                )],
327            ),
328            (
329                Button,
330                Node {
331                    width: px(28),
332                    height: px(28),
333                    margin: UiRect::left(px(8)),
334                    justify_content: JustifyContent::Center,
335                    align_items: AlignItems::Center,
336                    border_radius: BorderRadius::all(px(6)),
337                    ..default()
338                },
339                BackgroundColor(Color::WHITE),
340                dec,
341                children![(
342                    Text::new(if setting_type == SettingType::Shape {
343                        "<"
344                    } else {
345                        "-"
346                    }),
347                    TextFont {
348                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
349                        font_size: FontSize::Px(18.0),
350                        ..default()
351                    },
352                )],
353            ),
354            (
355                Node {
356                    width: px(48),
357                    height: px(28),
358                    margin: UiRect::horizontal(px(8)),
359                    justify_content: JustifyContent::Center,
360                    align_items: AlignItems::Center,
361                    border_radius: BorderRadius::all(px(6)),
362                    ..default()
363                },
364                children![{
365                    (
366                        Text::new(value_text),
367                        TextFont {
368                            font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
369                            font_size: FontSize::Px(16.0),
370                            ..default()
371                        },
372                        setting_type,
373                    )
374                }],
375            ),
376            (
377                Button,
378                Node {
379                    width: px(28),
380                    height: px(28),
381                    justify_content: JustifyContent::Center,
382                    align_items: AlignItems::Center,
383                    border_radius: BorderRadius::all(px(6)),
384                    ..default()
385                },
386                BackgroundColor(Color::WHITE),
387                inc,
388                children![(
389                    Text::new(if setting_type == SettingType::Shape {
390                        ">"
391                    } else {
392                        "+"
393                    }),
394                    TextFont {
395                        font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
396                        font_size: FontSize::Px(18.0),
397                        ..default()
398                    },
399                )],
400            ),
401        ],
402    )
403}
examples/ui/styling/borders.rs (line 40)
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}
examples/ui/styling/gradients.rs (line 117)
27fn setup(mut commands: Commands) {
28    commands.spawn(Camera2d);
29
30    commands
31        .spawn(Node {
32            flex_direction: FlexDirection::Column,
33            row_gap: px(20),
34            margin: UiRect::all(px(20)),
35            ..Default::default()
36        })
37        .with_children(|commands| {
38            for (b, stops) in [
39                (
40                    4.,
41                    vec![
42                        ColorStop::new(Color::WHITE, percent(15)),
43                        ColorStop::new(Color::BLACK, percent(85)),
44                    ],
45                ),
46                (4., vec![RED.into(), BLUE.into(), LIME.into()]),
47                (
48                    0.,
49                    vec![
50                        RED.into(),
51                        ColorStop::new(RED, percent(100. / 7.)),
52                        ColorStop::new(ORANGE, percent(100. / 7.)),
53                        ColorStop::new(ORANGE, percent(200. / 7.)),
54                        ColorStop::new(YELLOW, percent(200. / 7.)),
55                        ColorStop::new(YELLOW, percent(300. / 7.)),
56                        ColorStop::new(GREEN, percent(300. / 7.)),
57                        ColorStop::new(GREEN, percent(400. / 7.)),
58                        ColorStop::new(BLUE, percent(400. / 7.)),
59                        ColorStop::new(BLUE, percent(500. / 7.)),
60                        ColorStop::new(INDIGO, percent(500. / 7.)),
61                        ColorStop::new(INDIGO, percent(600. / 7.)),
62                        ColorStop::new(VIOLET, percent(600. / 7.)),
63                        VIOLET.into(),
64                    ],
65                ),
66            ] {
67                commands.spawn(Node::default()).with_children(|commands| {
68                    commands
69                        .spawn(Node {
70                            flex_direction: FlexDirection::Column,
71                            row_gap: px(5),
72                            ..Default::default()
73                        })
74                        .with_children(|commands| {
75                            for (w, h) in [(70., 70.), (35., 70.), (70., 35.)] {
76                                commands
77                                    .spawn(Node {
78                                        column_gap: px(10),
79                                        ..Default::default()
80                                    })
81                                    .with_children(|commands| {
82                                        for angle in (0..8).map(|i| i as f32 * TAU / 8.) {
83                                            commands.spawn((
84                                                Node {
85                                                    width: px(w),
86                                                    height: px(h),
87                                                    border: UiRect::all(px(b)),
88                                                    border_radius: BorderRadius::all(px(20)),
89                                                    ..default()
90                                                },
91                                                BackgroundGradient::from(LinearGradient {
92                                                    angle,
93                                                    stops: stops.clone(),
94                                                    ..default()
95                                                }),
96                                                BorderGradient::from(LinearGradient {
97                                                    angle: 3. * TAU / 8.,
98                                                    stops: vec![
99                                                        YELLOW.into(),
100                                                        Color::WHITE.into(),
101                                                        ORANGE.into(),
102                                                    ],
103                                                    ..default()
104                                                }),
105                                            ));
106                                        }
107                                    });
108                            }
109                        });
110
111                    commands.spawn(Node::default()).with_children(|commands| {
112                        commands.spawn((
113                            Node {
114                                aspect_ratio: Some(1.),
115                                height: percent(100),
116                                border: UiRect::all(px(b)),
117                                margin: UiRect::left(px(20)),
118                                border_radius: BorderRadius::all(px(20)),
119                                ..default()
120                            },
121                            BackgroundGradient::from(LinearGradient {
122                                angle: 0.,
123                                stops: stops.clone(),
124                                ..default()
125                            }),
126                            BorderGradient::from(LinearGradient {
127                                angle: 3. * TAU / 8.,
128                                stops: vec![YELLOW.into(), Color::WHITE.into(), ORANGE.into()],
129                                ..default()
130                            }),
131                            AnimateMarker,
132                        ));
133
134                        commands.spawn((
135                            Node {
136                                aspect_ratio: Some(1.),
137                                height: percent(100),
138                                border: UiRect::all(px(b)),
139                                margin: UiRect::left(px(20)),
140                                border_radius: BorderRadius::all(px(20)),
141                                ..default()
142                            },
143                            BackgroundGradient::from(RadialGradient {
144                                stops: stops.clone(),
145                                shape: RadialGradientShape::ClosestSide,
146                                position: UiPosition::CENTER,
147                                ..default()
148                            }),
149                            BorderGradient::from(LinearGradient {
150                                angle: 3. * TAU / 8.,
151                                stops: vec![YELLOW.into(), Color::WHITE.into(), ORANGE.into()],
152                                ..default()
153                            }),
154                            AnimateMarker,
155                        ));
156                        commands.spawn((
157                            Node {
158                                aspect_ratio: Some(1.),
159                                height: percent(100),
160                                border: UiRect::all(px(b)),
161                                margin: UiRect::left(px(20)),
162                                border_radius: BorderRadius::all(px(20)),
163                                ..default()
164                            },
165                            BackgroundGradient::from(ConicGradient {
166                                start: 0.,
167                                stops: stops
168                                    .iter()
169                                    .map(|stop| AngularColorStop::auto(stop.color))
170                                    .collect(),
171                                position: UiPosition::CENTER,
172                                ..default()
173                            }),
174                            BorderGradient::from(LinearGradient {
175                                angle: 3. * TAU / 8.,
176                                stops: vec![YELLOW.into(), Color::WHITE.into(), ORANGE.into()],
177                                ..default()
178                            }),
179                            AnimateMarker,
180                        ));
181                    });
182                });
183            }
184
185            let button = commands.spawn((
186                        Button,
187                        Node {
188                            border: UiRect::all(px(2)),
189                            padding: UiRect::axes(px(8), px(4)),
190                            // horizontally center child text
191                            justify_content: JustifyContent::Center,
192                            // vertically center child text
193                            align_items: AlignItems::Center,
194                            border_radius: BorderRadius::MAX,
195                            ..default()
196                        },
197                        BorderColor::all(Color::WHITE),
198                        BackgroundColor(Color::BLACK),
199                        children![(
200                            Text::new("next color space"),
201                            TextColor(Color::srgb(0.9, 0.9, 0.9)),
202                            TextShadow::default(),
203                        )]
204                )).observe(
205                    |_event: On<Pointer<Over>>, mut border_query: Query<&mut BorderColor, With<Button>>| {
206                    *border_query.single_mut().unwrap() = BorderColor::all(RED);
207
208
209                })
210                .observe(
211                    |_event: On<Pointer<Out>>, mut border_query: Query<&mut BorderColor, With<Button>>| {
212                    *border_query.single_mut().unwrap() = BorderColor::all(Color::WHITE);
213                })
214                .observe(
215                        |_event: On<Pointer<Click>>,
216                            mut gradients_query: Query<&mut BackgroundGradient>,
217                            mut label_query: Query<
218                            &mut Text,
219                            With<CurrentColorSpaceLabel>,
220                        >| {
221                            let mut current_space = InterpolationColorSpace::default();
222                            for mut gradients in gradients_query.iter_mut() {
223                                for gradient in gradients.0.iter_mut() {
224                                    let space = match gradient {
225                                        Gradient::Linear(linear_gradient) => {
226                                            &mut linear_gradient.color_space
227                                        }
228                                        Gradient::Radial(radial_gradient) => {
229                                            &mut radial_gradient.color_space
230                                        }
231                                        Gradient::Conic(conic_gradient) => {
232                                            &mut conic_gradient.color_space
233                                        }
234                                    };
235                                    *space = match *space {
236                                        InterpolationColorSpace::Oklaba => {
237                                            InterpolationColorSpace::Oklcha
238                                        }
239                                        InterpolationColorSpace::Oklcha => {
240                                            InterpolationColorSpace::OklchaLong
241                                        }
242                                        InterpolationColorSpace::OklchaLong => {
243                                            InterpolationColorSpace::Srgba
244                                        }
245                                        InterpolationColorSpace::Srgba => {
246                                            InterpolationColorSpace::LinearRgba
247                                        }
248                                        InterpolationColorSpace::LinearRgba => {
249                                            InterpolationColorSpace::Hsla
250                                        }
251                                        InterpolationColorSpace::Hsla => {
252                                            InterpolationColorSpace::HslaLong
253                                        }
254                                        InterpolationColorSpace::HslaLong => {
255                                            InterpolationColorSpace::Hsva
256                                        }
257                                        InterpolationColorSpace::Hsva => {
258                                            InterpolationColorSpace::HsvaLong
259                                        }
260                                        InterpolationColorSpace::HsvaLong => {
261                                            InterpolationColorSpace::Oklaba
262                                        }
263                                    };
264                                    current_space = *space;
265                                }
266                            }
267                            for mut label in label_query.iter_mut() {
268                                label.0 = format!("{current_space:?}");
269                            }
270                        }
271                    ).id();
272
273            commands.spawn(
274                Node {
275                    flex_direction: FlexDirection::Column,
276                    row_gap: px(10),
277                    align_items: AlignItems::Center,
278                    ..Default::default()
279                }
280            ).with_children(|commands| {
281                commands.spawn((Text::new(format!("{:?}", InterpolationColorSpace::default())), TextFont { font_size: FontSize::Px(25.), ..default() }, CurrentColorSpaceLabel));
282
283            })
284            .add_child(button);
285        });
286}
Source

pub const fn right(right: Val) -> UiRect

Creates a new UiRect where right takes the given value, and the other fields are set to Val::ZERO.

§Example
let ui_rect = UiRect::right(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::ZERO);
assert_eq!(ui_rect.right, Val::Px(10.0));
assert_eq!(ui_rect.top, Val::ZERO);
assert_eq!(ui_rect.bottom, Val::ZERO);
Examples found in repository?
examples/3d/color_grading.rs (line 247)
228fn button_for_value(
229    option: SelectedColorGradingOption,
230    color_grading: &ColorGrading,
231    font: &Handle<Font>,
232) -> impl Bundle {
233    let label = match option {
234        SelectedColorGradingOption::Global(option) => option.to_string(),
235        SelectedColorGradingOption::Section(_, option) => option.to_string(),
236    };
237
238    // Add the button node.
239    (
240        Button,
241        Node {
242            border: UiRect::all(px(1)),
243            width: px(200),
244            justify_content: JustifyContent::Center,
245            align_items: AlignItems::Center,
246            padding: UiRect::axes(px(12), px(6)),
247            margin: UiRect::right(px(12)),
248            border_radius: BorderRadius::MAX,
249            ..default()
250        },
251        BorderColor::all(Color::WHITE),
252        BackgroundColor(Color::BLACK),
253        ColorGradingOptionWidget {
254            widget_type: ColorGradingOptionWidgetType::Button,
255            option,
256        },
257        children![
258            // Add the button label.
259            (
260                text(&label, font, Color::WHITE),
261                ColorGradingOptionWidget {
262                    widget_type: ColorGradingOptionWidgetType::Label,
263                    option,
264                },
265            ),
266            // Add a spacer.
267            Node {
268                flex_grow: 1.0,
269                ..default()
270            },
271            // Add the value text.
272            (
273                text(
274                    &format!("{:.3}", option.get(color_grading)),
275                    font,
276                    Color::WHITE,
277                ),
278                ColorGradingOptionWidget {
279                    widget_type: ColorGradingOptionWidgetType::Value,
280                    option,
281                },
282            ),
283        ],
284    )
285}
More examples
Hide additional examples
examples/testbed/ui.rs (line 1698)
1648    pub fn setup(mut commands: Commands) {
1649        commands.spawn((Camera2d, DespawnOnExit(super::Scene::ViewportCoords)));
1650        commands
1651            .spawn((
1652                Node {
1653                    width: vw(100),
1654                    height: vh(100),
1655                    border: UiRect::axes(vw(5), vh(5)),
1656                    flex_wrap: FlexWrap::Wrap,
1657                    ..default()
1658                },
1659                BorderColor::all(PALETTE[0]),
1660                DespawnOnExit(super::Scene::ViewportCoords),
1661            ))
1662            .with_children(|builder| {
1663                builder.spawn((
1664                    Node {
1665                        width: vw(30),
1666                        height: vh(30),
1667                        border: UiRect::all(vmin(5)),
1668                        ..default()
1669                    },
1670                    BackgroundColor(PALETTE[1].into()),
1671                    BorderColor::all(PALETTE[8]),
1672                ));
1673
1674                builder.spawn((
1675                    Node {
1676                        width: vw(60),
1677                        height: vh(30),
1678                        ..default()
1679                    },
1680                    BackgroundColor(PALETTE[2].into()),
1681                ));
1682
1683                builder.spawn((
1684                    Node {
1685                        width: vw(45),
1686                        height: vh(30),
1687                        border: UiRect::left(vmax(45. / 2.)),
1688                        ..default()
1689                    },
1690                    BackgroundColor(PALETTE[3].into()),
1691                    BorderColor::all(PALETTE[7]),
1692                ));
1693
1694                builder.spawn((
1695                    Node {
1696                        width: vw(45),
1697                        height: vh(30),
1698                        border: UiRect::right(vmax(45. / 2.)),
1699                        ..default()
1700                    },
1701                    BackgroundColor(PALETTE[4].into()),
1702                    BorderColor::all(PALETTE[7]),
1703                ));
1704
1705                builder.spawn((
1706                    Node {
1707                        width: vw(60),
1708                        height: vh(30),
1709                        ..default()
1710                    },
1711                    BackgroundColor(PALETTE[5].into()),
1712                ));
1713
1714                builder.spawn((
1715                    Node {
1716                        width: vw(30),
1717                        height: vh(30),
1718                        border: UiRect::all(vmin(5)),
1719                        ..default()
1720                    },
1721                    BackgroundColor(PALETTE[6].into()),
1722                    BorderColor::all(PALETTE[8]),
1723                ));
1724            });
1725    }
1726}
1727
1728mod outer_color {
1729    use bevy::prelude::*;
1730
1731    pub fn setup(mut commands: Commands) {
1732        let radius = percent(33.);
1733        let width = px(10.);
1734
1735        commands.spawn((Camera2d, DespawnOnExit(super::Scene::OuterColor)));
1736        commands
1737            .spawn((
1738                Node {
1739                    display: Display::Grid,
1740                    grid_template_columns: RepeatedGridTrack::px(3, 200.),
1741                    grid_template_rows: RepeatedGridTrack::px(3, 200.),
1742                    margin: UiRect::AUTO,
1743                    ..default()
1744                },
1745                DespawnOnExit(super::Scene::OuterColor),
1746            ))
1747            .with_children(|builder| {
1748                for (border, border_radius, invert) in [
1749                    (UiRect::ZERO, BorderRadius::bottom_right(radius), true),
1750                    (UiRect::top(width), BorderRadius::top(radius), false),
1751                    (UiRect::ZERO, BorderRadius::bottom_left(radius), true),
1752                    (UiRect::left(width), BorderRadius::left(radius), false),
1753                    (UiRect::all(width), BorderRadius::all(radius), true),
1754                    (UiRect::right(width), BorderRadius::right(radius), false),
1755                    (UiRect::ZERO, BorderRadius::top_right(radius), true),
1756                    (UiRect::bottom(width), BorderRadius::bottom(radius), false),
1757                    (UiRect::ZERO, BorderRadius::top_left(radius), true),
1758                ] {
1759                    builder
1760                        .spawn((
1761                            Node {
1762                                width: px(200.),
1763                                height: px(200.),
1764                                border_radius,
1765                                border,
1766                                ..default()
1767                            },
1768                            BorderColor::all(bevy::color::palettes::css::RED),
1769                        ))
1770                        .insert_if(BackgroundColor(Color::WHITE), || !invert)
1771                        .insert_if(OuterColor(Color::WHITE), || invert);
1772                }
1773            });
1774    }
examples/ui/styling/borders.rs (line 41)
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}
Source

pub const fn top(top: Val) -> UiRect

Creates a new UiRect where top takes the given value, and the other fields are set to Val::ZERO.

§Example
let ui_rect = UiRect::top(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::ZERO);
assert_eq!(ui_rect.right, Val::ZERO);
assert_eq!(ui_rect.top, Val::Px(10.0));
assert_eq!(ui_rect.bottom, Val::ZERO);
Examples found in repository?
examples/testbed/ui.rs (line 1750)
1731    pub fn setup(mut commands: Commands) {
1732        let radius = percent(33.);
1733        let width = px(10.);
1734
1735        commands.spawn((Camera2d, DespawnOnExit(super::Scene::OuterColor)));
1736        commands
1737            .spawn((
1738                Node {
1739                    display: Display::Grid,
1740                    grid_template_columns: RepeatedGridTrack::px(3, 200.),
1741                    grid_template_rows: RepeatedGridTrack::px(3, 200.),
1742                    margin: UiRect::AUTO,
1743                    ..default()
1744                },
1745                DespawnOnExit(super::Scene::OuterColor),
1746            ))
1747            .with_children(|builder| {
1748                for (border, border_radius, invert) in [
1749                    (UiRect::ZERO, BorderRadius::bottom_right(radius), true),
1750                    (UiRect::top(width), BorderRadius::top(radius), false),
1751                    (UiRect::ZERO, BorderRadius::bottom_left(radius), true),
1752                    (UiRect::left(width), BorderRadius::left(radius), false),
1753                    (UiRect::all(width), BorderRadius::all(radius), true),
1754                    (UiRect::right(width), BorderRadius::right(radius), false),
1755                    (UiRect::ZERO, BorderRadius::top_right(radius), true),
1756                    (UiRect::bottom(width), BorderRadius::bottom(radius), false),
1757                    (UiRect::ZERO, BorderRadius::top_left(radius), true),
1758                ] {
1759                    builder
1760                        .spawn((
1761                            Node {
1762                                width: px(200.),
1763                                height: px(200.),
1764                                border_radius,
1765                                border,
1766                                ..default()
1767                            },
1768                            BorderColor::all(bevy::color::palettes::css::RED),
1769                        ))
1770                        .insert_if(BackgroundColor(Color::WHITE), || !invert)
1771                        .insert_if(OuterColor(Color::WHITE), || invert);
1772                }
1773            });
1774    }
More examples
Hide additional examples
examples/ui/layout/size_constraints.rs (line 91)
41fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
42    // ui camera
43    commands.spawn(Camera2d);
44
45    let text_font = (
46        TextFont {
47            font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
48            font_size: FontSize::Px(33.0),
49            ..Default::default()
50        },
51        TextColor(Color::srgb(0.9, 0.9, 0.9)),
52    );
53
54    commands
55        .spawn((
56            Node {
57                width: percent(100),
58                height: percent(100),
59                justify_content: JustifyContent::Center,
60                align_items: AlignItems::Center,
61                ..default()
62            },
63            BackgroundColor(Color::BLACK),
64        ))
65        .with_children(|parent| {
66            parent
67                .spawn(Node {
68                    flex_direction: FlexDirection::Column,
69                    align_items: AlignItems::Center,
70                    justify_content: JustifyContent::Center,
71                    ..default()
72                })
73                .with_children(|parent| {
74                    parent.spawn((
75                        Text::new("Size Constraints Example"),
76                        text_font.clone(),
77                        Node {
78                            margin: UiRect::bottom(px(25)),
79                            ..Default::default()
80                        },
81                    ));
82
83                    spawn_bar(parent);
84
85                    parent
86                        .spawn((
87                            Node {
88                                flex_direction: FlexDirection::Column,
89                                align_items: AlignItems::Stretch,
90                                padding: UiRect::all(px(10)),
91                                margin: UiRect::top(px(50)),
92                                ..default()
93                            },
94                            BackgroundColor(YELLOW.into()),
95                        ))
96                        .with_children(|parent| {
97                            for constraint in [
98                                Constraint::MinWidth,
99                                Constraint::FlexBasis,
100                                Constraint::Width,
101                                Constraint::MaxWidth,
102                            ] {
103                                spawn_button_row(parent, constraint, text_font.clone());
104                            }
105                        });
106                });
107        });
108}
examples/ui/scroll_and_overflow/overflow_clip_margin.rs (line 58)
12fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
13    commands.spawn(Camera2d);
14
15    let image = asset_server.load("branding/icon.png");
16
17    commands
18        .spawn((
19            Node {
20                width: percent(100),
21                height: percent(100),
22                align_items: AlignItems::Center,
23                justify_content: JustifyContent::Center,
24                row_gap: px(40),
25                flex_direction: FlexDirection::Column,
26                ..default()
27            },
28            BackgroundColor(ANTIQUE_WHITE.into()),
29        ))
30        .with_children(|parent| {
31            for overflow_clip_margin in [
32                OverflowClipMargin::border_box().with_margin(25.),
33                OverflowClipMargin::border_box(),
34                OverflowClipMargin::padding_box(),
35                OverflowClipMargin::content_box(),
36            ] {
37                parent
38                    .spawn(Node {
39                        flex_direction: FlexDirection::Row,
40                        column_gap: px(20),
41                        ..default()
42                    })
43                    .with_children(|parent| {
44                        parent
45                            .spawn((
46                                Node {
47                                    padding: UiRect::all(px(10)),
48                                    margin: UiRect::bottom(px(25)),
49                                    ..default()
50                                },
51                                BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
52                            ))
53                            .with_child(Text(format!("{overflow_clip_margin:#?}")));
54
55                        parent
56                            .spawn((
57                                Node {
58                                    margin: UiRect::top(px(10)),
59                                    width: px(100),
60                                    height: px(100),
61                                    padding: UiRect::all(px(20)),
62                                    border: UiRect::all(px(5)),
63                                    overflow: Overflow::clip(),
64                                    overflow_clip_margin,
65                                    ..default()
66                                },
67                                BackgroundColor(GRAY.into()),
68                                BorderColor::all(Color::BLACK),
69                            ))
70                            .with_children(|parent| {
71                                parent
72                                    .spawn((
73                                        Node {
74                                            min_width: px(50),
75                                            min_height: px(50),
76                                            ..default()
77                                        },
78                                        BackgroundColor(LIGHT_CYAN.into()),
79                                    ))
80                                    .with_child((
81                                        ImageNode::new(image.clone()),
82                                        Node {
83                                            min_width: px(100),
84                                            min_height: px(100),
85                                            ..default()
86                                        },
87                                    ));
88                            });
89                    });
90            }
91        });
92}
examples/animation/animation_masks.rs (line 323)
229fn new_mask_group_control(label: &str, width: Val, mask_group_id: u32) -> impl Bundle {
230    let button_text_style = (
231        TextFont {
232            font_size: FontSize::Px(14.0),
233            ..default()
234        },
235        TextColor::WHITE,
236    );
237    let selected_button_text_style = (button_text_style.0.clone(), TextColor::BLACK);
238    let label_text_style = (
239        button_text_style.0.clone(),
240        TextColor(Color::Srgba(LIGHT_GRAY)),
241    );
242
243    let make_animation_label = {
244        let button_text_style = button_text_style.clone();
245        let selected_button_text_style = selected_button_text_style.clone();
246        move |first: bool, label: AnimationLabel| {
247            (
248                Button,
249                BackgroundColor(if !first { Color::BLACK } else { Color::WHITE }),
250                Node {
251                    flex_grow: 1.0,
252                    border: if !first {
253                        UiRect::left(px(1))
254                    } else {
255                        UiRect::ZERO
256                    },
257                    ..default()
258                },
259                BorderColor::all(Color::WHITE),
260                AnimationControl {
261                    group_id: mask_group_id,
262                    label,
263                },
264                children![(
265                    Text(format!("{label:?}")),
266                    if !first {
267                        button_text_style.clone()
268                    } else {
269                        selected_button_text_style.clone()
270                    },
271                    TextLayout::new_with_justify(Justify::Center),
272                    Node {
273                        flex_grow: 1.0,
274                        margin: UiRect::vertical(px(3)),
275                        ..default()
276                    },
277                )],
278            )
279        }
280    };
281
282    (
283        Node {
284            border: UiRect::all(px(1)),
285            width,
286            flex_direction: FlexDirection::Column,
287            justify_content: JustifyContent::Center,
288            align_items: AlignItems::Center,
289            padding: UiRect::ZERO,
290            margin: UiRect::ZERO,
291            border_radius: BorderRadius::all(px(3)),
292            ..default()
293        },
294        BorderColor::all(Color::WHITE),
295        BackgroundColor(Color::BLACK),
296        children![
297            (
298                Node {
299                    border: UiRect::ZERO,
300                    width: percent(100),
301                    justify_content: JustifyContent::Center,
302                    align_items: AlignItems::Center,
303                    padding: UiRect::ZERO,
304                    margin: UiRect::ZERO,
305                    ..default()
306                },
307                BackgroundColor(Color::BLACK),
308                children![(
309                    Text::new(label),
310                    label_text_style.clone(),
311                    Node {
312                        margin: UiRect::vertical(px(3)),
313                        ..default()
314                    },
315                )]
316            ),
317            (
318                Node {
319                    width: percent(100),
320                    flex_direction: FlexDirection::Row,
321                    justify_content: JustifyContent::Center,
322                    align_items: AlignItems::Center,
323                    border: UiRect::top(px(1)),
324                    ..default()
325                },
326                BorderColor::all(Color::WHITE),
327                children![
328                    make_animation_label(true, AnimationLabel::Run),
329                    make_animation_label(false, AnimationLabel::Walk),
330                    make_animation_label(false, AnimationLabel::Idle),
331                    make_animation_label(false, AnimationLabel::Off),
332                ]
333            )
334        ],
335    )
336}
examples/ui/styling/box_shadow.rs (line 259)
139fn setup(
140    mut commands: Commands,
141    asset_server: Res<AssetServer>,
142    shadow: Res<ShadowSettings>,
143    shape: Res<ShapeSettings>,
144) {
145    commands.spawn((Camera2d, BoxShadowSamples(shadow.samples)));
146    // Spawn shape node
147    commands
148        .spawn((
149            Node {
150                width: percent(100),
151                height: percent(100),
152                align_items: AlignItems::Center,
153                justify_content: JustifyContent::Center,
154                ..default()
155            },
156            BackgroundColor(GRAY.into()),
157        ))
158        .insert(children![{
159            let mut node = Node {
160                width: px(164),
161                height: px(164),
162                border: UiRect::all(px(1)),
163                align_items: AlignItems::Center,
164                justify_content: JustifyContent::Center,
165                border_radius: BorderRadius::ZERO,
166                ..default()
167            };
168            SHAPES[shape.index % SHAPES.len()].1(&mut node);
169
170            (
171                node,
172                BorderColor::all(WHITE),
173                BackgroundColor(Color::srgb(0.21, 0.21, 0.21)),
174                BoxShadow(vec![ShadowStyle {
175                    color: Color::BLACK.with_alpha(0.8),
176                    x_offset: px(shadow.x_offset),
177                    y_offset: px(shadow.y_offset),
178                    spread_radius: px(shadow.spread),
179                    blur_radius: px(shadow.blur),
180                }]),
181                ShadowNode,
182            )
183        }]);
184
185    // Settings Panel
186    commands
187        .spawn((
188            Node {
189                flex_direction: FlexDirection::Column,
190                position_type: PositionType::Absolute,
191                left: px(24),
192                bottom: px(24),
193                width: px(270),
194                padding: UiRect::all(px(16)),
195                border_radius: BorderRadius::all(px(12)),
196                ..default()
197            },
198            BackgroundColor(Color::srgb(0.12, 0.12, 0.12).with_alpha(0.85)),
199            BorderColor::all(Color::WHITE.with_alpha(0.15)),
200            ZIndex(10),
201        ))
202        .insert(children![
203            build_setting_row(
204                SettingType::Shape,
205                SettingsButton::ShapePrev,
206                SettingsButton::ShapeNext,
207                shape.index as f32,
208                &asset_server,
209            ),
210            build_setting_row(
211                SettingType::XOffset,
212                SettingsButton::XOffsetDec,
213                SettingsButton::XOffsetInc,
214                shadow.x_offset,
215                &asset_server,
216            ),
217            build_setting_row(
218                SettingType::YOffset,
219                SettingsButton::YOffsetDec,
220                SettingsButton::YOffsetInc,
221                shadow.y_offset,
222                &asset_server,
223            ),
224            build_setting_row(
225                SettingType::Blur,
226                SettingsButton::BlurDec,
227                SettingsButton::BlurInc,
228                shadow.blur,
229                &asset_server,
230            ),
231            build_setting_row(
232                SettingType::Spread,
233                SettingsButton::SpreadDec,
234                SettingsButton::SpreadInc,
235                shadow.spread,
236                &asset_server,
237            ),
238            build_setting_row(
239                SettingType::Count,
240                SettingsButton::CountDec,
241                SettingsButton::CountInc,
242                shadow.count as f32,
243                &asset_server,
244            ),
245            // Add BoxShadowSamples as a setting row
246            build_setting_row(
247                SettingType::Samples,
248                SettingsButton::SamplesDec,
249                SettingsButton::SamplesInc,
250                shadow.samples as f32,
251                &asset_server,
252            ),
253            // Reset button
254            (
255                Node {
256                    flex_direction: FlexDirection::Row,
257                    align_items: AlignItems::Center,
258                    height: px(36),
259                    margin: UiRect::top(px(12)),
260                    ..default()
261                },
262                children![(
263                    Button,
264                    Node {
265                        width: px(90),
266                        height: px(32),
267                        justify_content: JustifyContent::Center,
268                        align_items: AlignItems::Center,
269                        border_radius: BorderRadius::all(px(8)),
270                        ..default()
271                    },
272                    BackgroundColor(NORMAL_BUTTON),
273                    SettingsButton::Reset,
274                    children![(
275                        Text::new("Reset"),
276                        TextFont {
277                            font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
278                            font_size: FontSize::Px(16.0),
279                            ..default()
280                        },
281                    )],
282                )],
283            ),
284        ]);
285}
examples/ui/styling/borders.rs (line 42)
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}
Source

pub const fn bottom(bottom: Val) -> UiRect

Creates a new UiRect where bottom takes the given value, and the other fields are set to Val::ZERO.

§Example
let ui_rect = UiRect::bottom(Val::Px(10.0));

assert_eq!(ui_rect.left, Val::ZERO);
assert_eq!(ui_rect.right, Val::ZERO);
assert_eq!(ui_rect.top, Val::ZERO);
assert_eq!(ui_rect.bottom, Val::Px(10.0));
Examples found in repository?
examples/animation/animation_graph.rs (line 355)
346fn setup_node_lines(commands: &mut Commands) {
347    for line in &HORIZONTAL_LINES {
348        commands.spawn((
349            Node {
350                position_type: PositionType::Absolute,
351                bottom: px(line.bottom),
352                left: px(line.left),
353                height: px(0),
354                width: px(line.length),
355                border: UiRect::bottom(px(1)),
356                ..default()
357            },
358            BorderColor::all(WHITE),
359        ));
360    }
361
362    for line in &VERTICAL_LINES {
363        commands.spawn((
364            Node {
365                position_type: PositionType::Absolute,
366                bottom: px(line.bottom),
367                left: px(line.left),
368                height: px(line.length),
369                width: px(0),
370                border: UiRect::left(px(1)),
371                ..default()
372            },
373            BorderColor::all(WHITE),
374        ));
375    }
376}
More examples
Hide additional examples
examples/ui/relative_cursor_position.rs (line 42)
13fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
14    commands.spawn((
15        Camera2d,
16        Camera {
17            // Cursor position will take the viewport offset into account
18            viewport: Some(Viewport {
19                physical_position: [200, 100].into(),
20                physical_size: [600, 600].into(),
21                ..default()
22            }),
23            ..default()
24        },
25    ));
26
27    commands
28        .spawn(Node {
29            width: percent(100),
30            height: percent(100),
31            align_items: AlignItems::Center,
32            justify_content: JustifyContent::Center,
33            flex_direction: FlexDirection::Column,
34            ..default()
35        })
36        .with_children(|parent| {
37            parent
38                .spawn((
39                    Node {
40                        width: px(250),
41                        height: px(250),
42                        margin: UiRect::bottom(px(15)),
43                        ..default()
44                    },
45                    BackgroundColor(Color::srgb(0.92, 0.14, 0.05)),
46                ))
47                .insert(RelativeCursorPosition::default());
48
49            parent.spawn((
50                Text::new("(0.0, 0.0)"),
51                TextFont {
52                    font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
53                    font_size: FontSize::Px(33.0),
54                    ..default()
55                },
56                TextColor(Color::srgb(0.9, 0.9, 0.9)),
57            ));
58        });
59}
examples/testbed/ui.rs (line 1756)
1731    pub fn setup(mut commands: Commands) {
1732        let radius = percent(33.);
1733        let width = px(10.);
1734
1735        commands.spawn((Camera2d, DespawnOnExit(super::Scene::OuterColor)));
1736        commands
1737            .spawn((
1738                Node {
1739                    display: Display::Grid,
1740                    grid_template_columns: RepeatedGridTrack::px(3, 200.),
1741                    grid_template_rows: RepeatedGridTrack::px(3, 200.),
1742                    margin: UiRect::AUTO,
1743                    ..default()
1744                },
1745                DespawnOnExit(super::Scene::OuterColor),
1746            ))
1747            .with_children(|builder| {
1748                for (border, border_radius, invert) in [
1749                    (UiRect::ZERO, BorderRadius::bottom_right(radius), true),
1750                    (UiRect::top(width), BorderRadius::top(radius), false),
1751                    (UiRect::ZERO, BorderRadius::bottom_left(radius), true),
1752                    (UiRect::left(width), BorderRadius::left(radius), false),
1753                    (UiRect::all(width), BorderRadius::all(radius), true),
1754                    (UiRect::right(width), BorderRadius::right(radius), false),
1755                    (UiRect::ZERO, BorderRadius::top_right(radius), true),
1756                    (UiRect::bottom(width), BorderRadius::bottom(radius), false),
1757                    (UiRect::ZERO, BorderRadius::top_left(radius), true),
1758                ] {
1759                    builder
1760                        .spawn((
1761                            Node {
1762                                width: px(200.),
1763                                height: px(200.),
1764                                border_radius,
1765                                border,
1766                                ..default()
1767                            },
1768                            BorderColor::all(bevy::color::palettes::css::RED),
1769                        ))
1770                        .insert_if(BackgroundColor(Color::WHITE), || !invert)
1771                        .insert_if(OuterColor(Color::WHITE), || invert);
1772                }
1773            });
1774    }
examples/ui/layout/size_constraints.rs (line 78)
41fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
42    // ui camera
43    commands.spawn(Camera2d);
44
45    let text_font = (
46        TextFont {
47            font: asset_server.load("fonts/FiraSans-Bold.ttf").into(),
48            font_size: FontSize::Px(33.0),
49            ..Default::default()
50        },
51        TextColor(Color::srgb(0.9, 0.9, 0.9)),
52    );
53
54    commands
55        .spawn((
56            Node {
57                width: percent(100),
58                height: percent(100),
59                justify_content: JustifyContent::Center,
60                align_items: AlignItems::Center,
61                ..default()
62            },
63            BackgroundColor(Color::BLACK),
64        ))
65        .with_children(|parent| {
66            parent
67                .spawn(Node {
68                    flex_direction: FlexDirection::Column,
69                    align_items: AlignItems::Center,
70                    justify_content: JustifyContent::Center,
71                    ..default()
72                })
73                .with_children(|parent| {
74                    parent.spawn((
75                        Text::new("Size Constraints Example"),
76                        text_font.clone(),
77                        Node {
78                            margin: UiRect::bottom(px(25)),
79                            ..Default::default()
80                        },
81                    ));
82
83                    spawn_bar(parent);
84
85                    parent
86                        .spawn((
87                            Node {
88                                flex_direction: FlexDirection::Column,
89                                align_items: AlignItems::Stretch,
90                                padding: UiRect::all(px(10)),
91                                margin: UiRect::top(px(50)),
92                                ..default()
93                            },
94                            BackgroundColor(YELLOW.into()),
95                        ))
96                        .with_children(|parent| {
97                            for constraint in [
98                                Constraint::MinWidth,
99                                Constraint::FlexBasis,
100                                Constraint::Width,
101                                Constraint::MaxWidth,
102                            ] {
103                                spawn_button_row(parent, constraint, text_font.clone());
104                            }
105                        });
106                });
107        });
108}
examples/ui/text/generic_font_families.rs (line 51)
33fn setup(mut commands: Commands, mut font_system: ResMut<FontCx>) {
34    // UI camera
35    commands.spawn(Camera2d);
36
37    commands
38        .spawn((Node {
39            display: Display::Grid,
40            grid_template_columns: vec![RepeatedGridTrack::fr(3, 1.)],
41            margin: UiRect::AUTO,
42            row_gap: px(25),
43            column_gap: px(15),
44            ..Default::default()
45        },))
46        .with_children(|builder| {
47            builder.spawn((
48                Node {
49                    justify_self: JustifySelf::Center,
50                    grid_column: GridPlacement::span(3),
51                    margin: UiRect::bottom(px(15)),
52                    ..default()
53                },
54                Text::new("Generic Font Families"),
55                TextFont::from_font_size(FONT_SIZE),
56                Underline,
57            ));
58
59            let outline = Outline {
60                color: ZINC_600.into(),
61                width: px(2.),
62                offset: px(4.),
63            };
64
65            for (source, description) in [
66                (FontSource::SansSerif, "generic sans serif font"),
67                (FontSource::Serif, "generic serif font"),
68                (FontSource::Fantasy, "generic fantasy font"),
69                (FontSource::Cursive, "generic cursive font"),
70                (FontSource::Monospace, "generic monospace font"),
71            ] {
72                builder.spawn((
73                    Text::new(description),
74                    TextFont::from(source.clone()).with_font_size(FONT_SIZE),
75                    TextColor(WHEAT.into()),
76                    TextLayout::new_with_justify(Justify::Center),
77                    outline,
78                ));
79
80                builder.spawn((
81                    Text::new(format!("FontSource::{source:?}")),
82                    TextFont::from_font_size(FONT_SIZE),
83                    TextColor(YELLOW.into()),
84                    TextLayout::new_with_justify(Justify::Center),
85                    outline,
86                ));
87
88                // Get the family name for the `FontSource` from `FontCx`.
89                // `get_family` only returns `None` for `FontSource::Handle`.
90                let family_name = font_system.get_family(&source).unwrap();
91                builder.spawn((
92                    Text::new(family_name),
93                    TextFont::from_font_size(FONT_SIZE),
94                    TextLayout::new_with_justify(Justify::Center),
95                    outline,
96                ));
97            }
98        });
99}
examples/ui/scroll_and_overflow/overflow.rs (line 51)
13fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
14    commands.spawn(Camera2d);
15
16    let text_style = TextFont::default();
17
18    let image = asset_server.load("branding/icon.png");
19
20    commands
21        .spawn((
22            Node {
23                width: percent(100),
24                height: percent(100),
25                align_items: AlignItems::Center,
26                justify_content: JustifyContent::Center,
27                ..Default::default()
28            },
29            BackgroundColor(ANTIQUE_WHITE.into()),
30        ))
31        .with_children(|parent| {
32            for overflow in [
33                Overflow::visible(),
34                Overflow::clip_x(),
35                Overflow::clip_y(),
36                Overflow::clip(),
37            ] {
38                parent
39                    .spawn(Node {
40                        flex_direction: FlexDirection::Column,
41                        align_items: AlignItems::Center,
42                        margin: UiRect::horizontal(px(25)),
43                        ..Default::default()
44                    })
45                    .with_children(|parent| {
46                        let label = format!("{overflow:#?}");
47                        parent
48                            .spawn((
49                                Node {
50                                    padding: UiRect::all(px(10)),
51                                    margin: UiRect::bottom(px(25)),
52                                    ..Default::default()
53                                },
54                                BackgroundColor(Color::srgb(0.25, 0.25, 0.25)),
55                            ))
56                            .with_children(|parent| {
57                                parent.spawn((Text::new(label), text_style.clone()));
58                            });
59                        parent
60                            .spawn((
61                                Node {
62                                    width: px(100),
63                                    height: px(100),
64                                    padding: UiRect {
65                                        left: px(25),
66                                        top: px(25),
67                                        ..Default::default()
68                                    },
69                                    border: UiRect::all(px(5)),
70                                    overflow,
71                                    ..default()
72                                },
73                                BorderColor::all(Color::BLACK),
74                                BackgroundColor(GRAY.into()),
75                            ))
76                            .with_children(|parent| {
77                                parent.spawn((
78                                    ImageNode::new(image.clone()),
79                                    Node {
80                                        min_width: px(100),
81                                        min_height: px(100),
82                                        ..default()
83                                    },
84                                    Interaction::default(),
85                                    Outline {
86                                        width: px(2),
87                                        offset: px(2),
88                                        color: Color::NONE,
89                                    },
90                                ));
91                            });
92                    });
93            }
94        });
95}
Source

pub const fn with_left(self, left: Val) -> UiRect

Returns the UiRect with its left field set to the given value.

§Example
let ui_rect = UiRect::all(Val::Px(20.0)).with_left(Val::Px(10.0));
assert_eq!(ui_rect.left, Val::Px(10.0));
assert_eq!(ui_rect.right, Val::Px(20.0));
assert_eq!(ui_rect.top, Val::Px(20.0));
assert_eq!(ui_rect.bottom, Val::Px(20.0));
Examples found in repository?
examples/3d/ssr.rs (line 572)
553fn range_controls(
554    value: f32,
555    marker: RangeValueText,
556    dec_setting: ExampleSetting,
557    inc_setting: ExampleSetting,
558) -> impl Bundle {
559    (
560        Node {
561            align_items: AlignItems::Center,
562            ..default()
563        },
564        Children::spawn((
565            Spawn(adjustment_button(dec_setting, "<", Some(true))),
566            Spawn((
567                Node {
568                    width: px(50),
569                    height: px(33),
570                    justify_content: JustifyContent::Center,
571                    align_items: AlignItems::Center,
572                    border: BUTTON_BORDER.with_left(px(0)).with_right(px(0)),
573                    ..default()
574                },
575                BackgroundColor(Color::WHITE),
576                BUTTON_BORDER_COLOR,
577                marker,
578                children![(widgets::ui_text(&format!("{:.2}", value), Color::BLACK))],
579            )),
580            Spawn(adjustment_button(inc_setting, ">", Some(false))),
581        )),
582    )
583}
584
585fn adjustment_button(
586    setting: ExampleSetting,
587    label: &str,
588    is_left_right: Option<bool>,
589) -> impl Bundle {
590    (
591        Button,
592        Node {
593            height: px(33),
594            border: if let Some(is_left) = is_left_right {
595                if is_left {
596                    BUTTON_BORDER.with_right(px(0))
597                } else {
598                    BUTTON_BORDER.with_left(px(0))
599                }
600            } else {
601                BUTTON_BORDER
602            },
603            justify_content: JustifyContent::Center,
604            align_items: AlignItems::Center,
605            padding: BUTTON_PADDING,
606            border_radius: match is_left_right {
607                Some(true) => BorderRadius::ZERO.with_left(BUTTON_BORDER_RADIUS_SIZE),
608                Some(false) => BorderRadius::ZERO.with_right(BUTTON_BORDER_RADIUS_SIZE),
609                None => BorderRadius::all(BUTTON_BORDER_RADIUS_SIZE),
610            },
611            ..default()
612        },
613        BUTTON_BORDER_COLOR,
614        BackgroundColor(Color::BLACK),
615        RadioButton,
616        WidgetClickSender(setting),
617        children![(widgets::ui_text(label, Color::WHITE), RadioButtonText)],
618    )
619}
More examples
Hide additional examples
examples/3d/../helpers/widgets.rs (line 82)
62pub fn option_button<T>(
63    option_value: T,
64    option_name: &str,
65    is_selected: bool,
66    is_first: bool,
67    is_last: bool,
68) -> impl Bundle
69where
70    T: Clone + Send + Sync + 'static,
71{
72    let (bg_color, fg_color) = if is_selected {
73        (Color::WHITE, Color::BLACK)
74    } else {
75        (Color::BLACK, Color::WHITE)
76    };
77
78    // Add the button node.
79    (
80        Button,
81        Node {
82            border: BUTTON_BORDER.with_left(if is_first { px(1) } else { px(0) }),
83            justify_content: JustifyContent::Center,
84            align_items: AlignItems::Center,
85            padding: BUTTON_PADDING,
86            border_radius: BorderRadius::ZERO
87                .with_left(if is_first {
88                    BUTTON_BORDER_RADIUS_SIZE
89                } else {
90                    px(0)
91                })
92                .with_right(if is_last {
93                    BUTTON_BORDER_RADIUS_SIZE
94                } else {
95                    px(0)
96                }),
97            ..default()
98        },
99        BUTTON_BORDER_COLOR,
100        BackgroundColor(bg_color),
101        RadioButton,
102        WidgetClickSender(option_value.clone()),
103        children![(
104            ui_text(option_name, fg_color),
105            RadioButtonText,
106            WidgetClickSender(option_value),
107        )],
108    )
109}
examples/testbed/ui.rs (line 1924)
1781    pub fn setup(mut commands: Commands) {
1782        commands.spawn((Camera2d, DespawnOnExit(super::Scene::BoxedContent)));
1783        commands
1784            .spawn((
1785                Node {
1786                    margin: auto().all(),
1787                    column_gap: px(30),
1788                    ..default()
1789                },
1790                DespawnOnExit(super::Scene::BoxedContent),
1791            ))
1792            .with_children(|builder| {
1793                for (heading, text_justify) in [
1794                    ("Left", Justify::Left),
1795                    ("Center", Justify::Center),
1796                    ("Right", Justify::Right),
1797                ] {
1798                    builder
1799                        .spawn(Node {
1800                            flex_direction: FlexDirection::Column,
1801                            align_items: AlignItems::Center,
1802                            justify_content: JustifyContent::Start,
1803                            row_gap: px(20),
1804                            ..default()
1805                        })
1806                        .with_children(|builder| {
1807                            builder.spawn((
1808                                Node::default(),
1809                                Text::new(format!("{heading} justify")),
1810                                TextFont::from_font_size(FontSize::Px(14.)),
1811                                TextLayout::new_with_justify(Justify::Center),
1812                            ));
1813
1814                            builder.spawn((
1815                                Node::default(),
1816                                Text::new("This text has\nno border or padding."),
1817                                TextFont::from_font_size(FontSize::Px(10.)),
1818                                TextLayout::new_with_justify(text_justify),
1819                                Outline {
1820                                    width: px(2),
1821                                    color: Color::WHITE,
1822                                    ..Default::default()
1823                                },
1824                            ));
1825
1826                            builder.spawn((
1827                                Node {
1828                                    border: px(10).all(),
1829                                    ..default()
1830                                },
1831                                Text::new("This text has\na border but no padding."),
1832                                TextFont::from_font_size(FontSize::Px(10.)),
1833                                TextLayout::new_with_justify(text_justify),
1834                                BorderColor::all(RED),
1835                                Outline {
1836                                    width: px(2),
1837                                    color: Color::WHITE,
1838                                    ..Default::default()
1839                                },
1840                            ));
1841
1842                            builder.spawn((
1843                                Node {
1844                                    padding: px(20).all(),
1845                                    ..default()
1846                                },
1847                                Text::new("This text has\npadding but no border."),
1848                                TextFont::from_font_size(FontSize::Px(10.)),
1849                                TextLayout::new_with_justify(text_justify),
1850                                Outline {
1851                                    width: px(2),
1852                                    color: Color::WHITE,
1853                                    ..Default::default()
1854                                },
1855                            ));
1856
1857                            builder.spawn((
1858                                Node {
1859                                    border: px(10).all(),
1860                                    padding: px(20).all(),
1861                                    ..default()
1862                                },
1863                                Text::new("This text has\nborder and padding."),
1864                                TextFont::from_font_size(FontSize::Px(10.)),
1865                                TextLayout::new_with_justify(text_justify),
1866                                BorderColor::all(RED),
1867                                Outline {
1868                                    width: px(2),
1869                                    color: Color::WHITE,
1870                                    ..Default::default()
1871                                },
1872                            ));
1873
1874                            builder.spawn((
1875                                Node {
1876                                    border: px(10).left(),
1877                                    ..default()
1878                                },
1879                                Text::new("This text has\na left border and no padding."),
1880                                TextFont::from_font_size(FontSize::Px(10.)),
1881                                TextLayout::new_with_justify(text_justify),
1882                                BorderColor::all(RED),
1883                                Outline {
1884                                    width: px(2),
1885                                    color: Color::WHITE,
1886                                    ..Default::default()
1887                                },
1888                            ));
1889
1890                            builder.spawn((
1891                                Node {
1892                                    border: px(10).right(),
1893                                    ..default()
1894                                },
1895                                Text::new("This text has\na right border and no padding."),
1896                                TextFont::from_font_size(FontSize::Px(10.)),
1897                                TextLayout::new_with_justify(text_justify),
1898                                BorderColor::all(RED),
1899                                Outline {
1900                                    width: px(2),
1901                                    color: Color::WHITE,
1902                                    ..Default::default()
1903                                },
1904                            ));
1905
1906                            builder.spawn((
1907                                Node {
1908                                    padding: px(20).top().with_right(px(20)),
1909                                    ..default()
1910                                },
1911                                Text::new("This text has\npadding on its top and right."),
1912                                TextFont::from_font_size(FontSize::Px(10.)),
1913                                TextLayout::new_with_justify(text_justify),
1914                                BorderColor::all(RED),
1915                                Outline {
1916                                    width: px(2),
1917                                    color: Color::WHITE,
1918                                    ..Default::default()
1919                                },
1920                            ));
1921
1922                            builder.spawn((
1923                                Node {
1924                                    padding: px(20).bottom().with_left(px(20)),
1925                                    ..default()
1926                                },
1927                                Text::new("This text has\npadding on its bottom and left."),
1928                                TextFont::from_font_size(FontSize::Px(10.)),
1929                                TextLayout::new_with_justify(text_justify),
1930                                BorderColor::all(RED),
1931                                Outline {
1932                                    width: px(2),
1933                                    color: Color::WHITE,
1934                                    ..Default::default()
1935                                },
1936                            ));
1937
1938                            builder.spawn((
1939                                Node {
1940                                    padding: px(20).top().with_left(px(20)),
1941                                    border: px(10).bottom().with_right(px(10)),
1942                                    ..default()
1943                                },
1944                                Text::new(
1945                                    "This text has\npadding on its top and left\nand a border on its bottom and right.",
1946                                ),
1947                                TextFont::from_font_size(FontSize::Px(10.)),
1948                                TextLayout::new_with_justify(text_justify),
1949                                BorderColor::all(RED),
1950                                Outline {
1951                                    width: px(2),
1952                                    color: Color::WHITE,
1953                                    ..Default::default()
1954                                },
1955                            ));
1956                        });
1957                }
1958            });
1959    }
Source

pub const fn with_right(self, right: Val) -> UiRect

Returns the UiRect with its right field set to the given value.

§Example
let ui_rect = UiRect::all(Val::Px(20.0)).with_right(Val::Px(10.0));
assert_eq!(ui_rect.left, Val::Px(20.0));
assert_eq!(ui_rect.right, Val::Px(10.0));
assert_eq!(ui_rect.top, Val::Px(20.0));
assert_eq!(ui_rect.bottom, Val::Px(20.0));
Examples found in repository?
examples/3d/ssr.rs (line 572)
553fn range_controls(
554    value: f32,
555    marker: RangeValueText,
556    dec_setting: ExampleSetting,
557    inc_setting: ExampleSetting,
558) -> impl Bundle {
559    (
560        Node {
561            align_items: AlignItems::Center,
562            ..default()
563        },
564        Children::spawn((
565            Spawn(adjustment_button(dec_setting, "<", Some(true))),
566            Spawn((
567                Node {
568                    width: px(50),
569                    height: px(33),
570                    justify_content: JustifyContent::Center,
571                    align_items: AlignItems::Center,
572                    border: BUTTON_BORDER.with_left(px(0)).with_right(px(0)),
573                    ..default()
574                },
575                BackgroundColor(Color::WHITE),
576                BUTTON_BORDER_COLOR,
577                marker,
578                children![(widgets::ui_text(&format!("{:.2}", value), Color::BLACK))],
579            )),
580            Spawn(adjustment_button(inc_setting, ">", Some(false))),
581        )),
582    )
583}
584
585fn adjustment_button(
586    setting: ExampleSetting,
587    label: &str,
588    is_left_right: Option<bool>,
589) -> impl Bundle {
590    (
591        Button,
592        Node {
593            height: px(33),
594            border: if let Some(is_left) = is_left_right {
595                if is_left {
596                    BUTTON_BORDER.with_right(px(0))
597                } else {
598                    BUTTON_BORDER.with_left(px(0))
599                }
600            } else {
601                BUTTON_BORDER
602            },
603            justify_content: JustifyContent::Center,
604            align_items: AlignItems::Center,
605            padding: BUTTON_PADDING,
606            border_radius: match is_left_right {
607                Some(true) => BorderRadius::ZERO.with_left(BUTTON_BORDER_RADIUS_SIZE),
608                Some(false) => BorderRadius::ZERO.with_right(BUTTON_BORDER_RADIUS_SIZE),
609                None => BorderRadius::all(BUTTON_BORDER_RADIUS_SIZE),
610            },
611            ..default()
612        },
613        BUTTON_BORDER_COLOR,
614        BackgroundColor(Color::BLACK),
615        RadioButton,
616        WidgetClickSender(setting),
617        children![(widgets::ui_text(label, Color::WHITE), RadioButtonText)],
618    )
619}
More examples
Hide additional examples
examples/testbed/ui.rs (line 1908)
1781    pub fn setup(mut commands: Commands) {
1782        commands.spawn((Camera2d, DespawnOnExit(super::Scene::BoxedContent)));
1783        commands
1784            .spawn((
1785                Node {
1786                    margin: auto().all(),
1787                    column_gap: px(30),
1788                    ..default()
1789                },
1790                DespawnOnExit(super::Scene::BoxedContent),
1791            ))
1792            .with_children(|builder| {
1793                for (heading, text_justify) in [
1794                    ("Left", Justify::Left),
1795                    ("Center", Justify::Center),
1796                    ("Right", Justify::Right),
1797                ] {
1798                    builder
1799                        .spawn(Node {
1800                            flex_direction: FlexDirection::Column,
1801                            align_items: AlignItems::Center,
1802                            justify_content: JustifyContent::Start,
1803                            row_gap: px(20),
1804                            ..default()
1805                        })
1806                        .with_children(|builder| {
1807                            builder.spawn((
1808                                Node::default(),
1809                                Text::new(format!("{heading} justify")),
1810                                TextFont::from_font_size(FontSize::Px(14.)),
1811                                TextLayout::new_with_justify(Justify::Center),
1812                            ));
1813
1814                            builder.spawn((
1815                                Node::default(),
1816                                Text::new("This text has\nno border or padding."),
1817                                TextFont::from_font_size(FontSize::Px(10.)),
1818                                TextLayout::new_with_justify(text_justify),
1819                                Outline {
1820                                    width: px(2),
1821                                    color: Color::WHITE,
1822                                    ..Default::default()
1823                                },
1824                            ));
1825
1826                            builder.spawn((
1827                                Node {
1828                                    border: px(10).all(),
1829                                    ..default()
1830                                },
1831                                Text::new("This text has\na border but no padding."),
1832                                TextFont::from_font_size(FontSize::Px(10.)),
1833                                TextLayout::new_with_justify(text_justify),
1834                                BorderColor::all(RED),
1835                                Outline {
1836                                    width: px(2),
1837                                    color: Color::WHITE,
1838                                    ..Default::default()
1839                                },
1840                            ));
1841
1842                            builder.spawn((
1843                                Node {
1844                                    padding: px(20).all(),
1845                                    ..default()
1846                                },
1847                                Text::new("This text has\npadding but no border."),
1848                                TextFont::from_font_size(FontSize::Px(10.)),
1849                                TextLayout::new_with_justify(text_justify),
1850                                Outline {
1851                                    width: px(2),
1852                                    color: Color::WHITE,
1853                                    ..Default::default()
1854                                },
1855                            ));
1856
1857                            builder.spawn((
1858                                Node {
1859                                    border: px(10).all(),
1860                                    padding: px(20).all(),
1861                                    ..default()
1862                                },
1863                                Text::new("This text has\nborder and padding."),
1864                                TextFont::from_font_size(FontSize::Px(10.)),
1865                                TextLayout::new_with_justify(text_justify),
1866                                BorderColor::all(RED),
1867                                Outline {
1868                                    width: px(2),
1869                                    color: Color::WHITE,
1870                                    ..Default::default()
1871                                },
1872                            ));
1873
1874                            builder.spawn((
1875                                Node {
1876                                    border: px(10).left(),
1877                                    ..default()
1878                                },
1879                                Text::new("This text has\na left border and no padding."),
1880                                TextFont::from_font_size(FontSize::Px(10.)),
1881                                TextLayout::new_with_justify(text_justify),
1882                                BorderColor::all(RED),
1883                                Outline {
1884                                    width: px(2),
1885                                    color: Color::WHITE,
1886                                    ..Default::default()
1887                                },
1888                            ));
1889
1890                            builder.spawn((
1891                                Node {
1892                                    border: px(10).right(),
1893                                    ..default()
1894                                },
1895                                Text::new("This text has\na right border and no padding."),
1896                                TextFont::from_font_size(FontSize::Px(10.)),
1897                                TextLayout::new_with_justify(text_justify),
1898                                BorderColor::all(RED),
1899                                Outline {
1900                                    width: px(2),
1901                                    color: Color::WHITE,
1902                                    ..Default::default()
1903                                },
1904                            ));
1905
1906                            builder.spawn((
1907                                Node {
1908                                    padding: px(20).top().with_right(px(20)),
1909                                    ..default()
1910                                },
1911                                Text::new("This text has\npadding on its top and right."),
1912                                TextFont::from_font_size(FontSize::Px(10.)),
1913                                TextLayout::new_with_justify(text_justify),
1914                                BorderColor::all(RED),
1915                                Outline {
1916                                    width: px(2),
1917                                    color: Color::WHITE,
1918                                    ..Default::default()
1919                                },
1920                            ));
1921
1922                            builder.spawn((
1923                                Node {
1924                                    padding: px(20).bottom().with_left(px(20)),
1925                                    ..default()
1926                                },
1927                                Text::new("This text has\npadding on its bottom and left."),
1928                                TextFont::from_font_size(FontSize::Px(10.)),
1929                                TextLayout::new_with_justify(text_justify),
1930                                BorderColor::all(RED),
1931                                Outline {
1932                                    width: px(2),
1933                                    color: Color::WHITE,
1934                                    ..Default::default()
1935                                },
1936                            ));
1937
1938                            builder.spawn((
1939                                Node {
1940                                    padding: px(20).top().with_left(px(20)),
1941                                    border: px(10).bottom().with_right(px(10)),
1942                                    ..default()
1943                                },
1944                                Text::new(
1945                                    "This text has\npadding on its top and left\nand a border on its bottom and right.",
1946                                ),
1947                                TextFont::from_font_size(FontSize::Px(10.)),
1948                                TextLayout::new_with_justify(text_justify),
1949                                BorderColor::all(RED),
1950                                Outline {
1951                                    width: px(2),
1952                                    color: Color::WHITE,
1953                                    ..Default::default()
1954                                },
1955                            ));
1956                        });
1957                }
1958            });
1959    }
Source

pub const fn with_top(self, top: Val) -> UiRect

Returns the UiRect with its top field set to the given value.

§Example
let ui_rect = UiRect::all(Val::Px(20.0)).with_top(Val::Px(10.0));
assert_eq!(ui_rect.left, Val::Px(20.0));
assert_eq!(ui_rect.right, Val::Px(20.0));
assert_eq!(ui_rect.top, Val::Px(10.0));
assert_eq!(ui_rect.bottom, Val::Px(20.0));
Source

pub const fn with_bottom(self, bottom: Val) -> UiRect

Returns the UiRect with its bottom field set to the given value.

§Example
let ui_rect = UiRect::all(Val::Px(20.0)).with_bottom(Val::Px(10.0));
assert_eq!(ui_rect.left, Val::Px(20.0));
assert_eq!(ui_rect.right, Val::Px(20.0));
assert_eq!(ui_rect.top, Val::Px(20.0));
assert_eq!(ui_rect.bottom, Val::Px(10.0));

Trait Implementations§

Source§

impl Clone for UiRect

Source§

fn clone(&self) -> UiRect

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for UiRect

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for UiRect

Source§

fn default() -> UiRect

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for UiRect

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<UiRect, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<Val> for UiRect

Source§

fn from(value: Val) -> UiRect

Converts to this type from the input type.
Source§

impl FromArg for UiRect

Source§

type This<'from_arg> = UiRect

The type to convert into. Read more
Source§

fn from_arg(arg: Arg<'_>) -> Result<<UiRect as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromReflect for UiRect

Source§

fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<UiRect>

Constructs a concrete instance of Self from a reflected value.
Source§

fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>

Attempts to downcast the given value to Self using, constructing the value using from_reflect if that fails. Read more
Source§

impl GetOwnership for UiRect

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetTypeRegistration for UiRect

Source§

fn get_type_registration() -> TypeRegistration

Returns the default TypeRegistration for this type.
Source§

fn register_type_dependencies(registry: &mut TypeRegistry)

Registers other types needed by this type. Read more
Source§

impl IntoReturn for UiRect

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where UiRect: 'into_return,

Converts Self into a Return value.
Source§

impl PartialEq for UiRect

Source§

fn eq(&self, other: &UiRect) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialReflect for UiRect

Source§

fn get_represented_type_info(&self) -> Option<&'static TypeInfo>

Returns the TypeInfo of the type represented by this value. Read more
Source§

fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>

Tries to apply a reflected value to this value. Read more
Source§

fn reflect_kind(&self) -> ReflectKind

Returns a zero-sized enumeration of “kinds” of type. Read more
Source§

fn reflect_ref(&self) -> ReflectRef<'_>

Returns an immutable enumeration of “kinds” of type. Read more
Source§

fn reflect_mut(&mut self) -> ReflectMut<'_>

Returns a mutable enumeration of “kinds” of type. Read more
Source§

fn reflect_owned(self: Box<UiRect>) -> ReflectOwned

Returns an owned enumeration of “kinds” of type. Read more
Source§

fn try_into_reflect( self: Box<UiRect>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>

Attempts to cast this type to a boxed, fully-reflected value.
Source§

fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>

Attempts to cast this type to a fully-reflected value.
Source§

fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>

Attempts to cast this type to a mutable, fully-reflected value.
Source§

fn into_partial_reflect(self: Box<UiRect>) -> Box<dyn PartialReflect>

Casts this type to a boxed, reflected value. Read more
Source§

fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)

Casts this type to a reflected value. Read more
Source§

fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)

Casts this type to a mutable, reflected value. Read more
Source§

fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>

Returns a “partial equality” comparison result. Read more
Source§

fn reflect_partial_cmp( &self, value: &(dyn PartialReflect + 'static), ) -> Option<Ordering>

Returns a “partial comparison” result. Read more
Source§

fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Debug formatter for the value. Read more
Source§

fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>

Attempts to clone Self using reflection. Read more
Source§

fn apply(&mut self, value: &(dyn PartialReflect + 'static))

Applies a reflected value to this value. Read more
Source§

fn to_dynamic(&self) -> Box<dyn PartialReflect>

Converts this reflected value into its dynamic representation based on its kind. Read more
Source§

fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
where T: 'static, Self: Sized + TypePath,

For a type implementing PartialReflect, combines reflect_clone and take in a useful fashion, automatically constructing an appropriate ReflectCloneError if the downcast fails.
Source§

fn reflect_hash(&self) -> Option<u64>

Returns a hash of the value (which includes the type). Read more
Source§

fn is_dynamic(&self) -> bool

Indicates whether or not this type is a dynamic type. Read more
Source§

impl Reflect for UiRect

Source§

fn into_any(self: Box<UiRect>) -> Box<dyn Any>

Returns the value as a Box<dyn Any>. Read more
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Returns the value as a &dyn Any. Read more
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Returns the value as a &mut dyn Any. Read more
Source§

fn into_reflect(self: Box<UiRect>) -> Box<dyn Reflect>

Casts this type to a boxed, fully-reflected value.
Source§

fn as_reflect(&self) -> &(dyn Reflect + 'static)

Casts this type to a fully-reflected value.
Source§

fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)

Casts this type to a mutable, fully-reflected value.
Source§

fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>

Performs a type-checked assignment of a reflected value to this value. Read more
Source§

impl Serialize for UiRect

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Struct for UiRect

Source§

fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>

Gets a reference to the value of the field named name as a &dyn PartialReflect.
Source§

fn field_mut( &mut self, name: &str, ) -> Option<&mut (dyn PartialReflect + 'static)>

Gets a mutable reference to the value of the field named name as a &mut dyn PartialReflect.
Source§

fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>

Gets a reference to the value of the field with index index as a &dyn PartialReflect.
Source§

fn field_at_mut( &mut self, index: usize, ) -> Option<&mut (dyn PartialReflect + 'static)>

Gets a mutable reference to the value of the field with index index as a &mut dyn PartialReflect.
Source§

fn name_at(&self, index: usize) -> Option<&str>

Gets the name of the field with index index.
Source§

fn index_of_name(&self, name: &str) -> Option<usize>

Gets the index of the field with the given name.
Source§

fn field_len(&self) -> usize

Returns the number of fields in the struct.
Source§

fn iter_fields(&self) -> FieldIter<'_>

Returns an iterator over the values of the reflectable fields for this struct.
Source§

fn to_dynamic_struct(&self) -> DynamicStruct

Creates a new DynamicStruct from this struct.
Source§

fn get_represented_struct_info(&self) -> Option<&'static StructInfo>

Will return None if TypeInfo is not available.
Source§

impl TypePath for UiRect

Source§

fn type_path() -> &'static str

Returns the fully qualified path of the underlying type. Read more
Source§

fn short_type_path() -> &'static str

Returns a short, pretty-print enabled path to the type. Read more
Source§

fn type_ident() -> Option<&'static str>

Returns the name of the type, or None if it is anonymous. Read more
Source§

fn crate_name() -> Option<&'static str>

Returns the name of the crate the type is in, or None if it is anonymous. Read more
Source§

fn module_path() -> Option<&'static str>

Returns the path to the module the type is in, or None if it is anonymous. Read more
Source§

impl Typed for UiRect

Source§

fn type_info() -> &'static TypeInfo

Returns the compile-time info for the underlying type.
Source§

impl Copy for UiRect

Source§

impl StructuralPartialEq for UiRect

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynamicTypePath for T
where T: TypePath,

Source§

impl<T> DynamicTyped for T
where T: Typed,

§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

Source§

impl<T> FromTemplate for T
where T: Clone + Default + Unpin,

Source§

type Template = T

The Template for this type.
Source§

impl<T> FromWorld for T
where T: Default,

Source§

fn from_world(_world: &mut World) -> T

Creates Self using default().

Source§

impl<S> GetField for S
where S: Struct,

Source§

fn get_field<T>(&self, name: &str) -> Option<&T>
where T: Reflect,

Gets a reference to the value of the field named name, downcast to T.
Source§

fn get_field_mut<T>(&mut self, name: &str) -> Option<&mut T>
where T: Reflect,

Gets a mutable reference to the value of the field named name, downcast to T.
Source§

impl<T> GetPath for T
where T: Reflect + ?Sized,

Source§

fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>

Returns a reference to the value specified by path. Read more
Source§

fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>

Returns a mutable reference to the value specified by path. Read more
Source§

fn path<'p, T>( &self, path: impl ReflectPath<'p>, ) -> Result<&T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed reference to the value specified by path. Read more
Source§

fn path_mut<'p, T>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed mutable reference to the value specified by path. Read more
§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

§

const WITNESS: W = W::MAKE

A constant of the type witness
§

impl<T> Identity for T
where T: ?Sized,

§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
§

impl<T> InitializeFromFunction<T> for T

§

fn initialize_from_function(f: fn() -> T) -> T

Create an instance of this type from an initialization function
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
§

impl<T> NoneValue for T
where T: Default,

§

type NoneType = T

§

fn null_value() -> T

The none-equivalent value.
Source§

impl<G> PatchFromTemplate for G
where G: FromTemplate,

Source§

type Template = <G as FromTemplate>::Template

The Template that will be patched.
Source§

fn patch<F>(func: F) -> TemplatePatch<F, <G as PatchFromTemplate>::Template>
where F: Fn(&mut <G as PatchFromTemplate>::Template, &mut ResolveContext<'_>),

Takes a “patch function” func, and turns it into a TemplatePatch.
Source§

impl<T> PatchTemplate for T
where T: Template,

Source§

fn patch_template<F>(func: F) -> TemplatePatch<F, T>
where F: Fn(&mut T, &mut ResolveContext<'_>),

Takes a “patch function” func that patches this Template, and turns it into a TemplatePatch.
§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Serialize for T
where T: Serialize + ?Sized,

Source§

fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>

Source§

fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>

§

impl<Ret> SpawnIfAsync<(), Ret> for Ret

§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

§

fn super_from(input: T) -> O

Convert from a type to another type.
§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

§

fn super_into(self) -> O

Convert from a type to another type.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> Template for T
where T: Clone + Default + Unpin,

Source§

type Output = T

The type of value produced by this Template.
Source§

fn build_template( &self, _context: &mut TemplateContext<'_, '_>, ) -> Result<<T as Template>::Output, BevyError>

Uses this template and the given entity context to produce a Template::Output.
Source§

fn clone_template(&self) -> T

Clones this template. See Clone.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
§

impl<T> Brush for T
where T: Clone + PartialEq + Default + Debug,

Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> Reflectable for T

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,