Skip to main content

flatland_client_ui/
input.rs

1//! Engine-neutral keyboard and pointer events.
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum UiKeyEventKind {
5    Press,
6    Release,
7    Repeat,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
11pub struct UiKeyModifiers {
12    pub shift: bool,
13    pub control: bool,
14    pub alt: bool,
15}
16
17impl UiKeyModifiers {
18    pub fn contains_shift(self) -> bool {
19        self.shift
20    }
21
22    pub fn contains_control(self) -> bool {
23        self.control
24    }
25
26    pub fn contains_alt(self) -> bool {
27        self.alt
28    }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum UiKeyCode {
33    Char(char),
34    Up,
35    Down,
36    Left,
37    Right,
38    Esc,
39    Enter,
40    Tab,
41    BackTab,
42    PageUp,
43    PageDown,
44    Delete,
45    Backspace,
46    Space,
47    ShiftLeft,
48    ShiftRight,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub struct UiKeyEvent {
53    pub kind: UiKeyEventKind,
54    pub code: UiKeyCode,
55    pub modifiers: UiKeyModifiers,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum UiMouseButton {
60    Left,
61    Right,
62    Middle,
63}
64
65#[derive(Debug, Clone, Copy, PartialEq)]
66pub enum UiPointerEvent {
67    Move {
68        x: f32,
69        y: f32,
70    },
71    Click {
72        x: f32,
73        y: f32,
74        button: UiMouseButton,
75        /// True when Shift was held at click time (T2 combat targeting).
76        shift: bool,
77    },
78    Scroll {
79        x: f32,
80        y: f32,
81        delta: f32,
82    },
83}
84
85/// Number-row digit from a typed char (US QWERTY).
86///
87/// Shift+digit may arrive as `'1'` (macOS / physical `Key1`) or the shifted
88/// glyph `'!'` (Linux X11/Wayland `get_char_pressed`). Use this whenever a
89/// shortcut is bound to `1`–`9` / `0` rather than the punctuation itself.
90pub fn digit_from_typed_char(c: char) -> Option<u8> {
91    Some(match c {
92        '0' | ')' => 0,
93        '1' | '!' => 1,
94        '2' | '@' => 2,
95        '3' | '#' => 3,
96        '4' | '$' => 4,
97        '5' | '%' => 5,
98        '6' | '^' => 6,
99        '7' | '&' => 7,
100        '8' | '*' => 8,
101        '9' | '(' => 9,
102        _ => return None,
103    })
104}
105
106/// Shifted US QWERTY glyph for a digit char (`'1'` → `'!'`).
107pub fn us_qwerty_shifted_digit(c: char) -> Option<char> {
108    Some(match c {
109        '0' => ')',
110        '1' => '!',
111        '2' => '@',
112        '3' => '#',
113        '4' => '$',
114        '5' => '%',
115        '6' => '^',
116        '7' => '&',
117        '8' => '*',
118        '9' => '(',
119        _ => return None,
120    })
121}
122
123#[cfg(test)]
124mod tests {
125    use super::*;
126
127    #[test]
128    fn digit_from_typed_char_accepts_shift_glyphs() {
129        assert_eq!(digit_from_typed_char('1'), Some(1));
130        assert_eq!(digit_from_typed_char('!'), Some(1));
131        assert_eq!(digit_from_typed_char('5'), Some(5));
132        assert_eq!(digit_from_typed_char('%'), Some(5));
133        assert_eq!(digit_from_typed_char('0'), Some(0));
134        assert_eq!(digit_from_typed_char(')'), Some(0));
135        assert_eq!(digit_from_typed_char('a'), None);
136        assert_eq!(digit_from_typed_char('A'), None);
137    }
138}