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
|
inline LayoutInfo LayoutInfo::merge(const LayoutInfo &other) const
|
||||||
{
|
{
|
||||||
// Note: This "logic" is duplicated from LayoutInfo::merge in layout.rs.
|
// 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),
|
return LayoutInfo { std::max(min, other.min),
|
||||||
std::min(max, other.max),
|
std::min(max, other.max),
|
||||||
std::max(min_percent, other.min_percent),
|
std::max(min_percent, other.min_percent),
|
||||||
std::min(max_percent, other.max_percent),
|
std::min(max_percent, other.max_percent),
|
||||||
merge_preferred_size(stretch, preferred,
|
std::max(preferred, other.preferred),
|
||||||
other.stretch, other.preferred),
|
|
||||||
std::min(stretch, other.stretch) };
|
std::min(stretch, other.stretch) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,18 +146,18 @@ fn gen_layout_info_prop(elem: &ElementRc) {
|
||||||
"layoutinfo_h",
|
"layoutinfo_h",
|
||||||
crate::layout::layout_info_type(),
|
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_h = implicit_layout_info_call(elem, Orientation::Horizontal);
|
||||||
let mut expr_v = implicit_layout_info_call(elem, Orientation::Vertical);
|
let mut expr_v = implicit_layout_info_call(elem, Orientation::Vertical);
|
||||||
|
|
||||||
for child_info in child_infos {
|
for child_info in child_infos {
|
||||||
expr_v = Expression::BinaryExpression {
|
expr_h = Expression::BinaryExpression {
|
||||||
lhs: Box::new(std::mem::take(&mut expr_v)),
|
lhs: Box::new(std::mem::take(&mut expr_h)),
|
||||||
rhs: Box::new(Expression::PropertyReference(child_info.0)),
|
rhs: Box::new(Expression::PropertyReference(child_info.0)),
|
||||||
op: '+',
|
op: '+',
|
||||||
};
|
};
|
||||||
expr_h = Expression::BinaryExpression {
|
expr_v = Expression::BinaryExpression {
|
||||||
lhs: Box::new(std::mem::take(&mut expr_h)),
|
lhs: Box::new(std::mem::take(&mut expr_v)),
|
||||||
rhs: Box::new(Expression::PropertyReference(child_info.1)),
|
rhs: Box::new(Expression::PropertyReference(child_info.1)),
|
||||||
op: '+',
|
op: '+',
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,17 +20,17 @@ use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn materialize_fake_properties(component: &Rc<Component>) {
|
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, _| {
|
recurse_elem_including_sub_components_no_borrow(component, &(), &mut |elem, _| {
|
||||||
visit_all_named_references_in_element(elem, |nr| {
|
visit_all_named_references_in_element(elem, |nr| {
|
||||||
let elem = nr.element();
|
let elem = nr.element();
|
||||||
let must_initialize = {
|
|
||||||
let mut elem = elem.borrow_mut();
|
let mut elem = elem.borrow_mut();
|
||||||
let elem = &mut *elem;
|
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())
|
&& !elem.bindings.contains_key(nr.name())
|
||||||
};
|
{
|
||||||
if must_initialize {
|
to_initialize.insert(nr.clone());
|
||||||
initialize(elem, nr.name());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut elem = elem.borrow_mut();
|
let mut elem = elem.borrow_mut();
|
||||||
|
@ -38,7 +38,14 @@ pub fn materialize_fake_properties(component: &Rc<Component>) {
|
||||||
for prop in elem.bindings.keys() {
|
for prop in elem.bindings.keys() {
|
||||||
maybe_materialize(&mut elem.property_declarations, &elem.base_type, prop);
|
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(
|
fn maybe_materialize(
|
||||||
|
|
|
@ -59,27 +59,12 @@ impl Default for LayoutInfo {
|
||||||
impl LayoutInfo {
|
impl LayoutInfo {
|
||||||
// Note: This "logic" is duplicated in the cpp generator's generated code for merging layout infos.
|
// Note: This "logic" is duplicated in the cpp generator's generated code for merging layout infos.
|
||||||
pub fn merge(&self, other: &LayoutInfo) -> Self {
|
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 {
|
Self {
|
||||||
min: self.min.max(other.min),
|
min: self.min.max(other.min),
|
||||||
max: self.max.min(other.max),
|
max: self.max.min(other.max),
|
||||||
min_percent: self.min_percent.max(other.min_percent),
|
min_percent: self.min_percent.max(other.min_percent),
|
||||||
max_percent: self.max_percent.min(other.max_percent),
|
max_percent: self.max_percent.min(other.max_percent),
|
||||||
preferred: merge_preferred_size(
|
preferred: self.preferred.max(other.preferred),
|
||||||
self.stretch,
|
|
||||||
self.preferred,
|
|
||||||
other.stretch,
|
|
||||||
other.preferred,
|
|
||||||
),
|
|
||||||
stretch: self.stretch.min(other.stretch),
|
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