sixtyfps_compilerlib/passes/
visible.rs1use std::cell::RefCell;
7use std::rc::Rc;
8
9use crate::expression_tree::{Expression, NamedReference};
10use crate::langtype::{NativeClass, Type};
11use crate::object_tree::{self, Component, Element, ElementRc};
12use crate::typeregister::TypeRegister;
13
14pub fn handle_visible(component: &Rc<Component>, type_register: &TypeRegister) {
15 let native_clip = type_register.lookup("Clip").as_builtin().native_class.clone();
16
17 crate::object_tree::recurse_elem_including_sub_components(
18 component,
19 &(),
20 &mut |elem: &ElementRc, _| {
21 let is_lowered_from_visible_property =
22 elem.borrow().native_class().map_or(false, |n| {
23 Rc::ptr_eq(&n, &native_clip) && elem.borrow().id.ends_with("-visibility")
24 });
25 if is_lowered_from_visible_property {
26 return;
28 }
29
30 let old_children = {
31 let mut elem = elem.borrow_mut();
32 let new_children = Vec::with_capacity(elem.children.len());
33 std::mem::replace(&mut elem.children, new_children)
34 };
35
36 let has_visible_binding = |e: &ElementRc| {
37 e.borrow().base_type.lookup_property("visible").property_type != Type::Invalid
38 && (e.borrow().bindings.contains_key("visible")
39 || e.borrow()
40 .property_analysis
41 .borrow()
42 .get("visible")
43 .map_or(false, |a| a.is_set))
44 };
45
46 for mut child in old_children {
47 if child.borrow().repeated.is_some() {
48 let root_elem = child.borrow().base_type.as_component().root_element.clone();
49 if has_visible_binding(&root_elem) {
50 object_tree::inject_element_as_repeated_element(
51 &child,
52 create_visibility_element(&root_elem, &native_clip),
53 )
54 }
55 } else if has_visible_binding(&child) {
56 let new_child = create_visibility_element(&child, &native_clip);
57 new_child.borrow_mut().children.push(child);
58 child = new_child;
59 }
60
61 elem.borrow_mut().children.push(child);
62 }
63 },
64 );
65}
66
67fn create_visibility_element(child: &ElementRc, native_clip: &Rc<NativeClass>) -> ElementRc {
68 let element = Element {
69 id: format!("{}-visibility", child.borrow().id),
70 base_type: Type::Native(native_clip.clone()),
71 enclosing_component: child.borrow().enclosing_component.clone(),
72 bindings: std::iter::once((
73 "clip".to_owned(),
74 RefCell::new(
75 Expression::UnaryOp {
76 sub: Box::new(Expression::PropertyReference(NamedReference::new(
77 child, "visible",
78 ))),
79 op: '!',
80 }
81 .into(),
82 ),
83 ))
84 .collect(),
85 ..Default::default()
86 };
87 Rc::new(RefCell::new(element))
88}