use alloc::vec; use crate::card::model::Card; use crate::card::{decoder::split_nfc_hex, mock::*}; use crate::navigation::inputs::ButtonAction; use crate::navigation::outputs::Outputs; use crate::views::card_view::CardView; use crate::views::journal_view::JournalView; use crate::views::{menu_item, settings_menu::SettingsMenu, view::View}; use crate::navigation::navigation::{Action, Navigable, NewState}; use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::RgbColor; use embedded_graphics_core::draw_target::DrawTarget; pub const MAX_SELECTED: i32 = 4; #[derive(Debug, Clone)] pub struct MainMenu { pub selected: i32, } impl Navigable for MainMenu { fn display(&self, outputs: &mut Outputs) -> impl core::future::Future + Send { let display = &mut outputs.primary_display; display.clear(Rgb565::BLACK).unwrap(); menu_item::show(display, "Scan card", 0, self.selected); menu_item::show(display, "Last card", 1, self.selected); menu_item::show(display, "Journal", 2, self.selected); menu_item::show(display, "Settings", 3, self.selected); core::future::ready(()) } fn handle_input(&self, input: Action) -> impl core::future::Future + Send { async move { let Action::Button(input) = input else { // Skip timer inputs return NewState { view: View::Main(self.clone()), replace_view: true, redraw: false, }; }; let card_mock1 = Card::try_from(split_nfc_hex(&MOCK_PAYLOAD3).unwrap()).unwrap(); let card_mock2 = Card::try_from(split_nfc_hex(&MOCK_PAYLOAD2).unwrap()).unwrap(); let new_menu = match input { ButtonAction::Up => { let new_selected = if (self.selected - 1) < 0 { MAX_SELECTED - 1 } else { self.selected - 1 }; View::Main(MainMenu { selected: new_selected, }) } ButtonAction::Down => { let new_selected = self.selected.wrapping_add(1) % MAX_SELECTED; View::Main(MainMenu { selected: new_selected, }) } ButtonAction::Ok => match self.selected { 0 => View::Scan(crate::views::scan_menu::ScanMenu { progress: 0 }), 1 => View::Card(CardView { card: card_mock1 }), 2 => View::Journal(JournalView { cards: vec![card_mock1, card_mock2], selected_card: 0, }), 3 => View::Settings(SettingsMenu { selected: 0 }), _ => View::Main(self.clone()), }, _ => View::Main(self.clone()), }; NewState { replace_view: matches!(new_menu, View::Main(_)), view: new_menu, redraw: true, } } } }