1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4//! Passes that fills the root component used_types.sub_components
5
6use by_address::ByAddress;
7
8use crate::langtype::ElementType;
9use crate::object_tree::*;
10use std::collections::HashSet;
11use std::rc::Rc;
12
13/// Fill the root_component's used_types.sub_components
14pub fn collect_subcomponents(doc: &Document) {
15 let mut result: Vec> = vec![];
16 let mut hash: HashSet>> = HashSet::new();
17 for component: Rc in doc.exported_roots().chain(doc.popup_menu_impl.iter().cloned()) {
18 collect_subcomponents_recursive(&component, &mut result, &mut hash);
19 }
20 doc.used_types.borrow_mut().sub_components = result;
21}
22
23fn collect_subcomponents_recursive(
24 component: &Rc<Component>,
25 result: &mut Vec<Rc<Component>>,
26 hash: &mut HashSet<ByAddress<Rc<Component>>>,
27) {
28 hash.insert(ByAddress(component.clone()));
29 recurse_elem(&component.root_element, &(), &mut |elem: &ElementRc, &()| {
30 let base_comp: Rc = match &elem.borrow().base_type {
31 ElementType::Component(base_comp: &Rc) => {
32 if hash.contains(&ByAddress(base_comp.clone())) {
33 return;
34 }
35 base_comp.clone()
36 }
37 _ => return,
38 };
39 collect_subcomponents_recursive(&base_comp, result, hash);
40 if base_comp.parent_element.upgrade().is_some() {
41 // This is not a sub-component, but is a repeated component
42 return;
43 }
44 result.push(base_comp);
45 });
46 for popup: &PopupWindow in component.popup_windows.borrow().iter() {
47 collect_subcomponents_recursive(&popup.component, result, hash);
48 }
49}
50