viewport_lib/interaction/input/binding.rs
1//! Input binding types: triggers, modifiers, and bindings that map actions to physical inputs.
2
3use super::action::Action;
4use super::mode::InputMode;
5
6/// Modifier key state : exact-match semantics (all must match).
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct Modifiers {
10 /// Alt/Option key held.
11 pub alt: bool,
12 /// Shift key held.
13 pub shift: bool,
14 /// Ctrl/Cmd key held.
15 pub ctrl: bool,
16}
17
18impl Modifiers {
19 /// No modifier keys held.
20 pub const NONE: Self = Self {
21 alt: false,
22 shift: false,
23 ctrl: false,
24 };
25 /// Only Alt held.
26 pub const ALT: Self = Self {
27 alt: true,
28 shift: false,
29 ctrl: false,
30 };
31 /// Only Shift held.
32 pub const SHIFT: Self = Self {
33 alt: false,
34 shift: true,
35 ctrl: false,
36 };
37 /// Only Ctrl held.
38 pub const CTRL: Self = Self {
39 alt: false,
40 shift: false,
41 ctrl: true,
42 };
43 /// Ctrl + Shift held.
44 pub const CTRL_SHIFT: Self = Self {
45 alt: false,
46 shift: true,
47 ctrl: true,
48 };
49}
50
51/// Keyboard key codes : subset covering keys used in the default bindings.
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54pub enum KeyCode {
55 /// Letter key A.
56 A,
57 /// Letter key B.
58 B,
59 /// Letter key C.
60 C,
61 /// Letter key D.
62 D,
63 /// Letter key E.
64 E,
65 /// Letter key F.
66 F,
67 /// Letter key G.
68 G,
69 /// Letter key H.
70 H,
71 /// Letter key I.
72 I,
73 /// Letter key J.
74 J,
75 /// Letter key K.
76 K,
77 /// Letter key L.
78 L,
79 /// Letter key M.
80 M,
81 /// Letter key N.
82 N,
83 /// Letter key O.
84 O,
85 /// Letter key P.
86 P,
87 /// Letter key Q.
88 Q,
89 /// Letter key R.
90 R,
91 /// Letter key S.
92 S,
93 /// Letter key T.
94 T,
95 /// Letter key U.
96 U,
97 /// Letter key V.
98 V,
99 /// Letter key W.
100 W,
101 /// Letter key X.
102 X,
103 /// Letter key Y.
104 Y,
105 /// Letter key Z.
106 Z,
107 /// Tab key.
108 Tab,
109 /// Enter/Return key.
110 Enter,
111 /// Escape key.
112 Escape,
113 /// Backtick/grave-accent key.
114 Backtick,
115 /// Backspace key.
116 Backspace,
117 /// Comma key.
118 Comma,
119 /// Period/full-stop key.
120 Period,
121 /// Left square bracket `[` key.
122 LeftBracket,
123 /// Right square bracket `]` key.
124 RightBracket,
125 /// Forward-slash `/` key.
126 Slash,
127}
128
129/// Mouse buttons.
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
132pub enum MouseButton {
133 /// Primary (left) mouse button.
134 Left,
135 /// Secondary (right) mouse button.
136 Right,
137 /// Middle mouse button (scroll wheel click).
138 Middle,
139}
140
141/// What physical input fires the trigger.
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
143#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
144pub enum TriggerKind {
145 /// A keyboard key.
146 Key(KeyCode),
147 /// A mouse button.
148 MouseButton(MouseButton),
149 /// The scroll wheel (used with `OnScroll` activation).
150 Scroll,
151}
152
153/// How the trigger activates the action.
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
156pub enum ActivationMode {
157 /// Fires once on key/button press.
158 OnPress,
159 /// Active every frame while held.
160 WhileHeld,
161 /// Active while dragging (mouse button held + moved).
162 OnDrag,
163 /// Active when scroll wheel moves.
164 OnScroll,
165}
166
167/// A physical trigger that can activate an action.
168#[derive(Debug, Clone)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
170pub struct Trigger {
171 /// The physical input kind (key, mouse button, or scroll).
172 pub kind: TriggerKind,
173 /// Required modifier state (exact match unless `ignore_modifiers` is set).
174 pub modifiers: Modifiers,
175 /// How the trigger fires relative to the input event.
176 pub activation: ActivationMode,
177 /// When true, modifier keys are not checked. Useful for fly-mode WASD
178 /// so that holding Shift for speed boost doesn't break movement keys.
179 pub ignore_modifiers: bool,
180}
181
182/// Maps an action to a physical trigger, optionally restricted to specific modes.
183#[derive(Debug, Clone)]
184#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
185pub struct Binding {
186 /// The semantic action this binding fires.
187 pub action: Action,
188 /// The physical trigger that fires the action.
189 pub trigger: Trigger,
190 /// Which input modes this binding is active in. Empty = all modes.
191 pub active_modes: Vec<InputMode>,
192}
193
194impl Binding {
195 /// Convenience: create a binding active in all modes.
196 pub fn global(action: Action, trigger: Trigger) -> Self {
197 Self {
198 action,
199 trigger,
200 active_modes: Vec::new(),
201 }
202 }
203
204 /// Convenience: create a binding active only in the given modes.
205 pub fn in_modes(action: Action, trigger: Trigger, modes: &[InputMode]) -> Self {
206 Self {
207 action,
208 trigger,
209 active_modes: modes.to_vec(),
210 }
211 }
212}