60 lines
1.7 KiB
Rust
60 lines
1.7 KiB
Rust
use crate::navigation::state::{Menu, NavigationState};
|
|
use crate::{display::primary_lcd::PrimaryLcdDisplay, navigation::inputs::Inputs};
|
|
|
|
use embassy_futures::select::Either6;
|
|
use embassy_futures::select::select6;
|
|
use embassy_time::{Duration, Timer};
|
|
|
|
const DEBOUNCE_DURATION_MILLIS: u64 = 100;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum Action {
|
|
Up,
|
|
Down,
|
|
Left,
|
|
Right,
|
|
Ok,
|
|
Back,
|
|
}
|
|
|
|
pub trait Navigable {
|
|
fn display(
|
|
&self,
|
|
display: &mut PrimaryLcdDisplay<'static>,
|
|
) -> impl core::future::Future<Output = ()> + Send;
|
|
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = Menu> + Send;
|
|
}
|
|
|
|
#[embassy_executor::task]
|
|
pub async fn run(mut inputs: Inputs, display: &'static mut PrimaryLcdDisplay<'static>) {
|
|
let mut state = NavigationState::default();
|
|
|
|
log::info!("starting navigation");
|
|
loop {
|
|
let selection = select6(
|
|
inputs.up.wait_for_low(),
|
|
inputs.down.wait_for_low(),
|
|
inputs.left.wait_for_low(),
|
|
inputs.right.wait_for_low(),
|
|
inputs.ok.wait_for_low(),
|
|
inputs.back.wait_for_low(),
|
|
)
|
|
.await;
|
|
|
|
let action = match selection {
|
|
Either6::First(_) => Action::Up,
|
|
Either6::Second(_) => Action::Down,
|
|
Either6::Third(_) => Action::Left,
|
|
Either6::Fourth(_) => Action::Right,
|
|
Either6::Fifth(_) => Action::Ok,
|
|
Either6::Sixth(_) => Action::Back,
|
|
};
|
|
|
|
log::info!("Action: {:?}", action);
|
|
state.current_screen = state.current_screen.handle_input(action).await;
|
|
state.current_screen.display(display).await;
|
|
|
|
Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)).await;
|
|
}
|
|
}
|