Skip to content

Commit dd70852

Browse files
committed
Move reordering of dialog buttons to the organize step
This repairs the feature of reordering buttons, which was temporarily left out in the previous commit.
1 parent 0ba6261 commit dd70852

File tree

8 files changed

+141
-148
lines changed

8 files changed

+141
-148
lines changed

internal/compiler/generator/cpp.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,23 +3555,6 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
35553555
sub_expression,
35563556
ctx,
35573557
),
3558-
Expression::ComputeDialogLayoutCells { cells_variable, roles, unsorted_cells } => {
3559-
let cells_variable = ident(cells_variable);
3560-
let mut cells = match &**unsorted_cells {
3561-
Expression::Array { values, .. } => {
3562-
values.iter().map(|v| compile_expression(v, ctx))
3563-
}
3564-
_ => panic!("dialog layout unsorted cells not an array"),
3565-
};
3566-
format!("slint::cbindgen_private::GridLayoutCellData {cv}_array [] = {{ {c} }};\
3567-
slint::cbindgen_private::slint_reorder_dialog_button_layout({cv}_array, {r});\
3568-
slint::cbindgen_private::Slice<slint::cbindgen_private::GridLayoutCellData> {cv} = slint::private_api::make_slice(std::span({cv}_array))",
3569-
r = compile_expression(roles, ctx),
3570-
cv = cells_variable,
3571-
c = cells.join(", "),
3572-
)
3573-
3574-
}
35753558
Expression::MinMax { ty, op, lhs, rhs } => {
35763559
let ident = match op {
35773560
MinMaxOp::Min => "min",

internal/compiler/generator/rust.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,21 +2711,6 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
27112711
sub_expression,
27122712
ctx,
27132713
),
2714-
Expression::ComputeDialogLayoutCells { cells_variable, roles, unsorted_cells } => {
2715-
let cells_variable = ident(cells_variable);
2716-
let roles = compile_expression(roles, ctx);
2717-
let cells = match &**unsorted_cells {
2718-
Expression::Array { values, .. } => {
2719-
values.iter().map(|v| compile_expression(v, ctx))
2720-
}
2721-
_ => panic!("dialog layout unsorted cells not an array"),
2722-
};
2723-
quote! {
2724-
let mut #cells_variable = [#(#cells),*];
2725-
sp::reorder_dialog_button_layout(&mut #cells_variable, &#roles);
2726-
let #cells_variable = sp::Slice::from_slice(&#cells_variable);
2727-
}
2728-
}
27292714
Expression::MinMax { ty, op, lhs, rhs } => {
27302715
let lhs = compile_expression(lhs, ctx);
27312716
let t = rust_primitive_type(ty);

internal/compiler/llr/expression.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,6 @@ pub enum Expression {
184184
orientation: Orientation,
185185
sub_expression: Box<Expression>,
186186
},
187-
188-
ComputeDialogLayoutCells {
189-
/// The local variable where the slice of cells is going to be stored
190-
cells_variable: String,
191-
roles: Box<Expression>,
192-
/// This is an Expression::Array
193-
unsorted_cells: Box<Expression>,
194-
},
195-
196187
MinMax {
197188
ty: Type,
198189
op: MinMaxOp,
@@ -320,9 +311,6 @@ impl Expression {
320311
Self::EnumerationValue(e) => Type::Enumeration(e.enumeration.clone()),
321312
Self::LayoutCacheAccess { .. } => Type::LogicalLength,
322313
Self::BoxLayoutFunction { sub_expression, .. } => sub_expression.ty(ctx),
323-
Self::ComputeDialogLayoutCells { .. } => {
324-
Type::Array(super::lower_expression::grid_layout_cell_data_ty().into())
325-
}
326314
Self::MinMax { ty, .. } => ty.clone(),
327315
Self::EmptyComponentFactory => Type::ComponentFactory,
328316
Self::TranslationReference { .. } => Type::String,
@@ -406,10 +394,6 @@ macro_rules! visit_impl {
406394
$visitor(sub_expression);
407395
elements.$iter().filter_map(|x| x.$as_ref().left()).for_each($visitor);
408396
}
409-
Expression::ComputeDialogLayoutCells { roles, unsorted_cells, .. } => {
410-
$visitor(roles);
411-
$visitor(unsorted_cells);
412-
}
413397
Expression::MinMax { ty: _, op: _, lhs, rhs } => {
414398
$visitor(lhs);
415399
$visitor(rhs);

internal/compiler/llr/lower_expression.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -667,10 +667,34 @@ fn organize_grid_layout(
667667
ctx: &mut ExpressionLoweringCtx,
668668
) -> llr_Expression {
669669
let cells = grid_layout_input_data(layout, ctx);
670-
llr_Expression::ExtraBuiltinFunctionCall {
671-
function: "organize_grid_layout".into(),
672-
arguments: vec![cells],
673-
return_ty: Type::Array(Type::Int32.into()),
670+
671+
if let Some(button_roles) = &layout.dialog_button_roles {
672+
let e = crate::typeregister::BUILTIN.with(|e| e.enums.DialogButtonRole.clone());
673+
let roles = button_roles
674+
.iter()
675+
.map(|r| {
676+
llr_Expression::EnumerationValue(EnumerationValue {
677+
value: e.values.iter().position(|x| x == r).unwrap() as _,
678+
enumeration: e.clone(),
679+
})
680+
})
681+
.collect();
682+
let roles_expr = llr_Expression::Array {
683+
element_ty: Type::Enumeration(e),
684+
values: roles,
685+
as_model: false,
686+
};
687+
llr_Expression::ExtraBuiltinFunctionCall {
688+
function: "organize_dialog_button_layout".into(),
689+
arguments: vec![cells, roles_expr],
690+
return_ty: Type::Array(Type::Int32.into()),
691+
}
692+
} else {
693+
llr_Expression::ExtraBuiltinFunctionCall {
694+
function: "organize_grid_layout".into(),
695+
arguments: vec![cells],
696+
return_ty: Type::Array(Type::Int32.into()),
697+
}
674698
}
675699
}
676700

internal/compiler/llr/optim_passes/inline_expressions.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ fn expression_cost(exp: &Expression, ctx: &EvaluationContext) -> isize {
6767
Expression::EnumerationValue(_) => 0,
6868
Expression::LayoutCacheAccess { .. } => PROPERTY_ACCESS_COST,
6969
Expression::BoxLayoutFunction { .. } => return isize::MAX,
70-
Expression::ComputeDialogLayoutCells { .. } => return isize::MAX,
7170
Expression::MinMax { .. } => 10,
7271
Expression::EmptyComponentFactory => 10,
7372
Expression::TranslationReference { .. } => PROPERTY_ACCESS_COST + 2 * ALLOC_COST,

internal/compiler/llr/pretty_print.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,6 @@ impl<'a, T> Display for DisplayExpression<'a, T> {
362362
write!(f, "{}[{} % {}]", DisplayPropertyRef(layout_cache_prop, ctx), index, e(ri))
363363
}
364364
Expression::BoxLayoutFunction { .. } => write!(f, "BoxLayoutFunction(TODO)",),
365-
Expression::ComputeDialogLayoutCells { .. } => {
366-
write!(f, "ComputeDialogLayoutCells(TODO)",)
367-
}
368365
Expression::MinMax { ty: _, op, lhs, rhs } => match op {
369366
MinMaxOp::Min => write!(f, "min({}, {})", e(lhs), e(rhs)),
370367
MinMaxOp::Max => write!(f, "max({}, {})", e(lhs), e(rhs)),

internal/core/layout.rs

Lines changed: 99 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,6 @@ pub struct GridLayoutData {
454454
/// The horizontal or vertical data for a cell of a GridLayout
455455
#[repr(C)]
456456
#[derive(Default, Debug, Clone, PartialEq)]
457-
// Remember to apply any changes to grid_layout_cell_data()/grid_layout_cell_data_ty()
458457
pub struct GridLayoutCellData {
459458
/// col or row (u16::MAX means auto).
460459
pub col_or_row: u16,
@@ -491,16 +490,111 @@ impl GridLayoutOrganizedData {
491490
}
492491
}
493492

493+
/// Given the cells of a layout of a Dialog, re-order the buttons according to the platform
494+
/// This function assume that the `roles` contains the roles of the button which are the first cells in `input_data`
495+
pub fn organize_dialog_button_layout(
496+
input_data: Slice<GridLayoutInputData>,
497+
dialog_button_roles: Slice<DialogButtonRole>,
498+
) -> GridLayoutOrganizedData {
499+
let mut organized_data = GridLayoutOrganizedData::default();
500+
organized_data.reserve(input_data.len() * 4);
501+
502+
#[cfg(feature = "std")]
503+
fn is_kde() -> bool {
504+
// assume some Unix, check if XDG_CURRENT_DESKTOP starts with K
505+
std::env::var("XDG_CURRENT_DESKTOP")
506+
.ok()
507+
.and_then(|v| v.as_bytes().first().copied())
508+
.is_some_and(|x| x.eq_ignore_ascii_case(&b'K'))
509+
}
510+
#[cfg(not(feature = "std"))]
511+
let is_kde = || true;
512+
513+
let expected_order: &[DialogButtonRole] = match crate::detect_operating_system() {
514+
crate::items::OperatingSystemType::Windows => {
515+
&[
516+
DialogButtonRole::Reset,
517+
DialogButtonRole::None, // spacer
518+
DialogButtonRole::Accept,
519+
DialogButtonRole::Action,
520+
DialogButtonRole::Reject,
521+
DialogButtonRole::Apply,
522+
DialogButtonRole::Help,
523+
]
524+
}
525+
crate::items::OperatingSystemType::Macos | crate::items::OperatingSystemType::Ios => {
526+
&[
527+
DialogButtonRole::Help,
528+
DialogButtonRole::Reset,
529+
DialogButtonRole::Apply,
530+
DialogButtonRole::Action,
531+
DialogButtonRole::None, // spacer
532+
DialogButtonRole::Reject,
533+
DialogButtonRole::Accept,
534+
]
535+
}
536+
_ if is_kde() => {
537+
// KDE variant
538+
&[
539+
DialogButtonRole::Help,
540+
DialogButtonRole::Reset,
541+
DialogButtonRole::None, // spacer
542+
DialogButtonRole::Action,
543+
DialogButtonRole::Accept,
544+
DialogButtonRole::Apply,
545+
DialogButtonRole::Reject,
546+
]
547+
}
548+
_ => {
549+
// GNOME variant and fallback for WASM build
550+
&[
551+
DialogButtonRole::Help,
552+
DialogButtonRole::Reset,
553+
DialogButtonRole::None, // spacer
554+
DialogButtonRole::Action,
555+
DialogButtonRole::Accept,
556+
DialogButtonRole::Apply,
557+
DialogButtonRole::Reject,
558+
]
559+
}
560+
};
561+
562+
// Reorder the actual buttons according to expected_order
563+
let mut column_for_input: Vec<usize> = Vec::with_capacity(dialog_button_roles.len());
564+
for role in expected_order.iter() {
565+
if role == &DialogButtonRole::None {
566+
column_for_input.push(usize::MAX); // empty column, ensure nothing will match
567+
continue;
568+
}
569+
for (idx, r) in dialog_button_roles.as_slice().iter().enumerate() {
570+
if *r == *role {
571+
column_for_input.push(idx);
572+
}
573+
}
574+
}
575+
576+
for (input_index, cell) in input_data.as_slice().iter().enumerate() {
577+
let col = column_for_input.iter().position(|&x| x == input_index);
578+
if let Some(col) = col {
579+
organized_data.push_cell(col as u16, cell.colspan, cell.row, cell.rowspan);
580+
} else {
581+
// This is used for the main window (which is the only cell which isn't a button)
582+
// Given lower_dialog_layout(), this will always be a single cell at 0,0 with a colspan of number_of_buttons
583+
organized_data.push_cell(cell.col, cell.colspan, cell.row, cell.rowspan);
584+
}
585+
}
586+
organized_data
587+
}
588+
494589
// Implement "auto" behavior for row/col numbers (unless specified in the slint file).
495-
pub fn organize_grid_layout(core_slice: Slice<GridLayoutInputData>) -> GridLayoutOrganizedData {
496-
let data = core_slice.as_slice();
590+
pub fn organize_grid_layout(input_data: Slice<GridLayoutInputData>) -> GridLayoutOrganizedData {
497591
let mut organized_data = GridLayoutOrganizedData::default();
498-
organized_data.reserve(data.len() * 4);
592+
organized_data.reserve(input_data.len() * 4);
499593
let mut row = 0;
500594
let mut col = 0;
501595
let mut first = true;
502596
let auto = u16::MAX;
503-
for cell in data.iter() {
597+
for cell in input_data.as_slice().iter() {
504598
if cell.new_row && !first {
505599
row += 1;
506600
col = 0;
@@ -753,80 +847,6 @@ pub fn box_layout_info_ortho(cells: Slice<BoxLayoutCellData>, padding: &Padding)
753847
fold
754848
}
755849

756-
/// Given the cells of a layout of a Dialog, re-order the button according to the platform
757-
///
758-
/// This function assume that the `roles` contains the roles of the button which are the first `cells`
759-
/// It will simply change the column field of the cell
760-
pub fn reorder_dialog_button_layout(cells: &mut [GridLayoutCellData], roles: &[DialogButtonRole]) {
761-
fn add_buttons(
762-
cells: &mut [GridLayoutCellData],
763-
roles: &[DialogButtonRole],
764-
idx: &mut u16,
765-
role: DialogButtonRole,
766-
) {
767-
for (cell, r) in cells.iter_mut().zip(roles.iter()) {
768-
if *r == role {
769-
cell.col_or_row = *idx;
770-
*idx += 1;
771-
}
772-
}
773-
}
774-
775-
#[cfg(feature = "std")]
776-
fn is_kde() -> bool {
777-
// assume some Unix, check if XDG_CURRENT_DESKTOP starts with K
778-
std::env::var("XDG_CURRENT_DESKTOP")
779-
.ok()
780-
.and_then(|v| v.as_bytes().first().copied())
781-
.is_some_and(|x| x.eq_ignore_ascii_case(&b'K'))
782-
}
783-
#[cfg(not(feature = "std"))]
784-
let is_kde = || true;
785-
786-
let mut idx = 0;
787-
788-
match crate::detect_operating_system() {
789-
crate::items::OperatingSystemType::Windows => {
790-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reset);
791-
idx += 1;
792-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Accept);
793-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Action);
794-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reject);
795-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Apply);
796-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Help);
797-
}
798-
crate::items::OperatingSystemType::Macos | crate::items::OperatingSystemType::Ios => {
799-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Help);
800-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reset);
801-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Apply);
802-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Action);
803-
idx += 1;
804-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reject);
805-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Accept);
806-
}
807-
_ if is_kde() => {
808-
// KDE variant
809-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Help);
810-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reset);
811-
idx += 1;
812-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Action);
813-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Accept);
814-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Apply);
815-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reject);
816-
}
817-
_ => {
818-
// GNOME variant and fallback for everything else
819-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Help);
820-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reset);
821-
idx += 1;
822-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Action);
823-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Apply);
824-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Reject);
825-
add_buttons(cells, roles, &mut idx, DialogButtonRole::Accept);
826-
}
827-
}
828-
}
829-
830850
#[cfg(feature = "ffi")]
831851
pub(crate) mod ffi {
832852
#![allow(unsafe_code)]
@@ -890,16 +910,4 @@ pub(crate) mod ffi {
890910
) -> LayoutInfo {
891911
super::box_layout_info_ortho(cells, padding)
892912
}
893-
894-
/// Calls [`reorder_dialog_button_layout`].
895-
///
896-
/// Safety: `cells` must be a pointer to a mutable array of cell data, the array must have at
897-
/// least `roles.len()` elements.
898-
#[unsafe(no_mangle)]
899-
pub unsafe extern "C" fn slint_reorder_dialog_button_layout(
900-
cells: *mut GridLayoutCellData,
901-
roles: Slice<DialogButtonRole>,
902-
) {
903-
reorder_dialog_button_layout(core::slice::from_raw_parts_mut(cells, roles.len()), &roles);
904-
}
905913
}

internal/interpreter/eval_layout.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,20 @@ pub(crate) fn organize_grid_layout(
9393
local_context: &mut EvalLocalContext,
9494
) -> Value {
9595
let cells = grid_layout_input_data(layout, local_context);
96-
core_layout::organize_grid_layout(Slice::from_slice(cells.as_slice())).into()
96+
97+
if let Some(buttons_roles) = &layout.dialog_button_roles {
98+
let roles = buttons_roles
99+
.iter()
100+
.map(|r| DialogButtonRole::from_str(r).unwrap())
101+
.collect::<Vec<_>>();
102+
core_layout::organize_dialog_button_layout(
103+
Slice::from_slice(cells.as_slice()),
104+
Slice::from_slice(roles.as_slice()),
105+
)
106+
.into()
107+
} else {
108+
core_layout::organize_grid_layout(Slice::from_slice(cells.as_slice())).into()
109+
}
97110
}
98111

99112
pub(crate) fn solve_grid_layout(

0 commit comments

Comments
 (0)