use crate::*; use phosphor::*; use std::collections::VecDeque; const CONTROL: u8 = 0x80; const ALT: u8 = 0x40; const SHIFT: u8 = 0x20; const UP: u8 = 0x80; const DOWN: u8 = 0x40; const LEFT: u8 = 0x20; const RIGHT: u8 = 0x10; const CONFIRM: u8 = 0x08; const CANCEL: u8 = 0x04; const NEXT: u8 = 0x02; const PREVIOUS: u8 = 0x01; const AUX1: u8 = 0x02; const AUX2: u8 = 0x01; macro_rules! test { ($value:expr, $mask:expr) => { $value & $mask != 0 }; } pub struct InputDevice { pub wake_flag: bool, pub pointer_position: ScreenPosition, pub pointer_buttons: u8, pub pointer_active: bool, pub horizontal_scroll: i8, pub vertical_scroll: i8, pub horizontal_scroll_delta: f64, pub vertical_scroll_delta: f64, pub text_queue: VecDeque, pub modifiers: u8, pub navigation: u8, pub controller_1: u8, pub controller_2: u8, pub controller_3: u8, pub controller_4: u8, } impl InputDevice { pub fn new() -> Self { Self { wake_flag: false, pointer_position: ScreenPosition::ZERO, pointer_buttons: 0x00, pointer_active: false, horizontal_scroll: 0x0000, vertical_scroll: 0x0000, horizontal_scroll_delta: 0.0, vertical_scroll_delta: 0.0, text_queue: VecDeque::new(), modifiers: 0x00, navigation: 0x00, controller_1: 0x00, controller_2: 0x00, controller_3: 0x00, controller_4: 0x00, } } pub fn read_horizontal_scroll(&mut self) -> u8 { let output_value = self.horizontal_scroll; self.horizontal_scroll = 0; return output_value as u8; } pub fn read_vertical_scroll(&mut self) -> u8 { let output_value = self.vertical_scroll; self.vertical_scroll = 0; return output_value as u8; } pub fn on_pointer_button(&mut self, mask: u8, action: Action) { let new_buttons = match action { Action::Pressed => self.pointer_buttons | mask, Action::Released => self.pointer_buttons & !mask, }; if new_buttons != self.pointer_buttons { self.pointer_buttons = new_buttons; self.wake_flag = true; } } pub fn on_pointer_move(&mut self, position: ScreenPosition) { if position != self.pointer_position { self.pointer_position = position; self.wake_flag = true; } } pub fn on_scroll_horizontal(&mut self, delta: f64) { self.horizontal_scroll_delta += delta; while self.horizontal_scroll_delta >= 1.0 { self.horizontal_scroll = self.horizontal_scroll.saturating_add(1); self.horizontal_scroll_delta -= 1.0; self.wake_flag = true; } while self.horizontal_scroll_delta <= -1.0 { self.horizontal_scroll = self.horizontal_scroll.saturating_sub(1); self.horizontal_scroll_delta += 1.0; self.wake_flag = true; } } pub fn on_scroll_vertical(&mut self, delta: f64) { self.vertical_scroll_delta += delta; while self.vertical_scroll_delta >= 1.0 { self.vertical_scroll = self.vertical_scroll.saturating_add(1); self.vertical_scroll_delta -= 1.0; self.wake_flag = true; } while self.vertical_scroll_delta <= -1.0 { self.vertical_scroll = self.vertical_scroll.saturating_sub(1); self.vertical_scroll_delta += 1.0; self.wake_flag = true; } } pub fn on_character_input(&mut self, input: char) { if let Ok(byte) = u8::try_from(u32::from(input)) { self.text_queue.push_back(byte); self.wake_flag = true; } } pub fn on_keyboard_input(&mut self, input: KeyboardInput) { let mask = match input.key { KeyCode::Up => UP, KeyCode::Down => DOWN, KeyCode::Left => LEFT, KeyCode::Right => RIGHT, KeyCode::Return => CONFIRM, KeyCode::Escape => CANCEL, KeyCode::Tab => match test!(self.modifiers, SHIFT) { false => NEXT, true => PREVIOUS }, _ => return, }; let navigation = match input.action { Action::Pressed => self.navigation | mask, Action::Released => self.navigation & !mask, }; if navigation != self.navigation { self.navigation = navigation; self.wake_flag = true; } } pub fn on_modifier_change(&mut self, modifiers: ModifiersState) { let mut new_modifiers = 0x00; if modifiers.ctrl() { new_modifiers |= CONTROL } if modifiers.alt() { new_modifiers |= ALT } if modifiers.shift() { new_modifiers |= SHIFT } if new_modifiers != self.modifiers { self.modifiers = new_modifiers; self.wake_flag = true; } } }