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