mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 14:51:15 +00:00

Using #component_id::item_tree for it does not work because the public component id is not the right one, we need the one from the current item tree which is not known at compile time (could be several if the component is re-used accross item trees) Also disable the code that sets the focus to the focued element for anything but the window component: before, the setup code was only run for the non-sub component, but now it is run for every sub component, and we don't want to set the focus to anything that has a forward focus property
103 lines
3.6 KiB
Rust
103 lines
3.6 KiB
Rust
// Copyright © SixtyFPS GmbH <info@sixtyfps.io>
|
|
// SPDX-License-Identifier: (GPL-3.0-only OR LicenseRef-SixtyFPS-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,
|
|
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(),
|
|
};
|
|
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(),
|
|
),
|
|
);
|
|
}
|