tab_navigation
example improvements (#19239)
# Objective Improve the `tab_navigation` example. ## Solution * Set different `TabIndex`s for the buttons of each group. * Label each button with its associated `TabIndex`. * Reduce the code duplication using a loop. I tried to flatten it further using the new spawning APIs and `children!` macro but not sure what the current best way to attach the observers is.
This commit is contained in:
parent
158d9aff0e
commit
f04c0ef689
@ -26,31 +26,21 @@ const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35);
|
||||
|
||||
fn button_system(
|
||||
mut interaction_query: Query<
|
||||
(
|
||||
&Interaction,
|
||||
&mut BackgroundColor,
|
||||
&mut BorderColor,
|
||||
&Children,
|
||||
),
|
||||
(&Interaction, &mut BackgroundColor, &mut BorderColor),
|
||||
(Changed<Interaction>, With<Button>),
|
||||
>,
|
||||
mut text_query: Query<&mut Text>,
|
||||
) {
|
||||
for (interaction, mut color, mut border_color, children) in &mut interaction_query {
|
||||
let mut text = text_query.get_mut(children[0]).unwrap();
|
||||
for (interaction, mut color, mut border_color) in &mut interaction_query {
|
||||
match *interaction {
|
||||
Interaction::Pressed => {
|
||||
**text = "Press".to_string();
|
||||
*color = PRESSED_BUTTON.into();
|
||||
*border_color = BorderColor::all(RED.into());
|
||||
}
|
||||
Interaction::Hovered => {
|
||||
**text = "Hover".to_string();
|
||||
*color = HOVERED_BUTTON.into();
|
||||
*border_color = BorderColor::all(Color::WHITE);
|
||||
}
|
||||
Interaction::None => {
|
||||
**text = "Button".to_string();
|
||||
*color = NORMAL_BUTTON.into();
|
||||
*border_color = BorderColor::all(Color::BLACK);
|
||||
}
|
||||
@ -78,7 +68,7 @@ fn focus_system(
|
||||
}
|
||||
}
|
||||
|
||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
fn setup(mut commands: Commands) {
|
||||
// ui camera
|
||||
commands.spawn(Camera2d);
|
||||
commands
|
||||
@ -89,6 +79,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
flex_direction: FlexDirection::Column,
|
||||
align_items: AlignItems::Center,
|
||||
justify_content: JustifyContent::Center,
|
||||
row_gap: Val::Px(6.0),
|
||||
..default()
|
||||
})
|
||||
.observe(
|
||||
@ -98,124 +89,65 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
},
|
||||
)
|
||||
.with_children(|parent| {
|
||||
parent.spawn(Text::new("Tab Group 0"));
|
||||
parent
|
||||
.spawn((
|
||||
Node {
|
||||
display: Display::Flex,
|
||||
flex_direction: FlexDirection::Row,
|
||||
column_gap: Val::Px(6.0),
|
||||
margin: UiRect {
|
||||
bottom: Val::Px(10.0),
|
||||
for (label, tab_group, indices) in [
|
||||
// In this group all the buttons have the same `TabIndex` so they will be visited according to their order as children.
|
||||
("TabGroup 0", TabGroup::new(0), [0, 0, 0, 0]),
|
||||
// In this group the `TabIndex`s are reversed so the buttons will be visited in right-to-left order.
|
||||
("TabGroup 2", TabGroup::new(2), [3, 2, 1, 0]),
|
||||
// In this group the orders of the indices and buttons match so the buttons will be visited in left-to-right order.
|
||||
("TabGroup 1", TabGroup::new(1), [0, 1, 2, 3]),
|
||||
// Visit the modal group's buttons in an arbitrary order.
|
||||
("Modal TabGroup", TabGroup::modal(), [0, 3, 1, 2]),
|
||||
] {
|
||||
parent.spawn(Text::new(label));
|
||||
parent
|
||||
.spawn((
|
||||
Node {
|
||||
display: Display::Flex,
|
||||
flex_direction: FlexDirection::Row,
|
||||
column_gap: Val::Px(6.0),
|
||||
margin: UiRect {
|
||||
bottom: Val::Px(10.0),
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
},
|
||||
TabGroup::new(0),
|
||||
))
|
||||
.with_children(|parent| {
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
});
|
||||
|
||||
parent.spawn(Text::new("Tab Group 2"));
|
||||
parent
|
||||
.spawn((
|
||||
Node {
|
||||
display: Display::Flex,
|
||||
flex_direction: FlexDirection::Row,
|
||||
column_gap: Val::Px(6.0),
|
||||
margin: UiRect {
|
||||
bottom: Val::Px(10.0),
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
},
|
||||
TabGroup::new(2),
|
||||
))
|
||||
.with_children(|parent| {
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
});
|
||||
|
||||
parent.spawn(Text::new("Tab Group 1"));
|
||||
parent
|
||||
.spawn((
|
||||
Node {
|
||||
display: Display::Flex,
|
||||
flex_direction: FlexDirection::Row,
|
||||
column_gap: Val::Px(6.0),
|
||||
margin: UiRect {
|
||||
bottom: Val::Px(10.0),
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
},
|
||||
TabGroup::new(1),
|
||||
))
|
||||
.with_children(|parent| {
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
});
|
||||
|
||||
parent.spawn(Text::new("Modal Tab Group"));
|
||||
parent
|
||||
.spawn((
|
||||
Node {
|
||||
display: Display::Flex,
|
||||
flex_direction: FlexDirection::Row,
|
||||
column_gap: Val::Px(6.0),
|
||||
..default()
|
||||
},
|
||||
TabGroup::modal(),
|
||||
))
|
||||
.with_children(|parent| {
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
create_button(parent, &asset_server);
|
||||
});
|
||||
tab_group,
|
||||
))
|
||||
.with_children(|parent| {
|
||||
for i in indices {
|
||||
parent
|
||||
.spawn((
|
||||
Button,
|
||||
Node {
|
||||
width: Val::Px(200.0),
|
||||
height: Val::Px(65.0),
|
||||
border: UiRect::all(Val::Px(5.0)),
|
||||
justify_content: JustifyContent::Center,
|
||||
align_items: AlignItems::Center,
|
||||
..default()
|
||||
},
|
||||
BorderColor::all(Color::BLACK),
|
||||
BackgroundColor(NORMAL_BUTTON),
|
||||
TabIndex(i),
|
||||
children![(
|
||||
Text::new(format!("TabIndex {}", i)),
|
||||
TextFont {
|
||||
font_size: 20.0,
|
||||
..default()
|
||||
},
|
||||
TextColor(Color::srgb(0.9, 0.9, 0.9)),
|
||||
)],
|
||||
))
|
||||
.observe(
|
||||
|mut trigger: Trigger<Pointer<Click>>,
|
||||
mut focus: ResMut<InputFocus>| {
|
||||
focus.0 = Some(trigger.target());
|
||||
trigger.propagate(false);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn create_button(parent: &mut ChildSpawnerCommands<'_>, asset_server: &AssetServer) {
|
||||
parent
|
||||
.spawn((
|
||||
Button,
|
||||
Node {
|
||||
width: Val::Px(150.0),
|
||||
height: Val::Px(65.0),
|
||||
border: UiRect::all(Val::Px(5.0)),
|
||||
// horizontally center child text
|
||||
justify_content: JustifyContent::Center,
|
||||
// vertically center child text
|
||||
align_items: AlignItems::Center,
|
||||
..default()
|
||||
},
|
||||
BorderColor::all(Color::BLACK),
|
||||
BorderRadius::MAX,
|
||||
BackgroundColor(NORMAL_BUTTON),
|
||||
TabIndex(0),
|
||||
))
|
||||
.observe(
|
||||
|mut trigger: Trigger<Pointer<Click>>, mut focus: ResMut<InputFocus>| {
|
||||
focus.0 = Some(trigger.target());
|
||||
trigger.propagate(false);
|
||||
},
|
||||
)
|
||||
.with_child((
|
||||
Text::new("Button"),
|
||||
TextFont {
|
||||
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
|
||||
font_size: 23.0,
|
||||
..default()
|
||||
},
|
||||
TextColor(Color::srgb(0.9, 0.9, 0.9)),
|
||||
));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user