pax_std_primitives/
checkbox.rs1use pax_message::{AnyCreatePatch, CheckboxPatch};
2use pax_runtime::api::{Layer, Property};
3use pax_runtime::{
4 BaseInstance, ExpandedNode, ExpandedNodeIdentifier, InstanceFlags, InstanceNode,
5 InstantiationArgs, RuntimeContext,
6};
7use_RefCell!();
8use pax_runtime_api::{borrow, borrow_mut, use_RefCell};
9use pax_std::primitives::Checkbox;
10use std::collections::HashMap;
11use std::rc::Rc;
12
13use crate::patch_if_needed;
14
15pub struct CheckboxInstance {
16 base: BaseInstance,
17 native_message_props: RefCell<HashMap<ExpandedNodeIdentifier, Property<()>>>,
22}
23
24impl InstanceNode for CheckboxInstance {
25 fn instantiate(args: InstantiationArgs) -> Rc<Self>
26 where
27 Self: Sized,
28 {
29 Rc::new(Self {
30 base: BaseInstance::new(
31 args,
32 InstanceFlags {
33 invisible_to_slot: false,
34 invisible_to_raycasting: false,
35 layer: Layer::Native,
36 is_component: false,
37 },
38 ),
39 native_message_props: Default::default(),
40 })
41 }
42
43 fn update(self: Rc<Self>, expanded_node: &Rc<ExpandedNode>, _context: &Rc<RuntimeContext>) {
44 borrow!(self.native_message_props)
46 .get(&expanded_node.id)
47 .unwrap()
48 .get();
49 }
50
51 fn handle_mount(
52 self: Rc<Self>,
53 expanded_node: &Rc<ExpandedNode>,
54 context: &Rc<RuntimeContext>,
55 ) {
56 let id = expanded_node.id.to_u32();
57 context.enqueue_native_message(pax_message::NativeMessage::CheckboxCreate(
58 AnyCreatePatch {
59 id,
60 parent_frame: expanded_node.parent_frame.get().map(|v| v.to_u32()),
61 occlusion_layer_id: 0,
62 },
63 ));
64 let weak_self_ref = Rc::downgrade(&expanded_node);
65 let context = Rc::clone(context);
66 let last_patch = Rc::new(RefCell::new(CheckboxPatch {
67 id,
68 ..Default::default()
69 }));
70
71 let deps: Vec<_> = borrow!(expanded_node.properties_scope)
72 .values()
73 .cloned()
74 .chain([expanded_node.transform_and_bounds.untyped()])
75 .collect();
76 borrow_mut!(self.native_message_props).insert(
77 expanded_node.id,
78 Property::computed(
79 move || {
80 let Some(expanded_node) = weak_self_ref.upgrade() else {
81 unreachable!()
82 };
83 let mut old_state = borrow_mut!(last_patch);
84
85 let mut patch = CheckboxPatch {
86 id,
87 ..Default::default()
88 };
89 expanded_node.with_properties_unwrapped(|properties: &mut Checkbox| {
90 let computed_tab = expanded_node.transform_and_bounds.get();
91 let (width, height) = computed_tab.bounds;
92 let updates = [
93 patch_if_needed(
94 &mut old_state.checked,
95 &mut patch.checked,
96 properties.checked.get(),
97 ),
98 patch_if_needed(&mut old_state.size_x, &mut patch.size_x, width),
99 patch_if_needed(&mut old_state.size_y, &mut patch.size_y, height),
100 patch_if_needed(
101 &mut old_state.transform,
102 &mut patch.transform,
103 computed_tab.transform.coeffs().to_vec(),
104 ),
105 ];
106 if updates.into_iter().any(|v| v == true) {
107 context.enqueue_native_message(
108 pax_message::NativeMessage::CheckboxUpdate(patch),
109 );
110 }
111 });
112 ()
113 },
114 &deps,
115 ),
116 );
117 }
118
119 fn handle_unmount(&self, expanded_node: &Rc<ExpandedNode>, context: &Rc<RuntimeContext>) {
120 let id = expanded_node.id.clone();
121 context.enqueue_native_message(pax_message::NativeMessage::CheckboxDelete(id.to_u32()));
122 borrow_mut!(self.native_message_props).remove(&id);
124 }
125
126 fn base(&self) -> &BaseInstance {
127 &self.base
128 }
129
130 fn resolve_debug(
131 &self,
132 f: &mut std::fmt::Formatter,
133 _expanded_node: Option<&ExpandedNode>,
134 ) -> std::fmt::Result {
135 f.debug_struct("Checkbox").finish_non_exhaustive()
136 }
137}