Skip to content

Commit bf9031e

Browse files
dfaure-kdabogoffart
authored andcommitted
Lay out grids at runtime rather than at compile time
This includes support for row and col properties to be expressions rather than just constants.
1 parent e01af64 commit bf9031e

File tree

9 files changed

+401
-135
lines changed

9 files changed

+401
-135
lines changed

api/cpp/include/slint.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,19 @@ inline SharedVector<float> solve_box_layout(const cbindgen_private::BoxLayoutDat
123123
return result;
124124
}
125125

126-
inline SharedVector<float> solve_grid_layout(const cbindgen_private::GridLayoutData &data)
126+
inline SharedVector<float> solve_grid_layout(const cbindgen_private::GridLayoutData &data,
127+
cbindgen_private::Orientation orientation)
127128
{
128129
SharedVector<float> result;
129-
cbindgen_private::slint_solve_grid_layout(&data, &result);
130+
cbindgen_private::slint_solve_grid_layout(&data, orientation, &result);
130131
return result;
131132
}
132133

133134
inline cbindgen_private::LayoutInfo
134135
grid_layout_info(cbindgen_private::Slice<cbindgen_private::GridLayoutCellData> cells, float spacing,
135-
const cbindgen_private::Padding &padding)
136+
const cbindgen_private::Padding &padding, cbindgen_private::Orientation o)
136137
{
137-
return cbindgen_private::slint_grid_layout_info(cells, spacing, &padding);
138+
return cbindgen_private::slint_grid_layout_info(cells, spacing, &padding, o);
138139
}
139140

140141
inline cbindgen_private::LayoutInfo

internal/compiler/layout.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,18 +278,19 @@ impl LayoutConstraints {
278278
/// An element in a GridLayout
279279
#[derive(Debug, Clone)]
280280
pub struct GridLayoutElement {
281-
pub col: u16,
282-
pub row: u16,
281+
pub new_row: bool,
282+
pub col_expr: Option<Expression>,
283+
pub row_expr: Option<Expression>,
283284
pub colspan: u16,
284285
pub rowspan: u16,
285286
pub item: LayoutItem,
286287
}
287288

288289
impl GridLayoutElement {
289-
pub fn col_or_row_and_span(&self, orientation: Orientation) -> (u16, u16) {
290+
pub fn span(&self, orientation: Orientation) -> u16 {
290291
match orientation {
291-
Orientation::Horizontal => (self.col, self.colspan),
292-
Orientation::Vertical => (self.row, self.rowspan),
292+
Orientation::Horizontal => self.colspan,
293+
Orientation::Vertical => self.rowspan,
293294
}
294295
}
295296
}

internal/compiler/llr/lower_expression.rs

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,13 @@ fn compute_layout_info(
594594
crate::layout::Layout::GridLayout(layout) => {
595595
let (padding, spacing) = generate_layout_padding_and_spacing(&layout.geometry, o, ctx);
596596
let cells = grid_layout_cell_data(layout, o, ctx);
597+
let orientation_literal = llr_Expression::EnumerationValue(EnumerationValue {
598+
value: o as _,
599+
enumeration: crate::typeregister::BUILTIN.with(|b| b.enums.Orientation.clone()),
600+
});
597601
llr_Expression::ExtraBuiltinFunctionCall {
598602
function: "grid_layout_info".into(),
599-
arguments: vec![cells, spacing, padding],
603+
arguments: vec![cells, spacing, padding, orientation_literal],
600604
return_ty: crate::typeregister::layout_info_type().into(),
601605
}
602606
}
@@ -640,6 +644,10 @@ fn solve_layout(
640644
let (padding, spacing) = generate_layout_padding_and_spacing(&layout.geometry, o, ctx);
641645
let cells = grid_layout_cell_data(layout, o, ctx);
642646
let size = layout_geometry_size(&layout.geometry.rect, o, ctx);
647+
let orientation_expr = llr_Expression::EnumerationValue(EnumerationValue {
648+
value: o as _,
649+
enumeration: crate::typeregister::BUILTIN.with(|b| b.enums.Orientation.clone()),
650+
});
643651
if let (Some(button_roles), Orientation::Horizontal) = (&layout.dialog_button_roles, o)
644652
{
645653
let cells_ty = cells.ty(ctx);
@@ -666,37 +674,43 @@ fn solve_layout(
666674
},
667675
llr_Expression::ExtraBuiltinFunctionCall {
668676
function: "solve_grid_layout".into(),
669-
arguments: vec![make_struct(
677+
arguments: vec![
678+
make_struct(
670679
BuiltinPrivateStruct::GridLayoutData,
671-
[
672-
("size", Type::Float32, size),
673-
("spacing", Type::Float32, spacing),
674-
("padding", padding.ty(ctx), padding),
675-
(
676-
"cells",
677-
cells_ty.clone(),
678-
llr_Expression::ReadLocalVariable {
679-
name: "cells".into(),
680-
ty: cells_ty,
681-
},
682-
),
683-
],
684-
)],
680+
[
681+
("size", Type::Float32, size),
682+
("spacing", Type::Float32, spacing),
683+
("padding", padding.ty(ctx), padding),
684+
(
685+
"cells",
686+
cells_ty.clone(),
687+
llr_Expression::ReadLocalVariable {
688+
name: "cells".into(),
689+
ty: cells_ty,
690+
},
691+
),
692+
],
693+
),
694+
orientation_expr,
695+
],
685696
return_ty: Type::LayoutCache,
686697
},
687698
])
688699
} else {
689700
llr_Expression::ExtraBuiltinFunctionCall {
690701
function: "solve_grid_layout".into(),
691-
arguments: vec![make_struct(
692-
BuiltinPrivateStruct::GridLayoutData,
693-
[
694-
("size", Type::Float32, size),
695-
("spacing", Type::Float32, spacing),
696-
("padding", padding.ty(ctx), padding),
697-
("cells", cells.ty(ctx), cells),
698-
],
699-
)],
702+
arguments: vec![
703+
make_struct(
704+
BuiltinPrivateStruct::GridLayoutData,
705+
[
706+
("size", Type::Float32, size),
707+
("spacing", Type::Float32, spacing),
708+
("padding", padding.ty(ctx), padding),
709+
("cells", cells.ty(ctx), cells),
710+
],
711+
),
712+
orientation_expr,
713+
],
700714
return_ty: Type::LayoutCache,
701715
}
702716
}
@@ -843,15 +857,33 @@ fn grid_layout_cell_data(
843857
.elems
844858
.iter()
845859
.map(|c| {
846-
let (col_or_row, span) = c.col_or_row_and_span(orientation);
860+
let span = c.span(orientation);
847861
let layout_info =
848862
get_layout_info(&c.item.element, ctx, &c.item.constraints, orientation);
849863

864+
let mut lower_expr_or_auto = |expr: &Option<crate::expression_tree::Expression>| {
865+
expr.as_ref().map_or_else(
866+
|| llr_Expression::NumberLiteral(u16::MAX.into()), // MAX means "auto", see to_layout_data()
867+
|e| lower_expression(e, ctx),
868+
)
869+
};
870+
let row_expr = lower_expr_or_auto(&c.row_expr);
871+
let col_expr = lower_expr_or_auto(&c.col_expr);
872+
850873
make_struct(
851874
BuiltinPrivateStruct::GridLayoutCellData,
852875
[
853876
("constraint", crate::typeregister::layout_info_type().into(), layout_info),
854-
("col_or_row", Type::Int32, llr_Expression::NumberLiteral(col_or_row as _)),
877+
("new_row", Type::Bool, llr_Expression::BoolLiteral(c.new_row)),
878+
(
879+
"col_or_row",
880+
Type::Int32,
881+
match orientation {
882+
Orientation::Horizontal => col_expr,
883+
Orientation::Vertical => row_expr.clone(),
884+
},
885+
),
886+
("row", Type::Int32, row_expr),
855887
("span", Type::Int32, llr_Expression::NumberLiteral(span as _)),
856888
],
857889
)
@@ -864,6 +896,7 @@ fn grid_layout_cell_data(
864896
pub(super) fn grid_layout_cell_data_ty() -> Type {
865897
Type::Struct(Rc::new(Struct {
866898
fields: IntoIterator::into_iter([
899+
(SmolStr::new_static("new_row"), Type::Bool),
867900
(SmolStr::new_static("col_or_row"), Type::Int32),
868901
(SmolStr::new_static("span"), Type::Int32),
869902
(SmolStr::new_static("constraint"), crate::typeregister::layout_info_type().into()),

0 commit comments

Comments
 (0)