Fix default geometry of items with inject_element_as_repeated_element

Fixes #3027
This commit is contained in:
Olivier Goffart 2023-06-30 17:04:39 +02:00 committed by Olivier Goffart
parent 530e6783ab
commit 03bed94072
6 changed files with 80 additions and 38 deletions

View file

@ -514,3 +514,24 @@ pub fn implicit_layout_info_call(elem: &ElementRc, orientation: Orientation) ->
};
}
}
/// Create a new property based on the name. (it might get a different name if that property exist)
pub fn create_new_prop(elem: &ElementRc, tentative_name: &str, ty: Type) -> NamedReference {
let mut e = elem.borrow_mut();
if !e.lookup_property(tentative_name).is_valid() {
e.property_declarations.insert(tentative_name.into(), ty.into());
drop(e);
NamedReference::new(elem, tentative_name)
} else {
let mut counter = 0;
loop {
counter += 1;
let name = format!("{}{}", tentative_name, counter);
if !e.lookup_property(&name).is_valid() {
e.property_declarations.insert(name.clone(), ty.into());
drop(e);
return NamedReference::new(elem, &name);
}
}
}
}

View file

@ -2436,7 +2436,29 @@ pub fn inject_element_as_repeated_element(repeated_element: &ElementRc, new_root
new_root.borrow_mut().child_of_layout =
std::mem::replace(&mut old_root.borrow_mut().child_of_layout, false);
new_root.borrow_mut().layout_info_prop = old_root.borrow().layout_info_prop.clone();
let layout_info_prop = old_root.borrow().layout_info_prop.clone().or_else(|| {
// generate the layout_info_prop that forward to the implicit layout for that item
let li_v = crate::layout::create_new_prop(
&new_root,
"layoutinfo-v",
crate::layout::layout_info_type(),
);
let li_h = crate::layout::create_new_prop(
&new_root,
"layoutinfo-h",
crate::layout::layout_info_type(),
);
let expr_h = crate::layout::implicit_layout_info_call(&old_root, Orientation::Horizontal);
let expr_v = crate::layout::implicit_layout_info_call(&old_root, Orientation::Vertical);
let expr_v =
BindingExpression::new_with_span(expr_v, old_root.borrow().to_source_location());
li_v.element().borrow_mut().bindings.insert(li_v.name().into(), expr_v.into());
let expr_h =
BindingExpression::new_with_span(expr_h, old_root.borrow().to_source_location());
li_h.element().borrow_mut().bindings.insert(li_h.name().into(), expr_h.into());
Some((li_h.clone(), li_v.clone()))
});
new_root.borrow_mut().layout_info_prop = dbg!(layout_info_prop);
// Replace the repeated component's element with our shadow element. That requires a bit of reference counting
// surgery and relies on nobody having a strong reference left to the component, which we take out of the Rc.

View file

@ -188,16 +188,10 @@ fn gen_layout_info_prop(elem: &ElementRc, diag: &mut BuildDiagnostics) {
return;
}
let li_v = super::lower_layout::create_new_prop(
elem,
"layoutinfo-v",
crate::layout::layout_info_type(),
);
let li_h = super::lower_layout::create_new_prop(
elem,
"layoutinfo-h",
crate::layout::layout_info_type(),
);
let li_v =
crate::layout::create_new_prop(elem, "layoutinfo-v", crate::layout::layout_info_type());
let li_h =
crate::layout::create_new_prop(elem, "layoutinfo-h", crate::layout::layout_info_type());
elem.borrow_mut().layout_info_prop = Some((li_h.clone(), li_v.clone()));
let mut expr_h = implicit_layout_info_call(elem, Orientation::Horizontal);
let mut expr_v = implicit_layout_info_call(elem, Orientation::Vertical);

View file

@ -736,27 +736,6 @@ fn eval_const_expr(
}
}
/// Create a new property based on the name. (it might get a different name if that property exist)
pub fn create_new_prop(elem: &ElementRc, tentative_name: &str, ty: Type) -> NamedReference {
let mut e = elem.borrow_mut();
if !e.lookup_property(tentative_name).is_valid() {
e.property_declarations.insert(tentative_name.into(), ty.into());
drop(e);
NamedReference::new(elem, tentative_name)
} else {
let mut counter = 0;
loop {
counter += 1;
let name = format!("{}{}", tentative_name, counter);
if !e.lookup_property(&name).is_valid() {
e.property_declarations.insert(name.clone(), ty.into());
drop(e);
return NamedReference::new(elem, &name);
}
}
}
}
/// Checks that there is grid-layout specific properties left
fn check_no_layout_properties(item: &ElementRc, diag: &mut BuildDiagnostics) {
for (prop, expr) in item.borrow().bindings.iter() {

View file

@ -2,10 +2,10 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.0 OR LicenseRef-Slint-commercial
// Test that the default geometry is taken from the right parent, even when some
//
//of visible or opacity or so are set
export TestCase := Window {
property <bool> condition: true;
export component TestCase {
in property <bool> condition: true;
Rectangle {
width: 10px;
height: 20px;
@ -39,9 +39,10 @@ export TestCase := Window {
drop-shadow-blur: 8px;
background: orange;
}
}
property <bool> test:
out property <bool> test:
invisible.width == 10px && invisible.height == 20px &&
opaque.width == 10px && opaque.height == 20px &&
clipped.width == 10px && clipped.height == 20px &&

View file

@ -1,7 +1,29 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.0 OR LicenseRef-Slint-commercial
TestCase := Window {
component TextTextGeomWithOpacityOrClip {
in property<bool> cond: true;
reference := Text { text: "Hello"; }
t1 := VerticalLayout {
if cond: Text {
text: "Hello";
opacity: 0.5;
}
}
t2 := VerticalLayout {
if cond: Text {
text: "Hello";
visible: cond;
}
}
out property <bool> test: reference.preferred-width > 0 && reference.preferred-height > 0 &&
reference.preferred-width == t1.preferred-width && reference.preferred-height == t1.preferred-height &&
reference.preferred-width == t2.preferred-width && reference.preferred-height == t2.preferred-height;
}
export component TestCase inherits Window {
width: 400px;
height: 640px;
VerticalLayout {
@ -14,7 +36,10 @@ TestCase := Window {
}
}
property <bool> test: text.height > 0 && text.width == root.width;
in property <bool> cond <=> in_if.cond;
in_if := TextTextGeomWithOpacityOrClip { }
out property <bool> test: text.height > 0 && text.width == root.width && in_if.test;
}
/*