Skip to main content

input_pipeline/
utils.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// TODO(https://fxbug.dev/494333485): Delete this module in favor of using the autogenerated
6// fidl_next conversions, once available.
7
8use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
9
10pub fn duplicate_view_ref_next(
11    view_ref: &fidl_next_fuchsia_ui_views::ViewRef,
12) -> Result<fidl_next_fuchsia_ui_views::ViewRef, fidl::Status> {
13    let handle = view_ref.reference.as_handle_ref().duplicate(fidl::Rights::SAME_RIGHTS)?;
14    Ok(fidl_next_fuchsia_ui_views::ViewRef { reference: handle.into() })
15}
16
17pub fn axis_to_next(
18    axis: Option<&fidl_fuchsia_input_report::Axis>,
19) -> Option<fidl_next_fuchsia_input_report::Axis> {
20    axis.map(|a| fidl_next_fuchsia_input_report::Axis {
21        range: fidl_next_fuchsia_input_report::Range { min: a.range.min, max: a.range.max },
22        unit: fidl_next_fuchsia_input_report::Unit {
23            type_: a.unit.type_.into_primitive().into(),
24            exponent: a.unit.exponent,
25        },
26    })
27}
28
29pub fn axis_to_old(
30    axis: Option<&fidl_next_fuchsia_input_report::Axis>,
31) -> Option<fidl_fuchsia_input_report::Axis> {
32    axis.map(|a| fidl_fuchsia_input_report::Axis {
33        range: fidl_fuchsia_input_report::Range { min: a.range.min, max: a.range.max },
34        unit: unit_to_old(&a.unit),
35    })
36}
37
38pub fn viewport_to_next(
39    viewport: &fidl_fuchsia_ui_pointerinjector::Viewport,
40) -> fidl_next_fuchsia_ui_pointerinjector::Viewport {
41    fidl_next_fuchsia_ui_pointerinjector::Viewport {
42        extents: viewport.extents.clone(),
43        viewport_to_context_transform: viewport.viewport_to_context_transform.clone(),
44    }
45}
46
47pub fn range_to_old(
48    range: &fidl_next_fuchsia_input_report::Range,
49) -> fidl_fuchsia_input_report::Range {
50    fidl_fuchsia_input_report::Range { min: range.min, max: range.max }
51}
52
53pub fn unit_to_old(unit: &fidl_next_fuchsia_input_report::Unit) -> fidl_fuchsia_input_report::Unit {
54    let discriminant: u32 =
55        unsafe { *(&unit.type_ as *const fidl_next_fuchsia_input_report::UnitType as *const u32) };
56    fidl_fuchsia_input_report::Unit {
57        type_: fidl_fuchsia_input_report::UnitType::from_primitive_allow_unknown(discriminant),
58        exponent: unit.exponent,
59    }
60}
61
62pub fn key_to_old(key: &fidl_next_fuchsia_input::Key) -> fidl_fuchsia_input::Key {
63    let discriminant: u32 = unsafe { *(key as *const fidl_next_fuchsia_input::Key as *const u32) };
64    fidl_fuchsia_input::Key::from_primitive_allow_unknown(discriminant)
65}
66
67#[cfg(test)]
68pub fn key_to_next(key: &fidl_fuchsia_input::Key) -> fidl_next_fuchsia_input::Key {
69    let discriminant = key.into_primitive();
70    fidl_next_fuchsia_input::Key::from(discriminant)
71}
72
73#[cfg(test)]
74pub fn touch_button_to_next(
75    button: &fidl_fuchsia_input_report::TouchButton,
76) -> fidl_next_fuchsia_input_report::TouchButton {
77    let discriminant = button.into_primitive();
78    fidl_next_fuchsia_input_report::TouchButton::from(discriminant)
79}
80
81pub fn consumer_control_button_to_old(
82    button: &fidl_next_fuchsia_input_report::ConsumerControlButton,
83) -> fidl_fuchsia_input_report::ConsumerControlButton {
84    let discriminant: u32 = unsafe {
85        *(button as *const fidl_next_fuchsia_input_report::ConsumerControlButton as *const u32)
86    };
87    fidl_fuchsia_input_report::ConsumerControlButton::from_primitive_allow_unknown(discriminant)
88}
89
90#[cfg(test)]
91pub fn consumer_control_button_to_next(
92    button: &fidl_fuchsia_input_report::ConsumerControlButton,
93) -> fidl_next_fuchsia_input_report::ConsumerControlButton {
94    let discriminant = button.into_primitive();
95    fidl_next_fuchsia_input_report::ConsumerControlButton::from(discriminant)
96}
97
98/// Cursor messages.
99#[derive(Debug, PartialEq)]
100pub enum CursorMessage {
101    /// Set the position of the cursor.
102    SetPosition(Position),
103    /// Set the visibility of the cursor.
104    SetVisibility(bool),
105}
106
107/// Represents a generic 2D position.
108#[derive(Clone, Copy, Debug, PartialEq)]
109pub struct Position {
110    /// The x component of the position, in pixels.
111    pub x: f32,
112
113    /// The y component of the position, in pixels.
114    pub y: f32,
115}
116
117impl Position {
118    pub fn clamp(target: &mut Position, min: Position, max: Position) {
119        if (*target).x < min.x {
120            (*target).x = min.x;
121        }
122        if (*target).x > max.x {
123            (*target).x = max.x;
124        }
125
126        if (*target).y < min.y {
127            (*target).y = min.y;
128        }
129        if (*target).y > max.y {
130            (*target).y = max.y;
131        }
132    }
133
134    pub fn clamp_size(target: &mut Position, min: Size, max: Size) {
135        if (*target).x < min.width {
136            (*target).x = min.width;
137        }
138        if (*target).x > max.width {
139            (*target).x = max.width;
140        }
141
142        if (*target).y < min.height {
143            (*target).y = min.height;
144        }
145        if (*target).y > max.height {
146            (*target).y = max.height;
147        }
148    }
149
150    pub fn zero() -> Position {
151        Position { x: 0.0, y: 0.0 }
152    }
153}
154
155impl Add for Position {
156    type Output = Self;
157
158    #[inline]
159    fn add(self, other: Self) -> Self {
160        Self { x: self.x + other.x, y: self.y + other.y }
161    }
162}
163
164impl AddAssign for Position {
165    #[inline]
166    fn add_assign(&mut self, other: Self) {
167        *self = Self { x: self.x + other.x, y: self.y + other.y };
168    }
169}
170
171impl Sub for Position {
172    type Output = Self;
173
174    #[inline]
175    fn sub(self, other: Self) -> Self {
176        Self { x: self.x - other.x, y: self.y - other.y }
177    }
178}
179
180impl SubAssign for Position {
181    #[inline]
182    fn sub_assign(&mut self, other: Self) {
183        *self = Self { x: self.x - other.x, y: self.y - other.y };
184    }
185}
186
187impl Div for Position {
188    type Output = Self;
189
190    #[inline]
191    fn div(self, other: Self) -> Self {
192        Self { x: self.x / other.x, y: self.y / other.y }
193    }
194}
195
196impl DivAssign for Position {
197    #[inline]
198    fn div_assign(&mut self, other: Self) {
199        *self = Self { x: self.x / other.x, y: self.y / other.y };
200    }
201}
202
203impl Mul for Position {
204    type Output = Self;
205
206    #[inline]
207    fn mul(self, other: Self) -> Self {
208        Self { x: self.x * other.x, y: self.y * other.y }
209    }
210}
211
212impl MulAssign for Position {
213    #[inline]
214    fn mul_assign(&mut self, other: Self) {
215        *self = Self { x: self.x * other.x, y: self.y * other.y };
216    }
217}
218
219impl Mul<Size> for Position {
220    type Output = Self;
221
222    #[inline]
223    fn mul(self, other: Size) -> Position {
224        Self { x: self.x * other.width, y: self.y * other.height }
225    }
226}
227
228macro_rules! scale_position_impl {
229    ($($t:ty)*) => ($(
230        impl Div<$t> for Position {
231            type Output = Position;
232
233            #[inline]
234            fn div(self, other: $t) -> Position {
235                Self { x: self.x / other as f32, y: self.y / other as f32 }
236            }
237        }
238
239        impl DivAssign<$t> for Position {
240            #[inline]
241            fn div_assign(&mut self, other: $t) {
242                *self = Self { x: self.x / other as f32, y: self.y / other as f32 };
243            }
244        }
245
246        impl Mul<$t> for Position {
247            type Output = Position;
248
249            #[inline]
250            fn mul(self, other: $t) -> Position {
251                Self { x: self.x * other as f32, y: self.y * other as f32 }
252            }
253        }
254
255        impl Mul<Position> for $t {
256            type Output = Position;
257
258            #[inline]
259            fn mul(self, other: Position) -> Position {
260                Position { x: self as f32 * other.x, y: self as f32 * other.y }
261            }
262        }
263
264        impl MulAssign<$t> for Position {
265            #[inline]
266            fn mul_assign(&mut self, other: $t) {
267                *self = Self { x: self.x * other as f32, y: self.y * other as f32 };
268            }
269        }
270    )*)
271}
272
273scale_position_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
274
275/// Represents a generic size.
276#[derive(Clone, Copy, Debug, PartialEq)]
277pub struct Size {
278    /// The width in pixels.
279    pub width: f32,
280
281    /// The height in pixels.
282    pub height: f32,
283}
284
285impl Size {
286    pub fn zero() -> Size {
287        Size { width: 0.0, height: 0.0 }
288    }
289}
290
291impl Add for Size {
292    type Output = Self;
293
294    #[inline]
295    fn add(self, other: Self) -> Self {
296        Self { width: self.width + other.width, height: self.height + other.height }
297    }
298}
299
300impl AddAssign for Size {
301    #[inline]
302    fn add_assign(&mut self, other: Self) {
303        *self = Self { width: self.width + other.width, height: self.height + other.height };
304    }
305}
306
307impl Sub for Size {
308    type Output = Self;
309
310    #[inline]
311    fn sub(self, other: Self) -> Self {
312        Self { width: self.width - other.width, height: self.height - other.height }
313    }
314}
315
316impl SubAssign for Size {
317    fn sub_assign(&mut self, other: Self) {
318        *self = Self { width: self.width - other.width, height: self.height - other.height };
319    }
320}
321
322impl Div for Size {
323    type Output = Self;
324
325    #[inline]
326    fn div(self, other: Self) -> Self {
327        Self { width: self.width / other.width, height: self.height / other.height }
328    }
329}
330
331impl DivAssign for Size {
332    #[inline]
333    fn div_assign(&mut self, other: Self) {
334        *self = Self { width: self.width / other.width, height: self.height / other.height };
335    }
336}
337
338impl Mul for Size {
339    type Output = Self;
340
341    #[inline]
342    fn mul(self, other: Self) -> Self {
343        Self { width: self.width * other.width, height: self.height * other.height }
344    }
345}
346
347impl MulAssign for Size {
348    #[inline]
349    fn mul_assign(&mut self, other: Self) {
350        *self = Self { width: self.width * other.width, height: self.height * other.height };
351    }
352}
353
354macro_rules! scale_size_impl {
355    ($($t:ty)*) => ($(
356        impl Div<$t> for Size {
357            type Output = Size;
358
359            #[inline]
360            fn div(self, other: $t) -> Size {
361                Self { width: self.width / other as f32, height: self.height / other as f32 }
362            }
363        }
364
365        impl DivAssign<$t> for Size {
366            #[inline]
367            fn div_assign(&mut self, other: $t) {
368                *self = Self { width: self.width / other as f32, height: self.height / other as f32 };
369            }
370        }
371
372        impl Mul<$t> for Size {
373            type Output = Size;
374
375            #[inline]
376            fn mul(self, other: $t) -> Size {
377                Self { width: self.width * other as f32, height: self.height * other as f32 }
378            }
379        }
380
381        impl MulAssign<$t> for Size {
382            #[inline]
383            fn mul_assign(&mut self, other: $t) {
384                *self = Self { width: self.width * other as f32, height: self.height * other as f32 };
385            }
386        }
387    )*)
388}
389
390scale_size_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
391
392/// Calculate Euclidean distance of 2 position.
393/// sqrt((x1-x2)^2 + (y1-y2)^2)
394pub fn euclidean_distance(p1: Position, p2: Position) -> f32 {
395    ((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)).sqrt()
396}