mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +00:00
Fix preferred size of the Window with a layout
A few problem: - the horizontal and vertical property were swapped - The implementation of the "preferred_xxx" property was not materialized properly because the `bindings` were borrowed in the materialize_fake_properties pass - Since the Window has a stretch factor of 0., the preferred size of the inner layout was not taken into account when merging the LayoutInfo. I believe taking the maximum preferred size is the right solution when merging them.
This commit is contained in:
parent
0a3ec534ae
commit
a0bea36e43
5 changed files with 74 additions and 42 deletions
|
@ -321,22 +321,11 @@ using cbindgen_private::sixtyfps_solve_path_layout;
|
|||
inline LayoutInfo LayoutInfo::merge(const LayoutInfo &other) const
|
||||
{
|
||||
// Note: This "logic" is duplicated from LayoutInfo::merge in layout.rs.
|
||||
const auto merge_preferred_size = [](float left_stretch, float left_size, float right_stretch,
|
||||
float right_size) -> float {
|
||||
if (left_stretch < right_stretch) {
|
||||
return left_size;
|
||||
} else if (left_stretch > right_stretch) {
|
||||
return right_size;
|
||||
} else {
|
||||
return (left_size + right_size) / 2.;
|
||||
}
|
||||
};
|
||||
return LayoutInfo { std::max(min, other.min),
|
||||
std::min(max, other.max),
|
||||
std::max(min_percent, other.min_percent),
|
||||
std::min(max_percent, other.max_percent),
|
||||
merge_preferred_size(stretch, preferred,
|
||||
other.stretch, other.preferred),
|
||||
std::max(preferred, other.preferred),
|
||||
std::min(stretch, other.stretch) };
|
||||
}
|
||||
|
||||
|
|
|
@ -146,18 +146,18 @@ fn gen_layout_info_prop(elem: &ElementRc) {
|
|||
"layoutinfo_h",
|
||||
crate::layout::layout_info_type(),
|
||||
);
|
||||
elem.borrow_mut().layout_info_prop = Some((li_v.clone(), li_h.clone()));
|
||||
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);
|
||||
|
||||
for child_info in child_infos {
|
||||
expr_v = Expression::BinaryExpression {
|
||||
lhs: Box::new(std::mem::take(&mut expr_v)),
|
||||
expr_h = Expression::BinaryExpression {
|
||||
lhs: Box::new(std::mem::take(&mut expr_h)),
|
||||
rhs: Box::new(Expression::PropertyReference(child_info.0)),
|
||||
op: '+',
|
||||
};
|
||||
expr_h = Expression::BinaryExpression {
|
||||
lhs: Box::new(std::mem::take(&mut expr_h)),
|
||||
expr_v = Expression::BinaryExpression {
|
||||
lhs: Box::new(std::mem::take(&mut expr_v)),
|
||||
rhs: Box::new(Expression::PropertyReference(child_info.1)),
|
||||
op: '+',
|
||||
};
|
||||
|
|
|
@ -20,17 +20,17 @@ use std::collections::HashMap;
|
|||
use std::rc::Rc;
|
||||
|
||||
pub fn materialize_fake_properties(component: &Rc<Component>) {
|
||||
let mut to_initialize = std::collections::HashSet::new();
|
||||
|
||||
recurse_elem_including_sub_components_no_borrow(component, &(), &mut |elem, _| {
|
||||
visit_all_named_references_in_element(elem, |nr| {
|
||||
let elem = nr.element();
|
||||
let must_initialize = {
|
||||
let mut elem = elem.borrow_mut();
|
||||
let elem = &mut *elem;
|
||||
maybe_materialize(&mut elem.property_declarations, &elem.base_type, nr.name())
|
||||
if maybe_materialize(&mut elem.property_declarations, &elem.base_type, nr.name())
|
||||
&& !elem.bindings.contains_key(nr.name())
|
||||
};
|
||||
if must_initialize {
|
||||
initialize(elem, nr.name());
|
||||
{
|
||||
to_initialize.insert(nr.clone());
|
||||
}
|
||||
});
|
||||
let mut elem = elem.borrow_mut();
|
||||
|
@ -38,7 +38,14 @@ pub fn materialize_fake_properties(component: &Rc<Component>) {
|
|||
for prop in elem.bindings.keys() {
|
||||
maybe_materialize(&mut elem.property_declarations, &elem.base_type, prop);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
for nr in to_initialize {
|
||||
let elem = nr.element();
|
||||
if !elem.borrow().bindings.contains_key(nr.name()) {
|
||||
initialize(elem, nr.name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_materialize(
|
||||
|
|
|
@ -59,27 +59,12 @@ impl Default for LayoutInfo {
|
|||
impl LayoutInfo {
|
||||
// Note: This "logic" is duplicated in the cpp generator's generated code for merging layout infos.
|
||||
pub fn merge(&self, other: &LayoutInfo) -> Self {
|
||||
let merge_preferred_size = |left_stretch, left_size, right_stretch, right_size| {
|
||||
if left_stretch < right_stretch {
|
||||
left_size
|
||||
} else if left_stretch > right_stretch {
|
||||
right_size
|
||||
} else {
|
||||
(left_size + right_size) / 2.
|
||||
}
|
||||
};
|
||||
|
||||
Self {
|
||||
min: self.min.max(other.min),
|
||||
max: self.max.min(other.max),
|
||||
min_percent: self.min_percent.max(other.min_percent),
|
||||
max_percent: self.max_percent.min(other.max_percent),
|
||||
preferred: merge_preferred_size(
|
||||
self.stretch,
|
||||
self.preferred,
|
||||
other.stretch,
|
||||
other.preferred,
|
||||
),
|
||||
preferred: self.preferred.max(other.preferred),
|
||||
stretch: self.stretch.min(other.stretch),
|
||||
}
|
||||
}
|
||||
|
|
51
tests/cases/layout/window_preferred.60
Normal file
51
tests/cases/layout/window_preferred.60
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* LICENSE BEGIN
|
||||
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
||||
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
||||
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
This file is also available under commercial licensing terms.
|
||||
Please contact info@sixtyfps.io for more information.
|
||||
LICENSE END */
|
||||
TestCase := Window {
|
||||
VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 27px;
|
||||
Rectangle {
|
||||
background: blue;
|
||||
preferred-width: 25phx;
|
||||
preferred-height: 500phx;
|
||||
horizontal-stretch: 0;
|
||||
vertical-stretch: 0;
|
||||
}
|
||||
Rectangle {
|
||||
background: green;
|
||||
// implicit: horizontal-stretch: 1
|
||||
}
|
||||
}
|
||||
|
||||
property w <=> root.preferred-width;
|
||||
|
||||
property <bool> test: root.preferred_height == 500phx + 20px + 27px && root.preferred_width == 25phx + 20px;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
```cpp
|
||||
auto handle = TestCase::create();
|
||||
const TestCase &instance = *handle;
|
||||
assert(instance.get_test());
|
||||
```
|
||||
|
||||
|
||||
```rust
|
||||
let instance = TestCase::new();
|
||||
assert!(instance.get_test());
|
||||
```
|
||||
|
||||
```js
|
||||
var instance = new sixtyfps.TestCase();
|
||||
assert(instance.test);
|
||||
```
|
||||
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue