This commit is contained in:
2026-10-20 20:34:05 -05:00
parent e46a9a2aa9
commit 4607f12756
4 changed files with 500 additions and 34 deletions
+49 -4
View File
@@ -1,9 +1,12 @@
use bevy::{
color::palettes::tailwind::SLATE_900,
input_focus::tab_navigation::TabIndex,
input_focus::{
AutoFocus, InputFocus,
tab_navigation::{TabGroup, TabIndex},
},
prelude::*,
text::{EditableText, EditableTextFilter, TextCursorStyle},
ui::Checked,
ui::{Checked, auto_directional_navigation::AutoDirectionalNavigation},
ui_widgets::{Activate, Button, RadioButton, RadioGroup, ValueChange},
};
@@ -83,6 +86,7 @@ impl Plugin for LobbyPlugin {
session_visuals,
sync_lobby_fields,
style_privacy_options,
style_lobby_focus,
)
.chain(),
);
@@ -101,6 +105,7 @@ fn setup_lobby(mut commands: Commands) {
commands.spawn_scene(bsn! {
#LobbyUiRoot
LobbyUiRoot
TabGroup::default()
DespawnOnExit::<AppState>(AppState::Lobby)
Node {
width: percent(100),
@@ -148,6 +153,8 @@ fn build_lobby_ui(mut commands: Commands, root_ui: Single<Entity, With<LobbyUiRo
),
(
RadioGroup
AutoFocus
AutoDirectionalNavigation::default()
Node {
display: Display::Flex,
flex_direction: FlexDirection::Row,
@@ -183,6 +190,8 @@ fn build_lobby_ui(mut commands: Commands, root_ui: Single<Entity, With<LobbyUiRo
(
Button
ResetPortButton
AutoDirectionalNavigation::default()
TabIndex(2)
Node {
width: px(600),
height: px(130),
@@ -230,6 +239,8 @@ fn build_lobby_ui(mut commands: Commands, root_ui: Single<Entity, With<LobbyUiRo
BorderColor::from(Color::BLACK)
InteractionColors::GOOD
Interaction
AutoDirectionalNavigation::default()
TabIndex(4)
on(|_event: On<Activate>, mut lobby: ResMut<LobbyUiState>| {
info!("Session clicked!");
lobby.session_active = !lobby.session_active;
@@ -313,7 +324,8 @@ fn port_field() -> impl Scene {
TextCursorStyle {
color: Color::BLACK,
}
TabIndex(0)
AutoDirectionalNavigation::default()
TabIndex(1)
BackgroundColor(TEXT_INPUT_BACKGROUND)
}
}
@@ -339,7 +351,8 @@ fn password_field() -> impl Scene {
TextCursorStyle {
color: Color::BLACK,
}
TabIndex(1)
AutoDirectionalNavigation::default()
TabIndex(3)
BackgroundColor(TEXT_INPUT_BACKGROUND)
}
}
@@ -494,6 +507,28 @@ fn style_privacy_options(
}
}
fn style_lobby_focus(
input_focus: Res<InputFocus>,
mut options: Query<
(&ChildOf, &mut BorderColor),
(With<LobbyPrivacyOption>, Without<InteractionColors>),
>,
) {
let focused_entity = input_focus.get();
for (parent, mut border_color) in &mut options {
let color = if focused_entity == Some(parent.parent()) {
OPTION_TEXT_COLOR
} else {
OPTION_BORDER_COLOR
};
let new_border_color = BorderColor::all(color);
if *border_color != new_border_color {
*border_color = new_border_color;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -506,6 +541,16 @@ mod tests {
)
}
#[test]
fn autofocus_claims_initial_lobby_focus() {
let mut world = World::new();
world.insert_resource(InputFocus::default());
let radio_group = world.spawn((RadioGroup, AutoFocus)).id();
assert_eq!(world.resource::<InputFocus>().get(), Some(radio_group));
}
#[test]
fn checked_option_is_styled() {
let mut world = World::new();