use core::ops::AddAssign;
use crate::buttons::core::Transition;
pub trait HoldDescriptor: {
type width: PartialOrd + AddAssign + Copy;
const HOLD_START: Self::width;
const HOLD_INCREMENT: Self::width;
const HOLD_TICKS: Self::width;
}
pub struct DefaultHoldDescriptor ();
impl HoldDescriptor for DefaultHoldDescriptor {
type width = u8;
const HOLD_START: u8 = 0;
const HOLD_INCREMENT: u8 = 1;
const HOLD_TICKS: u8 = 250;
}
#[derive(Debug)]
pub enum Event {
Press,
Release,
Hold,
}
#[derive(Debug)]
pub struct HoldAnnotator<T: HoldDescriptor> {
counter: T::width,
}
impl<T: HoldDescriptor> HoldAnnotator<T> {
pub fn new() -> HoldAnnotator<T> {
HoldAnnotator { counter: T::HOLD_START }
}
pub fn annotate(&mut self, transition: Transition)
-> Option<Event> {
match transition {
Transition {was_pressed: false, is_pressed: true} => {
self.counter = T::HOLD_START;
Some(Event::Press)
},
Transition {was_pressed: true, is_pressed: false} => {
Some(Event::Release)
},
Transition {was_pressed: true, is_pressed: true} => {
if self.counter <= T::HOLD_TICKS {
self.counter += T::HOLD_INCREMENT;
}
if self.counter == T::HOLD_TICKS {
Some(Event::Hold)
} else {
None
}
},
Transition {was_pressed: false, is_pressed: false} => None,
}
}
}