114 lines
4.1 KiB
Rust
114 lines
4.1 KiB
Rust
use crate::display::primary_lcd::PrimaryLcdDisplay;
|
|
use crate::navigation::inputs::ButtonAction;
|
|
use crate::navigation::navigation::CARD_DATA;
|
|
use crate::navigation::navigation::NewState;
|
|
|
|
use alloc::format;
|
|
use embedded_graphics::Drawable;
|
|
use embedded_graphics::geometry::AngleUnit as _;
|
|
use embedded_graphics::geometry::Dimensions as _;
|
|
use embedded_graphics::geometry::Size;
|
|
use embedded_graphics::mono_font::MonoTextStyle;
|
|
use embedded_graphics::mono_font::ascii::FONT_10X20;
|
|
use embedded_graphics::pixelcolor::Rgb565;
|
|
use embedded_graphics::prelude::Point;
|
|
use embedded_graphics::prelude::RgbColor;
|
|
use embedded_graphics::primitives::Arc;
|
|
use embedded_graphics::primitives::Primitive as _;
|
|
use embedded_graphics::primitives::PrimitiveStyleBuilder;
|
|
use embedded_graphics::primitives::Rectangle;
|
|
use embedded_graphics::primitives::StrokeAlignment;
|
|
use embedded_graphics::text::Alignment;
|
|
use embedded_graphics::text::Baseline;
|
|
use embedded_graphics::text::Text;
|
|
use embedded_graphics::text::TextStyleBuilder;
|
|
use embedded_graphics_core::draw_target::DrawTarget;
|
|
|
|
use crate::navigation::navigation::{Action, Navigable};
|
|
use crate::views::view::View;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct ScanMenu {
|
|
pub progress: u8, // 0..255
|
|
}
|
|
|
|
impl Navigable for ScanMenu {
|
|
fn display(
|
|
&self,
|
|
display: &mut PrimaryLcdDisplay<'static>,
|
|
) -> impl core::future::Future<Output = ()> + Send {
|
|
let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
|
|
display.clear(Rgb565::BLACK).unwrap();
|
|
|
|
let display_area = display.bounding_box();
|
|
|
|
Text::new("Scanning...", Point::new(20, 30), style)
|
|
.draw(display)
|
|
.unwrap();
|
|
|
|
// Create styles used by the drawing operations.
|
|
let arc_stroke = PrimitiveStyleBuilder::new()
|
|
.stroke_color(Rgb565::WHITE)
|
|
.stroke_width(5)
|
|
.stroke_alignment(StrokeAlignment::Inside)
|
|
.build();
|
|
let character_style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
|
|
let text_style = TextStyleBuilder::new()
|
|
.baseline(Baseline::Middle)
|
|
.alignment(Alignment::Center)
|
|
.build();
|
|
|
|
let sweep = self.progress as f32 * 360.0 / 255.0;
|
|
|
|
let width = display_area.size.width;
|
|
let bounding_box =
|
|
Rectangle::with_center(display_area.center(), Size::new_equal(4 * width / 5));
|
|
// log::info!("bounding_box: {:?}", bounding_box);
|
|
// log::info!("display_area: {:?}", display_area);
|
|
// Draw an arc with a 5px wide stroke.
|
|
Arc::new(
|
|
bounding_box.top_left,
|
|
bounding_box.size.width,
|
|
90.0.deg(),
|
|
sweep.deg(),
|
|
)
|
|
.into_styled(arc_stroke)
|
|
.draw(display)
|
|
.unwrap();
|
|
|
|
// Draw centered text.
|
|
let text = format!("{:.2}%", 100. * (self.progress as f32) / 255.);
|
|
Text::with_text_style(&text, display_area.center(), character_style, text_style)
|
|
.draw(display)
|
|
.unwrap();
|
|
|
|
core::future::ready(())
|
|
}
|
|
|
|
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send {
|
|
async move {
|
|
log::info!("Scan view detected, checking for NFC card data");
|
|
if let Some(card_data) = CARD_DATA.lock().await.take() {
|
|
log::info!("NFC Card to be displayed: {:?}", card_data);
|
|
NewState {
|
|
view: View::Card(crate::views::card_view::CardView { card: card_data }),
|
|
replace_view: true,
|
|
redraw: true,
|
|
}
|
|
} else {
|
|
let new_progress = match input {
|
|
Action::Button(ButtonAction::Up) => self.progress.wrapping_add(5),
|
|
_ => self.progress,
|
|
};
|
|
NewState {
|
|
view: View::Scan(ScanMenu {
|
|
progress: new_progress,
|
|
}),
|
|
replace_view: true,
|
|
redraw: matches!(input, Action::Button(ButtonAction::Up) | Action::Timer),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|