@@ -88,48 +88,9 @@ protected override Size ArrangeOverride(Size finalSize)
8888 var elements = Children . Where ( static e => e . Visibility is Visibility . Visible ) ;
8989 foreach ( var row in _rowSpecs )
9090 {
91- var spacingTotalSize = uvSpacing . U * ( row . ItemsCount - 1 ) ;
92- var remainingSpace = uvFinalSize . U - row . ReservedSpace - spacingTotalSize ;
93- var portionSize = row . MinPortionSize ;
94-
95- // Determine if the desired alignment is stretched.
96- bool stretch = GetAlignment ( ) is Alignment . Stretch && ! double . IsInfinity ( uvFinalSize . U ) ;
97-
98- // Calculate portion size if stretching
99- // Same logic applies for matching row lengths, since the size was determined during measure
100- if ( stretch || FixedRowLengths )
101- {
102- portionSize = remainingSpace / row . PortionsSum ;
103- }
104-
105- // Reset U position
106- pos . U = 0 ;
107-
108- // Adjust the starting position if not stretching
109- // Also do this if there are no star-sized items in the row/column
110- // and no forced streching is in use.
111- if ( ! stretch || ( row . PortionsSum is 0 && ForcedStretchMethod is ForcedStretchMethod . None ) )
112- {
113- // Determine the offset based on alignment
114- var rowSize = row . Measure ( uvSpacing . U ) ;
115- pos . U = GetStartByAlignment ( GetAlignment ( ) , rowSize , uvFinalSize . U ) ;
116- }
117-
118- // Set a flag for if the row is being forced to stretch
119- bool forceStrech = row . PortionsSum is 0 && ForcedStretchMethod is not ForcedStretchMethod . None ;
120-
121- // Setup portionSize for forced stretching
122- if ( forceStrech )
123- {
124- portionSize = ForcedStretchMethod switch
125- {
126- ForcedStretchMethod . First => remainingSpace + GetChildSize ( elements . ElementAt ( 0 ) ) ,
127- ForcedStretchMethod . Last => remainingSpace + GetChildSize ( elements . ElementAt ( row . ItemsCount - 1 ) ) ,
128- ForcedStretchMethod . Equal => ( uvFinalSize . U - spacingTotalSize ) / row . ItemsCount ,
129- ForcedStretchMethod . Equal or ForcedStretchMethod . Proportional => ( uvFinalSize . U - spacingTotalSize ) / row . ReservedSpace ,
130- _ => row . MinPortionSize ,
131- } ;
132- }
91+ // Setup the row/column for arrangement
92+ var ( uPos , portionSize , forceStrech ) = SetupArrangeRow ( row , uvFinalSize , uvSpacing , elements ) ;
93+ pos . U = uPos ;
13394
13495 for ( int i = 0 ; i < row . ItemsCount ; i ++ )
13596 {
@@ -143,51 +104,14 @@ protected override Size ArrangeOverride(Size finalSize)
143104 return finalSize ;
144105 }
145106
146- // Get layout and desired size
147- var layoutLength = GetLayoutLength ( child ) ;
148- var uvDesiredSize = new UVCoord ( child . DesiredSize , Orientation ) ;
149-
150- // Override the layout based on the forced stretch method if necessary
151- if ( forceStrech )
152- {
153- var oneStar = new GridLength ( 1 , GridUnitType . Star ) ;
154- layoutLength = ForcedStretchMethod switch
155- {
156- ForcedStretchMethod . First when i is 0 => oneStar ,
157- ForcedStretchMethod . Last when i == ( row . ItemsCount - 1 ) => oneStar ,
158- ForcedStretchMethod . Equal => oneStar ,
159- ForcedStretchMethod . Proportional => layoutLength . GridUnitType switch
160- {
161- GridUnitType . Auto => new GridLength ( uvDesiredSize . U , GridUnitType . Star ) ,
162- GridUnitType . Pixel or _ => new GridLength ( layoutLength . Value , GridUnitType . Star ) ,
163- } ,
164-
165- // If the above conditions aren't met, do nothing
166- _ => layoutLength ,
167- } ;
168- }
169-
170- // Determine the child's U size
171- double uSize = layoutLength . GridUnitType switch
172- {
173- GridUnitType . Auto => uvDesiredSize . U ,
174- GridUnitType . Pixel => layoutLength . Value ,
175- GridUnitType . Star => layoutLength . Value * portionSize ,
176- _ => uvDesiredSize . U ,
177- } ;
178-
179- // Arrange the child
180- var size = new UVCoord ( 0 , 0 , Orientation )
181- {
182- U = uSize ,
183- V = row . MaxOffAxisSize
184- } ;
107+ // Determine the child's size
108+ var size = GetChildSize ( child , i , row , portionSize , forceStrech ) ;
185109
186110 // NOTE: The arrange method is still in X/Y coordinate system
187111 child . Arrange ( new Rect ( pos . X , pos . Y , size . X , size . Y ) ) ;
188112
189113 // Advance the position
190- pos . U += uSize + uvSpacing . U ;
114+ pos . U += size . U + uvSpacing . U ;
191115 }
192116
193117 // Advance to the next row/column
@@ -196,6 +120,94 @@ protected override Size ArrangeOverride(Size finalSize)
196120
197121 return finalSize ;
198122 }
123+ private ( double uPos , double portionSize , bool forceStretch ) SetupArrangeRow ( RowSpec row , UVCoord uvFinalSize , UVCoord uvSpacing , IEnumerable < UIElement > elements )
124+ {
125+ double uPos = 0 ;
126+
127+ var spacingTotalSize = uvSpacing . U * ( row . ItemsCount - 1 ) ;
128+ var remainingSpace = uvFinalSize . U - row . ReservedSpace - spacingTotalSize ;
129+ var portionSize = row . MinPortionSize ;
130+
131+ // Determine if the desired alignment is stretched.
132+ bool stretch = GetAlignment ( ) is Alignment . Stretch && ! double . IsInfinity ( uvFinalSize . U ) ;
133+
134+ // Calculate portion size if stretching
135+ // Same logic applies for matching row lengths, since the size was determined during measure
136+ if ( stretch || FixedRowLengths )
137+ {
138+ portionSize = remainingSpace / row . PortionsSum ;
139+ }
140+
141+ // Adjust the starting position if not stretching
142+ // Also do this if there are no star-sized items in the row/column
143+ // and no forced streching is in use.
144+ if ( ! ( stretch || FixedRowLengths ) || ( row . PortionsSum is 0 && ForcedStretchMethod is ForcedStretchMethod . None ) )
145+ {
146+ var rowSize = row . Measure ( uvSpacing . U ) ;
147+ uPos = GetStartByAlignment ( GetAlignment ( ) , rowSize , uvFinalSize . U ) ;
148+ }
149+
150+ // Set a flag for if the row is being forced to stretch
151+ bool forceStretch = row . PortionsSum is 0 && ForcedStretchMethod is not ForcedStretchMethod . None ;
152+
153+ // Setup portionSize for forced stretching
154+ if ( forceStretch )
155+ {
156+ portionSize = ForcedStretchMethod switch
157+ {
158+ ForcedStretchMethod . First => remainingSpace + GetChildSize ( elements . ElementAt ( 0 ) ) ,
159+ ForcedStretchMethod . Last => remainingSpace + GetChildSize ( elements . ElementAt ( row . ItemsCount - 1 ) ) ,
160+ ForcedStretchMethod . Equal => ( uvFinalSize . U - spacingTotalSize ) / row . ItemsCount ,
161+ ForcedStretchMethod . Equal or ForcedStretchMethod . Proportional => ( uvFinalSize . U - spacingTotalSize ) / row . ReservedSpace ,
162+ _ => row . MinPortionSize ,
163+ } ;
164+ }
165+
166+ return ( uPos , portionSize , forceStretch ) ;
167+ }
168+
169+ private UVCoord GetChildSize ( UIElement child , int rowIndex , RowSpec row , double portionSize , bool forceStretch )
170+ {
171+ // Get layout and desired size
172+ var layoutLength = GetLayoutLength ( child ) ;
173+ var uvDesiredSize = new UVCoord ( child . DesiredSize , Orientation ) ;
174+
175+ // Override the layout based on the forced stretch method if necessary
176+ if ( forceStretch )
177+ {
178+ var oneStar = new GridLength ( 1 , GridUnitType . Star ) ;
179+ layoutLength = ForcedStretchMethod switch
180+ {
181+ ForcedStretchMethod . First when rowIndex is 0 => oneStar ,
182+ ForcedStretchMethod . Last when rowIndex == ( row . ItemsCount - 1 ) => oneStar ,
183+ ForcedStretchMethod . Equal => oneStar ,
184+ ForcedStretchMethod . Proportional => layoutLength . GridUnitType switch
185+ {
186+ GridUnitType . Auto => new GridLength ( uvDesiredSize . U , GridUnitType . Star ) ,
187+ GridUnitType . Pixel or _ => new GridLength ( layoutLength . Value , GridUnitType . Star ) ,
188+ } ,
189+
190+ // If the above conditions aren't met, do nothing
191+ _ => layoutLength ,
192+ } ;
193+ }
194+
195+ // Determine the child's U size
196+ double uSize = layoutLength . GridUnitType switch
197+ {
198+ GridUnitType . Auto => uvDesiredSize . U ,
199+ GridUnitType . Pixel => layoutLength . Value ,
200+ GridUnitType . Star => layoutLength . Value * portionSize ,
201+ _ => uvDesiredSize . U ,
202+ } ;
203+
204+ // Return the final size
205+ return new UVCoord ( 0 , 0 , Orientation )
206+ {
207+ U = uSize ,
208+ V = row . MaxOffAxisSize
209+ } ;
210+ }
199211
200212 private static double GetStartByAlignment ( Alignment alignment , double size , double availableSize )
201213 {
@@ -391,7 +403,7 @@ public UVCoord(Size size, Orientation orientation) : this(size.Width, size.Heigh
391403 public double U
392404 {
393405 readonly get => _horizontal ? X : Y ;
394- set
406+ set
395407 {
396408 if ( _horizontal )
397409 {
0 commit comments