viewport_lib/interaction/input/action_frame.rs
1//! Per-frame resolved action output for the new input pipeline.
2
3use std::collections::HashMap;
4
5use super::action::Action;
6
7/// State of a resolved action for one frame.
8#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum ResolvedActionState {
10 /// The action was triggered this frame (KeyPress).
11 Pressed,
12 /// The action is actively held (KeyHold, Drag in progress).
13 Held,
14 /// The action is producing a two-axis delta (Drag, WheelXY).
15 Delta(glam::Vec2),
16}
17
18/// Resolved navigation actions for one frame.
19///
20/// Produced by [`super::viewport_input::ViewportInput`] after processing all
21/// events for a frame. Non-zero fields indicate active input in that direction.
22#[derive(Debug, Clone, Default)]
23pub struct NavigationActions {
24 /// Orbit delta in radians (x = yaw, y = pitch). Zero if no orbit input.
25 pub orbit: glam::Vec2,
26 /// Pan delta in viewport-local pixels (x = right, y = down). Zero if no pan input.
27 pub pan: glam::Vec2,
28 /// Zoom factor delta. Positive = zoom in. Zero if no zoom input.
29 pub zoom: f32,
30 /// Two-finger trackpad rotation gesture delta, in radians.
31 /// Positive = counter-clockwise. Zero if no gesture this frame.
32 pub twist: f32,
33}
34
35/// Per-frame resolved action output.
36///
37/// Returned by [`super::controller::OrbitCameraController::apply_to_camera`] and
38/// available from [`super::viewport_input::ViewportInput`] after a frame.
39#[derive(Debug, Clone, Default)]
40pub struct ActionFrame {
41 /// Resolved camera navigation actions.
42 pub navigation: NavigationActions,
43 /// General action states resolved this frame (key presses, holds, etc.).
44 pub actions: HashMap<Action, ResolvedActionState>,
45 /// Characters typed this frame, for numeric manipulation input.
46 ///
47 /// Only populated when the app forwards [`super::event::ViewportEvent::Character`]
48 /// events (which it should do only while `ManipulationController::is_active()`).
49 /// Already filtered to `0-9`, `.`, `-` by the input layer.
50 pub typed_chars: Vec<char>,
51}
52
53impl ActionFrame {
54 /// Returns the resolved state for the given action, if active this frame.
55 pub fn action(&self, action: Action) -> Option<&ResolvedActionState> {
56 self.actions.get(&action)
57 }
58
59 /// Returns `true` if the action is active (pressed, held, or producing a delta) this frame.
60 pub fn is_active(&self, action: Action) -> bool {
61 self.actions.contains_key(&action)
62 }
63}