use std::{cell::RefCell, os::raw::c_void, rc::Rc};
use crate::api::ARK_UI_NATIVE_DIALOG_API_1;
use crate::{Alignment, ArkUINode, ArkUIResult, DismissReason};
use ohos_arkui_sys::ArkUI_NativeDialogHandle;
pub(crate) struct InnerDialogDismissData {
pub dismiss_handle: Option<fn(DialogDismissData) -> Option<bool>>,
pub data: Option<*mut c_void>,
}
pub struct DialogDismissData {
pub dismiss_reason: DismissReason,
pub data: Option<*mut c_void>,
}
pub struct Dialog {
pub(crate) raw: ArkUI_NativeDialogHandle,
pub(crate) inner_dismiss_data: Rc<RefCell<InnerDialogDismissData>>,
}
impl Dialog {
pub fn new() -> ArkUIResult<Self> {
let dialog_controller = ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.create())?;
Ok(Dialog {
raw: dialog_controller,
inner_dismiss_data: Rc::new(RefCell::new(InnerDialogDismissData {
dismiss_handle: None,
data: None,
})),
})
}
pub fn content<T: Into<ArkUINode>>(&self, content: T) -> ArkUIResult<()> {
let node: ArkUINode = content.into();
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_content(self.raw, node.raw()))?;
Ok(())
}
pub fn show(&self) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.show(self.raw, false))?;
Ok(())
}
pub fn show_with_sub_window(&self) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.show(self.raw, true))?;
Ok(())
}
pub fn close(&self) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.close(self.raw))?;
Ok(())
}
pub fn modal_mode(&self, modal_mode: bool) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_modal_mode(self.raw, modal_mode))?;
Ok(())
}
pub fn auto_cancel(&self, auto_cancel: bool) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_auto_cancel(self.raw, auto_cancel))?;
Ok(())
}
pub fn background_color(&self, color: u32) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| api.set_background_color(self.raw, color))?;
Ok(())
}
pub fn content_alignment(&self, alignment: Alignment) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1
.with(|api| api.set_content_alignment(self.raw, alignment, 0.0, 0.0))?;
Ok(())
}
pub fn content_alignment_with_offset(
&self,
alignment: Alignment,
offset_x: f32,
offset_y: f32,
) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1
.with(|api| api.set_content_alignment(self.raw, alignment, offset_x, offset_y))?;
Ok(())
}
pub fn corner_radius(
&self,
top_left: f32,
top_right: f32,
bottom_left: f32,
bottom_right: f32,
) -> ArkUIResult<()> {
ARK_UI_NATIVE_DIALOG_API_1.with(|api| {
api.set_corner_radius(self.raw, top_left, top_right, bottom_left, bottom_right)
})?;
Ok(())
}
pub fn on_will_dismiss(
&self,
callback: fn(DialogDismissData) -> Option<bool>,
) -> ArkUIResult<()> {
self.inner_dismiss_data.borrow_mut().dismiss_handle = Some(callback);
ARK_UI_NATIVE_DIALOG_API_1
.with(|api| api.register_dismiss(self.raw, self.inner_dismiss_data.clone()))?;
Ok(())
}
pub fn on_will_dismiss_with_data<T: 'static>(
&self,
data: T,
callback: fn(data: DialogDismissData) -> Option<bool>,
) -> ArkUIResult<()> {
self.inner_dismiss_data.borrow_mut().dismiss_handle = Some(callback);
self.inner_dismiss_data.borrow_mut().data =
Some(Box::into_raw(Box::new(data)) as *mut c_void);
ARK_UI_NATIVE_DIALOG_API_1
.with(|api| api.register_dismiss(self.raw, self.inner_dismiss_data.clone()))?;
Ok(())
}
}