Fix layout property set in when deriving components

The layout pass needs to see when going over the layout, that these
properties are set. So inline the element that sets these properties if
they are not set in the base.

Fixes #8091
This commit is contained in:
Olivier Goffart 2025-04-22 17:10:31 +02:00
parent 1f09c0d440
commit cc46811d95
4 changed files with 79 additions and 9 deletions

View file

@ -573,3 +573,14 @@ pub fn create_new_prop(elem: &ElementRc, tentative_name: SmolStr, ty: Type) -> N
}
}
}
/// Return true if this type is a layout that has constraints
pub fn is_layout(base_type: &ElementType) -> bool {
match base_type {
ElementType::Component(c) => is_layout(&c.root_element.borrow().base_type),
ElementType::Builtin(be) => {
matches!(be.name.as_str(), "GridLayout" | "HorizontalLayout" | "VerticalLayout")
}
_ => false,
}
}

View file

@ -12,6 +12,7 @@
use crate::expression_tree::{BindingExpression, Expression, MinMaxOp, NamedReference};
use crate::langtype::{ElementType, NativeClass, Type};
use crate::layout::is_layout;
use crate::object_tree::{Component, Element, ElementRc};
use crate::typeregister::TypeRegister;
use core::cell::RefCell;
@ -208,15 +209,6 @@ fn fixup_geometry(flickable_elem: &ElementRc) {
});
}
/// Return true if this type is a layout that has constraints
fn is_layout(base_type: &ElementType) -> bool {
if let ElementType::Builtin(be) = base_type {
matches!(be.name.as_str(), "GridLayout" | "HorizontalLayout" | "VerticalLayout")
} else {
false
}
}
/// Set the property binding on the given element to the given expression (computed lazily).
/// The parameter to the lazily calculation is the element's children
fn set_binding_if_not_explicit(

View file

@ -644,6 +644,22 @@ fn element_require_inlining(elem: &ElementRc) -> bool {
return true;
}
if prop == "padding"
|| prop == "spacing"
|| prop.starts_with("padding-")
|| prop.starts_with("spacing-")
|| prop == "alignment"
{
if let ElementType::Component(base) = &elem.borrow().base_type {
if crate::layout::is_layout(&base.root_element.borrow().base_type) {
if !base.root_element.borrow().is_binding_set(prop, false) {
// The layout pass need to know that this property is set
return true;
}
}
}
}
let binding = binding.borrow();
if binding.animation.is_some() && matches!(binding.expression, Expression::Invalid) {
// If there is an animation but no binding, we must merge the binding with its animation.

View file

@ -0,0 +1,51 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
// ISSUE #8091
component TopBar inherits VerticalLayout {
// padding: 0; // uncommenting this line make it work
height: 56px;
ir := Rectangle {
background: red;
}
out property <int> ir_h: ir.height / 1px;
}
export component TestCase inherits Window {
preferred-height: 380px;
preferred-width: 230px;
background: blue;
VerticalLayout {
tb := TopBar {
padding: 16px;
}
Rectangle {
background: black;
}
}
out property <bool> test: tb.ir_h == 24;
}
/*
```rust
let instance = TestCase::new().unwrap();
assert!(instance.get_test());
```
```cpp
auto handle = TestCase::create();
const TestCase &instance = *handle;
assert(instance.get_test());
```
```js
var instance = new slint.TestCase();
assert(instance.test);
```
*/