wallet: correctly handle repeating keys with smoothing

This commit is contained in:
darkfi
2024-05-30 20:02:33 +02:00
parent 65df99394b
commit 149859454c
3 changed files with 572 additions and 147 deletions

View File

@@ -1,6 +1,8 @@
use miniquad::{KeyMods, UniformType, MouseButton, window};
use log::info;
use std::{io::Cursor, sync::{Arc, Mutex}};
use std::{
collections::HashMap,
io::Cursor, sync::{Arc, Mutex}, time::{Instant, Duration}};
use darkfi_serial::Decodable;
use freetype as ft;
@@ -10,6 +12,69 @@ use crate::{error::{Error, Result}, prop::{
const CURSOR_WIDTH: f32 = 4.;
struct PressedKeysSmoothRepeat {
/// When holding keys, we track from start and last sent time.
/// This is useful for initial delay and smooth scrolling.
pressed_keys: HashMap<String, RepeatingKeyTimer>,
/// Initial delay before allowing keys
start_delay: u32,
/// Minimum time between repeated keys
step_time: u32,
}
impl PressedKeysSmoothRepeat {
fn new(start_delay: u32, step_time: u32) -> Self {
Self {
pressed_keys: HashMap::new(),
start_delay,
step_time
}
}
fn key_down(&mut self, key: &str, repeat: bool) -> u32 {
if !repeat {
return 1;
}
// Insert key if not exists
if !self.pressed_keys.contains_key(key) {
self.pressed_keys.insert(key.to_string(), RepeatingKeyTimer::new());
}
let repeater = self.pressed_keys.get_mut(key).expect("repeat map");
repeater.update(self.start_delay, self.step_time)
}
fn key_up(&mut self, key: &str) {
self.pressed_keys.remove(key);
}
}
struct RepeatingKeyTimer {
start: Instant,
actions: u32,
}
impl RepeatingKeyTimer {
fn new() -> Self {
Self {
start: Instant::now(),
actions: 0
}
}
fn update(&mut self, start_delay: u32, step_time: u32) -> u32 {
let elapsed = self.start.elapsed().as_millis();
if elapsed < start_delay as u128 {
return 0
}
let total_actions = ((elapsed - start_delay as u128) / step_time as u128) as u32;
let remaining_actions = total_actions - self.actions;
self.actions = total_actions;
remaining_actions
}
}
pub type EditBoxPtr = Arc<EditBox>;
pub struct EditBox {
@@ -28,11 +93,13 @@ pub struct EditBox {
world_rect: Mutex<Rectangle<f32>>,
glyphs: Mutex<Vec<Glyph>>,
text_shaper: TextShaper,
key_repeat: Mutex<PressedKeysSmoothRepeat>,
}
impl EditBox {
pub fn new(scene_graph: &mut SceneGraph, node_id: SceneNodeId, font_faces: Vec<FreetypeFace>) -> Result<Pimpl> {
let node = scene_graph.get_node(node_id).unwrap();
let node_name = node.name.clone();
let is_active = PropertyBool::wrap(node, "is_active", 0)?;
let debug = PropertyBool::wrap(node, "debug", 0)?;
let baseline = PropertyFloat32::wrap(node, "baseline", 0)?;
@@ -65,12 +132,13 @@ impl EditBox {
world_rect: Mutex::new(Rectangle { x: 0., y: 0., w: 0., h: 0. }),
glyphs: Mutex::new(vec![]),
text_shaper,
key_repeat: Mutex::new(PressedKeysSmoothRepeat::new(400, 50)),
});
self_.regen_glyphs().unwrap();
let weak_self = Arc::downgrade(&self_);
let slot = Slot {
name: "editbox::key_down".to_string(),
let slot_key_down = Slot {
name: format!("{}::key_down", node_name),
func: Box::new(move |data| {
let mut cur = Cursor::new(&data);
let keymods = KeyMods {
@@ -84,7 +152,26 @@ impl EditBox {
let self_ = weak_self.upgrade();
if let Some(self_) = self_ {
self_.key_press(key, keymods, repeat);
self_.key_down(key, keymods, repeat);
}
}),
};
let weak_self = Arc::downgrade(&self_);
let slot_key_up = Slot {
name: format!("{}::key_up", node_name),
func: Box::new(move |data| {
let mut cur = Cursor::new(&data);
let keymods = KeyMods {
shift: Decodable::decode(&mut cur).unwrap(),
ctrl: Decodable::decode(&mut cur).unwrap(),
alt: Decodable::decode(&mut cur).unwrap(),
logo: Decodable::decode(&mut cur).unwrap(),
};
let key = String::decode(&mut cur).unwrap();
let self_ = weak_self.upgrade();
if let Some(self_) = self_ {
self_.key_up(key, keymods);
}
}),
};
@@ -93,11 +180,12 @@ impl EditBox {
scene_graph
.lookup_node_mut("/window/input/keyboard")
.expect("no keyboard attached!");
keyb_node.register("key_down", slot);
keyb_node.register("key_down", slot_key_down);
keyb_node.register("key_up", slot_key_up);
let weak_self = Arc::downgrade(&self_);
let slot_btn_down = Slot {
name: "editbox::mouse_button_down".to_string(),
name: format!("{}::mouse_button_down", node_name),
func: Box::new(move |data| {
let mut cur = Cursor::new(&data);
let button = MouseButton::from_u8(u8::decode(&mut cur).unwrap());
@@ -113,7 +201,7 @@ impl EditBox {
let weak_self = Arc::downgrade(&self_);
let slot_btn_up = Slot {
name: "editbox::mouse_button_up".to_string(),
name: format!("{}::mouse_button_up", node_name),
func: Box::new(move |data| {
let mut cur = Cursor::new(&data);
let button = MouseButton::from_u8(u8::decode(&mut cur).unwrap());
@@ -129,7 +217,7 @@ impl EditBox {
let weak_self = Arc::downgrade(&self_);
let slot_move = Slot {
name: "editbox::mouse_move".to_string(),
name: format!("{}::mouse_move", node_name),
func: Box::new(move |data| {
let mut cur = Cursor::new(&data);
let x = f32::decode(&mut cur).unwrap();
@@ -325,14 +413,21 @@ impl EditBox {
Ok(())
}
fn key_press(self: Arc<Self>, key: String, mods: KeyMods, repeat: bool) {
if repeat {
return;
}
fn key_down(self: Arc<Self>, key: String, mods: KeyMods, repeat: bool) {
if !self.is_active.get() {
return
}
match key.as_str() {
let actions = {
let mut repeater = self.key_repeat.lock().unwrap();
repeater.key_down(&key, repeat)
};
for _ in 0..actions {
self.do_key_down(&key, &mods)
}
}
fn do_key_down(&self, key: &str, mods: &KeyMods) {
match key {
"PageUp" => {
println!("pageup!");
}
@@ -429,6 +524,9 @@ impl EditBox {
}
}
fn insert_char(key: String) {
}
fn copy_highlighted_text(&self) -> Result<()> {
let start = self.selected.get_u32(0)? as usize;
let end = self.selected.get_u32(1)? as usize;
@@ -450,6 +548,11 @@ impl EditBox {
Ok(())
}
fn key_up(self: Arc<Self>, key: String, mods: KeyMods) {
let mut repeater = self.key_repeat.lock().unwrap();
repeater.key_up(&key);
}
fn mouse_button_down(self: Arc<Self>, button: MouseButton, x: f32, y: f32) {
let mouse_pos = Point { x, y };
let rect = self.world_rect.lock().unwrap();

View File

@@ -18,7 +18,7 @@ use crate::{
error::{Error, Result},
editbox,
expr::{SExprMachine, SExprVal},
keysym::MouseButtonAsU8,
keysym::{KeyCodeAsStr, MouseButtonAsU8},
prop::{Property, PropertySubType, PropertyType},
res::{ResourceId, ResourceManager},
scene::{
@@ -288,6 +288,19 @@ impl Stage {
],
)
.unwrap();
keyb.add_signal(
"key_up",
"Key press up event",
vec![
("shift", "", PropertyType::Bool),
("ctrl", "", PropertyType::Bool),
("alt", "", PropertyType::Bool),
("logo", "", PropertyType::Bool),
("repeat", "", PropertyType::Bool),
("keycode", "", PropertyType::Enum),
],
)
.unwrap();
let keyb_id = keyb.id;
scene_graph.link(keyb_id, input_id).unwrap();
@@ -1035,140 +1048,30 @@ impl EventHandler for Stage {
let mut scene_graph = self.scene_graph.lock().unwrap();
let win = scene_graph.lookup_node_mut("/window/input/keyboard").unwrap();
let send_key_down = |key: &str| {
let mut data = vec![];
modifiers.shift.encode(&mut data).unwrap();
modifiers.ctrl.encode(&mut data).unwrap();
modifiers.alt.encode(&mut data).unwrap();
modifiers.logo.encode(&mut data).unwrap();
repeat.encode(&mut data).unwrap();
key.encode(&mut data).unwrap();
win.trigger("key_down", data).unwrap();
};
let key = keycode.to_str();
match keycode {
KeyCode::Space => send_key_down(" "),
KeyCode::Apostrophe => send_key_down("'"),
KeyCode::Comma => send_key_down(","),
KeyCode::Minus => send_key_down("-"),
KeyCode::Period => send_key_down("."),
KeyCode::Slash => send_key_down("/"),
KeyCode::Key0 => send_key_down("0"),
KeyCode::Key1 => send_key_down("1"),
KeyCode::Key2 => send_key_down("2"),
KeyCode::Key3 => send_key_down("3"),
KeyCode::Key4 => send_key_down("4"),
KeyCode::Key5 => send_key_down("5"),
KeyCode::Key6 => send_key_down("6"),
KeyCode::Key7 => send_key_down("7"),
KeyCode::Key8 => send_key_down("8"),
KeyCode::Key9 => send_key_down("9"),
KeyCode::Semicolon => send_key_down(":"),
KeyCode::Equal => send_key_down("="),
KeyCode::A => send_key_down("A"),
KeyCode::B => send_key_down("B"),
KeyCode::C => send_key_down("C"),
KeyCode::D => send_key_down("D"),
KeyCode::E => send_key_down("E"),
KeyCode::F => send_key_down("F"),
KeyCode::G => send_key_down("G"),
KeyCode::H => send_key_down("H"),
KeyCode::I => send_key_down("I"),
KeyCode::J => send_key_down("J"),
KeyCode::K => send_key_down("K"),
KeyCode::L => send_key_down("L"),
KeyCode::M => send_key_down("M"),
KeyCode::N => send_key_down("N"),
KeyCode::O => send_key_down("O"),
KeyCode::P => send_key_down("P"),
KeyCode::Q => send_key_down("Q"),
KeyCode::R => send_key_down("R"),
KeyCode::S => send_key_down("S"),
KeyCode::T => send_key_down("T"),
KeyCode::U => send_key_down("U"),
KeyCode::V => send_key_down("V"),
KeyCode::W => send_key_down("W"),
KeyCode::X => send_key_down("X"),
KeyCode::Y => send_key_down("Y"),
KeyCode::Z => send_key_down("Z"),
KeyCode::LeftBracket => send_key_down("("),
KeyCode::Backslash => send_key_down("\\"),
KeyCode::RightBracket => send_key_down(")"),
KeyCode::GraveAccent => send_key_down("GraveAccent"),
KeyCode::World1 => send_key_down("World1"),
KeyCode::World2 => send_key_down("World2"),
KeyCode::Escape => send_key_down("Escape"),
KeyCode::Enter => send_key_down("Enter"),
KeyCode::Tab => send_key_down("Tab"),
KeyCode::Backspace => send_key_down("Backspace"),
KeyCode::Insert => send_key_down("Insert"),
KeyCode::Delete => send_key_down("Delete"),
KeyCode::Right => send_key_down("Right"),
KeyCode::Left => send_key_down("Left"),
KeyCode::Down => send_key_down("Down"),
KeyCode::Up => send_key_down("Up"),
KeyCode::PageUp => send_key_down("PageUp"),
KeyCode::PageDown => send_key_down("PageDown"),
KeyCode::Home => send_key_down("Home"),
KeyCode::End => send_key_down("End"),
KeyCode::CapsLock => send_key_down("CapsLock"),
KeyCode::ScrollLock => send_key_down("ScrollLock"),
KeyCode::NumLock => send_key_down("NumLock"),
KeyCode::PrintScreen => send_key_down("PrintScreen"),
KeyCode::Pause => send_key_down("Pause"),
KeyCode::F1 => send_key_down("F1"),
KeyCode::F2 => send_key_down("F2"),
KeyCode::F3 => send_key_down("F3"),
KeyCode::F4 => send_key_down("F4"),
KeyCode::F5 => send_key_down("F5"),
KeyCode::F6 => send_key_down("F6"),
KeyCode::F7 => send_key_down("F7"),
KeyCode::F8 => send_key_down("F8"),
KeyCode::F9 => send_key_down("F9"),
KeyCode::F10 => send_key_down("F10"),
KeyCode::F11 => send_key_down("F11"),
KeyCode::F12 => send_key_down("F12"),
KeyCode::F13 => send_key_down("F13"),
KeyCode::F14 => send_key_down("F14"),
KeyCode::F15 => send_key_down("F15"),
KeyCode::F16 => send_key_down("F16"),
KeyCode::F17 => send_key_down("F17"),
KeyCode::F18 => send_key_down("F18"),
KeyCode::F19 => send_key_down("F19"),
KeyCode::F20 => send_key_down("F20"),
KeyCode::F21 => send_key_down("F21"),
KeyCode::F22 => send_key_down("F22"),
KeyCode::F23 => send_key_down("F23"),
KeyCode::F24 => send_key_down("F24"),
KeyCode::F25 => send_key_down("F25"),
KeyCode::Kp0 => send_key_down("Kp0"),
KeyCode::Kp1 => send_key_down("Kp1"),
KeyCode::Kp2 => send_key_down("Kp2"),
KeyCode::Kp3 => send_key_down("Kp3"),
KeyCode::Kp4 => send_key_down("Kp4"),
KeyCode::Kp5 => send_key_down("Kp5"),
KeyCode::Kp6 => send_key_down("Kp6"),
KeyCode::Kp7 => send_key_down("Kp7"),
KeyCode::Kp8 => send_key_down("Kp8"),
KeyCode::Kp9 => send_key_down("Kp9"),
KeyCode::KpDecimal => send_key_down("KpDecimal"),
KeyCode::KpDivide => send_key_down("KpDivide"),
KeyCode::KpMultiply => send_key_down("KpMultiply"),
KeyCode::KpSubtract => send_key_down("KpSubtract"),
KeyCode::KpAdd => send_key_down("KpAdd"),
KeyCode::KpEnter => send_key_down("KpEnter"),
KeyCode::KpEqual => send_key_down("KpEqual"),
KeyCode::LeftShift => send_key_down("LeftShift"),
KeyCode::LeftControl => send_key_down("LeftControl"),
KeyCode::LeftAlt => send_key_down("LeftAlt"),
KeyCode::LeftSuper => send_key_down("LeftSuper"),
KeyCode::RightShift => send_key_down("RightShift"),
KeyCode::RightControl => send_key_down("RightControl"),
KeyCode::RightAlt => send_key_down("RightAlt"),
KeyCode::RightSuper => send_key_down("RightSuper"),
KeyCode::Menu => send_key_down("Menu"),
KeyCode::Unknown => send_key_down("Unknown"),
}
let mut data = vec![];
modifiers.shift.encode(&mut data).unwrap();
modifiers.ctrl.encode(&mut data).unwrap();
modifiers.alt.encode(&mut data).unwrap();
modifiers.logo.encode(&mut data).unwrap();
repeat.encode(&mut data).unwrap();
key.encode(&mut data).unwrap();
win.trigger("key_down", data).unwrap();
}
fn key_up_event(&mut self, keycode: KeyCode, modifiers: KeyMods) {
let mut scene_graph = self.scene_graph.lock().unwrap();
let win = scene_graph.lookup_node_mut("/window/input/keyboard").unwrap();
let key = keycode.to_str();
let mut data = vec![];
modifiers.shift.encode(&mut data).unwrap();
modifiers.ctrl.encode(&mut data).unwrap();
modifiers.alt.encode(&mut data).unwrap();
modifiers.logo.encode(&mut data).unwrap();
key.encode(&mut data).unwrap();
win.trigger("key_up", data).unwrap();
}
fn mouse_motion_event(&mut self, x: f32, y: f32) {
let mut scene_graph = self.scene_graph.lock().unwrap();

View File

@@ -0,0 +1,419 @@
use miniquad::{
KeyCode, MouseButton
};
pub trait KeyCodeAsStr {
fn to_str(&self) -> &str;
}
impl KeyCodeAsStr for KeyCode {
fn to_str(&self) -> &str {
match self {
Self::Space => " ",
Self::Apostrophe => "'",
Self::Comma => ",",
Self::Minus => "-",
Self::Period => ".",
Self::Slash => "/",
Self::Key0 => "0",
Self::Key1 => "1",
Self::Key2 => "2",
Self::Key3 => "3",
Self::Key4 => "4",
Self::Key5 => "5",
Self::Key6 => "6",
Self::Key7 => "7",
Self::Key8 => "8",
Self::Key9 => "9",
Self::Semicolon => ":",
Self::Equal => "=",
Self::A => "A",
Self::B => "B",
Self::C => "C",
Self::D => "D",
Self::E => "E",
Self::F => "F",
Self::G => "G",
Self::H => "H",
Self::I => "I",
Self::J => "J",
Self::K => "K",
Self::L => "L",
Self::M => "M",
Self::N => "N",
Self::O => "O",
Self::P => "P",
Self::Q => "Q",
Self::R => "R",
Self::S => "S",
Self::T => "T",
Self::U => "U",
Self::V => "V",
Self::W => "W",
Self::X => "X",
Self::Y => "Y",
Self::Z => "Z",
Self::LeftBracket => "(",
Self::Backslash => "\\",
Self::RightBracket => ")",
Self::GraveAccent => "GraveAccent",
Self::World1 => "World1",
Self::World2 => "World2",
Self::Escape => "Escape",
Self::Enter => "Enter",
Self::Tab => "Tab",
Self::Backspace => "Backspace",
Self::Insert => "Insert",
Self::Delete => "Delete",
Self::Right => "Right",
Self::Left => "Left",
Self::Down => "Down",
Self::Up => "Up",
Self::PageUp => "PageUp",
Self::PageDown => "PageDown",
Self::Home => "Home",
Self::End => "End",
Self::CapsLock => "CapsLock",
Self::ScrollLock => "ScrollLock",
Self::NumLock => "NumLock",
Self::PrintScreen => "PrintScreen",
Self::Pause => "Pause",
Self::F1 => "F1",
Self::F2 => "F2",
Self::F3 => "F3",
Self::F4 => "F4",
Self::F5 => "F5",
Self::F6 => "F6",
Self::F7 => "F7",
Self::F8 => "F8",
Self::F9 => "F9",
Self::F10 => "F10",
Self::F11 => "F11",
Self::F12 => "F12",
Self::F13 => "F13",
Self::F14 => "F14",
Self::F15 => "F15",
Self::F16 => "F16",
Self::F17 => "F17",
Self::F18 => "F18",
Self::F19 => "F19",
Self::F20 => "F20",
Self::F21 => "F21",
Self::F22 => "F22",
Self::F23 => "F23",
Self::F24 => "F24",
Self::F25 => "F25",
Self::Kp0 => "Kp0",
Self::Kp1 => "Kp1",
Self::Kp2 => "Kp2",
Self::Kp3 => "Kp3",
Self::Kp4 => "Kp4",
Self::Kp5 => "Kp5",
Self::Kp6 => "Kp6",
Self::Kp7 => "Kp7",
Self::Kp8 => "Kp8",
Self::Kp9 => "Kp9",
Self::KpDecimal => "KpDecimal",
Self::KpDivide => "KpDivide",
Self::KpMultiply => "KpMultiply",
Self::KpSubtract => "KpSubtract",
Self::KpAdd => "KpAdd",
Self::KpEnter => "KpEnter",
Self::KpEqual => "KpEqual",
Self::LeftShift => "LeftShift",
Self::LeftControl => "LeftControl",
Self::LeftAlt => "LeftAlt",
Self::LeftSuper => "LeftSuper",
Self::RightShift => "RightShift",
Self::RightControl => "RightControl",
Self::RightAlt => "RightAlt",
Self::RightSuper => "RightSuper",
Self::Menu => "Menu",
Self::Unknown => "Unknown",
}
}
}
pub trait KeyCodeAsU16 {
fn to_u16(&self) -> u16;
fn from_u16(keysym: u16) -> Self;
}
impl KeyCodeAsU16 for KeyCode {
fn to_u16(&self) -> u16 {
match self {
Self::Space => 0x0020,
Self::Apostrophe => 0x0027,
Self::Comma => 0x002c,
Self::Minus => 0x002d,
Self::Period => 0x002e,
Self::Slash => 0x002f,
Self::Key0 => 0x0030,
Self::Key1 => 0x0031,
Self::Key2 => 0x0032,
Self::Key3 => 0x0033,
Self::Key4 => 0x0034,
Self::Key5 => 0x0035,
Self::Key6 => 0x0036,
Self::Key7 => 0x0037,
Self::Key8 => 0x0038,
Self::Key9 => 0x0039,
Self::Semicolon => 0x003b,
Self::Equal => 0x003d,
Self::A => 0x0041,
Self::B => 0x0042,
Self::C => 0x0043,
Self::D => 0x0044,
Self::E => 0x0045,
Self::F => 0x0046,
Self::G => 0x0047,
Self::H => 0x0048,
Self::I => 0x0049,
Self::J => 0x004a,
Self::K => 0x004b,
Self::L => 0x004c,
Self::M => 0x004d,
Self::N => 0x004e,
Self::O => 0x004f,
Self::P => 0x0050,
Self::Q => 0x0051,
Self::R => 0x0052,
Self::S => 0x0053,
Self::T => 0x0054,
Self::U => 0x0055,
Self::V => 0x0056,
Self::W => 0x0057,
Self::X => 0x0058,
Self::Y => 0x0059,
Self::Z => 0x005a,
Self::LeftBracket => 0x005b,
Self::Backslash => 0x005c,
Self::RightBracket => 0x005d,
Self::GraveAccent => 0x0060,
Self::World1 => 0x0100,
Self::World2 => 0x0101,
Self::Escape => 0xff1b,
Self::Enter => 0xff0d,
Self::Tab => 0xff09,
Self::Backspace => 0xff08,
Self::Insert => 0xff63,
Self::Delete => 0xffff,
Self::Right => 0xff53,
Self::Left => 0xff51,
Self::Down => 0xff54,
Self::Up => 0xff52,
Self::PageUp => 0xff55,
Self::PageDown => 0xff56,
Self::Home => 0xff50,
Self::End => 0xff57,
Self::CapsLock => 0xffe5,
Self::ScrollLock => 0xff14,
Self::NumLock => 0xff7f,
Self::PrintScreen => 0xfd1d,
Self::Pause => 0xff13,
Self::F1 => 0xffbe,
Self::F2 => 0xffbf,
Self::F3 => 0xffc0,
Self::F4 => 0xffc1,
Self::F5 => 0xffc2,
Self::F6 => 0xffc3,
Self::F7 => 0xffc4,
Self::F8 => 0xffc5,
Self::F9 => 0xffc6,
Self::F10 => 0xffc7,
Self::F11 => 0xffc8,
Self::F12 => 0xffc9,
Self::F13 => 0xffca,
Self::F14 => 0xffcb,
Self::F15 => 0xffcc,
Self::F16 => 0xffcd,
Self::F17 => 0xffce,
Self::F18 => 0xffcf,
Self::F19 => 0xffd0,
Self::F20 => 0xffd1,
Self::F21 => 0xffd2,
Self::F22 => 0xffd3,
Self::F23 => 0xffd4,
Self::F24 => 0xffd5,
Self::F25 => 0xffd6,
Self::Kp0 => 0xffb0,
Self::Kp1 => 0xffb1,
Self::Kp2 => 0xffb2,
Self::Kp3 => 0xffb3,
Self::Kp4 => 0xffb4,
Self::Kp5 => 0xffb5,
Self::Kp6 => 0xffb6,
Self::Kp7 => 0xffb7,
Self::Kp8 => 0xffb8,
Self::Kp9 => 0xffb9,
Self::KpDecimal => 0xffae,
Self::KpDivide => 0xffaf,
Self::KpMultiply => 0xffaa,
Self::KpSubtract => 0xffad,
Self::KpAdd => 0xffab,
Self::KpEnter => 0xff8d,
Self::KpEqual => 0xffbd,
Self::LeftShift => 0xffe1,
Self::LeftControl => 0xffe3,
Self::LeftAlt => 0xffe9,
Self::LeftSuper => 0xffeb,
Self::RightShift => 0xffe2,
Self::RightControl => 0xffe4,
Self::RightAlt => 0xffea,
Self::RightSuper => 0xffec,
Self::Menu => 0xff67,
Self::Unknown => 0x01ff,
}
}
fn from_u16(keysym: u16) -> Self {
match keysym {
0x0020 => Self::Space,
0x0027 => Self::Apostrophe,
0x002c => Self::Comma,
0x002d => Self::Minus,
0x002e => Self::Period,
0x002f => Self::Slash,
0x0030 => Self::Key0,
0x0031 => Self::Key1,
0x0032 => Self::Key2,
0x0033 => Self::Key3,
0x0034 => Self::Key4,
0x0035 => Self::Key5,
0x0036 => Self::Key6,
0x0037 => Self::Key7,
0x0038 => Self::Key8,
0x0039 => Self::Key9,
0x003b => Self::Semicolon,
0x003d => Self::Equal,
0x0041 => Self::A,
0x0042 => Self::B,
0x0043 => Self::C,
0x0044 => Self::D,
0x0045 => Self::E,
0x0046 => Self::F,
0x0047 => Self::G,
0x0048 => Self::H,
0x0049 => Self::I,
0x004a => Self::J,
0x004b => Self::K,
0x004c => Self::L,
0x004d => Self::M,
0x004e => Self::N,
0x004f => Self::O,
0x0050 => Self::P,
0x0051 => Self::Q,
0x0052 => Self::R,
0x0053 => Self::S,
0x0054 => Self::T,
0x0055 => Self::U,
0x0056 => Self::V,
0x0057 => Self::W,
0x0058 => Self::X,
0x0059 => Self::Y,
0x005a => Self::Z,
0x005b => Self::LeftBracket,
0x005c => Self::Backslash,
0x005d => Self::RightBracket,
0x0060 => Self::GraveAccent,
0x0100 => Self::World1,
0x0101 => Self::World2,
0xff1b => Self::Escape,
0xff0d => Self::Enter,
0xff09 => Self::Tab,
0xff08 => Self::Backspace,
0xff63 => Self::Insert,
0xffff => Self::Delete,
0xff53 => Self::Right,
0xff51 => Self::Left,
0xff54 => Self::Down,
0xff52 => Self::Up,
0xff55 => Self::PageUp,
0xff56 => Self::PageDown,
0xff50 => Self::Home,
0xff57 => Self::End,
0xffe5 => Self::CapsLock,
0xff14 => Self::ScrollLock,
0xff7f => Self::NumLock,
0xfd1d => Self::PrintScreen,
0xff13 => Self::Pause,
0xffbe => Self::F1,
0xffbf => Self::F2,
0xffc0 => Self::F3,
0xffc1 => Self::F4,
0xffc2 => Self::F5,
0xffc3 => Self::F6,
0xffc4 => Self::F7,
0xffc5 => Self::F8,
0xffc6 => Self::F9,
0xffc7 => Self::F10,
0xffc8 => Self::F11,
0xffc9 => Self::F12,
0xffca => Self::F13,
0xffcb => Self::F14,
0xffcc => Self::F15,
0xffcd => Self::F16,
0xffce => Self::F17,
0xffcf => Self::F18,
0xffd0 => Self::F19,
0xffd1 => Self::F20,
0xffd2 => Self::F21,
0xffd3 => Self::F22,
0xffd4 => Self::F23,
0xffd5 => Self::F24,
0xffd6 => Self::F25,
0xffb0 => Self::Kp0,
0xffb1 => Self::Kp1,
0xffb2 => Self::Kp2,
0xffb3 => Self::Kp3,
0xffb4 => Self::Kp4,
0xffb5 => Self::Kp5,
0xffb6 => Self::Kp6,
0xffb7 => Self::Kp7,
0xffb8 => Self::Kp8,
0xffb9 => Self::Kp9,
0xffae => Self::KpDecimal,
0xffaf => Self::KpDivide,
0xffaa => Self::KpMultiply,
0xffad => Self::KpSubtract,
0xffab => Self::KpAdd,
0xff8d => Self::KpEnter,
0xffbd => Self::KpEqual,
0xffe1 => Self::LeftShift,
0xffe3 => Self::LeftControl,
0xffe9 => Self::LeftAlt,
0xffeb => Self::LeftSuper,
0xffe2 => Self::RightShift,
0xffe4 => Self::RightControl,
0xffea => Self::RightAlt,
0xffec => Self::RightSuper,
0xff67 => Self::Menu,
_ => Self::Unknown,
}
}
}
pub trait MouseButtonAsU8 {
fn to_u8(&self) -> u8;
fn from_u8(btn: u8) -> Self;
}
impl MouseButtonAsU8 for MouseButton {
fn to_u8(&self) -> u8 {
match self {
Self::Left => 0,
Self::Middle => 1,
Self::Right => 2,
Self::Unknown => 3,
}
}
fn from_u8(btn: u8) -> Self {
match btn {
0 => Self::Left,
1 => Self::Middle,
2 => Self::Right,
_ => Self::Unknown,
}
}
}