Skip to main content

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