shared/
confirmation.rs

1use embedded_graphics::{
2    Drawable,
3    mono_font::{MonoTextStyle, ascii::FONT_6X10},
4    pixelcolor::BinaryColor,
5    prelude::{Point, Primitive, Size},
6    primitives::{PrimitiveStyle, Rectangle},
7    text::{Alignment, Text},
8};
9use embedded_text::{
10    TextBox,
11    alignment::HorizontalAlignment,
12    style::{HeightMode, TextBoxStyleBuilder},
13};
14
15use crate::KeyEvent;
16
17#[derive(Clone, PartialEq)]
18pub struct Confirmation(&'static str, &'static str, &'static str, bool, Option<bool>);
19
20impl Confirmation {
21    pub fn new(
22        message: &'static str,
23        r#true: &'static str,
24        r#false: &'static str,
25        selected: bool,
26    ) -> Self {
27        Self(message, r#true, r#false, selected, None)
28    }
29
30    pub async fn run(&mut self, device: &mut impl crate::Device) -> Option<bool> {
31        if let Some(result) = self.4 {
32            return Some(result);
33        }
34        let _ = device.clear(BinaryColor::On);
35
36        let fill = PrimitiveStyle::with_fill(BinaryColor::Off);
37        if self.3 {
38            Rectangle::new(Point::new(0, 36), Size::new(42, 12))
39                .into_styled(fill)
40                .draw(device)
41                .unwrap();
42        } else {
43            Rectangle::new(Point::new(42, 36), Size::new(42, 12))
44                .into_styled(fill)
45                .draw(device)
46                .unwrap();
47        }
48
49        let true_style = if self.3 {
50            MonoTextStyle::new(&FONT_6X10, BinaryColor::On)
51        } else {
52            MonoTextStyle::new(&FONT_6X10, BinaryColor::Off)
53        };
54        Text::with_alignment(self.1, Point::new(21, 44), true_style, Alignment::Center)
55            .draw(device)
56            .unwrap();
57        let false_style = if self.3 {
58            MonoTextStyle::new(&FONT_6X10, BinaryColor::Off)
59        } else {
60            MonoTextStyle::new(&FONT_6X10, BinaryColor::On)
61        };
62        Text::with_alignment(self.2, Point::new(63, 44), false_style, Alignment::Center)
63            .draw(device)
64            .unwrap();
65
66        TextBox::with_textbox_style(
67            self.0,
68            Rectangle::new(Point::zero(), Size::new(84, 48)),
69            MonoTextStyle::new(&FONT_6X10, BinaryColor::Off),
70            TextBoxStyleBuilder::new()
71                .height_mode(HeightMode::FitToText)
72                .alignment(HorizontalAlignment::Left)
73                .paragraph_spacing(6)
74                .build(),
75        )
76        .draw(device)
77        .unwrap();
78
79        match device.event().await {
80            KeyEvent::Down(crate::Key::Up | crate::Key::Down) => {
81                self.3 = !self.3;
82                None
83            }
84            KeyEvent::Down(crate::Key::Select) => {
85                self.4 = Some(self.3);
86                self.4
87            }
88            _ => None,
89        }
90    }
91}