Skip to main content

ohos_arkui_binding/dialog/
mod.rs

1//! Dialog builder and lifecycle callback wrappers.
2
3use std::{cell::RefCell, os::raw::c_void, rc::Rc};
4
5use crate::api::ARK_UI_NATIVE_DIALOG_API_1;
6use crate::{Alignment, ArkUINode, ArkUIResult, DismissReason};
7
8use ohos_arkui_sys::ArkUI_NativeDialogHandle;
9
10pub(crate) struct InnerDialogDismissData {
11    pub dismiss_handle: Option<fn(DialogDismissData) -> Option<bool>>,
12    pub data: Option<*mut c_void>,
13}
14
15/// OnDismiss callback data
16pub struct DialogDismissData {
17    /// dismiss reason
18    pub dismiss_reason: DismissReason,
19    /// User custom data,if not and it will be None
20    pub data: Option<*mut c_void>,
21}
22
23/// High-level dialog wrapper for creating and controlling native dialogs.
24pub struct Dialog {
25    pub(crate) raw: ArkUI_NativeDialogHandle,
26    pub(crate) inner_dismiss_data: Rc<RefCell<InnerDialogDismissData>>,
27}
28
29impl Dialog {
30    /// Create a new dialog controller.
31    pub fn new() -> ArkUIResult<Self> {
32        let dialog_controller = ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.create())?;
33        Ok(Dialog {
34            raw: dialog_controller,
35            inner_dismiss_data: Rc::new(RefCell::new(InnerDialogDismissData {
36                dismiss_handle: None,
37                data: None,
38            })),
39        })
40    }
41
42    /// Set dialog content node.
43    pub fn content<T: Into<ArkUINode>>(&self, content: T) -> ArkUIResult<()> {
44        let node: ArkUINode = content.into();
45        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_content(self.raw, node.raw()))?;
46        Ok(())
47    }
48
49    /// Show the dialog in current window.
50    pub fn show(&self) -> ArkUIResult<()> {
51        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.show(self.raw, false))?;
52        Ok(())
53    }
54
55    /// Show the dialog in sub-window mode.
56    pub fn show_with_sub_window(&self) -> ArkUIResult<()> {
57        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.show(self.raw, true))?;
58        Ok(())
59    }
60
61    /// Close the dialog.
62    pub fn close(&self) -> ArkUIResult<()> {
63        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.close(self.raw))?;
64        Ok(())
65    }
66
67    pub fn modal_mode(&self, modal_mode: bool) -> ArkUIResult<()> {
68        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_modal_mode(self.raw, modal_mode))?;
69        Ok(())
70    }
71
72    pub fn auto_cancel(&self, auto_cancel: bool) -> ArkUIResult<()> {
73        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_auto_cancel(self.raw, auto_cancel))?;
74        Ok(())
75    }
76
77    pub fn background_color(&self, color: u32) -> ArkUIResult<()> {
78        ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_background_color(self.raw, color))?;
79        Ok(())
80    }
81
82    /// Set content alignment, offset_x and offset_y will be set with 0.0
83    pub fn content_alignment(&self, alignment: Alignment) -> ArkUIResult<()> {
84        ARK_UI_NATIVE_DIALOG_API_1
85            .with(|api| api.set_content_alignment(self.raw, alignment, 0.0, 0.0))?;
86        Ok(())
87    }
88
89    /// Set content alignment with offset_x and offset_y.
90    pub fn content_alignment_with_offset(
91        &self,
92        alignment: Alignment,
93        offset_x: f32,
94        offset_y: f32,
95    ) -> ArkUIResult<()> {
96        ARK_UI_NATIVE_DIALOG_API_1
97            .with(|api| api.set_content_alignment(self.raw, alignment, offset_x, offset_y))?;
98        Ok(())
99    }
100
101    pub fn corner_radius(
102        &self,
103        top_left: f32,
104        top_right: f32,
105        bottom_left: f32,
106        bottom_right: f32,
107    ) -> ArkUIResult<()> {
108        ARK_UI_NATIVE_DIALOG_API_1.with(|api| {
109            api.set_corner_radius(self.raw, top_left, top_right, bottom_left, bottom_right)
110        })?;
111        Ok(())
112    }
113
114    pub fn on_will_dismiss(
115        &self,
116        callback: fn(DialogDismissData) -> Option<bool>,
117    ) -> ArkUIResult<()> {
118        self.inner_dismiss_data.borrow_mut().dismiss_handle = Some(callback);
119
120        ARK_UI_NATIVE_DIALOG_API_1
121            .with(|api| api.register_dismiss(self.raw, self.inner_dismiss_data.clone()))?;
122        Ok(())
123    }
124
125    /// For user custom data, you can use this method
126    /// And you need to convert raw pointer to your data type after callback
127    pub fn on_will_dismiss_with_data<T: 'static>(
128        &self,
129        data: T,
130        callback: fn(data: DialogDismissData) -> Option<bool>,
131    ) -> ArkUIResult<()> {
132        self.inner_dismiss_data.borrow_mut().dismiss_handle = Some(callback);
133
134        self.inner_dismiss_data.borrow_mut().data =
135            Some(Box::into_raw(Box::new(data)) as *mut c_void);
136
137        ARK_UI_NATIVE_DIALOG_API_1
138            .with(|api| api.register_dismiss(self.raw, self.inner_dismiss_data.clone()))?;
139        Ok(())
140    }
141}