Compare commits

..

No commits in common. "8d81f94b70705fd91eecfc343d0d858c59e2a739" and "1bb29b5f750cdfe9f5485a3cd45cc2a98e031f65" have entirely different histories.

2 changed files with 217 additions and 387 deletions

View file

@ -3,7 +3,7 @@ Game store page: https://crispypin.itch.io/marble-machinations
## [Unreleased] ## [Unreleased]
### added ### added
- configurable key bindings for the basic editor actions - configurable hotkeys (via file only, only some actions)
- OS clipboard copy/paste, with fallback to old behavior when copying - OS clipboard copy/paste, with fallback to old behavior when copying
- in-grid text comments (not yet editable in-game) - in-grid text comments (not yet editable in-game)
- changelog file - changelog file

View file

@ -1,4 +1,4 @@
use std::{collections::BTreeMap, mem::transmute, vec}; use std::{collections::BTreeMap, mem::transmute};
use raylib::{ use raylib::{
color::Color, color::Color,
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
theme::{BG_DARK, BG_LIGHT}, theme::{BG_DARK, BG_LIGHT},
ui::text_button, ui::text_button,
util::{rect, screen_centered_rect}, util::screen_centered_rect,
Globals, Globals,
}; };
@ -27,28 +27,32 @@ pub enum ActionId {
StopSim, StopSim,
StepSim, StepSim,
// just like in C, because this way doesn't need more dependencies // just like in C, because this way doesn't need more dependencies
_EnumSize, _ActionIdSize,
} }
impl Default for Input { impl Default for Input {
fn default() -> Self { fn default() -> Self {
use Button::*; use KeyboardKey::*;
let mut bindings = [(); ActionId::SIZE].map(|_| Vec::new()); let mut bindings = [(); ActionId::SIZE].map(|_| Vec::new());
let mut bind_key = |action, mods, trigger| { let mut bind_key = |action, mods, key| {
bindings[action as usize].push(Binding { bindings[action as usize].push(Binding {
modifiers: mods, modifiers: mods,
trigger, trigger: InputTrigger::Key(key),
}); });
}; };
bind_key(ActionId::Undo, vec![LCtrl], Z); bind_key(ActionId::Undo, vec![KEY_LEFT_CONTROL], KEY_Z);
bind_key(ActionId::Redo, vec![LCtrl], Y); bind_key(ActionId::Redo, vec![KEY_LEFT_CONTROL], KEY_Y);
bind_key(ActionId::Redo, vec![LCtrl, LShift], Z); bind_key(
bind_key(ActionId::Copy, vec![LCtrl], C); ActionId::Redo,
bind_key(ActionId::Paste, vec![LCtrl], V); vec![KEY_LEFT_CONTROL, KEY_LEFT_SHIFT],
bind_key(ActionId::ToggleMenu, vec![], Escape); KEY_Z,
bind_key(ActionId::StartSim, vec![], Enter); );
bind_key(ActionId::StopSim, vec![], Enter); bind_key(ActionId::Copy, vec![KEY_LEFT_CONTROL], KEY_C);
bind_key(ActionId::StepSim, vec![], Space); bind_key(ActionId::Paste, vec![KEY_LEFT_CONTROL], KEY_V);
bind_key(ActionId::ToggleMenu, vec![], KEY_ESCAPE);
bind_key(ActionId::StartSim, vec![], KEY_ENTER);
bind_key(ActionId::StopSim, vec![], KEY_ENTER);
bind_key(ActionId::StepSim, vec![], KEY_SPACE);
Self { Self {
bindings, bindings,
@ -75,14 +79,7 @@ pub struct Input {
bindings: [Vec<Binding>; ActionId::SIZE], bindings: [Vec<Binding>; ActionId::SIZE],
states: [BindingState; ActionId::SIZE], states: [BindingState; ActionId::SIZE],
#[serde(skip)] #[serde(skip)]
editing_input: Option<(ActionId, usize, BindingEdit)>, editing_input: Option<(ActionId, usize)>,
}
#[derive(Clone, Debug)]
enum BindingEdit {
Init,
Adding(Binding),
Releasing(Binding),
} }
impl Input { impl Input {
@ -105,7 +102,7 @@ impl Input {
return; return;
} }
if text_button(d, &globals.mouse, 245, y, 45, "edit") { if text_button(d, &globals.mouse, 245, y, 45, "edit") {
self.editing_input = Some((action, binding_index, BindingEdit::Init)); self.editing_input = Some((action, binding_index));
} }
let trigger = format!("{:?}", binding.trigger); let trigger = format!("{:?}", binding.trigger);
d.draw_text(&trigger, 300, y, 20, Color::LIMEGREEN); d.draw_text(&trigger, 300, y, 20, Color::LIMEGREEN);
@ -114,93 +111,21 @@ impl Input {
d.draw_text(&modifiers, x, y, 20, Color::LIGHTBLUE); d.draw_text(&modifiers, x, y, 20, Color::LIGHTBLUE);
y += 32; y += 32;
} }
if text_button(d, &globals.mouse, 160, y, 130, "add binding") { y += 8;
self.editing_input =
Some((action, self.bindings[action_index].len(), BindingEdit::Init));
}
y += 45;
} }
if let Some((action, binding_index, edit_state)) = &mut self.editing_input { if let Some((action, binding_index)) = &self.editing_input {
globals.mouse.update(d); globals.mouse.update(d); // todo less scuffed
let border = screen_centered_rect(d, 368, 128); let border = screen_centered_rect(d, 208, 88);
d.draw_rectangle_rec(border, BG_LIGHT); d.draw_rectangle_rec(border, BG_LIGHT);
let bounds = screen_centered_rect(d, 360, 120); let bounds = screen_centered_rect(d, 200, 80);
d.draw_rectangle_rec(bounds, BG_DARK); d.draw_rectangle_rec(bounds, BG_DARK);
// TODO capture and display current input
let x = bounds.x as i32; let x = bounds.x as i32;
let y = bounds.y as i32; let y = bounds.y as i32;
d.draw_text( if text_button(d, &globals.mouse, x + 10, y + 40, 80, "ok") {}
&format!("editing binding for {action:?}"),
x + 5,
y + 5,
20,
Color::WHITE,
);
let y = y + 30;
let ok_btn_x = x + 10;
let ok_btn_y = y + 40;
let ok_btn_width = 80;
let ok_btn_rect = rect(ok_btn_x, ok_btn_y, ok_btn_width, 30);
for key_index in 0..Button::SIZE {
let key = Button::from_usize(key_index).unwrap();
match edit_state {
BindingEdit::Init => {
if key.just_pressed(d) {
*edit_state = BindingEdit::Adding(Binding {
modifiers: Vec::new(),
trigger: key,
});
}
}
BindingEdit::Adding(binding) => {
if key.just_pressed(d) {
if key != binding.trigger && !binding.modifiers.contains(&key) {
binding.modifiers.push(binding.trigger);
binding.trigger = key;
}
} else if key.released(d) {
if let Some(i) = binding.modifiers.iter().position(|&k| k == key) {
binding.modifiers.remove(i);
binding.modifiers.push(binding.trigger);
binding.trigger = key;
}
*edit_state = BindingEdit::Releasing(binding.clone());
}
}
BindingEdit::Releasing(_binding) => {
let clicking_ok =
globals.mouse.is_over(ok_btn_rect) && key == Button::MouseLeft;
if key.just_pressed(d) && !clicking_ok {
*edit_state = BindingEdit::Adding(Binding {
modifiers: Vec::new(),
trigger: key,
});
}
}
}
}
if let BindingEdit::Adding(b) | BindingEdit::Releasing(b) = &edit_state {
let colour = if matches!(edit_state, BindingEdit::Releasing(_)) {
Color::GREEN
} else {
Color::ORANGE
};
let text = format!("{:?} + {:?}", b.modifiers, b.trigger);
d.draw_text(&text, x + 5, y + 5, 20, colour);
}
if text_button(d, &globals.mouse, ok_btn_x, ok_btn_y, ok_btn_width, "ok") {
if let BindingEdit::Releasing(binding) = edit_state {
let binding_list = &mut self.bindings[*action as usize];
if *binding_index < binding_list.len() {
binding_list[*binding_index] = binding.clone();
} else {
binding_list.push(binding.clone());
}
self.editing_input = None;
}
}
if text_button(d, &globals.mouse, x + 100, y + 40, 80, "cancel") { if text_button(d, &globals.mouse, x + 100, y + 40, 80, "cancel") {
self.editing_input = None; self.editing_input = None;
} }
@ -212,8 +137,11 @@ impl Input {
let bindings = &self.bindings[i]; let bindings = &self.bindings[i];
let mut is_active = false; let mut is_active = false;
for binding in bindings { for binding in bindings {
if binding.modifiers.iter().all(|&m| m.is_down(rl)) { if binding.modifiers.iter().all(|&m| rl.is_key_down(m)) {
is_active |= binding.trigger.is_down(rl); is_active |= match binding.trigger {
InputTrigger::Mouse(btn) => rl.is_mouse_button_down(btn),
InputTrigger::Key(key) => rl.is_key_down(key),
}
} }
} }
let state = &mut self.states[i]; let state = &mut self.states[i];
@ -246,11 +174,11 @@ impl Input {
} }
impl ActionId { impl ActionId {
pub const SIZE: usize = Self::_EnumSize as usize; pub const SIZE: usize = Self::_ActionIdSize as usize;
fn from_usize(val: usize) -> Option<Self> { fn from_usize(val: usize) -> Option<Self> {
if val < Self::SIZE { if val < Self::SIZE {
Some(unsafe { transmute::<u8, Self>(val as u8) }) Some(unsafe { transmute::<u8, ActionId>(val as u8) })
} else { } else {
None None
} }
@ -258,11 +186,20 @@ impl ActionId {
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(from = "BindingSerde", into = "BindingSerde")]
pub struct Binding { pub struct Binding {
modifiers: Vec<Button>, modifiers: Vec<KeyboardKey>,
trigger: Button, trigger: InputTrigger,
} }
#[derive(Clone, Debug)]
pub enum InputTrigger {
Mouse(MouseButton),
Key(KeyboardKey),
}
// ###### everything below is for serialization of key bindings ######
impl From<InputMap> for Input { impl From<InputMap> for Input {
fn from(value: InputMap) -> Self { fn from(value: InputMap) -> Self {
let mut new = Self::default(); let mut new = Self::default();
@ -285,285 +222,178 @@ impl From<Input> for InputMap {
} }
} }
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[repr(u8)] struct BindingSerde {
enum Button { modifiers: Vec<String>,
MouseLeft, trigger: InputTriggerSerde,
MouseRight,
MouseMiddle,
Mouse3,
Mouse4,
Mouse5,
Mouse6,
Apostrophe,
Comma,
Minus,
Period,
Slash,
Zero,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Semicolon,
Equal,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
LeftBracket,
Backslash,
RightBracket,
Grave,
Space,
Escape,
Enter,
Tab,
Backspace,
Insert,
Delete,
Right,
Left,
Down,
Up,
PageUp,
PageDown,
Home,
End,
CapsLock,
ScrollLock,
NumLock,
PrintScreen,
Pause,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
LShift,
LCtrl,
LAlt,
LeftSuper,
RShift,
RCtrl,
RAlt,
RightSuper,
Menu,
Kp0,
Kp1,
Kp2,
Kp3,
Kp4,
Kp5,
Kp6,
Kp7,
Kp8,
Kp9,
KpDecimal,
KpDivide,
KpMultiply,
KpSubtract,
KpAdd,
KpEnter,
KpEqual,
Back,
VolumeUp,
VolumeDown,
//
_EnumSize,
} }
enum RlInput { #[derive(Clone, Debug, Serialize, Deserialize)]
Key(KeyboardKey), enum InputTriggerSerde {
Mouse(MouseButton), Mouse(String),
Key(String),
} }
impl Button { impl From<BindingSerde> for Binding {
const SIZE: usize = Self::_EnumSize as usize; fn from(value: BindingSerde) -> Self {
Self {
fn from_usize(val: usize) -> Option<Self> { modifiers: value
if val < Self::SIZE { .modifiers
Some(unsafe { transmute::<u8, Self>(val as u8) }) .iter()
} else { .map(|s| key_string_to_enum(s))
None .collect(),
trigger: value.trigger.into(),
}
} }
} }
fn is_down(self, rl: &RaylibHandle) -> bool { impl From<Binding> for BindingSerde {
match self.to_raylib() { fn from(value: Binding) -> Self {
RlInput::Key(key) => rl.is_key_down(key), Self {
RlInput::Mouse(btn) => rl.is_mouse_button_down(btn), modifiers: value.modifiers.iter().map(|c| format!("{c:?}")).collect(),
trigger: value.trigger.into(),
}
} }
} }
fn just_pressed(self, rl: &RaylibHandle) -> bool { impl From<InputTrigger> for InputTriggerSerde {
match self.to_raylib() { fn from(value: InputTrigger) -> Self {
RlInput::Key(key) => rl.is_key_pressed(key), match value {
RlInput::Mouse(btn) => rl.is_mouse_button_pressed(btn), InputTrigger::Mouse(btn) => InputTriggerSerde::Mouse(format!("{btn:?}")),
InputTrigger::Key(key) => InputTriggerSerde::Key(format!("{key:?}")),
}
} }
} }
fn released(self, rl: &RaylibHandle) -> bool { impl From<InputTriggerSerde> for InputTrigger {
match self.to_raylib() { fn from(value: InputTriggerSerde) -> Self {
RlInput::Key(key) => rl.is_key_released(key), match value {
RlInput::Mouse(btn) => rl.is_mouse_button_released(btn), InputTriggerSerde::Mouse(btn) => InputTrigger::Mouse(match btn.as_str() {
"MOUSE_BUTTON_LEFT" => MouseButton::MOUSE_BUTTON_LEFT,
"MOUSE_BUTTON_RIGHT" => MouseButton::MOUSE_BUTTON_RIGHT,
"MOUSE_BUTTON_MIDDLE" => MouseButton::MOUSE_BUTTON_MIDDLE,
"MOUSE_BUTTON_SIDE" => MouseButton::MOUSE_BUTTON_SIDE,
"MOUSE_BUTTON_EXTRA" => MouseButton::MOUSE_BUTTON_EXTRA,
"MOUSE_BUTTON_FORWARD" => MouseButton::MOUSE_BUTTON_FORWARD,
"MOUSE_BUTTON_BACK" => MouseButton::MOUSE_BUTTON_BACK,
_ => panic!("{btn} not a valid mouse button"),
}),
InputTriggerSerde::Key(key) => InputTrigger::Key(key_string_to_enum(key.as_str())),
}
} }
} }
fn to_raylib(self) -> RlInput { fn key_string_to_enum(key: &str) -> KeyboardKey {
use KeyboardKey::*; match key {
use RlInput::*; "KEY_NULL" => KeyboardKey::KEY_NULL,
match self { "KEY_APOSTROPHE" => KeyboardKey::KEY_APOSTROPHE,
Button::MouseLeft => Mouse(MouseButton::MOUSE_BUTTON_LEFT), "KEY_COMMA" => KeyboardKey::KEY_COMMA,
Button::MouseRight => Mouse(MouseButton::MOUSE_BUTTON_RIGHT), "KEY_MINUS" => KeyboardKey::KEY_MINUS,
Button::MouseMiddle => Mouse(MouseButton::MOUSE_BUTTON_MIDDLE), "KEY_PERIOD" => KeyboardKey::KEY_PERIOD,
Button::Mouse3 => Mouse(MouseButton::MOUSE_BUTTON_SIDE), "KEY_SLASH" => KeyboardKey::KEY_SLASH,
Button::Mouse4 => Mouse(MouseButton::MOUSE_BUTTON_EXTRA), "KEY_ZERO" => KeyboardKey::KEY_ZERO,
Button::Mouse5 => Mouse(MouseButton::MOUSE_BUTTON_FORWARD), "KEY_ONE" => KeyboardKey::KEY_ONE,
Button::Mouse6 => Mouse(MouseButton::MOUSE_BUTTON_BACK), "KEY_TWO" => KeyboardKey::KEY_TWO,
Button::Apostrophe => Key(KEY_APOSTROPHE), "KEY_THREE" => KeyboardKey::KEY_THREE,
Button::Comma => Key(KEY_COMMA), "KEY_FOUR" => KeyboardKey::KEY_FOUR,
Button::Minus => Key(KEY_MINUS), "KEY_FIVE" => KeyboardKey::KEY_FIVE,
Button::Period => Key(KEY_PERIOD), "KEY_SIX" => KeyboardKey::KEY_SIX,
Button::Slash => Key(KEY_SLASH), "KEY_SEVEN" => KeyboardKey::KEY_SEVEN,
Button::Zero => Key(KEY_ZERO), "KEY_EIGHT" => KeyboardKey::KEY_EIGHT,
Button::One => Key(KEY_ONE), "KEY_NINE" => KeyboardKey::KEY_NINE,
Button::Two => Key(KEY_TWO), "KEY_SEMICOLON" => KeyboardKey::KEY_SEMICOLON,
Button::Three => Key(KEY_THREE), "KEY_EQUAL" => KeyboardKey::KEY_EQUAL,
Button::Four => Key(KEY_FOUR), "KEY_A" => KeyboardKey::KEY_A,
Button::Five => Key(KEY_FIVE), "KEY_B" => KeyboardKey::KEY_B,
Button::Six => Key(KEY_SIX), "KEY_C" => KeyboardKey::KEY_C,
Button::Seven => Key(KEY_SEVEN), "KEY_D" => KeyboardKey::KEY_D,
Button::Eight => Key(KEY_EIGHT), "KEY_E" => KeyboardKey::KEY_E,
Button::Nine => Key(KEY_NINE), "KEY_F" => KeyboardKey::KEY_F,
Button::Semicolon => Key(KEY_SEMICOLON), "KEY_G" => KeyboardKey::KEY_G,
Button::Equal => Key(KEY_EQUAL), "KEY_H" => KeyboardKey::KEY_H,
Button::A => Key(KEY_A), "KEY_I" => KeyboardKey::KEY_I,
Button::B => Key(KEY_B), "KEY_J" => KeyboardKey::KEY_J,
Button::C => Key(KEY_C), "KEY_K" => KeyboardKey::KEY_K,
Button::D => Key(KEY_D), "KEY_L" => KeyboardKey::KEY_L,
Button::E => Key(KEY_E), "KEY_M" => KeyboardKey::KEY_M,
Button::F => Key(KEY_F), "KEY_N" => KeyboardKey::KEY_N,
Button::G => Key(KEY_G), "KEY_O" => KeyboardKey::KEY_O,
Button::H => Key(KEY_H), "KEY_P" => KeyboardKey::KEY_P,
Button::I => Key(KEY_I), "KEY_Q" => KeyboardKey::KEY_Q,
Button::J => Key(KEY_J), "KEY_R" => KeyboardKey::KEY_R,
Button::K => Key(KEY_K), "KEY_S" => KeyboardKey::KEY_S,
Button::L => Key(KEY_L), "KEY_T" => KeyboardKey::KEY_T,
Button::M => Key(KEY_M), "KEY_U" => KeyboardKey::KEY_U,
Button::N => Key(KEY_N), "KEY_V" => KeyboardKey::KEY_V,
Button::O => Key(KEY_O), "KEY_W" => KeyboardKey::KEY_W,
Button::P => Key(KEY_P), "KEY_X" => KeyboardKey::KEY_X,
Button::Q => Key(KEY_Q), "KEY_Y" => KeyboardKey::KEY_Y,
Button::R => Key(KEY_R), "KEY_Z" => KeyboardKey::KEY_Z,
Button::S => Key(KEY_S), "KEY_LEFT_BRACKET" => KeyboardKey::KEY_LEFT_BRACKET,
Button::T => Key(KEY_T), "KEY_BACKSLASH" => KeyboardKey::KEY_BACKSLASH,
Button::U => Key(KEY_U), "KEY_RIGHT_BRACKET" => KeyboardKey::KEY_RIGHT_BRACKET,
Button::V => Key(KEY_V), "KEY_GRAVE" => KeyboardKey::KEY_GRAVE,
Button::W => Key(KEY_W), "KEY_SPACE" => KeyboardKey::KEY_SPACE,
Button::X => Key(KEY_X), "KEY_ESCAPE" => KeyboardKey::KEY_ESCAPE,
Button::Y => Key(KEY_Y), "KEY_ENTER" => KeyboardKey::KEY_ENTER,
Button::Z => Key(KEY_Z), "KEY_TAB" => KeyboardKey::KEY_TAB,
Button::LeftBracket => Key(KEY_LEFT_BRACKET), "KEY_BACKSPACE" => KeyboardKey::KEY_BACKSPACE,
Button::Backslash => Key(KEY_BACKSLASH), "KEY_INSERT" => KeyboardKey::KEY_INSERT,
Button::RightBracket => Key(KEY_RIGHT_BRACKET), "KEY_DELETE" => KeyboardKey::KEY_DELETE,
Button::Grave => Key(KEY_GRAVE), "KEY_RIGHT" => KeyboardKey::KEY_RIGHT,
Button::Space => Key(KEY_SPACE), "KEY_LEFT" => KeyboardKey::KEY_LEFT,
Button::Escape => Key(KEY_ESCAPE), "KEY_DOWN" => KeyboardKey::KEY_DOWN,
Button::Enter => Key(KEY_ENTER), "KEY_UP" => KeyboardKey::KEY_UP,
Button::Tab => Key(KEY_TAB), "KEY_PAGE_UP" => KeyboardKey::KEY_PAGE_UP,
Button::Backspace => Key(KEY_BACKSPACE), "KEY_PAGE_DOWN" => KeyboardKey::KEY_PAGE_DOWN,
Button::Insert => Key(KEY_INSERT), "KEY_HOME" => KeyboardKey::KEY_HOME,
Button::Delete => Key(KEY_DELETE), "KEY_END" => KeyboardKey::KEY_END,
Button::Right => Key(KEY_RIGHT), "KEY_CAPS_LOCK" => KeyboardKey::KEY_CAPS_LOCK,
Button::Left => Key(KEY_LEFT), "KEY_SCROLL_LOCK" => KeyboardKey::KEY_SCROLL_LOCK,
Button::Down => Key(KEY_DOWN), "KEY_NUM_LOCK" => KeyboardKey::KEY_NUM_LOCK,
Button::Up => Key(KEY_UP), "KEY_PRINT_SCREEN" => KeyboardKey::KEY_PRINT_SCREEN,
Button::PageUp => Key(KEY_PAGE_UP), "KEY_PAUSE" => KeyboardKey::KEY_PAUSE,
Button::PageDown => Key(KEY_PAGE_DOWN), "KEY_F1" => KeyboardKey::KEY_F1,
Button::Home => Key(KEY_HOME), "KEY_F2" => KeyboardKey::KEY_F2,
Button::End => Key(KEY_END), "KEY_F3" => KeyboardKey::KEY_F3,
Button::CapsLock => Key(KEY_CAPS_LOCK), "KEY_F4" => KeyboardKey::KEY_F4,
Button::ScrollLock => Key(KEY_SCROLL_LOCK), "KEY_F5" => KeyboardKey::KEY_F5,
Button::NumLock => Key(KEY_NUM_LOCK), "KEY_F6" => KeyboardKey::KEY_F6,
Button::PrintScreen => Key(KEY_PRINT_SCREEN), "KEY_F7" => KeyboardKey::KEY_F7,
Button::Pause => Key(KEY_PAUSE), "KEY_F8" => KeyboardKey::KEY_F8,
Button::F1 => Key(KEY_F1), "KEY_F9" => KeyboardKey::KEY_F9,
Button::F2 => Key(KEY_F2), "KEY_F10" => KeyboardKey::KEY_F10,
Button::F3 => Key(KEY_F3), "KEY_F11" => KeyboardKey::KEY_F11,
Button::F4 => Key(KEY_F4), "KEY_F12" => KeyboardKey::KEY_F12,
Button::F5 => Key(KEY_F5), "KEY_LEFT_SHIFT" => KeyboardKey::KEY_LEFT_SHIFT,
Button::F6 => Key(KEY_F6), "KEY_LEFT_CONTROL" => KeyboardKey::KEY_LEFT_CONTROL,
Button::F7 => Key(KEY_F7), "KEY_LEFT_ALT" => KeyboardKey::KEY_LEFT_ALT,
Button::F8 => Key(KEY_F8), "KEY_LEFT_SUPER" => KeyboardKey::KEY_LEFT_SUPER,
Button::F9 => Key(KEY_F9), "KEY_RIGHT_SHIFT" => KeyboardKey::KEY_RIGHT_SHIFT,
Button::F10 => Key(KEY_F10), "KEY_RIGHT_CONTROL" => KeyboardKey::KEY_RIGHT_CONTROL,
Button::F11 => Key(KEY_F11), "KEY_RIGHT_ALT" => KeyboardKey::KEY_RIGHT_ALT,
Button::F12 => Key(KEY_F12), "KEY_RIGHT_SUPER" => KeyboardKey::KEY_RIGHT_SUPER,
Button::LShift => Key(KEY_LEFT_SHIFT), "KEY_KB_MENU" => KeyboardKey::KEY_KB_MENU,
Button::LCtrl => Key(KEY_LEFT_CONTROL), "KEY_KP_0" => KeyboardKey::KEY_KP_0,
Button::LAlt => Key(KEY_LEFT_ALT), "KEY_KP_1" => KeyboardKey::KEY_KP_1,
Button::LeftSuper => Key(KEY_LEFT_SUPER), "KEY_KP_2" => KeyboardKey::KEY_KP_2,
Button::RShift => Key(KEY_RIGHT_SHIFT), "KEY_KP_3" => KeyboardKey::KEY_KP_3,
Button::RCtrl => Key(KEY_RIGHT_CONTROL), "KEY_KP_4" => KeyboardKey::KEY_KP_4,
Button::RAlt => Key(KEY_RIGHT_ALT), "KEY_KP_5" => KeyboardKey::KEY_KP_5,
Button::RightSuper => Key(KEY_RIGHT_SUPER), "KEY_KP_6" => KeyboardKey::KEY_KP_6,
Button::Menu => Key(KEY_KB_MENU), "KEY_KP_7" => KeyboardKey::KEY_KP_7,
Button::Kp0 => Key(KEY_KP_0), "KEY_KP_8" => KeyboardKey::KEY_KP_8,
Button::Kp1 => Key(KEY_KP_1), "KEY_KP_9" => KeyboardKey::KEY_KP_9,
Button::Kp2 => Key(KEY_KP_2), "KEY_KP_DECIMAL" => KeyboardKey::KEY_KP_DECIMAL,
Button::Kp3 => Key(KEY_KP_3), "KEY_KP_DIVIDE" => KeyboardKey::KEY_KP_DIVIDE,
Button::Kp4 => Key(KEY_KP_4), "KEY_KP_MULTIPLY" => KeyboardKey::KEY_KP_MULTIPLY,
Button::Kp5 => Key(KEY_KP_5), "KEY_KP_SUBTRACT" => KeyboardKey::KEY_KP_SUBTRACT,
Button::Kp6 => Key(KEY_KP_6), "KEY_KP_ADD" => KeyboardKey::KEY_KP_ADD,
Button::Kp7 => Key(KEY_KP_7), "KEY_KP_ENTER" => KeyboardKey::KEY_KP_ENTER,
Button::Kp8 => Key(KEY_KP_8), "KEY_KP_EQUAL" => KeyboardKey::KEY_KP_EQUAL,
Button::Kp9 => Key(KEY_KP_9), "KEY_BACK" => KeyboardKey::KEY_BACK,
Button::KpDecimal => Key(KEY_KP_DECIMAL), "KEY_VOLUME_UP" => KeyboardKey::KEY_VOLUME_UP,
Button::KpDivide => Key(KEY_KP_DIVIDE), "KEY_VOLUME_DOWN" => KeyboardKey::KEY_VOLUME_DOWN,
Button::KpMultiply => Key(KEY_KP_MULTIPLY), _ => panic!("{key} not a known key name"),
Button::KpSubtract => Key(KEY_KP_SUBTRACT),
Button::KpAdd => Key(KEY_KP_ADD),
Button::KpEnter => Key(KEY_KP_ENTER),
Button::KpEqual => Key(KEY_KP_EQUAL),
Button::Back => Key(KEY_BACK),
Button::VolumeUp => Key(KEY_VOLUME_UP),
Button::VolumeDown => Key(KEY_VOLUME_DOWN),
Button::_EnumSize => unreachable!(),
}
} }
} }