use crate::app::cycle::Turn;
use bevy::prelude::*;
pub const NUMBER_KEYS: [KeyCode; 9] = [
KeyCode::Digit1,
KeyCode::Digit2,
KeyCode::Digit3,
KeyCode::Digit4,
KeyCode::Digit5,
KeyCode::Digit6,
KeyCode::Digit7,
KeyCode::Digit8,
KeyCode::Digit9,
];
pub fn number_pressed(keys: &ButtonInput<KeyCode>, count: usize) -> Option<usize> {
NUMBER_KEYS
.iter()
.take(count)
.position(|&key| keys.just_pressed(key))
}
pub fn nav(keys: &ButtonInput<KeyCode>, selected: usize, len: usize) -> usize {
let mut at = selected;
if keys.just_pressed(KeyCode::KeyW) || keys.just_pressed(KeyCode::ArrowUp) {
at = (at + len - 1) % len;
}
if keys.just_pressed(KeyCode::KeyS) || keys.just_pressed(KeyCode::ArrowDown) {
at = (at + 1) % len;
}
at
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Nav {
Up,
Down,
Stay,
}
pub fn step(nav: Nav, selected: usize, len: usize) -> usize {
match nav {
Nav::Up => (selected + len - 1) % len,
Nav::Down => (selected + 1) % len,
Nav::Stay => selected,
}
}
pub fn screen_chosen(next: &NextState<crate::app::Screen>) -> bool {
!matches!(next, NextState::Unchanged)
}
pub fn enter(keys: &ButtonInput<KeyCode>) -> bool {
keys.just_pressed(KeyCode::Enter) || keys.just_pressed(KeyCode::NumpadEnter)
}
pub fn spend(keys: &mut ButtonInput<KeyCode>, codes: &[KeyCode]) {
for &code in codes {
keys.clear_just_pressed(code);
}
}
pub const CLOSERS: [KeyCode; 3] = [KeyCode::Enter, KeyCode::NumpadEnter, KeyCode::Escape];
pub fn left_right(keys: &ButtonInput<KeyCode>) -> Option<Turn> {
if keys.just_pressed(KeyCode::KeyD) || keys.just_pressed(KeyCode::ArrowRight) {
Some(Turn::Right)
} else if keys.just_pressed(KeyCode::KeyA) || keys.just_pressed(KeyCode::ArrowLeft) {
Some(Turn::Left)
} else {
None
}
}
#[derive(bevy::ecs::system::SystemParam)]
pub struct Buttons<'w, 's> {
pub keys: Res<'w, ButtonInput<KeyCode>>,
pub pads: Query<'w, 's, &'static Gamepad>,
pub face: Res<'w, crate::app::gamepad::PadFace>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nav_wraps_both_ways() {
let mut keys = ButtonInput::<KeyCode>::default();
keys.press(KeyCode::KeyW);
assert_eq!(nav(&keys, 0, 5), 4, "up from the top wraps to the bottom");
let mut keys = ButtonInput::<KeyCode>::default();
keys.press(KeyCode::KeyS);
assert_eq!(nav(&keys, 4, 5), 0, "down from the bottom wraps to the top");
}
#[test]
fn the_plain_walk_wraps_at_both_ends() {
assert_eq!(step(Nav::Down, 0, 3), 1);
assert_eq!(step(Nav::Down, 2, 3), 0, "off the bottom");
assert_eq!(step(Nav::Up, 0, 3), 2, "off the top");
assert_eq!(step(Nav::Stay, 1, 3), 1);
assert_eq!(step(Nav::Down, 0, 1), 0, "a list of one goes nowhere");
}
}