use winit::event::{VirtualKeyCode, ElementState, ModifiersState};
use spectrusty::peripherals::{ZXKeyboardMap,
joystick::{JoystickInterface, Directions},
serial::KeypadKeys
};
type ZXk = ZXKeyboardMap;
pub fn map_direct_key(key: VirtualKeyCode) -> ZXKeyboardMap {
match key {
VirtualKeyCode::Key1 => ZXk::N1,
VirtualKeyCode::Key2 => ZXk::N2,
VirtualKeyCode::Key3 => ZXk::N3,
VirtualKeyCode::Key4 => ZXk::N4,
VirtualKeyCode::Key5 => ZXk::N5,
VirtualKeyCode::Key6 => ZXk::N6,
VirtualKeyCode::Key7 => ZXk::N7,
VirtualKeyCode::Key8 => ZXk::N8,
VirtualKeyCode::Key9 => ZXk::N9,
VirtualKeyCode::Key0 => ZXk::N0,
VirtualKeyCode::A => ZXk::A,
VirtualKeyCode::B => ZXk::B,
VirtualKeyCode::C => ZXk::C,
VirtualKeyCode::D => ZXk::D,
VirtualKeyCode::E => ZXk::E,
VirtualKeyCode::F => ZXk::F,
VirtualKeyCode::G => ZXk::G,
VirtualKeyCode::H => ZXk::H,
VirtualKeyCode::I => ZXk::I,
VirtualKeyCode::J => ZXk::J,
VirtualKeyCode::K => ZXk::K,
VirtualKeyCode::L => ZXk::L,
VirtualKeyCode::M => ZXk::M,
VirtualKeyCode::N => ZXk::N,
VirtualKeyCode::O => ZXk::O,
VirtualKeyCode::P => ZXk::P,
VirtualKeyCode::Q => ZXk::Q,
VirtualKeyCode::R => ZXk::R,
VirtualKeyCode::S => ZXk::S,
VirtualKeyCode::T => ZXk::T,
VirtualKeyCode::U => ZXk::U,
VirtualKeyCode::V => ZXk::V,
VirtualKeyCode::W => ZXk::W,
VirtualKeyCode::X => ZXk::X,
VirtualKeyCode::Y => ZXk::Y,
VirtualKeyCode::Z => ZXk::Z,
VirtualKeyCode::LShift|VirtualKeyCode::RShift => ZXk::CS,
VirtualKeyCode::LControl|VirtualKeyCode::RControl => ZXk::SS,
VirtualKeyCode::Space => ZXk::BR,
VirtualKeyCode::Return => ZXk::EN,
_ => ZXk::empty()
}
}
pub fn map_combined_keys(key: VirtualKeyCode, state: ElementState, shift_down: bool) -> (ZXKeyboardMap, bool) {
let mut removecs = false;
let pressed = state == ElementState::Pressed;
let zxk = match key {
VirtualKeyCode::Left => ZXk::CS|ZXk::N5,
VirtualKeyCode::Down => ZXk::CS|ZXk::N6,
VirtualKeyCode::Up => ZXk::CS|ZXk::N7,
VirtualKeyCode::Right => ZXk::CS|ZXk::N8,
VirtualKeyCode::Capital => ZXk::CS|ZXk::N2,
VirtualKeyCode::Back => ZXk::CS|ZXk::N0,
VirtualKeyCode::LAlt|VirtualKeyCode::RAlt => ZXk::CS|ZXk::SS,
VirtualKeyCode::LBracket => ZXk::SS|ZXk::N8,
VirtualKeyCode::RBracket => ZXk::SS|ZXk::N9,
VirtualKeyCode::Grave => ZXk::SS|ZXk::X,
VirtualKeyCode::Minus if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::N0
}
else {
ZXk::SS|ZXk::J
},
VirtualKeyCode::Minus => ZXk::SS|ZXk::J|ZXk::N0,
VirtualKeyCode::Equals if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::K
}
else {
ZXk::SS|ZXk::L
},
VirtualKeyCode::Equals => ZXk::SS|ZXk::K|ZXk::L,
VirtualKeyCode::Comma if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::R
}
else {
ZXk::SS|ZXk::N
},
VirtualKeyCode::Comma => ZXk::SS|ZXk::R|ZXk::N,
VirtualKeyCode::Period if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::T
}
else {
ZXk::SS|ZXk::M
},
VirtualKeyCode::Period => ZXk::SS|ZXk::T|ZXk::M,
VirtualKeyCode::Apostrophe if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::P
}
else {
ZXk::SS|ZXk::N7
},
VirtualKeyCode::Apostrophe => ZXk::SS|ZXk::P|ZXk::N7,
VirtualKeyCode::Slash if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::C
}
else {
ZXk::SS|ZXk::V
},
VirtualKeyCode::Slash => ZXk::SS|ZXk::C|ZXk::V,
VirtualKeyCode::Semicolon if pressed => if shift_down {
removecs = true;
ZXk::SS|ZXk::Z
}
else {
ZXk::SS|ZXk::O
},
VirtualKeyCode::Semicolon => ZXk::SS|ZXk::Z|ZXk::O,
k => map_direct_key(k)
};
(zxk, removecs)
}
pub fn update_keymap(
mut cur: ZXKeyboardMap,
key: VirtualKeyCode,
state: ElementState,
shift_down: bool,
ctrl_down: bool
) -> ZXKeyboardMap
{
let (chg, removecs) = map_combined_keys(key, state, shift_down);
if let ElementState::Pressed = state {
cur.insert(chg);
if removecs {
cur.remove(ZXk::CS);
}
}
else {
cur.remove(chg);
}
if cur.is_empty() {
if shift_down {
cur.insert(ZXk::CS);
}
if ctrl_down {
cur.insert(ZXk::SS);
}
}
cur
}
pub fn update_keymap_with_modifier(
cur: ZXKeyboardMap,
key: VirtualKeyCode,
state: ElementState,
modifier: ModifiersState
) -> ZXKeyboardMap
{
update_keymap(cur, key, state, modifier.shift(), modifier.ctrl())
}
pub fn map_keypad_key(key: VirtualKeyCode, parens: bool) -> KeypadKeys {
match key {
VirtualKeyCode::NumpadDivide if parens => KeypadKeys::LPAREN,
VirtualKeyCode::NumpadDivide => KeypadKeys::DIVIDE,
VirtualKeyCode::NumpadMultiply if parens => KeypadKeys::RPAREN,
VirtualKeyCode::NumpadMultiply => KeypadKeys::MULTIPLY,
VirtualKeyCode::NumpadSubtract => KeypadKeys::MINUS,
VirtualKeyCode::NumpadAdd => KeypadKeys::PLUS,
VirtualKeyCode::NumpadEnter => KeypadKeys::ENTER,
VirtualKeyCode::Numpad1 => KeypadKeys::N1,
VirtualKeyCode::Numpad2 => KeypadKeys::N2,
VirtualKeyCode::Numpad3 => KeypadKeys::N3,
VirtualKeyCode::Numpad4 => KeypadKeys::N4,
VirtualKeyCode::Numpad5 => KeypadKeys::N5,
VirtualKeyCode::Numpad6 => KeypadKeys::N6,
VirtualKeyCode::Numpad7 => KeypadKeys::N7,
VirtualKeyCode::Numpad8 => KeypadKeys::N8,
VirtualKeyCode::Numpad9 => KeypadKeys::N9,
VirtualKeyCode::Numpad0 => KeypadKeys::N0,
VirtualKeyCode::NumpadDecimal => KeypadKeys::PERIOD,
_ => KeypadKeys::empty()
}
}
pub fn update_keypad_keys(mut cur: KeypadKeys, key: VirtualKeyCode, pressed: bool, parens: bool) -> KeypadKeys {
let chg = map_keypad_key(key, parens);
if !chg.is_empty() {
cur.set(chg, pressed);
}
cur
}
pub fn map_key_to_direction(key: VirtualKeyCode) -> Directions {
match key {
VirtualKeyCode::Up => Directions::UP,
VirtualKeyCode::Right => Directions::RIGHT,
VirtualKeyCode::Down => Directions::DOWN,
VirtualKeyCode::Left => Directions::LEFT,
_ => Directions::empty()
}
}
#[inline]
pub fn update_joystick_from_key_event<'a, J, F>(
key: VirtualKeyCode,
pressed: bool,
fire_key: VirtualKeyCode,
get_joy: F
) -> bool
where J: 'a + JoystickInterface + ?Sized,
F: FnOnce() -> Option<&'a mut J>
{
super::update_joystick_from_key_event(key, pressed, fire_key, map_key_to_direction, get_joy)
}