@@ -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()
458457pub 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" ) ]
831851pub ( 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}
0 commit comments