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}
118
119/// Mouse buttons.
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122pub enum MouseButton {
123 /// Primary (left) mouse button.
124 Left,
125 /// Secondary (right) mouse button.
126 Right,
127 /// Middle mouse button (scroll wheel click).
128 Middle,
129}
130
131/// What physical input fires the trigger.
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
133#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
134pub enum TriggerKind {
135 /// A keyboard key.
136 Key(KeyCode),
137 /// A mouse button.
138 MouseButton(MouseButton),
139 /// The scroll wheel (used with `OnScroll` activation).
140 Scroll,
141}
142
143/// How the trigger activates the action.
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
145#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
146pub enum ActivationMode {
147 /// Fires once on key/button press.
148 OnPress,
149 /// Active every frame while held.
150 WhileHeld,
151 /// Active while dragging (mouse button held + moved).
152 OnDrag,
153 /// Active when scroll wheel moves.
154 OnScroll,
155}
156
157/// A physical trigger that can activate an action.
158#[derive(Debug, Clone)]
159#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
160pub struct Trigger {
161 /// The physical input kind (key, mouse button, or scroll).
162 pub kind: TriggerKind,
163 /// Required modifier state (exact match unless `ignore_modifiers` is set).
164 pub modifiers: Modifiers,
165 /// How the trigger fires relative to the input event.
166 pub activation: ActivationMode,
167 /// When true, modifier keys are not checked. Useful for fly-mode WASD
168 /// so that holding Shift for speed boost doesn't break movement keys.
169 pub ignore_modifiers: bool,
170}
171
172/// Maps an action to a physical trigger, optionally restricted to specific modes.
173#[derive(Debug, Clone)]
174#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
175pub struct Binding {
176 /// The semantic action this binding fires.
177 pub action: Action,
178 /// The physical trigger that fires the action.
179 pub trigger: Trigger,
180 /// Which input modes this binding is active in. Empty = all modes.
181 pub active_modes: Vec<InputMode>,
182}
183
184impl Binding {
185 /// Convenience: create a binding active in all modes.
186 pub fn global(action: Action, trigger: Trigger) -> Self {
187 Self {
188 action,
189 trigger,
190 active_modes: Vec::new(),
191 }
192 }
193
194 /// Convenience: create a binding active only in the given modes.
195 pub fn in_modes(action: Action, trigger: Trigger, modes: &[InputMode]) -> Self {
196 Self {
197 action,
198 trigger,
199 active_modes: modes.to_vec(),
200 }
201 }
202}