use std::cell::RefCell;
use std::time::Duration;
use web_time::Instant;
use crate::animation::Tween;
use super::key::PaintedKey;
use super::layouts::Layer;
pub const SLIDE_DURATION_SECS: f64 = 0.22;
pub struct KeyboardState {
pub enabled: bool,
pub text_input_focused: bool,
pub slide: Tween,
pub current_layer: Layer,
pub last_painted_keys: Vec<PaintedKey>,
pub last_panel_height: Option<f64>,
pub pressed_key_index: Option<usize>,
pub captured_pointer: bool,
pub caps_lock: bool,
pub last_shift_tap: Option<Instant>,
pub key_repeat: Option<KeyRepeatState>,
pub dismiss_requested: bool,
}
#[derive(Debug, Clone, Copy)]
pub struct KeyRepeatState {
pub key_index: usize,
pub pressed_at: Instant,
pub last_fired_at: Option<Instant>,
}
impl KeyRepeatState {
pub const INITIAL_DELAY: Duration = Duration::from_millis(450);
pub const REPEAT_PERIOD: Duration = Duration::from_millis(70);
}
pub const SHIFT_DOUBLE_TAP_WINDOW: Duration = Duration::from_millis(350);
impl Default for KeyboardState {
fn default() -> Self {
Self {
enabled: false,
text_input_focused: false,
slide: Tween::new(0.0, SLIDE_DURATION_SECS),
current_layer: Layer::Letters,
last_painted_keys: Vec::new(),
last_panel_height: None,
pressed_key_index: None,
captured_pointer: false,
caps_lock: false,
last_shift_tap: None,
key_repeat: None,
dismiss_requested: false,
}
}
}
impl KeyboardState {
pub fn visible_fraction(&self) -> f64 {
self.slide.value()
}
}
thread_local! {
static STATE: RefCell<KeyboardState> = RefCell::new(KeyboardState::default());
}
pub fn with_state_ref<R>(f: impl FnOnce(&KeyboardState) -> R) -> R {
STATE.with(|cell| f(&cell.borrow()))
}
pub fn with_state_mut<R>(f: impl FnOnce(&mut KeyboardState) -> R) -> R {
STATE.with(|cell| f(&mut cell.borrow_mut()))
}