mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-28 21:04:47 +00:00

* Make sure that the compiler don't panic if the parent of a PopupWindow is optimized (by not optiizing such element) * Ensure that we can call popup.show() from within a deeper repeater * Ensure that the parent element of the popup is the right one in case of repeater (and not the node in the parent component) This partially revertad5991f8fa
and6c7a7aed0e
because we must do the lower_popup adter the repeater pass, because otherwise the parent element of the created component for the PopupWindow might be wrong and it is not easy to adjust (we would have to make Component::parent_element a RefCell or duplicate it again. Fixes #1132
105 lines
3.7 KiB
Rust
105 lines
3.7 KiB
Rust
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
|
|
|
//! Make sure that the top level element of the component is always a Window
|
|
|
|
use crate::expression_tree::{BindingExpression, Expression};
|
|
use crate::namedreference::NamedReference;
|
|
use crate::object_tree::{Component, Element};
|
|
use crate::typeregister::TypeRegister;
|
|
use std::cell::RefCell;
|
|
use std::collections::HashSet;
|
|
use std::rc::Rc;
|
|
|
|
pub fn ensure_window(
|
|
component: &Rc<Component>,
|
|
type_register: &TypeRegister,
|
|
style_metrics: &Rc<Component>,
|
|
) {
|
|
if component.root_element.borrow().builtin_type().map_or(true, |b| {
|
|
matches!(b.name.as_str(), "Window" | "Dialog" | "WindowItem" | "PopupWindow")
|
|
}) {
|
|
return; // already a window, nothing to do
|
|
}
|
|
|
|
let window_type = type_register.lookup_element("Window").unwrap();
|
|
|
|
let win_elem = component.root_element.clone();
|
|
|
|
// the old_root becomes the Window
|
|
let mut win_elem_mut = win_elem.borrow_mut();
|
|
let new_root = Element {
|
|
id: std::mem::replace(&mut win_elem_mut.id, "root_window".into()),
|
|
base_type: std::mem::replace(&mut win_elem_mut.base_type, window_type),
|
|
bindings: Default::default(),
|
|
property_analysis: Default::default(),
|
|
children: std::mem::take(&mut win_elem_mut.children),
|
|
enclosing_component: win_elem_mut.enclosing_component.clone(),
|
|
property_declarations: Default::default(),
|
|
named_references: Default::default(),
|
|
repeated: Default::default(),
|
|
states: Default::default(),
|
|
transitions: Default::default(),
|
|
child_of_layout: false,
|
|
has_popup_child: false,
|
|
layout_info_prop: Default::default(),
|
|
is_flickable_viewport: false,
|
|
item_index: Default::default(),
|
|
item_index_of_first_children: Default::default(),
|
|
node: win_elem_mut.node.clone(),
|
|
inline_depth: 0,
|
|
};
|
|
let new_root = Rc::new(RefCell::new(new_root));
|
|
win_elem_mut.children.push(new_root.clone());
|
|
drop(win_elem_mut);
|
|
|
|
let make_two_way = |name: &str| {
|
|
new_root.borrow_mut().bindings.insert(
|
|
name.into(),
|
|
RefCell::new(BindingExpression::new_two_way(NamedReference::new(&win_elem, name))),
|
|
);
|
|
};
|
|
make_two_way("width");
|
|
make_two_way("height");
|
|
|
|
let mut must_update = HashSet::new();
|
|
|
|
let mut base_props: HashSet<String> =
|
|
new_root.borrow().base_type.property_list().into_iter().map(|x| x.0).collect();
|
|
base_props.extend(win_elem.borrow().bindings.keys().cloned());
|
|
for prop in base_props {
|
|
if prop == "width" || prop == "height" {
|
|
continue;
|
|
}
|
|
|
|
if win_elem.borrow().property_declarations.contains_key(&prop) {
|
|
continue;
|
|
}
|
|
|
|
must_update.insert(NamedReference::new(&win_elem, &prop));
|
|
|
|
if let Some(b) = win_elem.borrow_mut().bindings.remove(&prop) {
|
|
new_root.borrow_mut().bindings.insert(prop.clone(), b);
|
|
}
|
|
if let Some(a) = win_elem.borrow().property_analysis.borrow_mut().remove(&prop) {
|
|
new_root.borrow().property_analysis.borrow_mut().insert(prop.clone(), a);
|
|
}
|
|
}
|
|
|
|
crate::object_tree::visit_all_named_references(component, &mut |nr| {
|
|
if must_update.contains(nr) {
|
|
*nr = NamedReference::new(&new_root, nr.name());
|
|
}
|
|
});
|
|
|
|
component.root_element.borrow_mut().bindings.insert(
|
|
"background".to_string(),
|
|
RefCell::new(
|
|
Expression::PropertyReference(NamedReference::new(
|
|
&style_metrics.root_element,
|
|
"window-background",
|
|
))
|
|
.into(),
|
|
),
|
|
);
|
|
}
|