Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:44:28.715Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

gestures.rs

124 lines · 4.6 KB · rust
1//! Touch gesture recognition vocabulary.
2//!
3//! GPUI recognizes gestures from raw [`TouchEvent`](crate::TouchEvent)s in a
4//! single, portable arena in gpui core: recognizers compete for in-flight
5//! touches, winners claim them, and losers are cancelled. Recognized gestures
6//! are surfaced through *existing* semantic events wherever possible, a tap
7//! becomes [`ClickEvent::Touch`](crate::ClickEvent), a pan becomes
8//! [`ScrollWheelEvent`](crate::ScrollWheelEvent)s carrying a
9//! [`TouchPhase`](crate::TouchPhase), and a pinch becomes
10//! [`PinchEvent`](crate::PinchEvent)s — so components written against
11//! `on_click` and scroll containers work untouched on mobile.
12
13use std::time::Duration;
14
15use crate::{Pixels, Point, px};
16
17/// Feel constants consumed by gesture recognizers. Provided on a best-effort
18/// basis, depending on each platform's support, defaulting to GPUI's own
19/// (iOS flavored) values
20#[derive(Clone, Copy, Debug, PartialEq)]
21pub struct GestureTuning {
22    /// Distance a touch may travel before it stops being a potential tap and
23    /// becomes a pan/drag.
24    pub touch_slop: Pixels,
25    /// Maximum interval between taps for them to accumulate a tap count.
26    pub multi_tap_interval: Duration,
27    /// Maximum distance between taps for them to accumulate a tap count.
28    pub multi_tap_slop: Pixels,
29    /// How long a touch must remain within [`Self::touch_slop`] to be
30    /// recognized as a long press.
31    pub long_press_duration: Duration,
32    /// Per-millisecond decay factor applied to scroll momentum after a fling.
33    /// (`UIScrollView` uses `0.998` per millisecond for its normal
34    /// deceleration rate.)
35    pub momentum_decay_per_ms: f32,
36    /// Minimum release velocity, in pixels per second, required to start
37    /// scroll momentum.
38    pub min_fling_velocity: f32,
39}
40
41impl Default for GestureTuning {
42    fn default() -> Self {
43        Self {
44            touch_slop: px(8.),
45            multi_tap_interval: Duration::from_millis(400),
46            multi_tap_slop: px(16.),
47            long_press_duration: Duration::from_millis(500),
48            momentum_decay_per_ms: 0.998,
49            min_fling_velocity: 50.,
50        }
51    }
52}
53
54/// The set of gesture kinds that participate in recognition.
55///
56/// Used by [`PlatformGestures::native_recognizers`] to declare which gestures
57/// the platform recognizes natively rather than leaving to gpui core's
58/// portable recognizers.
59#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
60pub struct GestureKinds {
61    /// Tap (and multi-tap), surfaced as [`ClickEvent::Touch`](crate::ClickEvent).
62    pub tap: bool,
63    /// Long press, surfaced as [`LongPressEvent`].
64    pub long_press: bool,
65    /// Pan/scroll (including fling momentum), surfaced as
66    /// [`ScrollWheelEvent`](crate::ScrollWheelEvent)s.
67    pub pan: bool,
68    /// Pinch to zoom, surfaced as [`PinchEvent`](crate::PinchEvent)s.
69    pub pinch: bool,
70}
71
72impl GestureKinds {
73    /// No gestures; gpui core's portable recognizers handle everything.
74    pub const NONE: Self = Self {
75        tap: false,
76        long_press: false,
77        pan: false,
78        pinch: false,
79    };
80
81    /// All gesture kinds.
82    pub const ALL: Self = Self {
83        tap: true,
84        long_press: true,
85        pan: true,
86        pinch: true,
87    };
88}
89
90/// A long-press gesture, mobile's context-menu trigger.
91///
92/// A bare long press is surfaced as a [`ClickEvent`](crate::ClickEvent) with
93/// `long_press: true`, delivered to aux-click listeners alongside right
94/// clicks. This event is the raw hook for elements that need the gesture
95/// itself (e.g. long-press to start a drag); the registration API ships
96/// together with the gesture arena.
97#[derive(Clone, Debug, Default)]
98pub struct LongPressEvent {
99    /// The position of the touch that was recognized as a long press.
100    pub position: Point<Pixels>,
101}
102
103/// Platform gesture recognition services.
104///
105/// If your mobile platform supports native gesture recognition, use this
106/// to share it with GPUI.
107pub trait PlatformGestures {
108    /// Feel constants for the portable recognizers on this platform.
109    fn tuning(&self) -> GestureTuning {
110        GestureTuning::default()
111    }
112
113    /// The gesture kinds this platform recognizes natively.
114    fn native_recognizers(&self) -> GestureKinds {
115        GestureKinds::NONE
116    }
117}
118
119/// A no-op [`PlatformGestures`] implementation: no native recognizers and
120/// default tuning. Suitable for desktop platforms and tests.
121pub struct NullPlatformGestures;
122
123impl PlatformGestures for NullPlatformGestures {}
124
Served at tenant.openagents/omega Member data and write actions are omitted.