11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4-
54using WinMan ;
65
76namespace FancyWM . Layouts
@@ -12,29 +11,67 @@ public class GridLayout(int spacing) : ILayoutFunction
1211
1312 public IReadOnlyList < Rectangle > Execute ( Rectangle availableArea , IEnumerable < Constraints > constraints )
1413 {
15- bool isHorizontal = availableArea . Width >= availableArea . Height ;
14+ var ( rows , columns ) = CalculateGridDimensions ( constraints . Count ( ) , availableArea . Width , availableArea . Height ) ;
15+
16+ var constraintList = constraints . ToList ( ) ;
17+ var result = new List < Rectangle > ( ) ;
1618
17- var count = constraints . Count ( ) ;
18- var root = ( int ) Math . Round ( Math . Sqrt ( count ) ) ;
19+ if ( constraintList . Count == 0 )
20+ {
21+ return result ;
22+ }
1923
20- var w = ( availableArea . Width - Spacing * ( root + 1 ) ) / root ;
21- var h = ( availableArea . Height - Spacing * ( root + 1 ) ) / root ;
24+ double cellWidth = ( double ) availableArea . Width / columns ;
25+ double cellHeight = ( double ) availableArea . Height / rows ;
2226
23- List < Rectangle > rects = [ ] ;
24- for ( int i = 0 ; i < w ; i ++ )
27+ for ( int i = 0 ; i < constraintList . Count ; i ++ )
2528 {
26- for ( int j = 0 ; j < h ; j ++ )
29+ if ( i >= rows * columns )
2730 {
28-
31+ break ;
2932 }
33+
34+ int row = i / columns ;
35+ int col = i % columns ;
36+
37+ int slotLeft = availableArea . Left + ( int ) ( col * cellWidth ) ;
38+ int slotRight = ( col == columns - 1 )
39+ ? availableArea . Right
40+ : availableArea . Left + ( int ) ( ( col + 1 ) * cellWidth ) ;
41+
42+ int slotTop = availableArea . Top + ( int ) ( row * cellHeight ) ;
43+ int slotBottom = ( row == rows - 1 )
44+ ? availableArea . Bottom
45+ : availableArea . Top + ( int ) ( ( row + 1 ) * cellHeight ) ;
46+
47+ int left = slotLeft + ( col == 0 ? Spacing : Spacing / 2 ) ;
48+ int right = slotRight - ( col == columns - 1 ? Spacing : Spacing / 2 ) ;
49+ int top = slotTop + ( row == 0 ? Spacing : Spacing / 2 ) ;
50+ int bottom = slotBottom - ( row == rows - 1 ? Spacing : Spacing / 2 ) ;
51+
52+ result . Add ( new Rectangle (
53+ left : Math . Min ( left , right ) ,
54+ top : Math . Min ( top , bottom ) ,
55+ bottom : Math . Max ( top , bottom ) ,
56+ right : Math . Max ( left , right )
57+ ) ) ;
58+ }
59+
60+ return result ;
61+ }
62+
63+ private ( int rows , int columns ) CalculateGridDimensions ( int count , int width , int height )
64+ {
65+ int a = 1 ;
66+ while ( a * a < count ) a ++ ;
67+ int b = ( count + a - 1 ) / a ;
68+
69+ if ( width > height && a >= b )
70+ {
71+ ( b , a ) = ( a , b ) ;
3072 }
3173
32- return constraints . Select ( ( rect , index ) => Rectangle . OffsetAndSize (
33- left : availableArea . Left + ( w * index ) + Spacing * ( index + 1 ) ,
34- top : availableArea . Top + Spacing ,
35- width : w ,
36- height : h - 2 * Spacing
37- ) ) . ToArray ( ) ;
74+ return ( a , b ) ;
3875 }
3976 }
4077}
0 commit comments