1use crate::api::TextInput;
2use crate::node_interface::NodeLocal;
3use pax_runtime_api::pax_value::{ImplToFromPaxAny, PaxAny, ToFromPaxAny};
4use pax_runtime_api::{
5 borrow, borrow_mut, use_RefCell, Focus, Interpolatable, Layer, Percent, Property, SelectStart,
6 Variable,
7};
8
9use crate::api::math::Point2;
10use crate::constants::{
11 BUTTON_CLICK_HANDLERS, CHECKBOX_CHANGE_HANDLERS, CLAP_HANDLERS, CLICK_HANDLERS,
12 CONTEXT_MENU_HANDLERS, DOUBLE_CLICK_HANDLERS, DROP_HANDLERS, FOCUSED_HANDLERS,
13 KEY_DOWN_HANDLERS, KEY_PRESS_HANDLERS, KEY_UP_HANDLERS, MOUSE_DOWN_HANDLERS,
14 MOUSE_MOVE_HANDLERS, MOUSE_OUT_HANDLERS, MOUSE_OVER_HANDLERS, MOUSE_UP_HANDLERS,
15 SCROLL_HANDLERS, SELECT_START_HANDLERS, TEXTBOX_CHANGE_HANDLERS, TEXTBOX_INPUT_HANDLERS,
16 TEXT_INPUT_HANDLERS, TOUCH_END_HANDLERS, TOUCH_MOVE_HANDLERS, TOUCH_START_HANDLERS,
17 WHEEL_HANDLERS,
18};
19use_RefCell!();
20use crate::{ExpandedNodeIdentifier, Globals, LayoutProperties, TransformAndBounds};
21use core::fmt;
22use std::cell::Cell;
23use std::collections::HashMap;
24use std::rc::{Rc, Weak};
25
26use crate::api::{
27 ButtonClick, CheckboxChange, Clap, Click, CommonProperties, ContextMenu, DoubleClick, Drop,
28 Event, KeyDown, KeyPress, KeyUp, MouseDown, MouseMove, MouseOut, MouseOver, MouseUp,
29 NodeContext, RenderContext, Scroll, Size, TextboxChange, TextboxInput, TouchEnd, TouchMove,
30 TouchStart, Wheel, Window,
31};
32
33use crate::{
34 compute_tab, ComponentInstance, HandlerLocation, InstanceNode, InstanceNodePtr, RuntimeContext,
35 RuntimePropertiesStackFrame,
36};
37
38#[derive(Clone)]
39pub struct ExpandedNode {
40 #[allow(dead_code)]
41 pub id: ExpandedNodeIdentifier,
44
45 pub instance_node: RefCell<InstanceNodePtr>,
47
48 pub render_parent: RefCell<Weak<ExpandedNode>>,
51
52 pub template_parent: Weak<ExpandedNode>,
55
56 pub parent_frame: Property<Option<ExpandedNodeIdentifier>>,
61
62 pub containing_component: Weak<ExpandedNode>,
67
68 pub stack: Rc<RuntimePropertiesStackFrame>,
72
73 pub children: Property<Vec<Rc<ExpandedNode>>>,
75
76 pub mounted_children: RefCell<Vec<Rc<ExpandedNode>>>,
78
79 pub properties: RefCell<Rc<RefCell<PaxAny>>>,
81
82 pub common_properties: RefCell<Rc<RefCell<CommonProperties>>>,
84 pub rendered_size: Property<Option<(f64, f64)>>,
87
88 pub transform_and_bounds: Property<TransformAndBounds<NodeLocal, Window>>,
91
92 pub expanded_slot_children: RefCell<Option<Vec<Rc<ExpandedNode>>>>,
97 pub expanded_and_flattened_slot_children: Property<Vec<Rc<ExpandedNode>>>,
102 pub flattened_slot_children_count: Property<usize>,
104
105 pub attached: Cell<u32>,
112
113 pub occlusion: Property<Occlusion>,
117
118 pub properties_scope: RefCell<HashMap<String, Variable>>,
121
122 pub slot_index: Property<Option<usize>>,
125
126 pub suspended: Property<bool>,
128
129 pub native_message_listener: Property<()>,
131
132 pub slot_child_attached_listener: Property<()>,
134
135 pub subscriptions: RefCell<Vec<Property<()>>>,
137}
138
139#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)]
140pub struct Occlusion {
141 pub occlusion_layer_id: usize,
142 pub z_index: i32,
143 pub parent_frame: Option<u32>,
147}
148
149impl Interpolatable for Occlusion {}
150
151impl ImplToFromPaxAny for ExpandedNode {}
152impl Interpolatable for ExpandedNode {}
153
154macro_rules! dispatch_event_handler {
155 ($fn_name:ident, $arg_type:ty, $handler_key:ident, $recurse:expr) => {
156 pub fn $fn_name(
157 self: &Rc<Self>,
158 event: Event<$arg_type>,
159 globals: &Globals,
160 ctx: &Rc<RuntimeContext>,
161 ) -> bool {
162 if let Some(registry) = borrow!(self.instance_node).base().get_handler_registry() {
163 let borrowed_registry = &borrow!(*registry);
164 if let Some(handlers) = borrowed_registry.handlers.get($handler_key) {
165 if handlers.len() > 0 {
166 let component_properties =
167 if let Some(cc) = self.containing_component.upgrade() {
168 Rc::clone(&*borrow!(cc.properties))
169 } else {
170 Rc::clone(&*borrow!(self.properties))
171 };
172
173 let context = self.get_node_context(ctx);
174 handlers.iter().for_each(|handler| {
175 let properties = if let HandlerLocation::Component = &handler.location {
176 Rc::clone(&*borrow!(self.properties))
177 } else {
178 Rc::clone(&component_properties)
179 };
180 (handler.function)(
181 Rc::clone(&properties),
182 &context,
183 Some(event.clone().to_pax_any()),
184 );
185 });
186 }
187 };
188 }
189
190 if $recurse {
191 if let Some(parent) = self.template_parent.upgrade() {
192 return parent.$fn_name(event, globals, ctx);
193 }
194 }
195 event.cancelled()
196 }
197 };
198}
199
200impl ExpandedNode {
201 pub fn initialize_root(template: Rc<ComponentInstance>, ctx: &Rc<RuntimeContext>) -> Rc<Self> {
202 let root_node = Self::new(
203 template,
204 ctx.globals().stack_frame(),
205 ctx,
206 Weak::new(),
207 Weak::new(),
208 );
209 root_node.bind_to_parent_bounds(ctx);
210 Rc::clone(&root_node).recurse_mount(ctx);
211 root_node
212 }
213
214 fn new(
215 template: Rc<dyn InstanceNode>,
216 env: Rc<RuntimePropertiesStackFrame>,
217 context: &Rc<RuntimeContext>,
218 containing_component: Weak<ExpandedNode>,
219 parent: Weak<ExpandedNode>,
220 ) -> Rc<Self> {
221 let properties =
222 (&template.base().instance_prototypical_properties_factory)(env.clone(), None).unwrap();
223
224 let common_properties =
225 (&template
226 .base()
227 .instance_prototypical_common_properties_factory)(env.clone(), None)
228 .unwrap();
229
230 let mut property_scope = borrow!(*common_properties).retrieve_property_scope();
231
232 if let Some(scope) = &template.base().properties_scope_factory {
233 property_scope.extend(scope(properties.clone()));
234 }
235
236 let id = context.gen_uid();
237 let res = Rc::new(ExpandedNode {
238 id,
239 stack: env,
240 instance_node: RefCell::new(Rc::clone(&template)),
241 attached: Cell::new(0),
242 properties: RefCell::new(properties),
243 common_properties: RefCell::new(common_properties),
244 rendered_size: Property::default(),
245
246 render_parent: Default::default(),
249 parent_frame: Default::default(),
250 template_parent: parent,
251
252 containing_component,
253 children: Property::new_with_name(
254 Vec::new(),
255 &format!("node children (node id: {})", id.0),
256 ),
257 mounted_children: RefCell::new(Vec::new()),
258 transform_and_bounds: Property::new(TransformAndBounds::default()),
259 expanded_slot_children: Default::default(),
260 expanded_and_flattened_slot_children: Default::default(),
261 flattened_slot_children_count: Property::new(0),
262 occlusion: Property::new(Occlusion::default()),
263 properties_scope: RefCell::new(property_scope),
264 slot_index: Property::default(),
265 suspended: Property::new(false),
266 native_message_listener: Property::default(),
267 slot_child_attached_listener: Property::default(),
268 subscriptions: Default::default(),
269 });
270 res
271 }
272
273 pub fn recreate_with_new_data(
274 self: &Rc<Self>,
275 template: Rc<dyn InstanceNode>,
276 context: &Rc<RuntimeContext>,
277 ) {
278 *borrow_mut!(self.instance_node) = Rc::clone(&template);
279 (&template
280 .base()
281 .instance_prototypical_common_properties_factory)(
282 Rc::clone(&self.stack),
283 Some(Rc::clone(&self)),
284 );
285 (&template.base().instance_prototypical_properties_factory)(
286 Rc::clone(&self.stack),
287 Some(Rc::clone(&self)),
288 );
289 self.bind_to_parent_bounds(context);
290 context.set_canvas_dirty(self.occlusion.get().occlusion_layer_id);
291 }
292
293 pub fn fully_recreate_with_new_data(
294 self: &Rc<Self>,
295 template: Rc<dyn InstanceNode>,
296 context: &Rc<RuntimeContext>,
297 ) {
298 Rc::clone(self).recurse_unmount(context);
299 let new_expanded_node = Self::new(
300 template.clone(),
301 Rc::clone(&self.stack),
302 context,
303 Weak::clone(&self.containing_component),
304 Weak::clone(&self.template_parent),
305 );
306 *borrow_mut!(self.instance_node) = Rc::clone(&*borrow!(new_expanded_node.instance_node));
307 *borrow_mut!(self.properties) = Rc::clone(&*borrow!(new_expanded_node.properties));
308 *borrow_mut!(self.properties_scope) = borrow!(new_expanded_node.properties_scope).clone();
309 *borrow_mut!(self.common_properties) =
310 Rc::clone(&*borrow!(new_expanded_node.common_properties));
311 self.occlusion.set(Default::default());
312
313 self.bind_to_parent_bounds(context);
314 Rc::clone(self).recurse_mount(context);
315 Rc::clone(self).recurse_update(context);
316 }
317
318 pub fn is_descendant_of(&self, other_expanded_node_id: &ExpandedNodeIdentifier) -> bool {
322 if let Some(parent) = borrow!(self.render_parent).upgrade() {
323 if parent.id.eq(other_expanded_node_id) {
325 true
326 } else {
327 parent.is_descendant_of(other_expanded_node_id)
328 }
329 } else {
330 false
331 }
332 }
333
334 pub fn create_children_detached(
335 self: &Rc<Self>,
336 templates: impl IntoIterator<Item = (Rc<dyn InstanceNode>, Rc<RuntimePropertiesStackFrame>)>,
337 context: &Rc<RuntimeContext>,
338 template_parent: &Weak<ExpandedNode>,
339 ) -> Vec<Rc<ExpandedNode>> {
340 let containing_component = if borrow!(self.instance_node).base().flags().is_component {
341 Rc::downgrade(&self)
342 } else {
343 Weak::clone(&self.containing_component)
344 };
345
346 let mut children = Vec::new();
347
348 for (template, env) in templates {
349 children.push(Self::new(
350 template,
351 env,
352 context,
353 Weak::clone(&containing_component),
354 Weak::clone(&template_parent),
355 ));
356 }
357 children
358 }
359
360 pub fn attach_children(
361 self: &Rc<Self>,
362 new_children: Vec<Rc<ExpandedNode>>,
363 context: &Rc<RuntimeContext>,
364 parent_frame: &Property<Option<ExpandedNodeIdentifier>>,
365 ) -> Vec<Rc<ExpandedNode>> {
366 let mut curr_children = borrow_mut!(self.mounted_children);
367 for child in new_children.iter() {
370 *borrow_mut!(child.render_parent) = Rc::downgrade(self);
372 let parent_frame = parent_frame.clone();
374 let deps = [parent_frame.untyped()];
375 child
376 .parent_frame
377 .replace_with(Property::computed(move || parent_frame.get(), &deps));
378
379 child.inherit_suspend(self);
381 child.bind_to_parent_bounds(context);
382 }
383 if self.attached.get() > 0 {
384 for child in curr_children.iter() {
385 Rc::clone(child).recurse_unmount(context);
386 }
387 for child in new_children.iter() {
388 Rc::clone(child).recurse_mount(context);
389 }
390 }
391 *curr_children = new_children.clone();
392 new_children
393 }
394
395 fn bind_to_parent_bounds(self: &Rc<Self>, ctx: &Rc<RuntimeContext>) {
396 let parent_transform_and_bounds = borrow!(self.render_parent)
397 .upgrade()
398 .map(|n| n.transform_and_bounds.clone())
399 .unwrap_or_else(|| ctx.globals().viewport);
400 let common_props = borrow!(self.common_properties);
401 let extra_transform = borrow!(common_props).transform.clone();
402
403 let transform_and_bounds = compute_tab(
404 self.layout_properties(),
405 extra_transform,
406 parent_transform_and_bounds,
407 );
408 self.transform_and_bounds.replace_with(transform_and_bounds);
409 }
410
411 pub fn inherit_suspend(self: &Rc<Self>, node: &Rc<Self>) {
412 let cp = self.get_common_properties();
413 let self_suspended = borrow!(cp)._suspended.clone();
414 let parent_suspended = node.suspended.clone();
415 let deps = [parent_suspended.untyped(), self_suspended.untyped()];
416 self.suspended.replace_with(Property::computed(
417 move || {
418 self_suspended
419 .get()
420 .unwrap_or_else(|| parent_suspended.get())
421 },
422 &deps,
423 ));
424 }
425
426 pub fn generate_children(
427 self: &Rc<Self>,
428 templates: impl IntoIterator<Item = (Rc<dyn InstanceNode>, Rc<RuntimePropertiesStackFrame>)>,
429 context: &Rc<RuntimeContext>,
430 parent_frame: &Property<Option<ExpandedNodeIdentifier>>,
431 is_mount: bool,
432 ) -> Vec<Rc<ExpandedNode>> {
433 let new_children = self.create_children_detached(templates, context, &Rc::downgrade(&self));
434 let res = if is_mount {
435 self.attach_children(new_children, context, parent_frame)
436 } else {
437 for child in new_children.iter() {
438 child.recurse_control_flow_expansion(context);
439 }
440
441 new_children
442 };
443 res
444 }
445
446 pub fn recurse_update(self: &Rc<Self>, context: &Rc<RuntimeContext>) {
449 if let Some(ref registry) = borrow!(self.instance_node).base().handler_registry {
450 for handler in borrow!(registry)
452 .handlers
453 .get("tick")
454 .unwrap_or(&Vec::new())
455 {
456 (handler.function)(
457 Rc::clone(&*borrow!(self.properties)),
458 &self.get_node_context(context),
459 None,
460 )
461 }
463 }
464 Rc::clone(&*borrow!(self.instance_node)).update(&self, context);
465 self.native_message_listener.get();
467
468 if let Some(ref registry) = borrow!(self.instance_node).base().handler_registry {
469 if !self.suspended.get() {
470 for handler in borrow!(registry)
471 .handlers
472 .get("pre_render")
473 .unwrap_or(&Vec::new())
474 {
475 (handler.function)(
476 Rc::clone(&*borrow!(self.properties)),
477 &self.get_node_context(context),
478 None,
479 )
480 }
481 }
482 }
483 for subscription in &*borrow!(self.subscriptions) {
484 subscription.get();
486 }
487 if borrow!(self.instance_node).base().flags().is_component {
488 self.compute_flattened_slot_children();
489 }
490 for child in self.children.get().iter() {
491 child.recurse_update(context);
492 }
493 }
494
495 pub fn recurse_control_flow_expansion(self: &Rc<Self>, context: &Rc<RuntimeContext>) {
496 borrow!(self.instance_node)
497 .clone()
498 .handle_control_flow_node_expansion(&self, context);
499 }
500
501 pub fn recurse_mount(self: &Rc<Self>, context: &Rc<RuntimeContext>) {
502 if self.attached.get() == 0 {
503 borrow!(self.instance_node)
505 .clone()
506 .handle_setup_slot_children(&self, context);
507
508 if let Some(slot_children) = borrow!(self.expanded_slot_children).as_ref() {
510 for slot_child in slot_children {
511 slot_child.recurse_control_flow_expansion(context);
512 }
513 self.compute_flattened_slot_children();
515 }
516
517 self.attached.set(self.attached.get() + 1);
518 context.add_to_cache(&self);
519 if let Some(ref registry) = borrow!(self.instance_node).base().handler_registry {
520 for handler in borrow!(registry)
521 .handlers
522 .get("mount")
523 .unwrap_or(&Vec::new())
524 {
525 (handler.function)(
526 Rc::clone(&*borrow!(self.properties)),
527 &self.get_node_context(context),
528 None,
529 )
530 }
531 }
532 borrow!(self.instance_node)
533 .clone()
534 .handle_mount(&self, context);
535 }
536 }
537
538 pub fn recurse_unmount(self: Rc<Self>, context: &Rc<RuntimeContext>) {
539 if self.attached.get() == 1 {
544 self.attached.set(self.attached.get() - 1);
545 context.remove_from_cache(&self);
546 for child in borrow!(self.mounted_children).iter() {
547 Rc::clone(child).recurse_unmount(context);
548 }
549 borrow!(self.instance_node).handle_unmount(&self, context);
550 if let Some(ref registry) = borrow!(self.instance_node).base().handler_registry {
551 for handler in borrow!(registry)
552 .handlers
553 .get("unmount")
554 .unwrap_or(&Vec::new())
555 {
556 (handler.function)(
557 Rc::clone(&*borrow!(self.properties)),
558 &self.get_node_context(context),
559 None,
560 )
561 }
562 }
563
564 if self.instance_node.borrow().base().flags().layer == Layer::Canvas {
565 context.set_canvas_dirty(self.occlusion.get().occlusion_layer_id);
566 }
567
568 self.occlusion.set(Default::default());
570 }
571 }
572
573 pub fn recurse_render_queue(
574 self: &Rc<Self>,
575 ctx: &Rc<RuntimeContext>,
576 rcs: &mut dyn RenderContext,
577 ) {
578 let cp = self.get_common_properties();
579 let cp = borrow!(cp);
580 if cp.unclippable.get().unwrap_or(false) {
581 ctx.queue_render(Rc::clone(&self));
582 } else {
583 self.recurse_render(ctx, rcs);
584 }
585 }
586
587 pub fn recurse_render(self: &Rc<Self>, ctx: &Rc<RuntimeContext>, rcs: &mut dyn RenderContext) {
588 borrow!(self.instance_node).handle_pre_render(&self, ctx, rcs);
589 for child in self.children.get().iter().rev() {
590 child.recurse_render_queue(ctx, rcs);
591 }
592 borrow!(self.instance_node).render(&self, ctx, rcs);
593 borrow!(self.instance_node).handle_post_render(&self, ctx, rcs);
594 }
595
596 pub fn with_properties_unwrapped<T: ToFromPaxAny, R>(
602 &self,
603 callback: impl FnOnce(&mut T) -> R,
604 ) -> R {
605 self.try_with_properties_unwrapped(callback)
606 .expect("properties not of expected type")
607 }
608
609 pub fn try_with_properties_unwrapped<T: ToFromPaxAny, R>(
610 &self,
611 callback: impl FnOnce(&mut T) -> R,
612 ) -> Option<R> {
613 let properties = borrow_mut!(self.properties);
615 let mut borrowed = borrow_mut!(properties);
616 let Ok(mut val) = T::mut_from_pax_any(&mut *borrowed) else {
618 return None;
619 };
620 Some(callback(&mut val))
621 }
622
623 pub fn recurse_visit_postorder(self: &Rc<Self>, func: &mut impl FnMut(&Rc<Self>)) {
624 self.compute_flattened_slot_children();
627 for child in self.children.get().iter().rev() {
628 child.recurse_visit_postorder(func)
629 }
630 func(self);
631 }
632
633 pub fn get_node_context(self: &Rc<Self>, ctx: &Rc<RuntimeContext>) -> NodeContext {
634 let globals = ctx.globals();
635 let t_and_b = self.transform_and_bounds.clone();
636 let deps = [t_and_b.untyped()];
637 let bounds_self = Property::computed(move || t_and_b.get().bounds, &deps);
638 let t_and_b_parent = if let Some(parent) = borrow!(self.render_parent).upgrade() {
639 parent.transform_and_bounds.clone()
640 } else {
641 globals.viewport.clone()
642 };
643 let deps = [t_and_b_parent.untyped()];
644 let bounds_parent = Property::computed(move || t_and_b_parent.get().bounds, &deps);
645
646 let slot_children_count = if borrow!(self.instance_node).base().flags().is_component {
647 self.flattened_slot_children_count.clone()
648 } else {
649 self.containing_component
650 .upgrade()
651 .map(|v| v.flattened_slot_children_count.clone())
652 .unwrap_or_default()
653 };
654
655 let slot_children = if borrow!(self.instance_node).base().flags().is_component {
656 self.expanded_and_flattened_slot_children.clone()
657 } else {
658 self.containing_component
659 .upgrade()
660 .map(|v| v.expanded_and_flattened_slot_children.clone())
661 .unwrap_or_default()
662 };
663
664 let slot_children_attached_listener =
665 if borrow!(self.instance_node).base().flags().is_component {
666 self.slot_child_attached_listener.clone()
667 } else {
668 self.containing_component
669 .upgrade()
670 .map(|v| v.slot_child_attached_listener.clone())
671 .unwrap_or_default()
672 };
673
674 let last_frame = Rc::new(RefCell::new(globals.frames_elapsed.get()));
675 let suspended = self.suspended.clone();
676 let frames_elapsed = globals.frames_elapsed.clone();
677 let deps = [frames_elapsed.untyped(), suspended.untyped()];
678 let frames_elapsed_frozen_if_suspended = Property::computed(
682 move || {
683 if suspended.get() {
684 *borrow!(last_frame)
685 } else {
686 let val = frames_elapsed.get();
687 *borrow_mut!(last_frame) = val;
688 val
689 }
690 },
691 &deps,
692 );
693 NodeContext {
697 slot_index: self.slot_index.clone(),
698 local_stack_frame: Rc::clone(&self.stack),
699 expanded_node: Rc::downgrade(&self),
700 containing_component: Weak::clone(&self.containing_component),
701 frames_elapsed: frames_elapsed_frozen_if_suspended,
702 bounds_self,
703 bounds_parent,
704 runtime_context: ctx.clone(),
705 platform: globals.platform.clone(),
706 os: globals.os.clone(),
707 get_elapsed_millis: globals.get_elapsed_millis,
708 slot_children_count,
709 slot_children,
710 node_transform_and_bounds: self.transform_and_bounds.get(),
711 slot_children_attached_listener,
712 #[cfg(feature = "designtime")]
713 designtime: globals.designtime.clone(),
714 }
715 }
716
717 pub fn get_common_properties(&self) -> Rc<RefCell<CommonProperties>> {
718 Rc::clone(&*borrow!(self.common_properties))
719 }
720
721 pub fn ray_cast_test(&self, ray: Point2<Window>) -> bool {
724 let cp = borrow!(self.common_properties);
725
726 if !borrow!(&*cp)._raycastable.get().unwrap_or(true) {
728 return false;
729 }
730 let t_and_b = self.transform_and_bounds.get();
731
732 let inverted_transform = t_and_b.transform.inverse();
733 let transformed_ray = inverted_transform * ray;
734 let (width, height) = t_and_b.bounds;
735 let res = transformed_ray.x > 0.0
737 && transformed_ray.y > 0.0
738 && transformed_ray.x < width
739 && transformed_ray.y < height;
740 res
741 }
742
743 pub fn compute_flattened_slot_children(&self) {
744 if let Some(slot_children) = borrow!(self.expanded_slot_children).as_ref() {
749 let new_flattened = flatten_expanded_nodes_for_slot(&slot_children);
750 let old_and_new_filtered_same =
751 self.expanded_and_flattened_slot_children.read(|flattened| {
752 flattened
753 .iter()
754 .map(|n| n.id)
755 .eq(new_flattened.iter().map(|n| n.id))
756 });
757
758 if !old_and_new_filtered_same {
759 self.flattened_slot_children_count.set(new_flattened.len());
760 self.expanded_and_flattened_slot_children.set(new_flattened);
761 for (i, slot_child) in self
762 .expanded_and_flattened_slot_children
763 .get()
764 .iter()
765 .enumerate()
766 {
767 if slot_child.slot_index.get() != Some(i) {
768 slot_child.slot_index.set(Some(i));
769 };
770 }
771 }
772 }
773 }
774
775 dispatch_event_handler!(dispatch_scroll, Scroll, SCROLL_HANDLERS, true);
776 dispatch_event_handler!(dispatch_clap, Clap, CLAP_HANDLERS, true);
777 dispatch_event_handler!(dispatch_touch_start, TouchStart, TOUCH_START_HANDLERS, true);
778
779 dispatch_event_handler!(dispatch_touch_move, TouchMove, TOUCH_MOVE_HANDLERS, true);
780 dispatch_event_handler!(dispatch_touch_end, TouchEnd, TOUCH_END_HANDLERS, true);
781 dispatch_event_handler!(dispatch_key_down, KeyDown, KEY_DOWN_HANDLERS, false);
782 dispatch_event_handler!(dispatch_key_up, KeyUp, KEY_UP_HANDLERS, false);
783 dispatch_event_handler!(dispatch_key_press, KeyPress, KEY_PRESS_HANDLERS, false);
784 dispatch_event_handler!(
785 dispatch_checkbox_change,
786 CheckboxChange,
787 CHECKBOX_CHANGE_HANDLERS,
788 true
789 );
790 dispatch_event_handler!(
791 dispatch_textbox_change,
792 TextboxChange,
793 TEXTBOX_CHANGE_HANDLERS,
794 true
795 );
796 dispatch_event_handler!(dispatch_text_input, TextInput, TEXT_INPUT_HANDLERS, true);
797 dispatch_event_handler!(
798 dispatch_textbox_input,
799 TextboxInput,
800 TEXTBOX_INPUT_HANDLERS,
801 true
802 );
803 dispatch_event_handler!(
804 dispatch_button_click,
805 ButtonClick,
806 BUTTON_CLICK_HANDLERS,
807 true
808 );
809 dispatch_event_handler!(dispatch_mouse_down, MouseDown, MOUSE_DOWN_HANDLERS, true);
810 dispatch_event_handler!(dispatch_mouse_up, MouseUp, MOUSE_UP_HANDLERS, true);
811 dispatch_event_handler!(dispatch_mouse_move, MouseMove, MOUSE_MOVE_HANDLERS, true);
812 dispatch_event_handler!(dispatch_mouse_over, MouseOver, MOUSE_OVER_HANDLERS, false);
813 dispatch_event_handler!(dispatch_mouse_out, MouseOut, MOUSE_OUT_HANDLERS, false);
814 dispatch_event_handler!(
815 dispatch_double_click,
816 DoubleClick,
817 DOUBLE_CLICK_HANDLERS,
818 true
819 );
820 dispatch_event_handler!(
821 dispatch_context_menu,
822 ContextMenu,
823 CONTEXT_MENU_HANDLERS,
824 true
825 );
826 dispatch_event_handler!(dispatch_click, Click, CLICK_HANDLERS, true);
827 dispatch_event_handler!(dispatch_wheel, Wheel, WHEEL_HANDLERS, true);
828 dispatch_event_handler!(dispatch_drop, Drop, DROP_HANDLERS, true);
829 dispatch_event_handler!(dispatch_focus, Focus, FOCUSED_HANDLERS, false);
830 dispatch_event_handler!(
831 dispatch_select_start,
832 SelectStart,
833 SELECT_START_HANDLERS,
834 false
835 );
836
837 pub fn dispatch_custom_event(
838 self: &Rc<Self>,
839 identifier: &str,
840 ctx: &Rc<RuntimeContext>,
841 ) -> Result<(), String> {
842 let component_origin_instance = borrow!(self.instance_node);
843 let registry = component_origin_instance
844 .base()
845 .handler_registry
846 .as_ref()
847 .ok_or_else(|| "no registry present".to_owned())?;
848
849 let parent_component = self
850 .containing_component
851 .upgrade()
852 .ok_or_else(|| "can't dispatch from root (has no parent)".to_owned())?;
853 let properties = borrow!(parent_component.properties);
854
855 for handler in borrow!(registry)
856 .handlers
857 .get(identifier)
858 .expect("presence should have been checked when added to custom_event_queue")
859 {
860 (handler.function)(Rc::clone(&*properties), &self.get_node_context(ctx), None)
861 }
862 Ok(())
863 }
864
865 pub fn chassis_resize_request(self: &Rc<ExpandedNode>, width: f64, height: f64) {
869 self.rendered_size.set(Some((width, height)));
870 }
871
872 pub fn layout_properties(self: &Rc<ExpandedNode>) -> Property<LayoutProperties> {
875 let common_props = self.get_common_properties();
876 let common_props = borrow!(common_props);
877 let cp_width = common_props.width.clone();
878 let cp_height = common_props.height.clone();
879 let cp_transform = common_props.transform.clone();
880 let cp_anchor_x = common_props.anchor_x.clone();
881 let cp_anchor_y = common_props.anchor_y.clone();
882 let cp_scale_x = common_props.scale_x.clone();
883 let cp_scale_y = common_props.scale_y.clone();
884 let cp_skew_x = common_props.skew_x.clone();
885 let cp_skew_y = common_props.skew_y.clone();
886 let cp_rotate = common_props.rotate.clone();
887 let cp_x = common_props.x.clone();
888 let cp_y = common_props.y.clone();
889 let rendered_size = self.rendered_size.clone();
890 let deps = [
891 cp_width.untyped(),
892 cp_height.untyped(),
893 cp_transform.untyped(),
894 cp_anchor_x.untyped(),
895 cp_anchor_y.untyped(),
896 cp_scale_x.untyped(),
897 cp_scale_y.untyped(),
898 cp_skew_x.untyped(),
899 cp_skew_y.untyped(),
900 cp_rotate.untyped(),
901 cp_x.untyped(),
902 cp_y.untyped(),
903 rendered_size.untyped(),
904 ];
905
906 Property::computed(
907 move || {
908 let fallback = rendered_size.get();
910 let (w_fallback, h_fallback) = match fallback {
911 Some((wf, hf)) => (Some(wf), Some(hf)),
912 None => (None, None),
913 };
914
915 LayoutProperties {
916 x: cp_x.get(),
917 y: cp_y.get(),
918 width: cp_width
919 .get()
920 .or(w_fallback.map(|v| Size::Pixels(v.into()))),
921 height: cp_height
922 .get()
923 .or(h_fallback.map(|v| Size::Pixels(v.into()))),
924 rotate: cp_rotate.get(),
925 scale_x: cp_scale_x
927 .get()
928 .map(|v| Percent((100.0 * v.expect_percent()).into())),
929 scale_y: cp_scale_y
930 .get()
931 .map(|v| Percent((100.0 * v.expect_percent()).into())),
932 anchor_x: cp_anchor_x.get(),
933 anchor_y: cp_anchor_y.get(),
934 skew_x: cp_skew_x.get(),
935 skew_y: cp_skew_y.get(),
936 }
937 },
938 &deps,
939 )
940 }
941}
942
943fn flatten_expanded_nodes_for_slot(nodes: &[Rc<ExpandedNode>]) -> Vec<Rc<ExpandedNode>> {
946 let mut result: Vec<Rc<ExpandedNode>> = vec![];
947 for node in nodes {
948 if borrow!(node.instance_node).base().flags().invisible_to_slot {
949 result.extend(flatten_expanded_nodes_for_slot(
950 node.children
951 .get()
952 .clone()
953 .into_iter()
954 .collect::<Vec<_>>()
955 .as_slice(),
956 ));
957 } else {
958 result.push(Rc::clone(&node))
959 }
960 }
961 result
962}
963
964impl std::fmt::Debug for ExpandedNode {
965 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
966 pub struct Fmt<F>(pub F)
969 where
970 F: Fn(&mut fmt::Formatter) -> fmt::Result;
971
972 impl<F> fmt::Debug for Fmt<F>
973 where
974 F: Fn(&mut fmt::Formatter) -> fmt::Result,
975 {
976 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
977 (self.0)(f)
978 }
979 }
980
981 f.debug_struct("ExpandedNode")
982 .field(
983 "instance_node",
984 &Fmt(|f| borrow!(self.instance_node).resolve_debug(f, Some(self))),
985 )
986 .field("id", &self.id)
987 .field("common_properties", &borrow!(self.common_properties))
988 .field("transform_and_bounds", &self.transform_and_bounds)
989 .field("children", &self.children.get().iter().collect::<Vec<_>>())
990 .field(
991 "slot_children",
992 &self
993 .expanded_and_flattened_slot_children
994 .get()
995 .iter()
996 .map(|v| v.id)
997 .collect::<Vec<_>>(),
998 )
999 .field("occlusion_id", &self.occlusion.get())
1000 .field(
1001 "containing_component",
1002 &self.containing_component.upgrade().map(|v| v.id.clone()),
1003 )
1004 .finish()
1005 }
1006}