Skip to content
33 changes: 28 additions & 5 deletions api/cpp/include/slint.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,41 @@ inline SharedVector<float> solve_box_layout(const cbindgen_private::BoxLayoutDat
return result;
}

inline SharedVector<float> solve_grid_layout(const cbindgen_private::GridLayoutData &data)
inline SharedVector<float>
organize_grid_layout(cbindgen_private::Slice<cbindgen_private::GridLayoutInputData> input_data)
{
SharedVector<float> result;
cbindgen_private::slint_solve_grid_layout(&data, &result);
cbindgen_private::slint_organize_grid_layout(input_data, &result);
return result;
}

inline SharedVector<float> organize_dialog_button_layout(
cbindgen_private::Slice<cbindgen_private::GridLayoutInputData> input_data,
cbindgen_private::Slice<DialogButtonRole> dialog_button_roles)
{
SharedVector<float> result;
cbindgen_private::slint_organize_dialog_button_layout(input_data, dialog_button_roles, &result);
return result;
}

inline SharedVector<float>
solve_grid_layout(const cbindgen_private::GridLayoutData &data,
cbindgen_private::Slice<cbindgen_private::LayoutInfo> constraints,
cbindgen_private::Orientation orientation)
{
SharedVector<float> result;
cbindgen_private::slint_solve_grid_layout(&data, constraints, orientation, &result);
return result;
}

inline cbindgen_private::LayoutInfo
grid_layout_info(cbindgen_private::Slice<cbindgen_private::GridLayoutCellData> cells, float spacing,
const cbindgen_private::Padding &padding)
grid_layout_info(const cbindgen_private::GridLayoutOrganizedData &organized_data,
cbindgen_private::Slice<cbindgen_private::LayoutInfo> constraints, float spacing,
const cbindgen_private::Padding &padding,
cbindgen_private::Orientation orientation)
{
return cbindgen_private::slint_grid_layout_info(cells, spacing, &padding);
return cbindgen_private::slint_grid_layout_info(&organized_data, constraints, spacing, &padding,
orientation);
}

inline cbindgen_private::LayoutInfo
Expand Down
29 changes: 29 additions & 0 deletions internal/compiler/expression_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,10 +756,24 @@ pub enum Expression {
/// So this looks like `layout_cache_prop[layout_cache_prop[index] + repeater_index]`
repeater_index: Option<Box<Expression>>,
},

/// Organize a grid layout, i.e. decide what goes where
OrganizeGridLayout(crate::layout::GridLayout),

/// Compute the LayoutInfo for the given layout.
/// The orientation is the orientation of the cache, not the orientation of the layout
ComputeLayoutInfo(crate::layout::Layout, crate::layout::Orientation),
ComputeGridLayoutInfo {
layout_organized_data_prop: NamedReference,
layout: crate::layout::GridLayout,
orientation: crate::layout::Orientation,
},
SolveLayout(crate::layout::Layout, crate::layout::Orientation),
SolveGridLayout {
layout_organized_data_prop: NamedReference,
layout: crate::layout::GridLayout,
orientation: crate::layout::Orientation,
},

MinMax {
ty: Type,
Expand Down Expand Up @@ -887,8 +901,11 @@ impl Expression {
// invalid because the expression is unreachable
Expression::ReturnStatement(_) => Type::Invalid,
Expression::LayoutCacheAccess { .. } => Type::LogicalLength,
Expression::OrganizeGridLayout(..) => typeregister::organized_layout_type().into(),
Expression::ComputeLayoutInfo(..) => typeregister::layout_info_type().into(),
Expression::ComputeGridLayoutInfo { .. } => typeregister::layout_info_type().into(),
Expression::SolveLayout(..) => Type::LayoutCache,
Expression::SolveGridLayout { .. } => Type::LayoutCache,
Expression::MinMax { ty, .. } => ty.clone(),
Expression::EmptyComponentFactory => Type::ComponentFactory,
Expression::DebugHook { expression, .. } => expression.ty(),
Expand Down Expand Up @@ -986,8 +1003,11 @@ impl Expression {
Expression::LayoutCacheAccess { repeater_index, .. } => {
repeater_index.as_deref().map(visitor);
}
Expression::OrganizeGridLayout(..) => {}
Expression::ComputeLayoutInfo(..) => {}
Expression::ComputeGridLayoutInfo { .. } => {}
Expression::SolveLayout(..) => {}
Expression::SolveGridLayout { .. } => {}
Expression::MinMax { lhs, rhs, .. } => {
visitor(lhs);
visitor(rhs);
Expand Down Expand Up @@ -1090,8 +1110,11 @@ impl Expression {
Expression::LayoutCacheAccess { repeater_index, .. } => {
repeater_index.as_deref_mut().map(visitor);
}
Expression::OrganizeGridLayout(..) => {}
Expression::ComputeLayoutInfo(..) => {}
Expression::ComputeGridLayoutInfo { .. } => {}
Expression::SolveLayout(..) => {}
Expression::SolveGridLayout { .. } => {}
Expression::MinMax { lhs, rhs, .. } => {
visitor(lhs);
visitor(rhs);
Expand Down Expand Up @@ -1184,8 +1207,11 @@ impl Expression {
}
// TODO: detect constant property within layouts
Expression::LayoutCacheAccess { .. } => false,
Expression::OrganizeGridLayout { .. } => false,
Expression::ComputeLayoutInfo(..) => false,
Expression::ComputeGridLayoutInfo { .. } => false,
Expression::SolveLayout(..) => false,
Expression::SolveGridLayout { .. } => false,
Expression::MinMax { lhs, rhs, .. } => lhs.is_constant(ga) && rhs.is_constant(ga),
Expression::EmptyComponentFactory => true,
Expression::DebugHook { .. } => false,
Expand Down Expand Up @@ -1860,8 +1886,11 @@ pub fn pretty_print(f: &mut dyn std::fmt::Write, expression: &Expression) -> std
if repeater_index.is_some() { " + $index" } else { "" }
)
}
Expression::OrganizeGridLayout(..) => write!(f, "organize_grid_layout(..)"),
Expression::ComputeLayoutInfo(..) => write!(f, "layout_info(..)"),
Expression::ComputeGridLayoutInfo { .. } => write!(f, "grid_layout_info(..)"),
Expression::SolveLayout(..) => write!(f, "solve_layout(..)"),
Expression::SolveGridLayout { .. } => write!(f, "solve_grid_layout(..)"),
Expression::MinMax { ty: _, op, lhs, rhs } => {
match op {
MinMaxOp::Min => write!(f, "min(")?,
Expand Down
17 changes: 0 additions & 17 deletions internal/compiler/generator/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3645,23 +3645,6 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
sub_expression,
ctx,
),
Expression::ComputeDialogLayoutCells { cells_variable, roles, unsorted_cells } => {
let cells_variable = ident(cells_variable);
let mut cells = match &**unsorted_cells {
Expression::Array { values, .. } => {
values.iter().map(|v| compile_expression(v, ctx))
}
_ => panic!("dialog layout unsorted cells not an array"),
};
format!(
"slint::cbindgen_private::GridLayoutCellData {cv}_array [] = {{ {c} }};\
slint::cbindgen_private::slint_reorder_dialog_button_layout({cv}_array, {r});\
slint::cbindgen_private::Slice<slint::cbindgen_private::GridLayoutCellData> {cv} = slint::private_api::make_slice(std::span({cv}_array))",
r = compile_expression(roles, ctx),
cv = cells_variable,
c = cells.join(", "),
)
}
Expression::MinMax { ty, op, lhs, rhs } => {
let ident = match op {
MinMaxOp::Min => "min",
Expand Down
15 changes: 0 additions & 15 deletions internal/compiler/generator/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2710,21 +2710,6 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
sub_expression,
ctx,
),
Expression::ComputeDialogLayoutCells { cells_variable, roles, unsorted_cells } => {
let cells_variable = ident(cells_variable);
let roles = compile_expression(roles, ctx);
let cells = match &**unsorted_cells {
Expression::Array { values, .. } => {
values.iter().map(|v| compile_expression(v, ctx))
}
_ => panic!("dialog layout unsorted cells not an array"),
};
quote! {
let mut #cells_variable = [#(#cells),*];
sp::reorder_dialog_button_layout(&mut #cells_variable, &#roles);
let #cells_variable = sp::Slice::from_slice(&#cells_variable);
}
}
Expression::MinMax { ty, op, lhs, rhs } => {
let lhs = compile_expression(lhs, ctx);
let t = rust_primitive_type(ty);
Expand Down
46 changes: 37 additions & 9 deletions internal/compiler/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,21 +275,28 @@ impl LayoutConstraints {
}
}

#[derive(Debug, Clone)]
pub enum RowColExpr {
Named(NamedReference),
Literal(u16),
}

/// An element in a GridLayout
#[derive(Debug, Clone)]
pub struct GridLayoutElement {
pub col: u16,
pub row: u16,
pub colspan: u16,
pub rowspan: u16,
pub new_row: bool,
pub col_expr: RowColExpr,
pub row_expr: RowColExpr,
pub colspan_expr: RowColExpr,
pub rowspan_expr: RowColExpr,
pub item: LayoutItem,
}

impl GridLayoutElement {
pub fn col_or_row_and_span(&self, orientation: Orientation) -> (u16, u16) {
pub fn span(&self, orientation: Orientation) -> &RowColExpr {
match orientation {
Orientation::Horizontal => (self.col, self.colspan),
Orientation::Vertical => (self.row, self.rowspan),
Orientation::Horizontal => &self.colspan_expr,
Orientation::Vertical => &self.rowspan_expr,
}
}
}
Expand Down Expand Up @@ -425,7 +432,7 @@ fn find_binding<R>(
}

/// Return a named reference to a property if a binding is set on that property
fn binding_reference(element: &ElementRc, name: &'static str) -> Option<NamedReference> {
pub fn binding_reference(element: &ElementRc, name: &'static str) -> Option<NamedReference> {
find_binding(element, name, |_, _, _| NamedReference::new(element, SmolStr::new_static(name)))
}

Expand Down Expand Up @@ -461,10 +468,31 @@ pub struct GridLayout {
/// When this GridLayout is actually the layout of a Dialog, then the cells start with all the buttons,
/// and this variable contains their roles. The string is actually one of the values from the i_slint_core::layout::DialogButtonRole
pub dialog_button_roles: Option<Vec<SmolStr>>,

/// Whether any of the row/column expressions use 'auto'
pub uses_auto: bool,
}

impl GridLayout {
fn visit_named_references(&mut self, visitor: &mut impl FnMut(&mut NamedReference)) {
pub fn visit_rowcol_named_references(&mut self, visitor: &mut impl FnMut(&mut NamedReference)) {
for cell in &mut self.elems {
if let RowColExpr::Named(ref mut e) = cell.col_expr {
visitor(e);
}
if let RowColExpr::Named(ref mut e) = cell.row_expr {
visitor(e);
}
if let RowColExpr::Named(ref mut e) = cell.colspan_expr {
visitor(e);
}
if let RowColExpr::Named(ref mut e) = cell.rowspan_expr {
visitor(e);
}
}
}

pub fn visit_named_references(&mut self, visitor: &mut impl FnMut(&mut NamedReference)) {
self.visit_rowcol_named_references(visitor);
for cell in &mut self.elems {
cell.item.constraints.visit_named_references(visitor);
}
Expand Down
16 changes: 0 additions & 16 deletions internal/compiler/llr/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,6 @@ pub enum Expression {
orientation: Orientation,
sub_expression: Box<Expression>,
},

ComputeDialogLayoutCells {
/// The local variable where the slice of cells is going to be stored
cells_variable: String,
roles: Box<Expression>,
/// This is an Expression::Array
unsorted_cells: Box<Expression>,
},

MinMax {
ty: Type,
op: MinMaxOp,
Expand Down Expand Up @@ -322,9 +313,6 @@ impl Expression {
Self::EnumerationValue(e) => Type::Enumeration(e.enumeration.clone()),
Self::LayoutCacheAccess { .. } => Type::LogicalLength,
Self::BoxLayoutFunction { sub_expression, .. } => sub_expression.ty(ctx),
Self::ComputeDialogLayoutCells { .. } => {
Type::Array(super::lower_expression::grid_layout_cell_data_ty().into())
}
Self::MinMax { ty, .. } => ty.clone(),
Self::EmptyComponentFactory => Type::ComponentFactory,
Self::TranslationReference { .. } => Type::String,
Expand Down Expand Up @@ -409,10 +397,6 @@ macro_rules! visit_impl {
$visitor(sub_expression);
elements.$iter().filter_map(|x| x.$as_ref().left()).for_each($visitor);
}
Expression::ComputeDialogLayoutCells { roles, unsorted_cells, .. } => {
$visitor(roles);
$visitor(unsorted_cells);
}
Expression::MinMax { ty: _, op: _, lhs, rhs } => {
$visitor(lhs);
$visitor(rhs);
Expand Down
Loading
Loading