@@ -137,16 +137,24 @@ where
137137 //
138138 // We use the maximum cross length obtained in the first pass as the maximum
139139 // cross limit.
140+ //
141+ // We can defer the layout of any elements that have a fixed size in the main axis,
142+ // allowing them to use the cross calculations of the next pass.
140143 if cross_compress && some_fill_cross {
141144 for ( i, ( child, tree) ) in items. iter ( ) . zip ( trees. iter_mut ( ) ) . enumerate ( )
142145 {
143- let ( fill_main_factor , fill_cross_factor ) = {
146+ let ( main_size , cross_size ) = {
144147 let size = child. as_widget ( ) . size ( ) ;
145148
146- axis. pack ( size. width . fill_factor ( ) , size. height . fill_factor ( ) )
149+ axis. pack ( size. width , size. height )
147150 } ;
148151
149- if fill_main_factor == 0 && fill_cross_factor != 0 {
152+ if main_size. fill_factor ( ) == 0 && cross_size. fill_factor ( ) != 0 {
153+ if let Length :: Fixed ( main) = main_size {
154+ available -= main;
155+ continue ;
156+ }
157+
150158 let ( max_width, max_height) = axis. pack ( available, cross) ;
151159
152160 let child_limits =
@@ -176,9 +184,9 @@ where
176184 } ;
177185
178186 // THIRD PASS
179- // We only have the elements that are fluid in the main axis left .
187+ // We lay out the elements that are fluid in the main axis.
180188 // We use the remaining space to evenly allocate space based on fill factors.
181- for ( i, ( child, tree) ) in items. iter ( ) . zip ( trees) . enumerate ( ) {
189+ for ( i, ( child, tree) ) in items. iter ( ) . zip ( trees. iter_mut ( ) ) . enumerate ( ) {
182190 let ( fill_main_factor, fill_cross_factor) = {
183191 let size = child. as_widget ( ) . size ( ) ;
184192
@@ -224,10 +232,43 @@ where
224232 }
225233 }
226234
235+ // FOURTH PASS (conditional)
236+ // We lay out any elements that were deferred in the second pass.
237+ // These are elements that must be compressed in their cross axis and have
238+ // a fixed length in the main axis.
239+ if cross_compress && some_fill_cross {
240+ for ( i, ( child, tree) ) in items. iter ( ) . zip ( trees) . enumerate ( ) {
241+ let ( main_size, cross_size) = {
242+ let size = child. as_widget ( ) . size ( ) ;
243+
244+ axis. pack ( size. width , size. height )
245+ } ;
246+
247+ if cross_size. fill_factor ( ) != 0 {
248+ let Length :: Fixed ( main) = main_size else {
249+ continue ;
250+ } ;
251+
252+ let ( max_width, max_height) = axis. pack ( main, cross) ;
253+
254+ let child_limits =
255+ Limits :: new ( Size :: ZERO , Size :: new ( max_width, max_height) ) ;
256+
257+ let layout =
258+ child. as_widget ( ) . layout ( tree, renderer, & child_limits) ;
259+ let size = layout. size ( ) ;
260+
261+ cross = cross. max ( axis. cross ( size) ) ;
262+
263+ nodes[ i] = layout;
264+ }
265+ }
266+ }
267+
227268 let pad = axis. pack ( padding. left , padding. top ) ;
228269 let mut main = pad. 0 ;
229270
230- // FOURTH PASS
271+ // FIFTH PASS
231272 // We align all the laid out nodes in the cross axis, if needed.
232273 for ( i, node) in nodes. iter_mut ( ) . enumerate ( ) {
233274 if i > 0 {
0 commit comments