Skip to content

Commit

Permalink
Layouting: Take in account explicit constraints when generating layou…
Browse files Browse the repository at this point in the history
…t info base on content

Fixes #6285

ChangeLog: Fixed geometry constraints when they are partially infered
from the content, and partially infered from the explicit constraints
  • Loading branch information
ogoffart committed Sep 25, 2024
1 parent d0896e6 commit 81984cf
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
2 changes: 1 addition & 1 deletion internal/compiler/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ impl LayoutConstraints {
apply_size_constraint("height", s, enclosing, depth, &mut constraints.max_height);
});
find_binding(element, "width", |s, enclosing, depth| {
constraints.fixed_width = true;
if s.expression.ty() == Type::Percent {
apply_size_constraint("width", s, enclosing, depth, &mut constraints.min_width);
} else {
constraints.fixed_width = true;
apply_size_constraint("width", s, enclosing, depth, &mut constraints.min_width);
apply_size_constraint("width", s, enclosing, depth, &mut constraints.max_width);
}
Expand Down
47 changes: 47 additions & 0 deletions internal/compiler/passes/default_geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,14 @@ fn gen_layout_info_prop(elem: &ElementRc, diag: &mut BuildDiagnostics) {
let mut expr_h = implicit_layout_info_call(elem, Orientation::Horizontal);
let mut expr_v = implicit_layout_info_call(elem, Orientation::Vertical);

let explicit_constraints = LayoutConstraints::new(elem, diag);
if !explicit_constraints.fixed_width {
merge_explicit_constraints(&mut expr_h, &explicit_constraints, Orientation::Horizontal);
}
if !explicit_constraints.fixed_height {
merge_explicit_constraints(&mut expr_v, &explicit_constraints, Orientation::Vertical);
}

for child_info in child_infos {
if let Some(h) = child_info.0 {
expr_h = Expression::BinaryExpression {
Expand All @@ -239,6 +247,45 @@ fn gen_layout_info_prop(elem: &ElementRc, diag: &mut BuildDiagnostics) {
li_h.element().borrow_mut().bindings.insert(li_h.name().into(), expr_h.into());
}

fn merge_explicit_constraints(
expr: &mut Expression,
constraints: &LayoutConstraints,
orientation: Orientation,
) {
if constraints.has_explicit_restrictions(orientation) {
static COUNT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
let unique_name =
format!("layout_info_{}", COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed));
let ty = expr.ty();
let store = Expression::StoreLocalVariable {
name: unique_name.clone(),
value: Box::new(std::mem::take(expr)),
};
let Type::Struct { fields, .. } = &ty else { unreachable!() };
let mut values = fields
.keys()
.map(|p| {
(
p.clone(),
Expression::StructFieldAccess {
base: Expression::ReadLocalVariable {
name: unique_name.clone(),
ty: ty.clone(),
}
.into(),
name: p.clone(),
},
)
})
.collect::<HashMap<_, _>>();

for (nr, s) in constraints.for_each_restrictions(orientation) {
values.insert(s.into(), Expression::PropertyReference(nr.clone()));
}
*expr = Expression::CodeBlock([store, Expression::Struct { ty, values }].into());
}
}

fn explicit_layout_info(e: &ElementRc, orientation: Orientation) -> Expression {
let mut values = HashMap::new();
let (size, orient) = match orientation {
Expand Down
26 changes: 26 additions & 0 deletions tests/cases/layout/issue6285_auto_explicit_restrictions.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright © SixtyFPS GmbH <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0


component C1 {
Rectangle {
min-width: 200px;
min-height: 300px;
inner := Rectangle {}
}
}
component C2 {
Rectangle {
min-width: 200px;
min-height: 300px;
inner := Rectangle { width: 100%; }
}
}


export component W inherits Window {
c1:= C1 {}
c2:= C2 {}
out property <bool> test: c1.min-height == 300px && c1.min-width == 200px
&& c2.min-height == 300px && c2.min-width == 200px;
}

0 comments on commit 81984cf

Please sign in to comment.