1use embassy_time::Timer;
2use futures::{future, future::Either, pin_mut};
3
4use crate::{Key, KeyEvent};
5
6#[derive(Clone, Debug, PartialEq)]
7pub enum Event {
8 Down(Key),
9 Delay(Key),
10 Repeat(Key),
11}
12
13pub struct HeldKey {
14 down: Option<Key>,
15 timer: Option<Timer>,
16 delay_duration: u64,
17 repeat_period: u64,
18 repeating: bool,
19}
20
21use core::fmt;
22
23impl fmt::Debug for HeldKey {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
25 #[allow(dead_code)]
26 #[derive(Debug)]
27 struct MySettings {
28 down: Option<Key>,
29 delay_duration: u64,
30 repeat_period: u64,
31 repeating: bool,
32 }
33
34 let Self {
35 down,
36 delay_duration,
37 repeat_period,
38 repeating,
39 ..
40 } = self;
41
42 fmt::Debug::fmt(
43 &MySettings {
44 down: down.clone(),
45 delay_duration: *delay_duration,
46 repeat_period: *repeat_period,
47 repeating: *repeating,
48 },
49 f,
50 )
51 }
52}
53
54impl HeldKey {
55 pub fn new(delay_duration: u64, repeat_period: u64) -> Self {
56 Self {
57 down: None,
58 timer: None,
59 delay_duration,
60 repeat_period,
61 repeating: false,
62 }
63 }
64
65 fn timeout_event(&mut self) -> Option<Event> {
66 let result = self.down.clone();
67
68 if self.repeating {
69 self.timer = Some(embassy_time::Timer::after_millis(self.repeat_period));
70 result.map(Event::Repeat)
71 } else {
72 self.repeating = true;
73 self.timer = Some(embassy_time::Timer::after_millis(self.repeat_period));
74 result.map(Event::Delay)
75 }
76 }
77
78 fn key_event(&mut self, key_event: KeyEvent) -> Option<Event> {
79 match key_event {
80 KeyEvent::Down(key) => {
81 self.timer = Some(embassy_time::Timer::after_millis(self.delay_duration));
82 self.down = Some(key.clone());
83 Some(Event::Down(key))
84 }
85 KeyEvent::Up(_key) => {
86 self.timer = None;
87 self.down = None;
88 self.repeating = false;
89 None
90 }
91 }
92 }
93
94 pub async fn event<KEYPAD>(&mut self, keypad: &mut KEYPAD) -> Option<Event>
95 where
96 KEYPAD: crate::Keypad,
97 {
98 let event_future = keypad.event();
99 pin_mut!(event_future);
100
101 if let Some(timer) = &mut self.timer {
102 match future::select(timer, event_future).await {
103 Either::Left((..)) => self.timeout_event(),
104 Either::Right((e, _)) => self.key_event(e),
105 }
106 } else {
107 self.key_event(event_future.await)
108 }
109 }
110}