Skip to main content

ohos_arkui_input_binding/ui_input_data/
mod.rs

1mod axis;
2#[cfg(feature = "api-22")]
3mod coasting;
4mod pointer;
5
6#[cfg(feature = "api-22")]
7pub use coasting::ArkUICoastingAxisEvent;
8#[cfg(feature = "api-15")]
9pub use pointer::ArkUIInputClonedEvent;
10
11use ohos_arkui_input_sys::{
12    ArkUI_ErrorCode_ARKUI_ERROR_CODE_NO_ERROR, ArkUI_ModifierKeyName, ArkUI_UIInputEvent,
13    OH_ArkUI_PointerEvent_GetPointerCount, OH_ArkUI_PointerEvent_GetPointerId,
14    OH_ArkUI_UIInputEvent_GetAction, OH_ArkUI_UIInputEvent_GetEventTime,
15    OH_ArkUI_UIInputEvent_GetSourceType, OH_ArkUI_UIInputEvent_GetToolType,
16    OH_ArkUI_UIInputEvent_GetType,
17};
18#[cfg(feature = "api-15")]
19use ohos_arkui_input_sys::{
20    OH_ArkUI_PointerEvent_GetChangedPointerId, OH_ArkUI_UIInputEvent_GetTargetDisplayId,
21};
22#[cfg(feature = "api-14")]
23use ohos_arkui_input_sys::{
24    OH_ArkUI_UIInputEvent_GetDeviceId, OH_ArkUI_UIInputEvent_GetPressedKeys,
25};
26#[cfg(feature = "api-17")]
27use ohos_arkui_input_sys::{
28    OH_ArkUI_UIInputEvent_GetEventTargetGlobalPositionX,
29    OH_ArkUI_UIInputEvent_GetEventTargetGlobalPositionY,
30    OH_ArkUI_UIInputEvent_GetEventTargetHeight, OH_ArkUI_UIInputEvent_GetEventTargetPositionX,
31    OH_ArkUI_UIInputEvent_GetEventTargetPositionY, OH_ArkUI_UIInputEvent_GetEventTargetWidth,
32    OH_ArkUI_UIInputEvent_GetModifierKeyStates,
33};
34use std::ptr::NonNull;
35
36use crate::{
37    ArkUIInputError, ModifierKey, UIInputAction, UIInputEvent, UIInputSourceType, UIInputToolType,
38};
39
40/// Wrapper for ArkUI_UIInputEvent.
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct ArkUIInputEvent {
43    event: NonNull<ArkUI_UIInputEvent>,
44
45    pub event_type: UIInputEvent,
46    pub action: UIInputAction,
47    pub source_type: UIInputSourceType,
48    pub tool_type: UIInputToolType,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub struct ModifierKeyStates(u64);
53
54impl ModifierKeyStates {
55    pub fn bits(self) -> u64 {
56        self.0
57    }
58
59    pub fn contains(self, key: ModifierKey) -> bool {
60        self.0 & modifier_key_mask(key) != 0
61    }
62}
63
64pub(crate) fn check_status(status: i32) -> Result<(), ArkUIInputError> {
65    if status == ArkUI_ErrorCode_ARKUI_ERROR_CODE_NO_ERROR as i32 {
66        Ok(())
67    } else {
68        Err(ArkUIInputError::InternalError(status))
69    }
70}
71
72fn modifier_key_mask(key: ModifierKey) -> u64 {
73    let raw: ArkUI_ModifierKeyName = key.into();
74    raw as u64
75}
76
77impl ArkUIInputEvent {
78    pub fn raw(&self) -> *const ArkUI_UIInputEvent {
79        self.event.as_ptr()
80    }
81
82    #[cfg(feature = "api-22")]
83    pub(crate) fn raw_mut(&self) -> *mut ArkUI_UIInputEvent {
84        self.event.as_ptr()
85    }
86
87    pub fn from_raw(event: *const ArkUI_UIInputEvent) -> Self {
88        let event = NonNull::new(event.cast_mut()).expect("ArkUI_UIInputEvent pointer is null");
89        let event_type = unsafe { OH_ArkUI_UIInputEvent_GetType(event.as_ptr()) };
90        let action = unsafe { OH_ArkUI_UIInputEvent_GetAction(event.as_ptr()) };
91        let source_type = unsafe { OH_ArkUI_UIInputEvent_GetSourceType(event.as_ptr()) };
92        let tool_type = unsafe { OH_ArkUI_UIInputEvent_GetToolType(event.as_ptr()) };
93        Self {
94            event,
95            event_type: UIInputEvent::from(event_type as u32),
96            action: UIInputAction::from(action as u32),
97            source_type: UIInputSourceType::from(source_type as u32),
98            tool_type: UIInputToolType::from(tool_type as u32),
99        }
100    }
101
102    pub fn event_time(&self) -> i64 {
103        unsafe { OH_ArkUI_UIInputEvent_GetEventTime(self.raw()) }
104    }
105
106    /// Get the number of contact points from a pointer event (such as a touch, mouse, or axis event).
107    pub fn pointer_count(&self) -> u32 {
108        unsafe { OH_ArkUI_PointerEvent_GetPointerCount(self.raw()) }
109    }
110
111    /// Get the unique ID of a contact point from a pointer event (such as a touch, mouse, or axis event).
112    pub fn pointer_id(&self, pointer_index: u32) -> i32 {
113        unsafe { OH_ArkUI_PointerEvent_GetPointerId(self.raw(), pointer_index) }
114    }
115
116    /// Get the ID of the touch pointer that triggers the current touch event.
117    #[cfg(feature = "api-15")]
118    pub fn get_changed_pointer_id(&self) -> Result<u32, ArkUIInputError> {
119        let mut pointer_index = 0;
120        check_status(unsafe {
121            OH_ArkUI_PointerEvent_GetChangedPointerId(self.raw(), &mut pointer_index)
122        })?;
123        Ok(pointer_index)
124    }
125
126    /// Get the vertical scroll delta of an axis event.
127    /// Only works for touch board and mouse wheel.
128    pub fn get_scroll_delta_y(&self) -> Result<f64, ArkUIInputError> {
129        match self.event_type {
130            UIInputEvent::Axis => Ok(self.axis_vertical_value()),
131            #[cfg(feature = "api-17")]
132            UIInputEvent::Mouse => Ok(self.axis_vertical_value() * self.axis_scroll_step() as f64),
133            _ => Err(ArkUIInputError::DeviceTypeNotSupported(
134                "get_scroll_delta_y".to_string(),
135                self.source_type.into(),
136            )),
137        }
138    }
139
140    /// Get the horizontal scroll delta of an axis event.
141    /// Only works for touch board.
142    pub fn get_scroll_delta_x(&self) -> Result<f64, ArkUIInputError> {
143        match self.event_type {
144            UIInputEvent::Axis => Ok(self.axis_horizontal_value()),
145            _ => Err(ArkUIInputError::DeviceTypeNotSupported(
146                "get_scroll_delta_x".to_string(),
147                self.source_type.into(),
148            )),
149        }
150    }
151
152    #[cfg(feature = "api-14")]
153    pub fn device_id(&self) -> i32 {
154        unsafe { OH_ArkUI_UIInputEvent_GetDeviceId(self.raw()) }
155    }
156
157    #[cfg(feature = "api-14")]
158    pub fn pressed_keys(&self, pressed_key_codes: &mut [i32]) -> Result<usize, ArkUIInputError> {
159        let mut length = pressed_key_codes.len() as i32;
160        check_status(unsafe {
161            OH_ArkUI_UIInputEvent_GetPressedKeys(
162                self.raw(),
163                pressed_key_codes.as_mut_ptr(),
164                &mut length,
165            )
166        })?;
167        Ok(length.max(0) as usize)
168    }
169
170    #[cfg(feature = "api-15")]
171    pub fn target_display_id(&self) -> i32 {
172        unsafe { OH_ArkUI_UIInputEvent_GetTargetDisplayId(self.raw()) }
173    }
174
175    #[cfg(feature = "api-17")]
176    pub fn event_target_width(&self) -> f32 {
177        unsafe { OH_ArkUI_UIInputEvent_GetEventTargetWidth(self.raw()) }
178    }
179
180    #[cfg(feature = "api-17")]
181    pub fn event_target_height(&self) -> f32 {
182        unsafe { OH_ArkUI_UIInputEvent_GetEventTargetHeight(self.raw()) }
183    }
184
185    #[cfg(feature = "api-17")]
186    pub fn event_target_position_x(&self) -> f32 {
187        unsafe { OH_ArkUI_UIInputEvent_GetEventTargetPositionX(self.raw()) }
188    }
189
190    #[cfg(feature = "api-17")]
191    pub fn event_target_position_y(&self) -> f32 {
192        unsafe { OH_ArkUI_UIInputEvent_GetEventTargetPositionY(self.raw()) }
193    }
194
195    #[cfg(feature = "api-17")]
196    pub fn event_target_global_position_x(&self) -> f32 {
197        unsafe { OH_ArkUI_UIInputEvent_GetEventTargetGlobalPositionX(self.raw()) }
198    }
199
200    #[cfg(feature = "api-17")]
201    pub fn event_target_global_position_y(&self) -> f32 {
202        unsafe { OH_ArkUI_UIInputEvent_GetEventTargetGlobalPositionY(self.raw()) }
203    }
204
205    #[cfg(feature = "api-17")]
206    pub fn modifier_key_states(&self) -> Result<ModifierKeyStates, ArkUIInputError> {
207        let mut keys = 0u64;
208        check_status(unsafe { OH_ArkUI_UIInputEvent_GetModifierKeyStates(self.raw(), &mut keys) })?;
209        Ok(ModifierKeyStates(keys))
210    }
211}