use bevy::prelude::*;
use bevy_ui_navigation::prelude::{
DefaultNavigationPlugins, FocusState, Focusable, NavEvent, NavRequest, NavRequestSystem,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(DefaultNavigationPlugins)
.init_resource::<Images>()
.add_startup_system(setup)
.add_system(extra_lock_key.before(NavRequestSystem))
.add_system(button_system.after(NavRequestSystem))
.add_system(print_nav_events.after(NavRequestSystem))
.run();
}
fn print_nav_events(mut events: EventReader<NavEvent>) {
for event in events.iter() {
println!("{:?}", event);
}
}
fn extra_lock_key(mut requests: EventWriter<NavRequest>, input: Res<Input<KeyCode>>) {
if input.just_pressed(KeyCode::L) {
requests.send(NavRequest::Lock);
}
}
#[allow(clippy::type_complexity)]
fn button_system(
mut interaction_query: Query<
(&Focusable, &mut BackgroundColor),
(Changed<Focusable>, With<Button>),
>,
) {
for (focus, mut material) in interaction_query.iter_mut() {
if let FocusState::Focused = focus.state() {
*material = Color::ORANGE_RED.into();
} else {
*material = Color::DARK_GRAY.into();
}
}
}
#[derive(Resource)]
struct Images {
lock: UiImage,
}
impl FromWorld for Images {
fn from_world(world: &mut World) -> Self {
let assets = world.get_resource::<AssetServer>().unwrap();
Images {
lock: assets.load("lock.png").into(),
}
}
}
fn setup(mut commands: Commands, imgs: Res<Images>) {
let center_pct = |v: usize| Val::Percent((v as f32) * 25.0 + 25.0);
commands.spawn(Camera2dBundle::default());
commands
.spawn(NodeBundle {
style: Style {
position_type: PositionType::Absolute,
size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
..Default::default()
},
..Default::default()
})
.with_children(|commands| {
for x in 0..3 {
for y in 0..3 {
let position = UiRect {
left: center_pct(x),
bottom: center_pct(y),
..Default::default()
};
let bundle = button_bundle(position);
let mut button_cmds = commands.spawn(bundle);
if x == 1 && y == 1 {
button_cmds.insert(Focusable::lock()).with_children(|cmds| {
cmds.spawn(ImageBundle {
image: imgs.lock.clone(),
..Default::default()
});
});
} else {
button_cmds.insert(Focusable::default());
}
}
}
});
}
fn button_bundle(position: UiRect) -> ButtonBundle {
ButtonBundle {
style: Style {
size: Size::new(Val::Px(95.0), Val::Px(65.0)),
position,
position_type: PositionType::Absolute,
..Default::default()
},
background_color: Color::DARK_GRAY.into(),
..Default::default()
}
}