Modified the "scroll.rs" example to use the new spawning API. (#19592)

# Objective

- Update the scroll example to use the latest API.

## Solution

- It now uses the 'children![]' API.

## Testing

- I manually verified that the scrolling was working

## Limitations
- Unfortunately, I couldn't find a way to spawn observers targeting the
entity inside the "fn() -> impl Bundle" function.
This commit is contained in:
LP 2025-06-11 22:32:18 -04:00 committed by GitHub
parent 0d620cdf29
commit 8ab71a6999
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3,6 +3,7 @@
use accesskit::{Node as Accessible, Role}; use accesskit::{Node as Accessible, Role};
use bevy::{ use bevy::{
a11y::AccessibilityNode, a11y::AccessibilityNode,
ecs::spawn::SpawnIter,
input::mouse::{MouseScrollUnit, MouseWheel}, input::mouse::{MouseScrollUnit, MouseWheel},
picking::hover::HoverMap, picking::hover::HoverMap,
prelude::*, prelude::*,
@ -26,6 +27,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// Camera // Camera
commands.spawn((Camera2d, IsDefaultUiCamera)); commands.spawn((Camera2d, IsDefaultUiCamera));
// Font
let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf");
// root node // root node
commands commands
.spawn(Node { .spawn(Node {
@ -49,7 +53,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
parent.spawn(( parent.spawn((
Text::new("Horizontally Scrolling list (Ctrl + MouseWheel)"), Text::new("Horizontally Scrolling list (Ctrl + MouseWheel)"),
TextFont { TextFont {
font: asset_server.load("fonts/FiraSans-Bold.ttf"), font: font_handle.clone(),
font_size: FONT_SIZE, font_size: FONT_SIZE,
..default() ..default()
}, },
@ -72,8 +76,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
for i in 0..100 { for i in 0..100 {
parent.spawn((Text(format!("Item {i}")), parent.spawn((Text(format!("Item {i}")),
TextFont { TextFont {
font: asset_server font: font_handle.clone(),
.load("fonts/FiraSans-Bold.ttf"),
..default() ..default()
}, },
Label, Label,
@ -101,38 +104,45 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
}); });
// container for all other examples // container for all other examples
parent parent.spawn((
.spawn(Node { Node {
width: Val::Percent(100.), width: Val::Percent(100.),
height: Val::Percent(100.), height: Val::Percent(100.),
flex_direction: FlexDirection::Row, flex_direction: FlexDirection::Row,
justify_content: JustifyContent::SpaceBetween, justify_content: JustifyContent::SpaceBetween,
..default() ..default()
}) },
.with_children(|parent| { children![
// vertical scroll example vertically_scrolling_list(asset_server.load("fonts/FiraSans-Bold.ttf")),
parent bidirectional_scrolling_list(asset_server.load("fonts/FiraSans-Bold.ttf")),
.spawn(Node { nested_scrolling_list(asset_server.load("fonts/FiraSans-Bold.ttf")),
],
));
});
}
fn vertically_scrolling_list(font_handle: Handle<Font>) -> impl Bundle {
(
Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, align_items: AlignItems::Center,
width: Val::Px(200.), width: Val::Px(200.),
..default() ..default()
}) },
.with_children(|parent| { children![
(
// Title // Title
parent.spawn((
Text::new("Vertically Scrolling List"), Text::new("Vertically Scrolling List"),
TextFont { TextFont {
font: asset_server.load("fonts/FiraSans-Bold.ttf"), font: font_handle.clone(),
font_size: FONT_SIZE, font_size: FONT_SIZE,
..default() ..default()
}, },
Label, Label,
)); ),
(
// Scrolling list // Scrolling list
parent
.spawn((
Node { Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
align_self: AlignSelf::Stretch, align_self: AlignSelf::Stretch,
@ -141,66 +151,57 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default() ..default()
}, },
BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
)) Children::spawn(SpawnIter((0..25).map(move |i| {
.with_children(|parent| { (
// List items Node {
for i in 0..25 {
parent
.spawn(Node {
min_height: Val::Px(LINE_HEIGHT), min_height: Val::Px(LINE_HEIGHT),
max_height: Val::Px(LINE_HEIGHT), max_height: Val::Px(LINE_HEIGHT),
..default() ..default()
}) },
.insert(Pickable { Pickable {
should_block_lower: false, should_block_lower: false,
..default() ..default()
}) },
.with_children(|parent| { children![(
parent
.spawn((
Text(format!("Item {i}")), Text(format!("Item {i}")),
TextFont { TextFont {
font: asset_server font: font_handle.clone(),
.load("fonts/FiraSans-Bold.ttf"),
..default() ..default()
}, },
Label, Label,
AccessibilityNode(Accessible::new( AccessibilityNode(Accessible::new(Role::ListItem)),
Role::ListItem, Pickable {
)),
))
.insert(Pickable {
should_block_lower: false, should_block_lower: false,
..default() ..default()
});
});
} }
}); )],
}); )
})))
),
],
)
}
// Bidirectional scroll example fn bidirectional_scrolling_list(font_handle: Handle<Font>) -> impl Bundle {
parent (
.spawn(Node { Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, align_items: AlignItems::Center,
width: Val::Px(200.), width: Val::Px(200.),
..default() ..default()
}) },
.with_children(|parent| { children![
// Title (
parent.spawn((
Text::new("Bidirectionally Scrolling List"), Text::new("Bidirectionally Scrolling List"),
TextFont { TextFont {
font: asset_server.load("fonts/FiraSans-Bold.ttf"), font: font_handle.clone(),
font_size: FONT_SIZE, font_size: FONT_SIZE,
..default() ..default()
}, },
Label, Label,
)); ),
// Scrolling list (
parent
.spawn((
Node { Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
align_self: AlignSelf::Stretch, align_self: AlignSelf::Stretch,
@ -209,66 +210,60 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default() ..default()
}, },
BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
)) Children::spawn(SpawnIter((0..25).map(move |oi| {
.with_children(|parent| { (
// Rows in each column Node {
for oi in 0..10 {
parent
.spawn(Node {
flex_direction: FlexDirection::Row, flex_direction: FlexDirection::Row,
..default() ..default()
}) },
.insert(Pickable::IGNORE) Pickable::IGNORE,
.with_children(|parent| { Children::spawn(SpawnIter((0..10).map({
// Elements in each row let value = font_handle.clone();
for i in 0..25 { move |i| {
parent (
.spawn(( Text(format!("Item {}", (oi * 10) + i)),
Text(format!("Item {}", (oi * 25) + i)),
TextFont { TextFont {
font: asset_server.load( font: value.clone(),
"fonts/FiraSans-Bold.ttf",
),
..default() ..default()
}, },
Label, Label,
AccessibilityNode(Accessible::new( AccessibilityNode(Accessible::new(Role::ListItem)),
Role::ListItem, Pickable {
)),
))
.insert(Pickable {
should_block_lower: false, should_block_lower: false,
..default() ..default()
}); },
)
} }
}); }))),
)
})))
)
],
)
} }
});
});
// Nested scrolls example fn nested_scrolling_list(font_handle: Handle<Font>) -> impl Bundle {
parent (
.spawn(Node { Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, align_items: AlignItems::Center,
width: Val::Px(200.), width: Val::Px(200.),
..default() ..default()
}) },
.with_children(|parent| { children![
(
// Title // Title
parent.spawn((
Text::new("Nested Scrolling Lists"), Text::new("Nested Scrolling Lists"),
TextFont { TextFont {
font: asset_server.load("fonts/FiraSans-Bold.ttf"), font: font_handle.clone(),
font_size: FONT_SIZE, font_size: FONT_SIZE,
..default() ..default()
}, },
Label, Label,
)); ),
(
// Outer, horizontal scrolling container // Outer, horizontal scrolling container
parent
.spawn((
Node { Node {
column_gap: Val::Px(20.), column_gap: Val::Px(20.),
flex_direction: FlexDirection::Row, flex_direction: FlexDirection::Row,
@ -278,12 +273,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default() ..default()
}, },
BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
))
.with_children(|parent| {
// Inner, scrolling columns // Inner, scrolling columns
for oi in 0..30 { Children::spawn(SpawnIter((0..30).map(move |oi| {
parent (
.spawn((
Node { Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
align_self: AlignSelf::Stretch, align_self: AlignSelf::Stretch,
@ -291,38 +283,33 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default() ..default()
}, },
BackgroundColor(Color::srgb(0.05, 0.05, 0.05)), BackgroundColor(Color::srgb(0.05, 0.05, 0.05)),
)) Pickable {
.insert(Pickable {
should_block_lower: false, should_block_lower: false,
..default() ..default()
}) },
.with_children(|parent| { Children::spawn(SpawnIter((0..30).map({
for i in 0..25 { let value = font_handle.clone();
parent move |i| {
.spawn(( (
Text(format!("Item {}", (oi * 25) + i)), Text(format!("Item {}", (oi * 25) + i)),
TextFont { TextFont {
font: asset_server.load( font: value.clone(),
"fonts/FiraSans-Bold.ttf",
),
..default() ..default()
}, },
Label, Label,
AccessibilityNode(Accessible::new( AccessibilityNode(Accessible::new(Role::ListItem)),
Role::ListItem, Pickable {
)),
))
.insert(Pickable {
should_block_lower: false, should_block_lower: false,
..default() ..default()
}); },
)
} }
}); }))),
} )
}); })))
}); )
}); ],
}); )
} }
/// Updates the scroll position of scrollable nodes in response to mouse input /// Updates the scroll position of scrollable nodes in response to mouse input