"""Key, button, and axis enumerations for the input system."""
from __future__ import annotations
from enum import IntEnum
[docs]
class Key(IntEnum):
"""Keyboard key codes (matching GLFW key values)."""
# Printable keys
SPACE = 32
APOSTROPHE = 39 # '
COMMA = 44 # ,
MINUS = 45 # -
PERIOD = 46 # .
SLASH = 47 # /
# Digits
KEY_0 = 48
KEY_1 = 49
KEY_2 = 50
KEY_3 = 51
KEY_4 = 52
KEY_5 = 53
KEY_6 = 54
KEY_7 = 55
KEY_8 = 56
KEY_9 = 57
SEMICOLON = 59 # ;
EQUAL = 61 # =
# Letters
A = 65
B = 66
C = 67
D = 68
E = 69
F = 70
G = 71
H = 72
I = 73 # noqa: E741
J = 74
K = 75
L = 76
M = 77
N = 78
O = 79 # noqa: E741
P = 80
Q = 81
R = 82
S = 83
T = 84
U = 85
V = 86
W = 87
X = 88
Y = 89
Z = 90
LEFT_BRACKET = 91 # [
BACKSLASH = 92 # backslash
RIGHT_BRACKET = 93 # ]
GRAVE_ACCENT = 96 # `
# Function keys
ESCAPE = 256
ENTER = 257
TAB = 258
BACKSPACE = 259
INSERT = 260
DELETE = 261
RIGHT = 262
LEFT = 263
DOWN = 264
UP = 265
PAGE_UP = 266
PAGE_DOWN = 267
HOME = 268
END = 269
CAPS_LOCK = 280
SCROLL_LOCK = 281
NUM_LOCK = 282
PRINT_SCREEN = 283
PAUSE = 284
F1 = 290
F2 = 291
F3 = 292
F4 = 293
F5 = 294
F6 = 295
F7 = 296
F8 = 297
F9 = 298
F10 = 299
F11 = 300
F12 = 301
# Keypad
KP_0 = 320
KP_1 = 321
KP_2 = 322
KP_3 = 323
KP_4 = 324
KP_5 = 325
KP_6 = 326
KP_7 = 327
KP_8 = 328
KP_9 = 329
KP_DECIMAL = 330
KP_DIVIDE = 331
KP_MULTIPLY = 332
KP_SUBTRACT = 333
KP_ADD = 334
KP_ENTER = 335
# Modifiers
LEFT_SHIFT = 340
LEFT_CONTROL = 341
LEFT_ALT = 342
LEFT_SUPER = 343
RIGHT_SHIFT = 344
RIGHT_CONTROL = 345
RIGHT_ALT = 346
RIGHT_SUPER = 347
MENU = 348
[docs]
class JoyAxis(IntEnum):
"""Gamepad axis codes."""
LEFT_X = 0
LEFT_Y = 1
RIGHT_X = 2
RIGHT_Y = 3
LEFT_TRIGGER = 4
RIGHT_TRIGGER = 5
[docs]
class MouseCaptureMode(IntEnum):
"""Mouse cursor capture modes."""
VISIBLE = 0
HIDDEN = 1
CAPTURED = 2
CONFINED = 3
# ============================================================================
# Key <-> string name mapping
# ============================================================================
_KEY_TO_NAME: dict[Key, str] = {
Key.SPACE: "space",
Key.APOSTROPHE: "'",
Key.COMMA: ",",
Key.MINUS: "-",
Key.PERIOD: ".",
Key.SLASH: "/",
Key.KEY_0: "0",
Key.KEY_1: "1",
Key.KEY_2: "2",
Key.KEY_3: "3",
Key.KEY_4: "4",
Key.KEY_5: "5",
Key.KEY_6: "6",
Key.KEY_7: "7",
Key.KEY_8: "8",
Key.KEY_9: "9",
Key.SEMICOLON: ";",
Key.EQUAL: "=",
Key.LEFT_BRACKET: "[",
Key.BACKSLASH: "\\",
Key.RIGHT_BRACKET: "]",
Key.GRAVE_ACCENT: "`",
Key.ESCAPE: "escape",
Key.ENTER: "enter",
Key.TAB: "tab",
Key.BACKSPACE: "backspace",
Key.INSERT: "insert",
Key.DELETE: "delete",
Key.RIGHT: "right",
Key.LEFT: "left",
Key.DOWN: "down",
Key.UP: "up",
Key.PAGE_UP: "pageup",
Key.PAGE_DOWN: "pagedown",
Key.HOME: "home",
Key.END: "end",
Key.LEFT_SHIFT: "shift",
Key.LEFT_CONTROL: "ctrl",
Key.LEFT_ALT: "alt",
Key.RIGHT_SHIFT: "shift",
Key.RIGHT_CONTROL: "ctrl",
Key.RIGHT_ALT: "alt",
Key.LEFT_SUPER: "super",
Key.RIGHT_SUPER: "super",
}
# Add letter keys
for _k in range(Key.A, Key.Z + 1):
_KEY_TO_NAME[Key(_k)] = chr(_k + 32) # 'a'..'z'
# Add function keys
for _i in range(1, 13):
_KEY_TO_NAME[Key(289 + _i)] = f"f{_i}"
# Reverse mapping: string name -> list of Key values (some names map to multiple keys)
_NAME_TO_KEYS: dict[str, list[Key]] = {}
for _key, _name in _KEY_TO_NAME.items():
_NAME_TO_KEYS.setdefault(_name, []).append(_key)
[docs]
def key_to_name(key: Key) -> str:
"""Convert a Key enum to its string name."""
return _KEY_TO_NAME.get(key, f"key_{int(key)}")
[docs]
def name_to_keys(name: str) -> list[Key]:
"""Convert a string key name to matching Key enum values."""
return _NAME_TO_KEYS.get(name, [])