Skip to main content

concinnity_core/components/
frame_input.rs

1// src/components/frame_input.rs
2
3/// Per-frame keyboard and mouse input state.
4///
5/// One `FrameInput` is updated each frame from the window's keyboard and mouse
6/// state and read by camera and UI behavior. It is maintained automatically and
7/// is never saved with the world.
8#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
9pub struct FrameInput {
10    /// True while the move-forward key (W) is held.
11    pub forward: bool,
12    /// True while the move-backward key (S) is held.
13    pub backward: bool,
14    /// True while the strafe-left key (A) is held.
15    pub left: bool,
16    /// True while the strafe-right key (D) is held.
17    pub right: bool,
18    /// True while the sprint key (Shift) is held.
19    pub sprint: bool,
20    /// True for exactly one frame when the interact key (E) is pressed.
21    pub interact: bool,
22    /// True for exactly one frame when the jump key (Space) is pressed.
23    pub jump: bool,
24    /// True while the Control key is held. A modifier used by UI (e.g. a story
25    /// fast-forwards its dialogue while it is down). Like [escape](#structfield.escape)
26    /// and [captured_key](#structfield.captured_key) it is not frozen while a
27    /// menu is open.
28    pub ctrl: bool,
29    /// True while the Shift key is held. A modifier used by UI (e.g. additive
30    /// selection in the editor). Unlike [sprint](#structfield.sprint) it is
31    /// not frozen while a menu is open, matching [ctrl](#structfield.ctrl).
32    pub shift: bool,
33    /// True while the Alt (Option) key is held. A modifier used by UI (e.g.
34    /// the editor's orbit drag). Not frozen while a menu is open, matching
35    /// [ctrl](#structfield.ctrl).
36    pub alt: bool,
37    /// True while the platform's command modifier is held: the Command key on
38    /// macOS, where application shortcuts are built on it. Windows and Linux
39    /// leave this false and use [ctrl](#structfield.ctrl) instead, since the
40    /// Super key there belongs to the desktop shell. UI that offers a shortcut
41    /// on both accepts either modifier. Not frozen while a menu is open,
42    /// matching [ctrl](#structfield.ctrl).
43    pub cmd: bool,
44    /// Gamepad left-stick movement vector `[x, y]`: `x` is rightward strafe,
45    /// `y` is forward. Radial deadzone applied, magnitude at most 1, so partial
46    /// deflection walks slower. `[0.0, 0.0]` with no gamepad; frozen (zeroed)
47    /// while a menu is open, like the movement keys.
48    pub move_axis: [f32; 2],
49    /// Gamepad right-stick look vector `[x, y]` in the mouse-delta sign
50    /// convention (positive `x` looks right, positive `y` looks down), with
51    /// deadzone and response curve applied, magnitude at most 1. Unlike the
52    /// pixel-based mouse deltas this is a deflection rate: consumers scale it
53    /// by their look speed and the frame time. Frozen while a menu is open.
54    pub look_axis: [f32; 2],
55    /// The gamepad button pressed this frame, for one frame, or `None`.
56    /// Surfaced regardless of menu state (like
57    /// [captured_key](#structfield.captured_key)) so the settings menu can
58    /// capture a button for rebinding.
59    pub captured_button: Option<crate::components::GamepadButton>,
60    /// The UI-navigation pulse this frame, or `None`. A one-frame
61    /// [NavDirection](#navdirection) produced from a d-pad press (repeating
62    /// while held) or a deliberate left-stick deflection. Surfaced regardless
63    /// of menu state (like [captured_key](#structfield.captured_key)); menu
64    /// focus movement consumes it only while a screen is active, so during
65    /// play the d-pad and stick keep their movement meaning.
66    pub nav: Option<crate::components::NavDirection>,
67    /// True for exactly one frame when the confirm button (South) is pressed.
68    /// Surfaced regardless of menu state; menus fire their focused control
69    /// from it while a screen is active.
70    pub confirm: bool,
71    /// True for exactly one frame when the back button (East) is pressed.
72    /// Surfaced regardless of menu state; menus treat it like Escape while a
73    /// screen is active.
74    pub back: bool,
75    /// Accumulated horizontal mouse movement since the last frame (pixels).
76    pub mouse_dx: f32,
77    /// Accumulated vertical mouse movement since the last frame (pixels).
78    pub mouse_dy: f32,
79    /// Accumulated vertical scroll-wheel movement since the last frame. Positive
80    /// scrolls the content up (a scrollable UI panel moves its rows up). Cleared
81    /// each frame like the mouse deltas.
82    pub scroll_delta: f32,
83    /// Absolute cursor X position in window pixels (origin top-left).
84    /// Only meaningful when the cursor is not captured.
85    pub mouse_x: f32,
86    /// Absolute cursor Y position in window pixels (origin top-left).
87    /// Only meaningful when the cursor is not captured.
88    pub mouse_y: f32,
89    /// True for exactly one frame when the left mouse button is pressed
90    /// while the cursor is not captured.
91    pub left_click: bool,
92    /// True while the left mouse button is held down (cursor not captured).
93    /// Unlike `left_click` this stays true across frames until release, so a
94    /// UI drag (e.g. a slider) can track the cursor for its whole duration.
95    pub left_button_down: bool,
96    /// True for exactly one frame when the right mouse button is pressed
97    /// while the cursor is not captured. Used for contextual UI (e.g. a
98    /// create-at-cursor menu); it never captures the cursor.
99    pub right_click: bool,
100    /// Live logical viewport size in pixels `[width, height]`. Used to map
101    /// overlay (Screen-owned) UI between its fixed reference resolution and the
102    /// window, so menus scale with the window and the cursor still hit-tests
103    /// against the scaled controls. `[0.0, 0.0]` before the backend is ready.
104    pub viewport: [f32; 2],
105    /// True for exactly one frame when the HUD-toggle key (F1) is pressed.
106    pub hud_toggle: bool,
107    /// True for exactly one frame when Escape is pressed while the cursor is
108    /// not captured (menu / UI worlds). Used to fire [KeyBinding](#keybinding)
109    /// actions. In worlds that capture the cursor, Escape instead releases the
110    /// cursor and this stays false.
111    pub escape: bool,
112    /// The canonical key pressed this frame, for one frame, or `None`. Surfaced
113    /// regardless of menu state (unlike the gameplay keys, which freeze while a
114    /// menu is open) so the settings menu can capture a key for rebinding and
115    /// scrollable menu lists can react to the arrow keys.
116    pub captured_key: Option<crate::components::InputKey>,
117    /// The printable character typed this frame (Unicode, with shift / layout
118    /// applied by the OS), for text-input fields, or `None`. A one-frame pulse
119    /// surfaced regardless of menu state, like
120    /// [captured_key](#structfield.captured_key). Editing keys (Backspace,
121    /// Delete, arrows) arrive via `captured_key`, not here.
122    pub typed_char: Option<char>,
123}