ohos-arkui-binding 0.2.0

OpenHarmony's arkui binding for rust
Documentation
//! Module api::drag::event wrappers and related types.

use std::{os::raw::c_char, ptr::NonNull};

use ohos_arkui_input_binding::ArkUIErrorCode;
use ohos_arkui_sys::*;
#[cfg(feature = "udmf")]
use ohos_udmf_binding::UdmfData;

#[cfg(all(feature = "api-20", feature = "udmf"))]
use ohos_udmf_binding::UdmfDataLoadParams;
#[cfg(all(feature = "api-15", feature = "udmf"))]
use ohos_udmf_binding::UdmfGetDataParams;

use crate::{check_arkui_status, ArkUIError, ArkUIResult, DragResult, DropOperation};

#[derive(Clone, Copy)]
pub(crate) struct DragAndDropInfo {
    raw: NonNull<ArkUI_DragAndDropInfo>,
}

impl DragAndDropInfo {
    pub(crate) unsafe fn from_raw(raw: *mut ArkUI_DragAndDropInfo) -> Option<Self> {
        NonNull::new(raw).map(|raw| Self { raw })
    }

    pub(crate) fn raw(&self) -> *mut ArkUI_DragAndDropInfo {
        self.raw.as_ptr()
    }

    pub(crate) fn drag_status(&self) -> crate::DragStatus {
        unsafe { OH_ArkUI_DragAndDropInfo_GetDragStatus(self.raw()).into() }
    }

    pub(crate) fn drag_event(&self) -> Option<DragEvent> {
        let event = unsafe { OH_ArkUI_DragAndDropInfo_GetDragEvent(self.raw()) };
        unsafe { DragEvent::from_raw(event) }
    }
}

#[derive(Clone, Copy)]
pub(crate) struct DragEvent {
    raw: NonNull<ArkUI_DragEvent>,
}

impl DragEvent {
    pub(crate) unsafe fn from_raw(raw: *mut ArkUI_DragEvent) -> Option<Self> {
        NonNull::new(raw).map(|raw| Self { raw })
    }

    pub(crate) fn raw(&self) -> *mut ArkUI_DragEvent {
        self.raw.as_ptr()
    }

    pub(crate) fn disable_default_drop_animation(&self, disable: bool) -> ArkUIResult<()> {
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_DisableDefaultDropAnimation(
                self.raw(),
                disable
            ))
        }
    }

    pub(crate) fn set_suggested_drop_operation(
        &self,
        drop_operation: DropOperation,
    ) -> ArkUIResult<()> {
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_SetSuggestedDropOperation(
                self.raw(),
                drop_operation.into()
            ))
        }
    }

    pub(crate) fn set_drag_result(&self, result: DragResult) -> ArkUIResult<()> {
        unsafe { check_arkui_status!(OH_ArkUI_DragEvent_SetDragResult(self.raw(), result.into())) }
    }

    #[cfg(feature = "udmf")]
    pub(crate) fn set_data(&self, data: &UdmfData) -> ArkUIResult<()> {
        unsafe { check_arkui_status!(OH_ArkUI_DragEvent_SetData(self.raw(), data.raw().as_ptr())) }
    }

    #[cfg(all(feature = "api-20", feature = "udmf"))]
    pub(crate) fn set_data_load_params(
        &self,
        data_load_params: &UdmfDataLoadParams,
    ) -> ArkUIResult<()> {
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_SetDataLoadParams(
                self.raw(),
                data_load_params.as_raw()
            ))
        }
    }

    #[cfg(feature = "udmf")]
    pub(crate) fn get_udmf_data(&self, data: &UdmfData) -> ArkUIResult<()> {
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetUdmfData(
                self.raw(),
                data.raw().as_ptr()
            ))
        }
    }

    pub(crate) fn data_type_count(&self) -> ArkUIResult<i32> {
        let mut count = 0;
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetDataTypeCount(self.raw(), &mut count))
        }?;
        Ok(count)
    }

    pub(crate) fn data_types(&self, max_str_len: i32) -> ArkUIResult<Vec<String>> {
        if max_str_len <= 0 {
            return Err(ArkUIError::new(
                ArkUIErrorCode::ParamInvalid,
                "max_str_len must be greater than 0",
            ));
        }
        let count = self.data_type_count()?;
        if count <= 0 {
            return Ok(Vec::new());
        }

        let mut buffers = vec![vec![0u8; max_str_len as usize]; count as usize];
        let mut ptrs: Vec<*mut c_char> = buffers
            .iter_mut()
            .map(|buffer| buffer.as_mut_ptr().cast())
            .collect();

        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetDataTypes(
                self.raw(),
                ptrs.as_mut_ptr(),
                count,
                max_str_len
            ))
        }?;

        Ok(buffers
            .into_iter()
            .map(|buffer| {
                let len = buffer.iter().position(|v| *v == 0).unwrap_or(buffer.len());
                String::from_utf8_lossy(&buffer[..len]).into_owned()
            })
            .collect())
    }

    pub(crate) fn drag_result(&self) -> ArkUIResult<DragResult> {
        let mut result = ArkUI_DragResult_ARKUI_DRAG_RESULT_CANCELED;
        unsafe { check_arkui_status!(OH_ArkUI_DragEvent_GetDragResult(self.raw(), &mut result)) }?;
        Ok(result.into())
    }

    pub(crate) fn drop_operation(&self) -> ArkUIResult<DropOperation> {
        let mut operation = ArkUI_DropOperation_ARKUI_DROP_OPERATION_COPY;
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetDropOperation(
                self.raw(),
                &mut operation
            ))
        }?;
        Ok(operation.into())
    }

    pub(crate) fn preview_touch_point_x(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetPreviewTouchPointX(self.raw()) }
    }

    pub(crate) fn preview_touch_point_y(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetPreviewTouchPointY(self.raw()) }
    }

    pub(crate) fn preview_rect_width(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetPreviewRectWidth(self.raw()) }
    }

    pub(crate) fn preview_rect_height(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetPreviewRectHeight(self.raw()) }
    }

    pub(crate) fn touch_point_x_to_window(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetTouchPointXToWindow(self.raw()) }
    }

    pub(crate) fn touch_point_y_to_window(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetTouchPointYToWindow(self.raw()) }
    }

    pub(crate) fn touch_point_x_to_display(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetTouchPointXToDisplay(self.raw()) }
    }

    pub(crate) fn touch_point_y_to_display(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetTouchPointYToDisplay(self.raw()) }
    }

    #[cfg(feature = "api-20")]
    pub(crate) fn touch_point_x_to_global_display(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetTouchPointXToGlobalDisplay(self.raw()) }
    }

    #[cfg(feature = "api-20")]
    pub(crate) fn touch_point_y_to_global_display(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetTouchPointYToGlobalDisplay(self.raw()) }
    }

    pub(crate) fn velocity_x(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetVelocityX(self.raw()) }
    }

    pub(crate) fn velocity_y(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetVelocityY(self.raw()) }
    }

    pub(crate) fn velocity(&self) -> f32 {
        unsafe { OH_ArkUI_DragEvent_GetVelocity(self.raw()) }
    }

    pub(crate) fn modifier_key_states(&self) -> ArkUIResult<u64> {
        let mut keys = 0u64;
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetModifierKeyStates(
                self.raw(),
                &mut keys
            ))
        }?;
        Ok(keys)
    }

    #[cfg(feature = "api-20")]
    pub(crate) fn display_id(&self) -> ArkUIResult<i32> {
        let mut display_id = 0;
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetDisplayId(self.raw(), &mut display_id))
        }?;
        Ok(display_id)
    }

    #[cfg(all(feature = "api-15", feature = "udmf"))]
    pub(crate) fn start_data_loading(
        &self,
        options: &UdmfGetDataParams,
        key_len: u32,
    ) -> ArkUIResult<String> {
        if key_len == 0 {
            return Err(ArkUIError::new(
                ArkUIErrorCode::ParamInvalid,
                "key_len must be greater than 0",
            ));
        }
        let mut key = vec![0u8; key_len as usize];
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_StartDataLoading(
                self.raw(),
                options.as_raw(),
                key.as_mut_ptr().cast(),
                key_len
            ))
        }?;
        let len = key.iter().position(|v| *v == 0).unwrap_or(key.len());
        Ok(String::from_utf8_lossy(&key[..len]).into_owned())
    }

    #[cfg(feature = "api-19")]
    pub(crate) fn request_drag_end_pending(&self) -> ArkUIResult<i32> {
        let mut request_identify = 0;
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_RequestDragEndPending(
                self.raw(),
                &mut request_identify
            ))
        }?;
        Ok(request_identify)
    }

    #[cfg(feature = "api-20")]
    pub(crate) fn drag_source(&self, length: i32) -> ArkUIResult<String> {
        if length <= 0 {
            return Err(ArkUIError::new(
                ArkUIErrorCode::ParamInvalid,
                "length must be greater than 0",
            ));
        }
        let mut buffer = vec![0u8; length as usize];
        unsafe {
            check_arkui_status!(OH_ArkUI_DragEvent_GetDragSource(
                self.raw(),
                buffer.as_mut_ptr().cast(),
                length
            ))
        }?;
        let len = buffer.iter().position(|v| *v == 0).unwrap_or(buffer.len());
        Ok(String::from_utf8_lossy(&buffer[..len]).into_owned())
    }

    #[cfg(feature = "api-20")]
    pub(crate) fn is_remote(&self) -> ArkUIResult<bool> {
        let mut is_remote = false;
        unsafe { check_arkui_status!(OH_ArkUI_DragEvent_IsRemote(self.raw(), &mut is_remote)) }?;
        Ok(is_remote)
    }
}