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    /// 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}