Skip to main content

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 [`crate::camera::controllers::orbit::OrbitCameraController::apply_to_camera`] and
38/// available from [`super::viewport_input::ViewportInput`] after a frame.
39#[non_exhaustive]
40#[derive(Debug, Clone, Default)]
41pub struct ActionFrame {
42    /// Resolved camera navigation actions.
43    pub navigation: NavigationActions,
44    /// General action states resolved this frame (key presses, holds, etc.).
45    pub actions: HashMap<Action, ResolvedActionState>,
46    /// Characters typed this frame, for numeric manipulation input.
47    ///
48    /// Only populated when the app forwards [`super::event::ViewportEvent::Character`]
49    /// events (which it should do only while `ManipulationController::is_active()`).
50    /// Already filtered to `0-9`, `.`, `-` by the input layer.
51    pub typed_chars: Vec<char>,
52}
53
54impl ActionFrame {
55    /// Returns the resolved state for the given action, if active this frame.
56    pub fn action(&self, action: Action) -> Option<&ResolvedActionState> {
57        self.actions.get(&action)
58    }
59
60    /// Returns `true` if the action is active (pressed, held, or producing a delta) this frame.
61    pub fn is_active(&self, action: Action) -> bool {
62        self.actions.contains_key(&action)
63    }
64}