Skip to main content

ohos_arkui_binding/component/
root.rs

1//! Module component::root wrappers and related types.
2
3use std::os::raw::c_void;
4
5use crate::{ArkUIError, ArkUIHandle, ArkUINode, ArkUIResult, ARK_UI_NATIVE_NODE_API_1};
6use ohos_arkui_input_binding::ArkUIErrorCode;
7
8/// root node for arkui   
9/// ```rust
10/// let mut root = RootNode::new();
11///
12/// ```
13pub struct RootNode {
14    base: Option<ArkUINode>,
15    handle: ArkUIHandle,
16}
17
18impl RootNode {
19    pub fn new(handle: ArkUIHandle) -> Self {
20        RootNode { base: None, handle }
21    }
22
23    pub fn handle(&self) -> &ArkUIHandle {
24        &self.handle
25    }
26
27    pub fn mount<T: Into<ArkUINode>>(&mut self, node: T) -> ArkUIResult<()> {
28        let node_raw = node.into();
29        self.base = Some(node_raw.clone());
30        if let Some(base) = self.base.as_ref() {
31            ARK_UI_NATIVE_NODE_API_1.with(|api| {
32                api.set_user_data(base, Box::into_raw(Box::new(base)) as *mut c_void)
33            })?;
34
35            // Node will be mounted, we can think it as a event receiver.
36            ARK_UI_NATIVE_NODE_API_1.with(|api| api.add_event_receiver(base))?;
37            self.handle.add_node(base)
38        } else {
39            Err(ArkUIError::new(
40                ArkUIErrorCode::ChildNodeExist,
41                "Mount root node failed, base is None",
42            ))
43        }
44    }
45
46    pub fn unmount(&mut self) -> ArkUIResult<()> {
47        // If root node is empty, just ignore it.
48        if let Some(base) = self.base.as_mut() {
49            self.handle.remove_node(base)?;
50            base.dispose()?;
51            self.base = None;
52        }
53        Ok(())
54    }
55}
56
57impl Drop for RootNode {
58    fn drop(&mut self) {
59        if let Some(base) = self.base.as_mut() {
60            let _ = self.handle.remove_node(base);
61            base.children_mut().clear();
62            self.base = None;
63        }
64    }
65}