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: ValThe value corresponding to the left side of the UI rect.
right: ValThe value corresponding to the right side of the UI rect.
top: ValThe value corresponding to the top side of the UI rect.
bottom: ValThe value corresponding to the bottom side of the UI rect.
Implementations§
Source§impl UiRect
impl UiRect
pub const DEFAULT: UiRect
pub const ZERO: UiRect
pub const AUTO: UiRect
Sourcepub const fn new(left: Val, right: Val, top: Val, bottom: Val) -> UiRect
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));Sourcepub const fn all(value: Val) -> UiRect
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?
More examples
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}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}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}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 }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}- examples/ui/widgets/standard_widgets.rs
- examples/ui/widgets/standard_widgets_observers.rs
- examples/window/scale_factor_override.rs
- examples/window/window_drag_move.rs
- examples/3d/tonemapping.rs
- examples/ui/widgets/button.rs
- examples/ui/ui_material.rs
- tests/window/desktop_request_redraw.rs
- examples/remote/app_under_test.rs
- examples/3d/color_grading.rs
- examples/stress_tests/many_buttons.rs
- examples/ui/images/ui_texture_slice.rs
- examples/ui/widgets/viewport_node.rs
- examples/camera/2d_on_ui.rs
- examples/time/virtual_time.rs
- examples/testbed/ui.rs
- examples/ui/layout/size_constraints.rs
- examples/picking/dragdrop_picking.rs
- examples/ui/layout/anchor_layout.rs
- examples/showcase/stepping.rs
- examples/asset/asset_saving.rs
- examples/showcase/game_menu.rs
- examples/ui/scroll_and_overflow/overflow.rs
- examples/ui/scroll_and_overflow/overflow_clip_margin.rs
- examples/stress_tests/bevymark_3d.rs
- examples/stress_tests/bevymark.rs
- examples/animation/animation_masks.rs
- examples/3d/shadow_biases.rs
- examples/ui/widgets/tab_navigation.rs
- examples/ui/scroll_and_overflow/scroll.rs
- examples/ui/render_ui_to_texture.rs
- examples/ui/layout/display_and_visibility.rs
- examples/ui/navigation/directional_navigation.rs
- examples/ui/styling/box_shadow.rs
- examples/ui/text/text.rs
- examples/ui/styling/borders.rs
- examples/ui/navigation/directional_navigation_overrides.rs
- examples/ui/layout/grid.rs
- examples/ui/ui_transform.rs
- examples/ui/styling/gradients.rs
- examples/testbed/full_ui.rs
Sourcepub const fn px(left: f32, right: f32, top: f32, bottom: f32) -> UiRect
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.));Sourcepub const fn percent(left: f32, right: f32, top: f32, bottom: f32) -> UiRect
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.));Sourcepub const fn horizontal(value: Val) -> UiRect
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?
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
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}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}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}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}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}Sourcepub const fn vertical(value: Val) -> UiRect
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?
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
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 }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}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}Sourcepub const fn axes(horizontal: Val, vertical: Val) -> UiRect
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?
More examples
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}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}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}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}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}Sourcepub const fn left(left: Val) -> UiRect
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?
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
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 }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}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}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}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}Sourcepub const fn right(right: Val) -> UiRect
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?
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
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 }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}Sourcepub const fn top(top: Val) -> UiRect
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?
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
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}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}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}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}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}Sourcepub const fn bottom(bottom: Val) -> UiRect
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?
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
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}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 }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}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}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}Sourcepub const fn with_left(self, left: Val) -> UiRect
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?
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
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}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 }Sourcepub const fn with_right(self, right: Val) -> UiRect
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?
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
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 }Sourcepub const fn with_top(self, top: Val) -> UiRect
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));Sourcepub const fn with_bottom(self, bottom: Val) -> UiRect
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<'de> Deserialize<'de> for UiRect
impl<'de> Deserialize<'de> for UiRect
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<UiRect, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<UiRect, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl FromReflect for UiRect
impl FromReflect for UiRect
Source§fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<UiRect>
fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<UiRect>
Self from a reflected value.Source§fn take_from_reflect(
reflect: Box<dyn PartialReflect>,
) -> Result<Self, Box<dyn PartialReflect>>
fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>
Self using,
constructing the value using from_reflect if that fails. Read moreSource§impl GetTypeRegistration for UiRect
impl GetTypeRegistration for UiRect
Source§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration for this type.Source§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
Source§impl IntoReturn for UiRect
impl IntoReturn for UiRect
Source§impl PartialReflect for UiRect
impl PartialReflect for UiRect
Source§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
Source§fn try_apply(
&mut self,
value: &(dyn PartialReflect + 'static),
) -> Result<(), ApplyError>
fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>
Source§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
Source§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
Source§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
Source§fn reflect_owned(self: Box<UiRect>) -> ReflectOwned
fn reflect_owned(self: Box<UiRect>) -> ReflectOwned
Source§fn try_into_reflect(
self: Box<UiRect>,
) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
fn try_into_reflect( self: Box<UiRect>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
Source§fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
Source§fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
Source§fn into_partial_reflect(self: Box<UiRect>) -> Box<dyn PartialReflect>
fn into_partial_reflect(self: Box<UiRect>) -> Box<dyn PartialReflect>
Source§fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
Source§fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
Source§fn reflect_partial_eq(
&self,
value: &(dyn PartialReflect + 'static),
) -> Option<bool>
fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>
Source§fn reflect_partial_cmp(
&self,
value: &(dyn PartialReflect + 'static),
) -> Option<Ordering>
fn reflect_partial_cmp( &self, value: &(dyn PartialReflect + 'static), ) -> Option<Ordering>
Source§fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
Source§fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
Self using reflection. Read moreSource§fn apply(&mut self, value: &(dyn PartialReflect + 'static))
fn apply(&mut self, value: &(dyn PartialReflect + 'static))
Source§fn to_dynamic(&self) -> Box<dyn PartialReflect>
fn to_dynamic(&self) -> Box<dyn PartialReflect>
Source§fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
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>
fn reflect_hash(&self) -> Option<u64>
Source§fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
Source§impl Reflect for UiRect
impl Reflect for UiRect
Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut dyn Any. Read moreSource§fn into_reflect(self: Box<UiRect>) -> Box<dyn Reflect>
fn into_reflect(self: Box<UiRect>) -> Box<dyn Reflect>
Source§fn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
Source§fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
Source§impl Serialize for UiRect
impl Serialize for UiRect
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Source§impl Struct for UiRect
impl Struct for UiRect
Source§fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>
fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>
name as a &dyn PartialReflect.Source§fn field_mut(
&mut self,
name: &str,
) -> Option<&mut (dyn PartialReflect + 'static)>
fn field_mut( &mut self, name: &str, ) -> Option<&mut (dyn PartialReflect + 'static)>
name as a
&mut dyn PartialReflect.Source§fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>
fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>
index as a
&dyn PartialReflect.Source§fn field_at_mut(
&mut self,
index: usize,
) -> Option<&mut (dyn PartialReflect + 'static)>
fn field_at_mut( &mut self, index: usize, ) -> Option<&mut (dyn PartialReflect + 'static)>
index
as a &mut dyn PartialReflect.Source§fn index_of_name(&self, name: &str) -> Option<usize>
fn index_of_name(&self, name: &str) -> Option<usize>
Source§fn iter_fields(&self) -> FieldIter<'_> ⓘ
fn iter_fields(&self) -> FieldIter<'_> ⓘ
Source§fn to_dynamic_struct(&self) -> DynamicStruct
fn to_dynamic_struct(&self) -> DynamicStruct
DynamicStruct from this struct.Source§fn get_represented_struct_info(&self) -> Option<&'static StructInfo>
fn get_represented_struct_info(&self) -> Option<&'static StructInfo>
None if TypeInfo is not available.Source§impl TypePath for UiRect
impl TypePath for UiRect
Source§fn type_path() -> &'static str
fn type_path() -> &'static str
Source§fn short_type_path() -> &'static str
fn short_type_path() -> &'static str
Source§fn type_ident() -> Option<&'static str>
fn type_ident() -> Option<&'static str>
Source§fn crate_name() -> Option<&'static str>
fn crate_name() -> Option<&'static str>
impl Copy for UiRect
impl StructuralPartialEq for UiRect
Auto Trait Implementations§
impl Freeze for UiRect
impl RefUnwindSafe for UiRect
impl Send for UiRect
impl Sync for UiRect
impl Unpin for UiRect
impl UnsafeUnpin for UiRect
impl UnwindSafe for UiRect
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T ShaderType for self. When used in AsBindGroup
derives, it is safe to assume that all images in self exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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 Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
Source§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path.Source§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
Source§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident.Source§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name.Source§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
Source§impl<T> DynamicTyped for Twhere
T: Typed,
impl<T> DynamicTyped for Twhere
T: Typed,
Source§fn reflect_type_info(&self) -> &'static TypeInfo
fn reflect_type_info(&self) -> &'static TypeInfo
Typed::type_info.§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> FromTemplate for T
impl<T> FromTemplate for T
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
Source§impl<S> GetField for Swhere
S: Struct,
impl<S> GetField for Swhere
S: Struct,
Source§impl<T> GetPath for T
impl<T> GetPath for T
Source§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
path. Read moreSource§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
path. Read moreSource§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path. Read moreSource§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path. Read more§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> InitializeFromFunction<T> for T
impl<T> InitializeFromFunction<T> for T
§fn initialize_from_function(f: fn() -> T) -> T
fn initialize_from_function(f: fn() -> T) -> T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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 moreSource§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
Source§fn into_result(self) -> Result<T, RunSystemError>
fn into_result(self) -> Result<T, RunSystemError>
§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
§impl<T> NoneValue for Twhere
T: Default,
impl<T> NoneValue for Twhere
T: Default,
type NoneType = T
§fn null_value() -> T
fn null_value() -> T
Source§impl<G> PatchFromTemplate for Gwhere
G: FromTemplate,
impl<G> PatchFromTemplate for Gwhere
G: FromTemplate,
Source§fn patch<F>(func: F) -> TemplatePatch<F, <G as PatchFromTemplate>::Template>
fn patch<F>(func: F) -> TemplatePatch<F, <G as PatchFromTemplate>::Template>
func, and turns it into a TemplatePatch.Source§impl<T> PatchTemplate for Twhere
T: Template,
impl<T> PatchTemplate for Twhere
T: Template,
Source§fn patch_template<F>(func: F) -> TemplatePatch<F, T>
fn patch_template<F>(func: F) -> TemplatePatch<F, T>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
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) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
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
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().Source§impl<T> Serialize for T
impl<T> Serialize for T
fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>
fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>
§impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
§fn super_from(input: T) -> O
fn super_from(input: T) -> O
§impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
§fn super_into(self) -> O
fn super_into(self) -> O
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.Source§impl<T> Template for T
impl<T> Template for T
Source§fn build_template(
&self,
_context: &mut TemplateContext<'_, '_>,
) -> Result<<T as Template>::Output, BevyError>
fn build_template( &self, _context: &mut TemplateContext<'_, '_>, ) -> Result<<T as Template>::Output, BevyError>
entity context to produce a Template::Output.Source§fn clone_template(&self) -> T
fn clone_template(&self) -> T
Clone.