| 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 | |
| 6 | use by_address::ByAddress; |
| 7 | |
| 8 | use crate::langtype::ElementType; |
| 9 | use crate::object_tree::*; |
| 10 | use std::collections::HashSet; |
| 11 | use std::rc::Rc; |
| 12 | |
| 13 | /// Fill the root_component's used_types.sub_components |
| 14 | pub 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 | |
| 23 | fn 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 | |