ohos_arkui_binding/common/
node.rs1#[cfg(feature = "napi")]
4use napi_ohos::bindgen_prelude::{check_status, FromNapiValue, TypeName, ValidateNapiValue};
5#[cfg(feature = "napi")]
6use napi_sys_ohos as sys;
7use ohos_arkui_input_binding::{sys::ArkUI_NodeHandle, ArkUIErrorCode};
8use ohos_arkui_sys::{
9 ArkUI_IntOffset, ArkUI_IntSize, OH_ArkUI_GetContextByNode,
10 OH_ArkUI_NodeUtils_GetLayoutPositionInWindow, OH_ArkUI_NodeUtils_GetLayoutSize,
11 OH_ArkUI_NodeUtils_GetPositionWithTranslateInWindow,
12};
13
14#[cfg(feature = "napi")]
15use ohos_arkui_sys::OH_ArkUI_GetNodeHandleFromNapiValue;
16#[cfg(feature = "napi")]
17use std::ptr;
18
19use std::{cell::RefCell, rc::Rc};
20
21use crate::{
22 animate::options::Animation,
23 api::node_custom_event::{IntOffset, IntSize},
24 api::ARK_UI_NATIVE_ANIMATE_API_1,
25 check_arkui_status, ArkUIAttributeBasic, ArkUICommonAttribute, ArkUIError, ArkUINodeType,
26 EventHandle, NodeDirtyFlag, ARK_UI_NATIVE_NODE_API_1,
27};
28
29use super::ArkUIResult;
30
31#[derive(Clone)]
32pub struct ArkUINode {
34 pub(crate) raw: ArkUI_NodeHandle,
36 pub(crate) tag: ArkUINodeType,
38 pub(crate) children: Vec<Rc<RefCell<ArkUINode>>>,
40 pub(crate) event_handle: EventHandle,
42}
43
44impl ArkUINode {
45 pub fn raw_handle(&self) -> ArkUI_NodeHandle {
47 self.raw
48 }
49
50 pub fn children(&self) -> &[Rc<RefCell<ArkUINode>>] {
52 self.children.as_slice()
53 }
54
55 pub fn children_mut(&mut self) -> &mut Vec<Rc<RefCell<ArkUINode>>> {
57 self.children.as_mut()
58 }
59
60 pub(crate) fn raw(&self) -> ArkUI_NodeHandle {
61 self.raw
62 }
63
64 pub fn from_raw_handle(raw: ArkUI_NodeHandle) -> Option<Self> {
65 if raw.is_null() {
66 return None;
67 }
68
69 Some(Self {
70 raw,
71 tag: ArkUINodeType::Custom,
72 children: vec![],
73 event_handle: Default::default(),
74 })
75 }
76
77 #[cfg(all(feature = "api-22", feature = "drawing"))]
78 pub fn text_layout_manager(&self) -> ArkUIResult<Option<crate::TextLayoutManager>> {
79 match self.get_attribute(crate::ArkUINodeAttributeType::TextLayoutManager)? {
80 crate::ArkUINodeAttributeItem::Object(ptr) => {
81 Ok(Some(crate::TextLayoutManager::from_raw(ptr.cast())))
82 }
83 _ => Ok(None),
84 }
85 }
86
87 pub fn dispose(&mut self) -> ArkUIResult<()> {
90 let handle = &self.event_handle;
91 if handle.has_callback() {
92 ARK_UI_NATIVE_NODE_API_1.with(|api| api.remove_event_receiver(self))?;
93 }
94 ARK_UI_NATIVE_NODE_API_1.with(|api| api.dispose(self))?;
97 self.children.clear();
98 Ok(())
99 }
100
101 pub fn animate_to(&self, animation: &Animation) -> ArkUIResult<()> {
103 let context = unsafe { OH_ArkUI_GetContextByNode(self.raw()) };
104 if context.is_null() {
105 return Err(ArkUIError::new(
106 ArkUIErrorCode::ParamInvalid,
107 "OH_ArkUI_GetContextByNode returned null",
108 ));
109 }
110
111 let update_ctx_raw = animation.update_ctx.borrow().raw();
112 let finish_ctx_raw = animation.finish_ctx.borrow().raw();
113 ARK_UI_NATIVE_ANIMATE_API_1
114 .with(|api| api.animate_to(context, animation.raw(), update_ctx_raw, finish_ctx_raw))
115 }
116
117 pub fn layout_size(&self) -> ArkUIResult<IntSize> {
119 let mut size: ArkUI_IntSize = unsafe { std::mem::zeroed() };
120 unsafe { check_arkui_status!(OH_ArkUI_NodeUtils_GetLayoutSize(self.raw(), &mut size)) }?;
121 Ok(size.into())
122 }
123
124 pub fn layout_position_in_window(&self) -> ArkUIResult<IntOffset> {
126 let mut offset: ArkUI_IntOffset = unsafe { std::mem::zeroed() };
127 unsafe {
128 check_arkui_status!(OH_ArkUI_NodeUtils_GetLayoutPositionInWindow(
129 self.raw(),
130 &mut offset
131 ))
132 }?;
133 Ok(offset.into())
134 }
135
136 pub fn position_with_translate_in_window(&self) -> ArkUIResult<IntOffset> {
138 let mut offset: ArkUI_IntOffset = unsafe { std::mem::zeroed() };
139 unsafe {
140 check_arkui_status!(OH_ArkUI_NodeUtils_GetPositionWithTranslateInWindow(
141 self.raw(),
142 &mut offset
143 ))
144 }?;
145 Ok(offset.into())
146 }
147
148 pub fn mark_dirty(&self, dirty_flag: NodeDirtyFlag) -> ArkUIResult<()> {
150 ARK_UI_NATIVE_NODE_API_1.with(|api| api.mark_dirty(self, dirty_flag))
151 }
152}
153
154impl ArkUIAttributeBasic for ArkUINode {
155 fn raw(&self) -> &ArkUINode {
156 self
157 }
158
159 fn borrow_mut(&mut self) -> &mut ArkUINode {
160 self
161 }
162}
163
164impl ArkUICommonAttribute for ArkUINode {}
165
166impl Default for ArkUINode {
169 fn default() -> Self {
170 Self {
171 raw: std::ptr::null_mut(),
172 tag: ArkUINodeType::Custom,
173 children: vec![],
174 event_handle: Default::default(),
175 }
176 }
177}
178
179#[cfg(feature = "napi")]
180pub struct ArkUINodeRaw {
182 pub(crate) env: sys::napi_env,
184 pub(crate) value: sys::napi_value,
186 pub raw: ArkUI_NodeHandle,
188}
189
190#[cfg(feature = "napi")]
191impl TypeName for ArkUINodeRaw {
192 fn type_name() -> &'static str {
193 "ArkUINode"
194 }
195 fn value_type() -> napi_ohos::ValueType {
196 napi_ohos::ValueType::Object
197 }
198}
199
200#[cfg(feature = "napi")]
201impl ValidateNapiValue for ArkUINodeRaw {}
202
203#[cfg(feature = "napi")]
204impl FromNapiValue for ArkUINodeRaw {
205 unsafe fn from_napi_value(
206 env: sys::napi_env,
207 napi_val: sys::napi_value,
208 ) -> napi_ohos::Result<Self> {
209 let mut slot = ptr::null_mut();
210 unsafe {
211 check_status!(
212 OH_ArkUI_GetNodeHandleFromNapiValue(env, napi_val, &mut slot),
213 "Get Node failed."
214 )?
215 };
216 Ok(ArkUINodeRaw {
217 env,
218 value: napi_val,
219 raw: slot,
220 })
221 }
222}