Skip to main content

ohos_arkui_binding/api/attribute_option/
list_and_layout.rs

1//! Module api::attribute_option::list_and_layout wrappers and related types.
2
3use std::{os::raw::c_void, ptr::NonNull};
4
5#[cfg(feature = "api-20")]
6use std::os::raw::c_char;
7#[cfg(feature = "api-20")]
8use std::sync::{Mutex, OnceLock};
9
10use ohos_arkui_input_binding::ArkUIErrorCode;
11use ohos_arkui_sys::*;
12
13use super::base::{c_char_ptr_to_string, non_null_or_panic, with_cstring};
14use crate::{check_arkui_status, ArkUIError, ArkUIResult};
15
16struct ListItemSwipeActionVoidCallbackContext {
17    callback: Box<dyn Fn()>,
18}
19
20struct ListItemSwipeActionStateCallbackContext {
21    callback: Box<dyn Fn(crate::ListItemSwipeActionState)>,
22}
23
24#[derive(Default)]
25struct ListItemSwipeActionItemCallbacks {
26    on_enter_action_area: Option<*mut ListItemSwipeActionVoidCallbackContext>,
27    on_action: Option<*mut ListItemSwipeActionVoidCallbackContext>,
28    on_exit_action_area: Option<*mut ListItemSwipeActionVoidCallbackContext>,
29    on_state_change: Option<*mut ListItemSwipeActionStateCallbackContext>,
30}
31
32/// List-item swipe action item descriptor.
33pub struct ListItemSwipeActionItem {
34    raw: NonNull<ArkUI_ListItemSwipeActionItem>,
35    callbacks: ListItemSwipeActionItemCallbacks,
36}
37
38impl ListItemSwipeActionItem {
39    pub fn new() -> ArkUIResult<Self> {
40        let item = unsafe { OH_ArkUI_ListItemSwipeActionItem_Create() };
41        NonNull::new(item)
42            .map(|raw| Self::from_raw(raw.as_ptr()))
43            .ok_or_else(|| {
44                ArkUIError::new(
45                    ArkUIErrorCode::ParamInvalid,
46                    "OH_ArkUI_ListItemSwipeActionItem_Create returned null",
47                )
48            })
49    }
50
51    pub(crate) fn raw(&self) -> *mut ArkUI_ListItemSwipeActionItem {
52        self.raw.as_ptr()
53    }
54
55    pub(crate) fn from_raw(raw: *mut ArkUI_ListItemSwipeActionItem) -> Self {
56        Self {
57            raw: non_null_or_panic(raw, "ArkUI_ListItemSwipeActionItem"),
58            callbacks: ListItemSwipeActionItemCallbacks::default(),
59        }
60    }
61
62    pub(crate) fn into_raw(self) -> *mut ArkUI_ListItemSwipeActionItem {
63        self.raw.as_ptr()
64    }
65
66    pub fn dispose(mut self) {
67        self.clear_on_enter_action_area();
68        self.clear_on_action();
69        self.clear_on_exit_action_area();
70        self.clear_on_state_change();
71        unsafe { OH_ArkUI_ListItemSwipeActionItem_Dispose(self.raw()) }
72    }
73
74    pub fn set_content(&mut self, node: &crate::ArkUINode) {
75        unsafe { OH_ArkUI_ListItemSwipeActionItem_SetContent(self.raw(), node.raw()) }
76    }
77
78    pub fn set_action_area_distance(&mut self, distance: f32) {
79        unsafe { OH_ArkUI_ListItemSwipeActionItem_SetActionAreaDistance(self.raw(), distance) }
80    }
81
82    pub fn get_action_area_distance(&self) -> f32 {
83        unsafe { OH_ArkUI_ListItemSwipeActionItem_GetActionAreaDistance(self.raw()) }
84    }
85
86    pub fn set_on_enter_action_area<T: Fn() + 'static>(&mut self, callback: T) {
87        self.clear_on_enter_action_area();
88        let callback = Box::into_raw(Box::new(ListItemSwipeActionVoidCallbackContext {
89            callback: Box::new(callback),
90        }));
91        unsafe {
92            OH_ArkUI_ListItemSwipeActionItem_SetOnEnterActionAreaWithUserData(
93                self.raw(),
94                callback.cast(),
95                Some(list_item_swipe_action_item_void_callback_trampoline),
96            )
97        };
98        self.callbacks.on_enter_action_area = Some(callback);
99    }
100
101    pub fn clear_on_enter_action_area(&mut self) {
102        unsafe {
103            OH_ArkUI_ListItemSwipeActionItem_SetOnEnterActionAreaWithUserData(
104                self.raw(),
105                std::ptr::null_mut(),
106                None,
107            )
108        };
109        if let Some(callback) = self.callbacks.on_enter_action_area.take() {
110            unsafe {
111                drop(Box::from_raw(callback));
112            }
113        }
114    }
115
116    pub fn set_on_action<T: Fn() + 'static>(&mut self, callback: T) {
117        self.clear_on_action();
118        let callback = Box::into_raw(Box::new(ListItemSwipeActionVoidCallbackContext {
119            callback: Box::new(callback),
120        }));
121        unsafe {
122            OH_ArkUI_ListItemSwipeActionItem_SetOnActionWithUserData(
123                self.raw(),
124                callback.cast(),
125                Some(list_item_swipe_action_item_void_callback_trampoline),
126            )
127        };
128        self.callbacks.on_action = Some(callback);
129    }
130
131    pub fn clear_on_action(&mut self) {
132        unsafe {
133            OH_ArkUI_ListItemSwipeActionItem_SetOnActionWithUserData(
134                self.raw(),
135                std::ptr::null_mut(),
136                None,
137            )
138        };
139        if let Some(callback) = self.callbacks.on_action.take() {
140            unsafe {
141                drop(Box::from_raw(callback));
142            }
143        }
144    }
145
146    pub fn set_on_exit_action_area<T: Fn() + 'static>(&mut self, callback: T) {
147        self.clear_on_exit_action_area();
148        let callback = Box::into_raw(Box::new(ListItemSwipeActionVoidCallbackContext {
149            callback: Box::new(callback),
150        }));
151        unsafe {
152            OH_ArkUI_ListItemSwipeActionItem_SetOnExitActionAreaWithUserData(
153                self.raw(),
154                callback.cast(),
155                Some(list_item_swipe_action_item_void_callback_trampoline),
156            )
157        };
158        self.callbacks.on_exit_action_area = Some(callback);
159    }
160
161    pub fn clear_on_exit_action_area(&mut self) {
162        unsafe {
163            OH_ArkUI_ListItemSwipeActionItem_SetOnExitActionAreaWithUserData(
164                self.raw(),
165                std::ptr::null_mut(),
166                None,
167            )
168        };
169        if let Some(callback) = self.callbacks.on_exit_action_area.take() {
170            unsafe {
171                drop(Box::from_raw(callback));
172            }
173        }
174    }
175
176    pub fn set_on_state_change<T: Fn(crate::ListItemSwipeActionState) + 'static>(
177        &mut self,
178        callback: T,
179    ) {
180        self.clear_on_state_change();
181        let callback = Box::into_raw(Box::new(ListItemSwipeActionStateCallbackContext {
182            callback: Box::new(callback),
183        }));
184        unsafe {
185            OH_ArkUI_ListItemSwipeActionItem_SetOnStateChangeWithUserData(
186                self.raw(),
187                callback.cast(),
188                Some(list_item_swipe_action_item_state_callback_trampoline),
189            )
190        };
191        self.callbacks.on_state_change = Some(callback);
192    }
193
194    pub fn clear_on_state_change(&mut self) {
195        unsafe {
196            OH_ArkUI_ListItemSwipeActionItem_SetOnStateChangeWithUserData(
197                self.raw(),
198                std::ptr::null_mut(),
199                None,
200            )
201        };
202        if let Some(callback) = self.callbacks.on_state_change.take() {
203            unsafe {
204                drop(Box::from_raw(callback));
205            }
206        }
207    }
208}
209
210unsafe extern "C" fn list_item_swipe_action_item_void_callback_trampoline(user_data: *mut c_void) {
211    if user_data.is_null() {
212        return;
213    }
214
215    let callback = unsafe { &*(user_data as *mut ListItemSwipeActionVoidCallbackContext) };
216    (callback.callback)();
217}
218
219unsafe extern "C" fn list_item_swipe_action_item_state_callback_trampoline(
220    swipe_action_state: ArkUI_ListItemSwipeActionState,
221    user_data: *mut c_void,
222) {
223    if user_data.is_null() {
224        return;
225    }
226
227    let callback = unsafe { &*(user_data as *mut ListItemSwipeActionStateCallbackContext) };
228    (callback.callback)(swipe_action_state.into());
229}
230
231struct NodeAdapterEventReceiverCallbackContext {
232    callback: Box<dyn Fn(&mut NodeAdapterEvent)>,
233}
234
235/// Node-adapter callback event wrapper.
236pub struct NodeAdapterEvent {
237    raw: NonNull<ArkUI_NodeAdapterEvent>,
238}
239
240impl NodeAdapterEvent {
241    pub(crate) fn from_raw(raw: *mut ArkUI_NodeAdapterEvent) -> Self {
242        Self {
243            raw: non_null_or_panic(raw, "ArkUI_NodeAdapterEvent"),
244        }
245    }
246
247    fn raw(&self) -> *mut ArkUI_NodeAdapterEvent {
248        self.raw.as_ptr()
249    }
250
251    pub fn event_type(&self) -> crate::NodeAdapterEventType {
252        unsafe { OH_ArkUI_NodeAdapterEvent_GetType(self.raw()).into() }
253    }
254
255    pub fn removed_node(&self) -> Option<crate::ArkUINode> {
256        crate::ArkUINode::from_raw_handle(unsafe {
257            OH_ArkUI_NodeAdapterEvent_GetRemovedNode(self.raw())
258        })
259    }
260
261    pub fn item_index(&self) -> u32 {
262        unsafe { OH_ArkUI_NodeAdapterEvent_GetItemIndex(self.raw()) }
263    }
264
265    pub fn host_node(&self) -> Option<crate::ArkUINode> {
266        crate::ArkUINode::from_raw_handle(unsafe {
267            OH_ArkUI_NodeAdapterEvent_GetHostNode(self.raw())
268        })
269    }
270
271    pub fn set_item(&mut self, node: &crate::ArkUINode) -> ArkUIResult<()> {
272        unsafe { check_arkui_status!(OH_ArkUI_NodeAdapterEvent_SetItem(self.raw(), node.raw())) }
273    }
274
275    pub fn set_node_id(&mut self, id: i32) -> ArkUIResult<()> {
276        unsafe { check_arkui_status!(OH_ArkUI_NodeAdapterEvent_SetNodeId(self.raw(), id)) }
277    }
278}
279
280/// Node-adapter wrapper for lazy data-driven list/grid.
281pub struct NodeAdapter {
282    raw: NonNull<ArkUI_NodeAdapter>,
283    event_receiver: Option<*mut NodeAdapterEventReceiverCallbackContext>,
284}
285
286impl NodeAdapter {
287    pub fn new() -> ArkUIResult<Self> {
288        let handle = unsafe { OH_ArkUI_NodeAdapter_Create() };
289        NonNull::new(handle)
290            .map(|raw| Self::from_raw(raw.as_ptr()))
291            .ok_or_else(|| {
292                ArkUIError::new(
293                    ArkUIErrorCode::ParamInvalid,
294                    "OH_ArkUI_NodeAdapter_Create returned null",
295                )
296            })
297    }
298
299    pub(crate) fn raw(&self) -> ArkUI_NodeAdapterHandle {
300        self.raw.as_ptr()
301    }
302
303    pub(crate) fn from_raw(raw: ArkUI_NodeAdapterHandle) -> Self {
304        Self {
305            raw: non_null_or_panic(raw, "ArkUI_NodeAdapter"),
306            event_receiver: None,
307        }
308    }
309
310    pub(crate) fn into_raw(self) -> ArkUI_NodeAdapterHandle {
311        self.raw.as_ptr()
312    }
313
314    pub fn dispose(mut self) {
315        self.unregister_event_receiver();
316        unsafe { OH_ArkUI_NodeAdapter_Dispose(self.raw()) }
317    }
318
319    pub fn set_total_node_count(&mut self, size: u32) -> ArkUIResult<()> {
320        unsafe { check_arkui_status!(OH_ArkUI_NodeAdapter_SetTotalNodeCount(self.raw(), size)) }
321    }
322
323    pub fn get_total_node_count(&self) -> u32 {
324        unsafe { OH_ArkUI_NodeAdapter_GetTotalNodeCount(self.raw()) }
325    }
326
327    pub fn register_event_receiver<T: Fn(&mut NodeAdapterEvent) + 'static>(
328        &mut self,
329        receiver: T,
330    ) -> ArkUIResult<()> {
331        self.unregister_event_receiver();
332        let receiver = Box::into_raw(Box::new(NodeAdapterEventReceiverCallbackContext {
333            callback: Box::new(receiver),
334        }));
335        let result = unsafe {
336            check_arkui_status!(OH_ArkUI_NodeAdapter_RegisterEventReceiver(
337                self.raw(),
338                receiver.cast(),
339                Some(node_adapter_event_receiver_callback_trampoline),
340            ))
341        };
342
343        if let Err(err) = result {
344            unsafe {
345                drop(Box::from_raw(receiver));
346            }
347            return Err(err);
348        }
349
350        self.event_receiver = Some(receiver);
351        Ok(())
352    }
353
354    pub fn unregister_event_receiver(&mut self) {
355        unsafe { OH_ArkUI_NodeAdapter_UnregisterEventReceiver(self.raw()) }
356        if let Some(receiver) = self.event_receiver.take() {
357            unsafe {
358                drop(Box::from_raw(receiver));
359            }
360        }
361    }
362
363    pub fn reload_all_items(&mut self) -> ArkUIResult<()> {
364        unsafe { check_arkui_status!(OH_ArkUI_NodeAdapter_ReloadAllItems(self.raw())) }
365    }
366
367    pub fn reload_item(&mut self, start_position: u32, item_count: u32) -> ArkUIResult<()> {
368        unsafe {
369            check_arkui_status!(OH_ArkUI_NodeAdapter_ReloadItem(
370                self.raw(),
371                start_position,
372                item_count
373            ))
374        }
375    }
376
377    pub fn remove_item(&mut self, start_position: u32, item_count: u32) -> ArkUIResult<()> {
378        unsafe {
379            check_arkui_status!(OH_ArkUI_NodeAdapter_RemoveItem(
380                self.raw(),
381                start_position,
382                item_count
383            ))
384        }
385    }
386
387    pub fn insert_item(&mut self, start_position: u32, item_count: u32) -> ArkUIResult<()> {
388        unsafe {
389            check_arkui_status!(OH_ArkUI_NodeAdapter_InsertItem(
390                self.raw(),
391                start_position,
392                item_count
393            ))
394        }
395    }
396
397    pub fn move_item(&mut self, from: u32, to: u32) -> ArkUIResult<()> {
398        unsafe { check_arkui_status!(OH_ArkUI_NodeAdapter_MoveItem(self.raw(), from, to)) }
399    }
400
401    pub fn get_all_items(&self) -> ArkUIResult<Vec<crate::ArkUINode>> {
402        let mut items = std::ptr::null_mut();
403        let mut size = 0;
404        unsafe {
405            check_arkui_status!(OH_ArkUI_NodeAdapter_GetAllItems(
406                self.raw(),
407                &mut items,
408                &mut size
409            ))
410        }?;
411        if items.is_null() || size == 0 {
412            return Ok(Vec::new());
413        }
414        let items = unsafe { std::slice::from_raw_parts(items, size as usize) };
415        Ok(items
416            .iter()
417            .copied()
418            .filter_map(crate::ArkUINode::from_raw_handle)
419            .collect())
420    }
421}
422
423unsafe extern "C" fn node_adapter_event_receiver_callback_trampoline(
424    event: *mut ArkUI_NodeAdapterEvent,
425) {
426    let user_data = unsafe { OH_ArkUI_NodeAdapterEvent_GetUserData(event) };
427    if user_data.is_null() {
428        return;
429    }
430
431    let callback = unsafe { &*(user_data as *mut NodeAdapterEventReceiverCallbackContext) };
432    let mut event = NodeAdapterEvent::from_raw(event);
433    (callback.callback)(&mut event);
434}
435
436struct ListItemSwipeOffsetCallbackContext {
437    callback: Box<dyn Fn(f32)>,
438}
439
440/// List-item swipe action option wrapper.
441pub struct ListItemSwipeActionOption {
442    raw: NonNull<ArkUI_ListItemSwipeActionOption>,
443    on_offset_change: Option<*mut ListItemSwipeOffsetCallbackContext>,
444}
445
446impl ListItemSwipeActionOption {
447    pub fn new() -> ArkUIResult<Self> {
448        let option = unsafe { OH_ArkUI_ListItemSwipeActionOption_Create() };
449        NonNull::new(option)
450            .map(|raw| Self::from_raw(raw.as_ptr()))
451            .ok_or_else(|| {
452                ArkUIError::new(
453                    ArkUIErrorCode::ParamInvalid,
454                    "OH_ArkUI_ListItemSwipeActionOption_Create returned null",
455                )
456            })
457    }
458
459    pub(crate) fn raw(&self) -> *mut ArkUI_ListItemSwipeActionOption {
460        self.raw.as_ptr()
461    }
462
463    pub(crate) fn from_raw(raw: *mut ArkUI_ListItemSwipeActionOption) -> Self {
464        Self {
465            raw: non_null_or_panic(raw, "ArkUI_ListItemSwipeActionOption"),
466            on_offset_change: None,
467        }
468    }
469
470    pub(crate) fn into_raw(self) -> *mut ArkUI_ListItemSwipeActionOption {
471        self.raw.as_ptr()
472    }
473
474    pub fn dispose(mut self) {
475        self.clear_on_offset_change();
476        unsafe { OH_ArkUI_ListItemSwipeActionOption_Dispose(self.raw()) }
477    }
478
479    pub fn set_start(&mut self, item: &ListItemSwipeActionItem) {
480        unsafe { OH_ArkUI_ListItemSwipeActionOption_SetStart(self.raw(), item.raw()) }
481    }
482
483    pub fn set_end(&mut self, item: &ListItemSwipeActionItem) {
484        unsafe { OH_ArkUI_ListItemSwipeActionOption_SetEnd(self.raw(), item.raw()) }
485    }
486
487    pub fn set_edge_effect(&mut self, edge_effect: crate::ListItemSwipeEdgeEffect) {
488        unsafe { OH_ArkUI_ListItemSwipeActionOption_SetEdgeEffect(self.raw(), edge_effect.into()) }
489    }
490
491    pub fn get_edge_effect(&self) -> crate::ListItemSwipeEdgeEffect {
492        unsafe { (OH_ArkUI_ListItemSwipeActionOption_GetEdgeEffect(self.raw()) as u32).into() }
493    }
494
495    pub fn set_on_offset_change<T: Fn(f32) + 'static>(&mut self, callback: T) {
496        self.clear_on_offset_change();
497        let callback = Box::into_raw(Box::new(ListItemSwipeOffsetCallbackContext {
498            callback: Box::new(callback),
499        }));
500        unsafe {
501            OH_ArkUI_ListItemSwipeActionOption_SetOnOffsetChangeWithUserData(
502                self.raw(),
503                callback.cast(),
504                Some(list_item_swipe_action_option_offset_callback_trampoline),
505            )
506        };
507        self.on_offset_change = Some(callback);
508    }
509
510    pub fn clear_on_offset_change(&mut self) {
511        unsafe {
512            OH_ArkUI_ListItemSwipeActionOption_SetOnOffsetChangeWithUserData(
513                self.raw(),
514                std::ptr::null_mut(),
515                None,
516            )
517        };
518        if let Some(callback) = self.on_offset_change.take() {
519            unsafe {
520                drop(Box::from_raw(callback));
521            }
522        }
523    }
524}
525
526unsafe extern "C" fn list_item_swipe_action_option_offset_callback_trampoline(
527    offset: f32,
528    user_data: *mut c_void,
529) {
530    if user_data.is_null() {
531        return;
532    }
533
534    let callback = unsafe { &*(user_data as *mut ListItemSwipeOffsetCallbackContext) };
535    (callback.callback)(offset);
536}
537
538/// Main-axis size array wrapper for list children.
539pub struct ListChildrenMainSize {
540    raw: NonNull<ArkUI_ListChildrenMainSize>,
541}
542
543impl ListChildrenMainSize {
544    pub fn new() -> ArkUIResult<Self> {
545        let option = unsafe { OH_ArkUI_ListChildrenMainSizeOption_Create() };
546        NonNull::new(option)
547            .map(|raw| Self::from_raw(raw.as_ptr()))
548            .ok_or_else(|| {
549                ArkUIError::new(
550                    ArkUIErrorCode::ParamInvalid,
551                    "OH_ArkUI_ListChildrenMainSizeOption_Create returned null",
552                )
553            })
554    }
555
556    pub(crate) fn raw(&self) -> *mut ArkUI_ListChildrenMainSize {
557        self.raw.as_ptr()
558    }
559
560    pub(crate) fn from_raw(raw: *mut ArkUI_ListChildrenMainSize) -> Self {
561        Self {
562            raw: non_null_or_panic(raw, "ArkUI_ListChildrenMainSize"),
563        }
564    }
565
566    pub(crate) fn into_raw(self) -> *mut ArkUI_ListChildrenMainSize {
567        self.raw.as_ptr()
568    }
569
570    pub fn dispose(self) {
571        unsafe { OH_ArkUI_ListChildrenMainSizeOption_Dispose(self.raw()) }
572    }
573
574    pub fn set_default_main_size(&mut self, default_main_size: f32) -> ArkUIResult<()> {
575        unsafe {
576            check_arkui_status!(OH_ArkUI_ListChildrenMainSizeOption_SetDefaultMainSize(
577                self.raw(),
578                default_main_size
579            ))
580        }
581    }
582
583    pub fn get_default_main_size(&self) -> f32 {
584        unsafe { OH_ArkUI_ListChildrenMainSizeOption_GetDefaultMainSize(self.raw()) }
585    }
586
587    pub fn resize(&mut self, total_size: i32) {
588        unsafe { OH_ArkUI_ListChildrenMainSizeOption_Resize(self.raw(), total_size) }
589    }
590
591    pub fn splice(&mut self, index: i32, delete_count: i32, add_count: i32) -> ArkUIResult<()> {
592        unsafe {
593            check_arkui_status!(OH_ArkUI_ListChildrenMainSizeOption_Splice(
594                self.raw(),
595                index,
596                delete_count,
597                add_count
598            ))
599        }
600    }
601
602    pub fn update_size(&mut self, index: i32, main_size: f32) -> ArkUIResult<()> {
603        unsafe {
604            check_arkui_status!(OH_ArkUI_ListChildrenMainSizeOption_UpdateSize(
605                self.raw(),
606                index,
607                main_size
608            ))
609        }
610    }
611
612    pub fn get_main_size(&self, index: i32) -> f32 {
613        unsafe { OH_ArkUI_ListChildrenMainSizeOption_GetMainSize(self.raw(), index) }
614    }
615}
616
617/// Accessibility state wrapper.
618pub struct AccessibilityState {
619    raw: NonNull<ArkUI_AccessibilityState>,
620}
621
622impl AccessibilityState {
623    pub fn new() -> ArkUIResult<Self> {
624        let state = unsafe { OH_ArkUI_AccessibilityState_Create() };
625        NonNull::new(state)
626            .map(|raw| Self::from_raw(raw.as_ptr()))
627            .ok_or_else(|| {
628                ArkUIError::new(
629                    ArkUIErrorCode::ParamInvalid,
630                    "OH_ArkUI_AccessibilityState_Create returned null",
631                )
632            })
633    }
634
635    pub(crate) fn raw(&self) -> *mut ArkUI_AccessibilityState {
636        self.raw.as_ptr()
637    }
638
639    pub(crate) fn from_raw(raw: *mut ArkUI_AccessibilityState) -> Self {
640        Self {
641            raw: non_null_or_panic(raw, "ArkUI_AccessibilityState"),
642        }
643    }
644
645    pub(crate) fn into_raw(self) -> *mut ArkUI_AccessibilityState {
646        self.raw.as_ptr()
647    }
648
649    pub fn dispose(self) {
650        unsafe { OH_ArkUI_AccessibilityState_Dispose(self.raw()) }
651    }
652
653    pub fn set_disabled(&mut self, is_disabled: i32) {
654        unsafe { OH_ArkUI_AccessibilityState_SetDisabled(self.raw(), is_disabled) }
655    }
656
657    pub fn is_disabled(&self) -> i32 {
658        unsafe { OH_ArkUI_AccessibilityState_IsDisabled(self.raw()) }
659    }
660
661    pub fn set_selected(&mut self, is_selected: i32) {
662        unsafe { OH_ArkUI_AccessibilityState_SetSelected(self.raw(), is_selected) }
663    }
664
665    pub fn is_selected(&self) -> i32 {
666        unsafe { OH_ArkUI_AccessibilityState_IsSelected(self.raw()) }
667    }
668
669    pub fn set_checked_state(&mut self, checked_state: i32) {
670        unsafe { OH_ArkUI_AccessibilityState_SetCheckedState(self.raw(), checked_state) }
671    }
672
673    pub fn get_checked_state(&self) -> i32 {
674        unsafe { OH_ArkUI_AccessibilityState_GetCheckedState(self.raw()) }
675    }
676}
677
678/// Guideline option wrapper for relative layout.
679pub struct GuidelineOption {
680    raw: NonNull<ArkUI_GuidelineOption>,
681}
682
683impl GuidelineOption {
684    pub fn new(size: i32) -> ArkUIResult<Self> {
685        let option = unsafe { OH_ArkUI_GuidelineOption_Create(size) };
686        NonNull::new(option)
687            .map(|raw| Self::from_raw(raw.as_ptr()))
688            .ok_or_else(|| {
689                ArkUIError::new(
690                    ArkUIErrorCode::ParamInvalid,
691                    "OH_ArkUI_GuidelineOption_Create returned null",
692                )
693            })
694    }
695
696    pub(crate) fn raw(&self) -> *mut ArkUI_GuidelineOption {
697        self.raw.as_ptr()
698    }
699
700    pub(crate) fn from_raw(raw: *mut ArkUI_GuidelineOption) -> Self {
701        Self {
702            raw: non_null_or_panic(raw, "ArkUI_GuidelineOption"),
703        }
704    }
705
706    pub(crate) fn into_raw(self) -> *mut ArkUI_GuidelineOption {
707        self.raw.as_ptr()
708    }
709
710    pub fn dispose(self) {
711        unsafe { OH_ArkUI_GuidelineOption_Dispose(self.raw()) }
712    }
713
714    pub fn set_id(&mut self, value: &str, index: i32) -> ArkUIResult<()> {
715        with_cstring(value, |value_ptr| unsafe {
716            OH_ArkUI_GuidelineOption_SetId(self.raw(), value_ptr, index)
717        })
718    }
719
720    pub fn set_direction(&mut self, value: crate::Axis, index: i32) {
721        unsafe { OH_ArkUI_GuidelineOption_SetDirection(self.raw(), value.into(), index) }
722    }
723
724    pub fn set_position_start(&mut self, value: f32, index: i32) {
725        unsafe { OH_ArkUI_GuidelineOption_SetPositionStart(self.raw(), value, index) }
726    }
727
728    pub fn set_position_end(&mut self, value: f32, index: i32) {
729        unsafe { OH_ArkUI_GuidelineOption_SetPositionEnd(self.raw(), value, index) }
730    }
731
732    pub fn get_id(&self, index: i32) -> Option<String> {
733        c_char_ptr_to_string(unsafe { OH_ArkUI_GuidelineOption_GetId(self.raw(), index) })
734    }
735
736    pub fn get_direction(&self, index: i32) -> crate::Axis {
737        unsafe { OH_ArkUI_GuidelineOption_GetDirection(self.raw(), index).into() }
738    }
739
740    pub fn get_position_start(&self, index: i32) -> f32 {
741        unsafe { OH_ArkUI_GuidelineOption_GetPositionStart(self.raw(), index) }
742    }
743
744    pub fn get_position_end(&self, index: i32) -> f32 {
745        unsafe { OH_ArkUI_GuidelineOption_GetPositionEnd(self.raw(), index) }
746    }
747}
748
749/// Barrier option wrapper for relative layout.
750pub struct BarrierOption {
751    raw: NonNull<ArkUI_BarrierOption>,
752}
753
754impl BarrierOption {
755    pub fn new(size: i32) -> ArkUIResult<Self> {
756        let option = unsafe { OH_ArkUI_BarrierOption_Create(size) };
757        NonNull::new(option)
758            .map(|raw| Self::from_raw(raw.as_ptr()))
759            .ok_or_else(|| {
760                ArkUIError::new(
761                    ArkUIErrorCode::ParamInvalid,
762                    "OH_ArkUI_BarrierOption_Create returned null",
763                )
764            })
765    }
766
767    pub(crate) fn raw(&self) -> *mut ArkUI_BarrierOption {
768        self.raw.as_ptr()
769    }
770
771    pub(crate) fn from_raw(raw: *mut ArkUI_BarrierOption) -> Self {
772        Self {
773            raw: non_null_or_panic(raw, "ArkUI_BarrierOption"),
774        }
775    }
776
777    pub(crate) fn into_raw(self) -> *mut ArkUI_BarrierOption {
778        self.raw.as_ptr()
779    }
780
781    pub fn dispose(self) {
782        unsafe { OH_ArkUI_BarrierOption_Dispose(self.raw()) }
783    }
784
785    pub fn set_id(&mut self, value: &str, index: i32) -> ArkUIResult<()> {
786        with_cstring(value, |value_ptr| unsafe {
787            OH_ArkUI_BarrierOption_SetId(self.raw(), value_ptr, index)
788        })
789    }
790
791    pub fn set_direction(&mut self, value: crate::BarrierDirection, index: i32) {
792        unsafe { OH_ArkUI_BarrierOption_SetDirection(self.raw(), value.into(), index) }
793    }
794
795    pub fn set_referenced_id(&mut self, value: &str, index: i32) -> ArkUIResult<()> {
796        with_cstring(value, |value_ptr| unsafe {
797            OH_ArkUI_BarrierOption_SetReferencedId(self.raw(), value_ptr, index)
798        })
799    }
800
801    pub fn get_id(&self, index: i32) -> Option<String> {
802        c_char_ptr_to_string(unsafe { OH_ArkUI_BarrierOption_GetId(self.raw(), index) })
803    }
804
805    pub fn get_direction(&self, index: i32) -> crate::BarrierDirection {
806        unsafe { OH_ArkUI_BarrierOption_GetDirection(self.raw(), index).into() }
807    }
808
809    pub fn get_referenced_id(&self, index: i32, referenced_index: i32) -> Option<String> {
810        c_char_ptr_to_string(unsafe {
811            OH_ArkUI_BarrierOption_GetReferencedId(self.raw(), index, referenced_index)
812        })
813    }
814
815    pub fn get_referenced_id_size(&self, index: i32) -> i32 {
816        unsafe { OH_ArkUI_BarrierOption_GetReferencedIdSize(self.raw(), index) }
817    }
818}
819
820#[cfg(feature = "api-15")]
821/// Linear-progress style option wrapper.
822pub struct ProgressLinearStyleOption {
823    raw: NonNull<ArkUI_ProgressLinearStyleOption>,
824}
825
826#[cfg(feature = "api-15")]
827impl ProgressLinearStyleOption {
828    pub fn new() -> ArkUIResult<Self> {
829        let option = unsafe { OH_ArkUI_ProgressLinearStyleOption_Create() };
830        NonNull::new(option)
831            .map(|raw| Self::from_raw(raw.as_ptr()))
832            .ok_or_else(|| {
833                ArkUIError::new(
834                    ArkUIErrorCode::ParamInvalid,
835                    "OH_ArkUI_ProgressLinearStyleOption_Create returned null",
836                )
837            })
838    }
839
840    pub(crate) fn raw(&self) -> *mut ArkUI_ProgressLinearStyleOption {
841        self.raw.as_ptr()
842    }
843
844    pub(crate) fn from_raw(raw: *mut ArkUI_ProgressLinearStyleOption) -> Self {
845        Self {
846            raw: non_null_or_panic(raw, "ArkUI_ProgressLinearStyleOption"),
847        }
848    }
849
850    pub(crate) fn into_raw(self) -> *mut ArkUI_ProgressLinearStyleOption {
851        self.raw.as_ptr()
852    }
853
854    pub fn destroy(self) {
855        unsafe { OH_ArkUI_ProgressLinearStyleOption_Destroy(self.raw()) }
856    }
857
858    pub fn set_scan_effect_enabled(&mut self, enabled: bool) {
859        unsafe { OH_ArkUI_ProgressLinearStyleOption_SetScanEffectEnabled(self.raw(), enabled) }
860    }
861
862    pub fn set_smooth_effect_enabled(&mut self, enabled: bool) {
863        unsafe { OH_ArkUI_ProgressLinearStyleOption_SetSmoothEffectEnabled(self.raw(), enabled) }
864    }
865
866    pub fn set_stroke_width(&mut self, stroke_width: f32) {
867        unsafe { OH_ArkUI_ProgressLinearStyleOption_SetStrokeWidth(self.raw(), stroke_width) }
868    }
869
870    pub fn set_stroke_radius(&mut self, stroke_radius: f32) {
871        unsafe { OH_ArkUI_ProgressLinearStyleOption_SetStrokeRadius(self.raw(), stroke_radius) }
872    }
873
874    pub fn get_scan_effect_enabled(&self) -> bool {
875        unsafe { OH_ArkUI_ProgressLinearStyleOption_GetScanEffectEnabled(self.raw()) }
876    }
877
878    pub fn get_smooth_effect_enabled(&self) -> bool {
879        unsafe { OH_ArkUI_ProgressLinearStyleOption_GetSmoothEffectEnabled(self.raw()) }
880    }
881
882    pub fn get_stroke_width(&self) -> f32 {
883        unsafe { OH_ArkUI_ProgressLinearStyleOption_GetStrokeWidth(self.raw()) }
884    }
885
886    pub fn get_stroke_radius(&self) -> f32 {
887        unsafe { OH_ArkUI_ProgressLinearStyleOption_GetStrokeRadius(self.raw()) }
888    }
889}
890
891#[cfg(feature = "api-21")]
892/// Position edge values used by side/edge-based APIs.
893pub struct PositionEdges {
894    raw: NonNull<ArkUI_PositionEdges>,
895}
896
897#[cfg(feature = "api-21")]
898impl PositionEdges {
899    pub fn new() -> ArkUIResult<Self> {
900        let edges = unsafe { OH_ArkUI_PositionEdges_Create() };
901        NonNull::new(edges)
902            .map(|raw| Self::from_raw(raw.as_ptr()))
903            .ok_or_else(|| {
904                ArkUIError::new(
905                    ArkUIErrorCode::ParamInvalid,
906                    "OH_ArkUI_PositionEdges_Create returned null",
907                )
908            })
909    }
910
911    pub fn copy(&self) -> ArkUIResult<Self> {
912        let copied = unsafe { OH_ArkUI_PositionEdges_Copy(self.raw()) };
913        NonNull::new(copied)
914            .map(|raw| Self::from_raw(raw.as_ptr()))
915            .ok_or_else(|| {
916                ArkUIError::new(
917                    ArkUIErrorCode::ParamInvalid,
918                    "OH_ArkUI_PositionEdges_Copy returned null",
919                )
920            })
921    }
922
923    pub(crate) fn raw(&self) -> *mut ArkUI_PositionEdges {
924        self.raw.as_ptr()
925    }
926
927    pub(crate) fn from_raw(raw: *mut ArkUI_PositionEdges) -> Self {
928        Self {
929            raw: non_null_or_panic(raw, "ArkUI_PositionEdges"),
930        }
931    }
932
933    pub(crate) fn into_raw(self) -> *mut ArkUI_PositionEdges {
934        self.raw.as_ptr()
935    }
936
937    pub fn dispose(self) {
938        unsafe { OH_ArkUI_PositionEdges_Dispose(self.raw()) }
939    }
940
941    pub fn set_top(&mut self, value: f32) {
942        unsafe { OH_ArkUI_PositionEdges_SetTop(self.raw(), value) }
943    }
944
945    pub fn get_top(&self) -> ArkUIResult<f32> {
946        let mut value = 0.0;
947        unsafe { check_arkui_status!(OH_ArkUI_PositionEdges_GetTop(self.raw(), &mut value)) }?;
948        Ok(value)
949    }
950
951    pub fn set_left(&mut self, value: f32) {
952        unsafe { OH_ArkUI_PositionEdges_SetLeft(self.raw(), value) }
953    }
954
955    pub fn get_left(&self) -> ArkUIResult<f32> {
956        let mut value = 0.0;
957        unsafe { check_arkui_status!(OH_ArkUI_PositionEdges_GetLeft(self.raw(), &mut value)) }?;
958        Ok(value)
959    }
960
961    pub fn set_bottom(&mut self, value: f32) {
962        unsafe { OH_ArkUI_PositionEdges_SetBottom(self.raw(), value) }
963    }
964
965    pub fn get_bottom(&self) -> ArkUIResult<f32> {
966        let mut value = 0.0;
967        unsafe { check_arkui_status!(OH_ArkUI_PositionEdges_GetBottom(self.raw(), &mut value)) }?;
968        Ok(value)
969    }
970
971    pub fn set_right(&mut self, value: f32) {
972        unsafe { OH_ArkUI_PositionEdges_SetRight(self.raw(), value) }
973    }
974
975    pub fn get_right(&self) -> ArkUIResult<f32> {
976        let mut value = 0.0;
977        unsafe { check_arkui_status!(OH_ArkUI_PositionEdges_GetRight(self.raw(), &mut value)) }?;
978        Ok(value)
979    }
980}
981
982#[cfg(feature = "api-21")]
983/// Pixel round-policy wrapper.
984pub struct PixelRoundPolicy {
985    raw: NonNull<ArkUI_PixelRoundPolicy>,
986}
987
988#[cfg(feature = "api-21")]
989impl PixelRoundPolicy {
990    pub fn new() -> ArkUIResult<Self> {
991        let policy = unsafe { OH_ArkUI_PixelRoundPolicy_Create() };
992        NonNull::new(policy)
993            .map(|raw| Self::from_raw(raw.as_ptr()))
994            .ok_or_else(|| {
995                ArkUIError::new(
996                    ArkUIErrorCode::ParamInvalid,
997                    "OH_ArkUI_PixelRoundPolicy_Create returned null",
998                )
999            })
1000    }
1001
1002    pub(crate) fn raw(&self) -> *mut ArkUI_PixelRoundPolicy {
1003        self.raw.as_ptr()
1004    }
1005
1006    pub(crate) fn from_raw(raw: *mut ArkUI_PixelRoundPolicy) -> Self {
1007        Self {
1008            raw: non_null_or_panic(raw, "ArkUI_PixelRoundPolicy"),
1009        }
1010    }
1011
1012    pub(crate) fn into_raw(self) -> *mut ArkUI_PixelRoundPolicy {
1013        self.raw.as_ptr()
1014    }
1015
1016    pub fn dispose(self) {
1017        unsafe { OH_ArkUI_PixelRoundPolicy_Dispose(self.raw()) }
1018    }
1019
1020    pub fn set_top(&mut self, value: crate::PixelRoundCalcPolicy) {
1021        unsafe { OH_ArkUI_PixelRoundPolicy_SetTop(self.raw(), value.into()) }
1022    }
1023
1024    pub fn get_top(&self) -> ArkUIResult<crate::PixelRoundCalcPolicy> {
1025        let mut value = ArkUI_PixelRoundCalcPolicy_ARKUI_PIXELROUNDCALCPOLICY_NOFORCEROUND;
1026        unsafe { check_arkui_status!(OH_ArkUI_PixelRoundPolicy_GetTop(self.raw(), &mut value)) }?;
1027        Ok(value.into())
1028    }
1029
1030    pub fn set_start(&mut self, value: crate::PixelRoundCalcPolicy) {
1031        unsafe { OH_ArkUI_PixelRoundPolicy_SetStart(self.raw(), value.into()) }
1032    }
1033
1034    pub fn get_start(&self) -> ArkUIResult<crate::PixelRoundCalcPolicy> {
1035        let mut value = ArkUI_PixelRoundCalcPolicy_ARKUI_PIXELROUNDCALCPOLICY_NOFORCEROUND;
1036        unsafe { check_arkui_status!(OH_ArkUI_PixelRoundPolicy_GetStart(self.raw(), &mut value)) }?;
1037        Ok(value.into())
1038    }
1039
1040    pub fn set_bottom(&mut self, value: crate::PixelRoundCalcPolicy) {
1041        unsafe { OH_ArkUI_PixelRoundPolicy_SetBottom(self.raw(), value.into()) }
1042    }
1043
1044    pub fn get_bottom(&self) -> ArkUIResult<crate::PixelRoundCalcPolicy> {
1045        let mut value = ArkUI_PixelRoundCalcPolicy_ARKUI_PIXELROUNDCALCPOLICY_NOFORCEROUND;
1046        unsafe {
1047            check_arkui_status!(OH_ArkUI_PixelRoundPolicy_GetBottom(self.raw(), &mut value))
1048        }?;
1049        Ok(value.into())
1050    }
1051
1052    pub fn set_end(&mut self, value: crate::PixelRoundCalcPolicy) {
1053        unsafe { OH_ArkUI_PixelRoundPolicy_SetEnd(self.raw(), value.into()) }
1054    }
1055
1056    pub fn get_end(&self) -> ArkUIResult<crate::PixelRoundCalcPolicy> {
1057        let mut value = ArkUI_PixelRoundCalcPolicy_ARKUI_PIXELROUNDCALCPOLICY_NOFORCEROUND;
1058        unsafe { check_arkui_status!(OH_ArkUI_PixelRoundPolicy_GetEnd(self.raw(), &mut value)) }?;
1059        Ok(value.into())
1060    }
1061}
1062
1063#[cfg(feature = "api-22")]
1064#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1065/// Grid item size value object.
1066pub struct GridItemSize {
1067    pub row_span: u32,
1068    pub column_span: u32,
1069}
1070
1071#[cfg(feature = "api-22")]
1072impl From<ArkUI_GridItemSize> for GridItemSize {
1073    fn from(value: ArkUI_GridItemSize) -> Self {
1074        Self {
1075            row_span: value.rowSpan,
1076            column_span: value.columnSpan,
1077        }
1078    }
1079}
1080
1081#[cfg(feature = "api-22")]
1082impl From<GridItemSize> for ArkUI_GridItemSize {
1083    fn from(value: GridItemSize) -> Self {
1084        Self {
1085            rowSpan: value.row_span,
1086            columnSpan: value.column_span,
1087        }
1088    }
1089}
1090
1091#[cfg(feature = "api-22")]
1092#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1093/// Grid item rectangle value object.
1094pub struct GridItemRect {
1095    pub row_start: u32,
1096    pub column_start: u32,
1097    pub row_span: u32,
1098    pub column_span: u32,
1099}
1100
1101#[cfg(feature = "api-22")]
1102impl From<ArkUI_GridItemRect> for GridItemRect {
1103    fn from(value: ArkUI_GridItemRect) -> Self {
1104        Self {
1105            row_start: value.rowStart,
1106            column_start: value.columnStart,
1107            row_span: value.rowSpan,
1108            column_span: value.columnSpan,
1109        }
1110    }
1111}
1112
1113#[cfg(feature = "api-22")]
1114impl From<GridItemRect> for ArkUI_GridItemRect {
1115    fn from(value: GridItemRect) -> Self {
1116        Self {
1117            rowStart: value.row_start,
1118            columnStart: value.column_start,
1119            rowSpan: value.row_span,
1120            columnSpan: value.column_span,
1121        }
1122    }
1123}
1124
1125#[cfg(feature = "api-22")]
1126struct GridLayoutIrregularSizeCallbackContext {
1127    callback: Box<dyn Fn(i32) -> GridItemSize>,
1128}
1129
1130#[cfg(feature = "api-22")]
1131struct GridLayoutRectCallbackContext {
1132    callback: Box<dyn Fn(i32) -> GridItemRect>,
1133}
1134
1135#[cfg(feature = "api-22")]
1136/// Grid layout options wrapper.
1137pub struct GridLayoutOptions {
1138    raw: NonNull<ArkUI_GridLayoutOptions>,
1139    irregular_size_callback: Option<*mut GridLayoutIrregularSizeCallbackContext>,
1140    rect_callback: Option<*mut GridLayoutRectCallbackContext>,
1141}
1142
1143#[cfg(feature = "api-22")]
1144impl GridLayoutOptions {
1145    pub fn new() -> ArkUIResult<Self> {
1146        let option = unsafe { OH_ArkUI_GridLayoutOptions_Create() };
1147        NonNull::new(option)
1148            .map(|raw| Self::from_raw(raw.as_ptr()))
1149            .ok_or_else(|| {
1150                ArkUIError::new(
1151                    ArkUIErrorCode::ParamInvalid,
1152                    "OH_ArkUI_GridLayoutOptions_Create returned null",
1153                )
1154            })
1155    }
1156
1157    pub(crate) fn raw(&self) -> *mut ArkUI_GridLayoutOptions {
1158        self.raw.as_ptr()
1159    }
1160
1161    pub(crate) fn from_raw(raw: *mut ArkUI_GridLayoutOptions) -> Self {
1162        Self {
1163            raw: non_null_or_panic(raw, "ArkUI_GridLayoutOptions"),
1164            irregular_size_callback: None,
1165            rect_callback: None,
1166        }
1167    }
1168
1169    pub(crate) fn into_raw(self) -> *mut ArkUI_GridLayoutOptions {
1170        self.raw.as_ptr()
1171    }
1172
1173    pub fn dispose(mut self) {
1174        self.clear_get_irregular_size_by_index_callback();
1175        self.clear_get_rect_by_index_callback();
1176        unsafe { OH_ArkUI_GridLayoutOptions_Dispose(self.raw()) }
1177    }
1178
1179    pub fn set_irregular_indexes(&mut self, irregular_indexes: &mut [u32]) -> ArkUIResult<()> {
1180        unsafe {
1181            check_arkui_status!(OH_ArkUI_GridLayoutOptions_SetIrregularIndexes(
1182                self.raw(),
1183                irregular_indexes.as_mut_ptr(),
1184                irregular_indexes.len() as i32
1185            ))
1186        }
1187    }
1188
1189    pub fn get_irregular_indexes(&self, irregular_indexes: &mut [u32]) -> ArkUIResult<i32> {
1190        let mut size = irregular_indexes.len() as i32;
1191        unsafe {
1192            check_arkui_status!(OH_ArkUI_GridLayoutOptions_GetIrregularIndexes(
1193                self.raw(),
1194                irregular_indexes.as_mut_ptr(),
1195                &mut size
1196            ))
1197        }?;
1198        Ok(size)
1199    }
1200
1201    pub fn register_get_irregular_size_by_index_callback<T: Fn(i32) -> GridItemSize + 'static>(
1202        &mut self,
1203        callback: T,
1204    ) {
1205        self.clear_get_irregular_size_by_index_callback();
1206        let callback = Box::into_raw(Box::new(GridLayoutIrregularSizeCallbackContext {
1207            callback: Box::new(callback),
1208        }));
1209        unsafe {
1210            OH_ArkUI_GridLayoutOptions_RegisterGetIrregularSizeByIndexCallback(
1211                self.raw(),
1212                callback.cast(),
1213                Some(grid_layout_irregular_size_callback_trampoline),
1214            )
1215        };
1216        self.irregular_size_callback = Some(callback);
1217    }
1218
1219    pub fn clear_get_irregular_size_by_index_callback(&mut self) {
1220        unsafe {
1221            OH_ArkUI_GridLayoutOptions_RegisterGetIrregularSizeByIndexCallback(
1222                self.raw(),
1223                std::ptr::null_mut(),
1224                None,
1225            )
1226        };
1227        if let Some(callback) = self.irregular_size_callback.take() {
1228            unsafe {
1229                drop(Box::from_raw(callback));
1230            }
1231        }
1232    }
1233
1234    pub fn register_get_rect_by_index_callback<T: Fn(i32) -> GridItemRect + 'static>(
1235        &mut self,
1236        callback: T,
1237    ) {
1238        self.clear_get_rect_by_index_callback();
1239        let callback = Box::into_raw(Box::new(GridLayoutRectCallbackContext {
1240            callback: Box::new(callback),
1241        }));
1242        unsafe {
1243            OH_ArkUI_GridLayoutOptions_RegisterGetRectByIndexCallback(
1244                self.raw(),
1245                callback.cast(),
1246                Some(grid_layout_rect_callback_trampoline),
1247            )
1248        };
1249        self.rect_callback = Some(callback);
1250    }
1251
1252    pub fn clear_get_rect_by_index_callback(&mut self) {
1253        unsafe {
1254            OH_ArkUI_GridLayoutOptions_RegisterGetRectByIndexCallback(
1255                self.raw(),
1256                std::ptr::null_mut(),
1257                None,
1258            )
1259        };
1260        if let Some(callback) = self.rect_callback.take() {
1261            unsafe {
1262                drop(Box::from_raw(callback));
1263            }
1264        }
1265    }
1266}
1267
1268#[cfg(feature = "api-22")]
1269unsafe extern "C" fn grid_layout_irregular_size_callback_trampoline(
1270    item_index: i32,
1271    user_data: *mut c_void,
1272) -> ArkUI_GridItemSize {
1273    if user_data.is_null() {
1274        return unsafe { std::mem::zeroed() };
1275    }
1276
1277    let callback = unsafe { &*(user_data as *mut GridLayoutIrregularSizeCallbackContext) };
1278    (callback.callback)(item_index).into()
1279}
1280
1281#[cfg(feature = "api-22")]
1282unsafe extern "C" fn grid_layout_rect_callback_trampoline(
1283    item_index: i32,
1284    user_data: *mut c_void,
1285) -> ArkUI_GridItemRect {
1286    if user_data.is_null() {
1287        return unsafe { std::mem::zeroed() };
1288    }
1289
1290    let callback = unsafe { &*(user_data as *mut GridLayoutRectCallbackContext) };
1291    (callback.callback)(item_index).into()
1292}
1293
1294#[cfg(feature = "api-22")]
1295/// Counter display configuration for text input/area.
1296pub struct ShowCounterConfig {
1297    raw: NonNull<ArkUI_ShowCounterConfig>,
1298}
1299
1300#[cfg(feature = "api-22")]
1301impl ShowCounterConfig {
1302    pub fn new() -> ArkUIResult<Self> {
1303        let config = unsafe { OH_ArkUI_ShowCounterConfig_Create() };
1304        NonNull::new(config)
1305            .map(|raw| Self::from_raw(raw.as_ptr()))
1306            .ok_or_else(|| {
1307                ArkUIError::new(
1308                    ArkUIErrorCode::ParamInvalid,
1309                    "OH_ArkUI_ShowCounterConfig_Create returned null",
1310                )
1311            })
1312    }
1313
1314    pub(crate) fn raw(&self) -> *mut ArkUI_ShowCounterConfig {
1315        self.raw.as_ptr()
1316    }
1317
1318    pub(crate) fn from_raw(raw: *mut ArkUI_ShowCounterConfig) -> Self {
1319        Self {
1320            raw: non_null_or_panic(raw, "ArkUI_ShowCounterConfig"),
1321        }
1322    }
1323
1324    pub(crate) fn into_raw(self) -> *mut ArkUI_ShowCounterConfig {
1325        self.raw.as_ptr()
1326    }
1327
1328    pub fn dispose(self) {
1329        unsafe { OH_ArkUI_ShowCounterConfig_Dispose(self.raw()) }
1330    }
1331
1332    pub fn set_counter_text_color(&mut self, color: u32) {
1333        unsafe { OH_ArkUI_ShowCounterConfig_SetCounterTextColor(self.raw(), color) }
1334    }
1335
1336    pub fn set_counter_text_overflow_color(&mut self, color: u32) {
1337        unsafe { OH_ArkUI_ShowCounterConfig_SetCounterTextOverflowColor(self.raw(), color) }
1338    }
1339
1340    pub fn get_counter_text_color(&self) -> u32 {
1341        unsafe { OH_ArkUI_ShowCounterConfig_GetCounterTextColor(self.raw()) }
1342    }
1343
1344    pub fn get_counter_text_overflow_color(&self) -> u32 {
1345        unsafe { OH_ArkUI_ShowCounterConfig_GetCounterTextOverflowColor(self.raw()) }
1346    }
1347}
1348
1349#[cfg(feature = "api-17")]
1350/// Options for visible-area change event registration.
1351pub struct VisibleAreaEventOptions {
1352    raw: NonNull<ArkUI_VisibleAreaEventOptions>,
1353}
1354
1355#[cfg(feature = "api-17")]
1356impl VisibleAreaEventOptions {
1357    pub fn new() -> ArkUIResult<Self> {
1358        let option = unsafe { OH_ArkUI_VisibleAreaEventOptions_Create() };
1359        NonNull::new(option)
1360            .map(|raw| Self::from_raw(raw.as_ptr()))
1361            .ok_or_else(|| {
1362                ArkUIError::new(
1363                    ArkUIErrorCode::ParamInvalid,
1364                    "OH_ArkUI_VisibleAreaEventOptions_Create returned null",
1365                )
1366            })
1367    }
1368
1369    pub(crate) fn raw(&self) -> *mut ArkUI_VisibleAreaEventOptions {
1370        self.raw.as_ptr()
1371    }
1372
1373    pub(crate) fn from_raw(raw: *mut ArkUI_VisibleAreaEventOptions) -> Self {
1374        Self {
1375            raw: non_null_or_panic(raw, "ArkUI_VisibleAreaEventOptions"),
1376        }
1377    }
1378
1379    pub(crate) fn into_raw(self) -> *mut ArkUI_VisibleAreaEventOptions {
1380        self.raw.as_ptr()
1381    }
1382
1383    pub fn dispose(self) {
1384        unsafe { OH_ArkUI_VisibleAreaEventOptions_Dispose(self.raw()) }
1385    }
1386
1387    pub fn set_ratios(&mut self, ratios: &mut [f32]) -> ArkUIResult<()> {
1388        unsafe {
1389            check_arkui_status!(OH_ArkUI_VisibleAreaEventOptions_SetRatios(
1390                self.raw(),
1391                ratios.as_mut_ptr(),
1392                ratios.len() as i32
1393            ))
1394        }
1395    }
1396
1397    pub fn get_ratios(&self, ratios: &mut [f32]) -> ArkUIResult<i32> {
1398        let mut size = ratios.len() as i32;
1399        unsafe {
1400            check_arkui_status!(OH_ArkUI_VisibleAreaEventOptions_GetRatios(
1401                self.raw(),
1402                ratios.as_mut_ptr(),
1403                &mut size
1404            ))
1405        }?;
1406        Ok(size)
1407    }
1408
1409    pub fn set_expected_update_interval(&mut self, interval: i32) -> ArkUIResult<()> {
1410        unsafe {
1411            check_arkui_status!(OH_ArkUI_VisibleAreaEventOptions_SetExpectedUpdateInterval(
1412                self.raw(),
1413                interval
1414            ))
1415        }
1416    }
1417
1418    pub fn get_expected_update_interval(&self) -> i32 {
1419        unsafe { OH_ArkUI_VisibleAreaEventOptions_GetExpectedUpdateInterval(self.raw()) }
1420    }
1421
1422    #[cfg(feature = "api-22")]
1423    pub fn set_measure_from_viewport(&mut self, measure_from_viewport: bool) -> ArkUIResult<()> {
1424        unsafe {
1425            check_arkui_status!(OH_ArkUI_VisibleAreaEventOptions_SetMeasureFromViewport(
1426                self.raw(),
1427                measure_from_viewport
1428            ))
1429        }
1430    }
1431
1432    #[cfg(feature = "api-22")]
1433    pub fn get_measure_from_viewport(&self) -> bool {
1434        unsafe { OH_ArkUI_VisibleAreaEventOptions_GetMeasureFromViewport(self.raw()) }
1435    }
1436}
1437
1438#[cfg(feature = "api-19")]
1439/// Range-content array wrapper for text picker.
1440pub struct TextPickerRangeContentArray {
1441    raw: NonNull<ArkUI_TextPickerRangeContentArray>,
1442}
1443
1444#[cfg(feature = "api-19")]
1445impl TextPickerRangeContentArray {
1446    pub fn new(length: i32) -> ArkUIResult<Self> {
1447        let handle = unsafe { OH_ArkUI_TextPickerRangeContentArray_Create(length) };
1448        NonNull::new(handle)
1449            .map(|raw| Self::from_raw(raw.as_ptr()))
1450            .ok_or_else(|| {
1451                ArkUIError::new(
1452                    ArkUIErrorCode::ParamInvalid,
1453                    "OH_ArkUI_TextPickerRangeContentArray_Create returned null",
1454                )
1455            })
1456    }
1457
1458    pub(crate) fn raw(&self) -> *mut ArkUI_TextPickerRangeContentArray {
1459        self.raw.as_ptr()
1460    }
1461
1462    pub(crate) fn from_raw(raw: *mut ArkUI_TextPickerRangeContentArray) -> Self {
1463        Self {
1464            raw: non_null_or_panic(raw, "ArkUI_TextPickerRangeContentArray"),
1465        }
1466    }
1467
1468    pub(crate) fn into_raw(self) -> *mut ArkUI_TextPickerRangeContentArray {
1469        self.raw.as_ptr()
1470    }
1471
1472    pub fn destroy(self) {
1473        unsafe { OH_ArkUI_TextPickerRangeContentArray_Destroy(self.raw()) }
1474    }
1475
1476    pub fn set_icon_at_index(&mut self, icon: &str, index: i32) -> ArkUIResult<()> {
1477        with_cstring(icon, |icon_ptr| unsafe {
1478            OH_ArkUI_TextPickerRangeContentArray_SetIconAtIndex(
1479                self.raw(),
1480                icon_ptr.cast_mut(),
1481                index,
1482            )
1483        })
1484    }
1485
1486    pub fn set_text_at_index(&mut self, text: &str, index: i32) -> ArkUIResult<()> {
1487        with_cstring(text, |text_ptr| unsafe {
1488            OH_ArkUI_TextPickerRangeContentArray_SetTextAtIndex(
1489                self.raw(),
1490                text_ptr.cast_mut(),
1491                index,
1492            )
1493        })
1494    }
1495}
1496
1497#[cfg(feature = "api-19")]
1498/// Range-content array wrapper for cascade text picker.
1499pub struct TextCascadePickerRangeContentArray {
1500    raw: NonNull<ArkUI_TextCascadePickerRangeContentArray>,
1501}
1502
1503#[cfg(feature = "api-19")]
1504impl TextCascadePickerRangeContentArray {
1505    pub fn new(length: i32) -> ArkUIResult<Self> {
1506        let handle = unsafe { OH_ArkUI_TextCascadePickerRangeContentArray_Create(length) };
1507        NonNull::new(handle)
1508            .map(|raw| Self::from_raw(raw.as_ptr()))
1509            .ok_or_else(|| {
1510                ArkUIError::new(
1511                    ArkUIErrorCode::ParamInvalid,
1512                    "OH_ArkUI_TextCascadePickerRangeContentArray_Create returned null",
1513                )
1514            })
1515    }
1516
1517    pub(crate) fn raw(&self) -> *mut ArkUI_TextCascadePickerRangeContentArray {
1518        self.raw.as_ptr()
1519    }
1520
1521    pub(crate) fn from_raw(raw: *mut ArkUI_TextCascadePickerRangeContentArray) -> Self {
1522        Self {
1523            raw: non_null_or_panic(raw, "ArkUI_TextCascadePickerRangeContentArray"),
1524        }
1525    }
1526
1527    pub(crate) fn into_raw(self) -> *mut ArkUI_TextCascadePickerRangeContentArray {
1528        self.raw.as_ptr()
1529    }
1530
1531    pub fn destroy(self) {
1532        unsafe { OH_ArkUI_TextCascadePickerRangeContentArray_Destroy(self.raw()) }
1533    }
1534
1535    pub fn set_text_at_index(&mut self, text: &str, index: i32) -> ArkUIResult<()> {
1536        with_cstring(text, |text_ptr| unsafe {
1537            OH_ArkUI_TextCascadePickerRangeContentArray_SetTextAtIndex(
1538                self.raw(),
1539                text_ptr.cast_mut(),
1540                index,
1541            )
1542        })
1543    }
1544
1545    pub fn set_child_at_index(&mut self, child: &TextCascadePickerRangeContentArray, index: i32) {
1546        unsafe {
1547            OH_ArkUI_TextCascadePickerRangeContentArray_SetChildAtIndex(
1548                self.raw(),
1549                child.raw(),
1550                index,
1551            )
1552        }
1553    }
1554}
1555
1556#[cfg(feature = "api-20")]
1557/// Embedded component option wrapper.
1558pub struct EmbeddedComponentOption {
1559    raw: NonNull<ArkUI_EmbeddedComponentOption>,
1560    on_error_callback: Option<EmbeddedComponentOnErrorCallbackRegistration>,
1561    on_terminated_callback: Option<EmbeddedComponentOnTerminatedCallbackRegistration>,
1562}
1563
1564#[cfg(feature = "api-20")]
1565impl EmbeddedComponentOption {
1566    pub fn new() -> ArkUIResult<Self> {
1567        let option = unsafe { OH_ArkUI_EmbeddedComponentOption_Create() };
1568        NonNull::new(option)
1569            .map(|raw| Self::from_raw(raw.as_ptr()))
1570            .ok_or_else(|| {
1571                ArkUIError::new(
1572                    ArkUIErrorCode::ParamInvalid,
1573                    "OH_ArkUI_EmbeddedComponentOption_Create returned null",
1574                )
1575            })
1576    }
1577
1578    pub(crate) fn raw(&self) -> *mut ArkUI_EmbeddedComponentOption {
1579        self.raw.as_ptr()
1580    }
1581
1582    pub(crate) fn from_raw(raw: *mut ArkUI_EmbeddedComponentOption) -> Self {
1583        Self {
1584            raw: non_null_or_panic(raw, "ArkUI_EmbeddedComponentOption"),
1585            on_error_callback: None,
1586            on_terminated_callback: None,
1587        }
1588    }
1589
1590    pub(crate) fn into_raw(mut self) -> *mut ArkUI_EmbeddedComponentOption {
1591        self.clear_on_error();
1592        self.clear_on_terminated();
1593        self.raw.as_ptr()
1594    }
1595
1596    pub fn dispose(mut self) {
1597        self.clear_on_error();
1598        self.clear_on_terminated();
1599        unsafe { OH_ArkUI_EmbeddedComponentOption_Dispose(self.raw()) }
1600    }
1601
1602    pub fn set_on_error<T: Fn(i32, Option<String>, Option<String>) + 'static>(
1603        &mut self,
1604        callback: T,
1605    ) -> ArkUIResult<()> {
1606        self.clear_on_error();
1607
1608        let callback = non_null_or_panic(
1609            Box::into_raw(Box::new(EmbeddedComponentOnErrorCallbackContext {
1610                callback: Box::new(callback),
1611            })),
1612            "EmbeddedComponentOnErrorCallbackContext",
1613        );
1614        let slot = {
1615            let mut slots = match embedded_component_on_error_callback_slots().lock() {
1616                Ok(slots) => slots,
1617                Err(poisoned) => poisoned.into_inner(),
1618            };
1619            let reserved = reserve_embedded_component_callback_slot(
1620                &mut slots,
1621                callback.as_ptr() as usize,
1622                "EmbeddedComponentOption on_error",
1623            );
1624            if let Err(err) = reserved {
1625                unsafe {
1626                    drop(Box::from_raw(callback.as_ptr()));
1627                }
1628                return Err(err);
1629            }
1630            reserved?
1631        };
1632        unsafe {
1633            OH_ArkUI_EmbeddedComponentOption_SetOnError(
1634                self.raw(),
1635                EMBEDDED_COMPONENT_ON_ERROR_CALLBACK_TRAMPOLINES[slot],
1636            )
1637        };
1638        self.on_error_callback =
1639            Some(EmbeddedComponentOnErrorCallbackRegistration { slot, callback });
1640        Ok(())
1641    }
1642
1643    pub fn clear_on_error(&mut self) {
1644        unsafe { OH_ArkUI_EmbeddedComponentOption_SetOnError(self.raw(), None) };
1645        if let Some(registration) = self.on_error_callback.take() {
1646            release_embedded_component_callback_slot(
1647                embedded_component_on_error_callback_slots(),
1648                registration.slot,
1649            );
1650            unsafe {
1651                drop(Box::from_raw(registration.callback.as_ptr()));
1652            }
1653        }
1654    }
1655
1656    pub fn set_on_terminated<T: Fn(i32, Option<EmbeddedComponentWantRef>) + 'static>(
1657        &mut self,
1658        callback: T,
1659    ) -> ArkUIResult<()> {
1660        self.clear_on_terminated();
1661
1662        let callback = non_null_or_panic(
1663            Box::into_raw(Box::new(EmbeddedComponentOnTerminatedCallbackContext {
1664                callback: Box::new(callback),
1665            })),
1666            "EmbeddedComponentOnTerminatedCallbackContext",
1667        );
1668        let slot = {
1669            let mut slots = match embedded_component_on_terminated_callback_slots().lock() {
1670                Ok(slots) => slots,
1671                Err(poisoned) => poisoned.into_inner(),
1672            };
1673            let reserved = reserve_embedded_component_callback_slot(
1674                &mut slots,
1675                callback.as_ptr() as usize,
1676                "EmbeddedComponentOption on_terminated",
1677            );
1678            if let Err(err) = reserved {
1679                unsafe {
1680                    drop(Box::from_raw(callback.as_ptr()));
1681                }
1682                return Err(err);
1683            }
1684            reserved?
1685        };
1686        unsafe {
1687            OH_ArkUI_EmbeddedComponentOption_SetOnTerminated(
1688                self.raw(),
1689                EMBEDDED_COMPONENT_ON_TERMINATED_CALLBACK_TRAMPOLINES[slot],
1690            )
1691        };
1692        self.on_terminated_callback =
1693            Some(EmbeddedComponentOnTerminatedCallbackRegistration { slot, callback });
1694        Ok(())
1695    }
1696
1697    pub fn clear_on_terminated(&mut self) {
1698        unsafe { OH_ArkUI_EmbeddedComponentOption_SetOnTerminated(self.raw(), None) };
1699        if let Some(registration) = self.on_terminated_callback.take() {
1700            release_embedded_component_callback_slot(
1701                embedded_component_on_terminated_callback_slots(),
1702                registration.slot,
1703            );
1704            unsafe {
1705                drop(Box::from_raw(registration.callback.as_ptr()));
1706            }
1707        }
1708    }
1709}
1710
1711#[cfg(feature = "api-20")]
1712#[derive(Clone, Copy, Debug)]
1713/// Borrowed reference wrapper for embedded component want object.
1714pub struct EmbeddedComponentWantRef {
1715    raw: NonNull<AbilityBase_Want>,
1716}
1717
1718#[cfg(feature = "api-20")]
1719impl EmbeddedComponentWantRef {
1720    pub(crate) fn from_raw(raw: *mut AbilityBase_Want) -> Option<Self> {
1721        NonNull::new(raw).map(|raw| Self { raw })
1722    }
1723
1724    pub(crate) fn raw(&self) -> *mut AbilityBase_Want {
1725        self.raw.as_ptr()
1726    }
1727}
1728
1729#[cfg(feature = "api-20")]
1730type EmbeddedComponentOnErrorHandler = dyn Fn(i32, Option<String>, Option<String>);
1731
1732#[cfg(feature = "api-20")]
1733struct EmbeddedComponentOnErrorCallbackContext {
1734    callback: Box<EmbeddedComponentOnErrorHandler>,
1735}
1736
1737#[cfg(feature = "api-20")]
1738struct EmbeddedComponentOnTerminatedCallbackContext {
1739    callback: Box<dyn Fn(i32, Option<EmbeddedComponentWantRef>)>,
1740}
1741
1742#[cfg(feature = "api-20")]
1743struct EmbeddedComponentOnErrorCallbackRegistration {
1744    slot: usize,
1745    callback: NonNull<EmbeddedComponentOnErrorCallbackContext>,
1746}
1747
1748#[cfg(feature = "api-20")]
1749struct EmbeddedComponentOnTerminatedCallbackRegistration {
1750    slot: usize,
1751    callback: NonNull<EmbeddedComponentOnTerminatedCallbackContext>,
1752}
1753
1754#[cfg(feature = "api-20")]
1755const EMBEDDED_COMPONENT_CALLBACK_SLOT_COUNT: usize = 16;
1756
1757#[cfg(feature = "api-20")]
1758type EmbeddedComponentCallbackSlots = [Option<usize>; EMBEDDED_COMPONENT_CALLBACK_SLOT_COUNT];
1759
1760#[cfg(feature = "api-20")]
1761static EMBEDDED_COMPONENT_ON_ERROR_CALLBACK_SLOTS: OnceLock<Mutex<EmbeddedComponentCallbackSlots>> =
1762    OnceLock::new();
1763#[cfg(feature = "api-20")]
1764static EMBEDDED_COMPONENT_ON_TERMINATED_CALLBACK_SLOTS: OnceLock<
1765    Mutex<EmbeddedComponentCallbackSlots>,
1766> = OnceLock::new();
1767
1768#[cfg(feature = "api-20")]
1769fn embedded_component_on_error_callback_slots() -> &'static Mutex<EmbeddedComponentCallbackSlots> {
1770    EMBEDDED_COMPONENT_ON_ERROR_CALLBACK_SLOTS
1771        .get_or_init(|| Mutex::new([None; EMBEDDED_COMPONENT_CALLBACK_SLOT_COUNT]))
1772}
1773
1774#[cfg(feature = "api-20")]
1775fn embedded_component_on_terminated_callback_slots(
1776) -> &'static Mutex<EmbeddedComponentCallbackSlots> {
1777    EMBEDDED_COMPONENT_ON_TERMINATED_CALLBACK_SLOTS
1778        .get_or_init(|| Mutex::new([None; EMBEDDED_COMPONENT_CALLBACK_SLOT_COUNT]))
1779}
1780
1781#[cfg(feature = "api-20")]
1782fn reserve_embedded_component_callback_slot(
1783    slots: &mut EmbeddedComponentCallbackSlots,
1784    callback: usize,
1785    callback_name: &'static str,
1786) -> ArkUIResult<usize> {
1787    for (index, slot) in slots.iter_mut().enumerate() {
1788        if slot.is_none() {
1789            *slot = Some(callback);
1790            return Ok(index);
1791        }
1792    }
1793    Err(ArkUIError::new(
1794        ArkUIErrorCode::ParamInvalid,
1795        format!("{callback_name} callbacks exceed slot limit"),
1796    ))
1797}
1798
1799#[cfg(feature = "api-20")]
1800fn release_embedded_component_callback_slot(
1801    slots: &Mutex<EmbeddedComponentCallbackSlots>,
1802    slot: usize,
1803) {
1804    let mut slots = match slots.lock() {
1805        Ok(slots) => slots,
1806        Err(poisoned) => poisoned.into_inner(),
1807    };
1808    if let Some(current) = slots.get_mut(slot) {
1809        *current = None;
1810    }
1811}
1812
1813#[cfg(feature = "api-20")]
1814type EmbeddedComponentOnErrorCallback =
1815    unsafe extern "C" fn(code: i32, name: *const c_char, message: *const c_char);
1816#[cfg(feature = "api-20")]
1817type EmbeddedComponentOnTerminatedCallback =
1818    unsafe extern "C" fn(code: i32, want: *mut AbilityBase_Want);
1819
1820#[cfg(feature = "api-20")]
1821macro_rules! define_embedded_component_on_error_trampoline {
1822    ($name:ident, $slot:expr) => {
1823        unsafe extern "C" fn $name(code: i32, name: *const c_char, message: *const c_char) {
1824            let callback = {
1825                let callbacks = match embedded_component_on_error_callback_slots().lock() {
1826                    Ok(callbacks) => callbacks,
1827                    Err(poisoned) => poisoned.into_inner(),
1828                };
1829                callbacks[$slot]
1830            };
1831            let Some(callback) = callback else {
1832                return;
1833            };
1834            let callback =
1835                unsafe { &*(callback as *const EmbeddedComponentOnErrorCallbackContext) };
1836            (callback.callback)(
1837                code,
1838                c_char_ptr_to_string(name),
1839                c_char_ptr_to_string(message),
1840            );
1841        }
1842    };
1843}
1844
1845#[cfg(feature = "api-20")]
1846macro_rules! define_embedded_component_on_terminated_trampoline {
1847    ($name:ident, $slot:expr) => {
1848        unsafe extern "C" fn $name(code: i32, want: *mut AbilityBase_Want) {
1849            let callback = {
1850                let callbacks = match embedded_component_on_terminated_callback_slots().lock() {
1851                    Ok(callbacks) => callbacks,
1852                    Err(poisoned) => poisoned.into_inner(),
1853                };
1854                callbacks[$slot]
1855            };
1856            let Some(callback) = callback else {
1857                return;
1858            };
1859            let callback =
1860                unsafe { &*(callback as *const EmbeddedComponentOnTerminatedCallbackContext) };
1861            (callback.callback)(code, EmbeddedComponentWantRef::from_raw(want));
1862        }
1863    };
1864}
1865
1866#[cfg(feature = "api-20")]
1867define_embedded_component_on_error_trampoline!(
1868    embedded_component_on_error_callback_trampoline_0,
1869    0
1870);
1871#[cfg(feature = "api-20")]
1872define_embedded_component_on_error_trampoline!(
1873    embedded_component_on_error_callback_trampoline_1,
1874    1
1875);
1876#[cfg(feature = "api-20")]
1877define_embedded_component_on_error_trampoline!(
1878    embedded_component_on_error_callback_trampoline_2,
1879    2
1880);
1881#[cfg(feature = "api-20")]
1882define_embedded_component_on_error_trampoline!(
1883    embedded_component_on_error_callback_trampoline_3,
1884    3
1885);
1886#[cfg(feature = "api-20")]
1887define_embedded_component_on_error_trampoline!(
1888    embedded_component_on_error_callback_trampoline_4,
1889    4
1890);
1891#[cfg(feature = "api-20")]
1892define_embedded_component_on_error_trampoline!(
1893    embedded_component_on_error_callback_trampoline_5,
1894    5
1895);
1896#[cfg(feature = "api-20")]
1897define_embedded_component_on_error_trampoline!(
1898    embedded_component_on_error_callback_trampoline_6,
1899    6
1900);
1901#[cfg(feature = "api-20")]
1902define_embedded_component_on_error_trampoline!(
1903    embedded_component_on_error_callback_trampoline_7,
1904    7
1905);
1906#[cfg(feature = "api-20")]
1907define_embedded_component_on_error_trampoline!(
1908    embedded_component_on_error_callback_trampoline_8,
1909    8
1910);
1911#[cfg(feature = "api-20")]
1912define_embedded_component_on_error_trampoline!(
1913    embedded_component_on_error_callback_trampoline_9,
1914    9
1915);
1916#[cfg(feature = "api-20")]
1917define_embedded_component_on_error_trampoline!(
1918    embedded_component_on_error_callback_trampoline_10,
1919    10
1920);
1921#[cfg(feature = "api-20")]
1922define_embedded_component_on_error_trampoline!(
1923    embedded_component_on_error_callback_trampoline_11,
1924    11
1925);
1926#[cfg(feature = "api-20")]
1927define_embedded_component_on_error_trampoline!(
1928    embedded_component_on_error_callback_trampoline_12,
1929    12
1930);
1931#[cfg(feature = "api-20")]
1932define_embedded_component_on_error_trampoline!(
1933    embedded_component_on_error_callback_trampoline_13,
1934    13
1935);
1936#[cfg(feature = "api-20")]
1937define_embedded_component_on_error_trampoline!(
1938    embedded_component_on_error_callback_trampoline_14,
1939    14
1940);
1941#[cfg(feature = "api-20")]
1942define_embedded_component_on_error_trampoline!(
1943    embedded_component_on_error_callback_trampoline_15,
1944    15
1945);
1946
1947#[cfg(feature = "api-20")]
1948const EMBEDDED_COMPONENT_ON_ERROR_CALLBACK_TRAMPOLINES: [Option<EmbeddedComponentOnErrorCallback>;
1949    EMBEDDED_COMPONENT_CALLBACK_SLOT_COUNT] = [
1950    Some(embedded_component_on_error_callback_trampoline_0),
1951    Some(embedded_component_on_error_callback_trampoline_1),
1952    Some(embedded_component_on_error_callback_trampoline_2),
1953    Some(embedded_component_on_error_callback_trampoline_3),
1954    Some(embedded_component_on_error_callback_trampoline_4),
1955    Some(embedded_component_on_error_callback_trampoline_5),
1956    Some(embedded_component_on_error_callback_trampoline_6),
1957    Some(embedded_component_on_error_callback_trampoline_7),
1958    Some(embedded_component_on_error_callback_trampoline_8),
1959    Some(embedded_component_on_error_callback_trampoline_9),
1960    Some(embedded_component_on_error_callback_trampoline_10),
1961    Some(embedded_component_on_error_callback_trampoline_11),
1962    Some(embedded_component_on_error_callback_trampoline_12),
1963    Some(embedded_component_on_error_callback_trampoline_13),
1964    Some(embedded_component_on_error_callback_trampoline_14),
1965    Some(embedded_component_on_error_callback_trampoline_15),
1966];
1967
1968#[cfg(feature = "api-20")]
1969define_embedded_component_on_terminated_trampoline!(
1970    embedded_component_on_terminated_callback_trampoline_0,
1971    0
1972);
1973#[cfg(feature = "api-20")]
1974define_embedded_component_on_terminated_trampoline!(
1975    embedded_component_on_terminated_callback_trampoline_1,
1976    1
1977);
1978#[cfg(feature = "api-20")]
1979define_embedded_component_on_terminated_trampoline!(
1980    embedded_component_on_terminated_callback_trampoline_2,
1981    2
1982);
1983#[cfg(feature = "api-20")]
1984define_embedded_component_on_terminated_trampoline!(
1985    embedded_component_on_terminated_callback_trampoline_3,
1986    3
1987);
1988#[cfg(feature = "api-20")]
1989define_embedded_component_on_terminated_trampoline!(
1990    embedded_component_on_terminated_callback_trampoline_4,
1991    4
1992);
1993#[cfg(feature = "api-20")]
1994define_embedded_component_on_terminated_trampoline!(
1995    embedded_component_on_terminated_callback_trampoline_5,
1996    5
1997);
1998#[cfg(feature = "api-20")]
1999define_embedded_component_on_terminated_trampoline!(
2000    embedded_component_on_terminated_callback_trampoline_6,
2001    6
2002);
2003#[cfg(feature = "api-20")]
2004define_embedded_component_on_terminated_trampoline!(
2005    embedded_component_on_terminated_callback_trampoline_7,
2006    7
2007);
2008#[cfg(feature = "api-20")]
2009define_embedded_component_on_terminated_trampoline!(
2010    embedded_component_on_terminated_callback_trampoline_8,
2011    8
2012);
2013#[cfg(feature = "api-20")]
2014define_embedded_component_on_terminated_trampoline!(
2015    embedded_component_on_terminated_callback_trampoline_9,
2016    9
2017);
2018#[cfg(feature = "api-20")]
2019define_embedded_component_on_terminated_trampoline!(
2020    embedded_component_on_terminated_callback_trampoline_10,
2021    10
2022);
2023#[cfg(feature = "api-20")]
2024define_embedded_component_on_terminated_trampoline!(
2025    embedded_component_on_terminated_callback_trampoline_11,
2026    11
2027);
2028#[cfg(feature = "api-20")]
2029define_embedded_component_on_terminated_trampoline!(
2030    embedded_component_on_terminated_callback_trampoline_12,
2031    12
2032);
2033#[cfg(feature = "api-20")]
2034define_embedded_component_on_terminated_trampoline!(
2035    embedded_component_on_terminated_callback_trampoline_13,
2036    13
2037);
2038#[cfg(feature = "api-20")]
2039define_embedded_component_on_terminated_trampoline!(
2040    embedded_component_on_terminated_callback_trampoline_14,
2041    14
2042);
2043#[cfg(feature = "api-20")]
2044define_embedded_component_on_terminated_trampoline!(
2045    embedded_component_on_terminated_callback_trampoline_15,
2046    15
2047);
2048
2049#[cfg(feature = "api-20")]
2050const EMBEDDED_COMPONENT_ON_TERMINATED_CALLBACK_TRAMPOLINES: [Option<
2051    EmbeddedComponentOnTerminatedCallback,
2052>;
2053    EMBEDDED_COMPONENT_CALLBACK_SLOT_COUNT] = [
2054    Some(embedded_component_on_terminated_callback_trampoline_0),
2055    Some(embedded_component_on_terminated_callback_trampoline_1),
2056    Some(embedded_component_on_terminated_callback_trampoline_2),
2057    Some(embedded_component_on_terminated_callback_trampoline_3),
2058    Some(embedded_component_on_terminated_callback_trampoline_4),
2059    Some(embedded_component_on_terminated_callback_trampoline_5),
2060    Some(embedded_component_on_terminated_callback_trampoline_6),
2061    Some(embedded_component_on_terminated_callback_trampoline_7),
2062    Some(embedded_component_on_terminated_callback_trampoline_8),
2063    Some(embedded_component_on_terminated_callback_trampoline_9),
2064    Some(embedded_component_on_terminated_callback_trampoline_10),
2065    Some(embedded_component_on_terminated_callback_trampoline_11),
2066    Some(embedded_component_on_terminated_callback_trampoline_12),
2067    Some(embedded_component_on_terminated_callback_trampoline_13),
2068    Some(embedded_component_on_terminated_callback_trampoline_14),
2069    Some(embedded_component_on_terminated_callback_trampoline_15),
2070];