This object computes a minimum, desired and maximum column width for each of its children. For each of these values it takes the maximum for all of its children. It then computes its own width as (maxChildWidth*nColumns)+(gutter*(nColumns-1)). It does this separately for min, desired and max.
The column width of a child object is the same as its own respective min, desired or max width if its columnSpan is 1. If its columnSpan is greater than 1 then its column width is
(myWidth-(columnSpan-1)*gutter)/columnSpan)
When Columns receives its width range it will compute a column width of (width-(nColumns-1)*gutter)/nColumns). Using this width, it will lay out all of its children in rows, giving each the width specified by its columnSpan attribute. If the column width is less than the minimum for some child, then it is given more columns until it has enough. If the total width is not enough then that child is given a row of its own and all the columns in that row. If it has more children than fit in nColumns it will wrap them onto new rows. It will now know how many rows it needs and which children are in each row.
When requested for its height information it will use the min, desired and max height information of its children to compute the height of each row and report the sum of the heights of the rows.
When it gets its height bounds, it will use the min,desired, and max values for the children in each row to determine how much of the vertical space to give to each row. This is then set as the height for each object in a row.
Root{ contents:[ HStack{ contents:[ Button{ label:"Long label", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20}, model: ["val"], value:4 } ] } ], model:{ val:10, size:20 } }
Root{ contents:[ HStack{ contents:[ Button{ label:"Long label", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20}, model: ["val"], value:4 }, Button{ label:"Short", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20}, model: ["val"], value:5 }, ScrollH{ state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20}, model: ["size"],min:0, max:50 } ] } ], model:{ val:10, size:20 } }
Root{ contents:[ VStack{ contents:[ Button{ label:"Long label", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} }, Button{ label:"Short", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} }, ScrollH{ state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} }, ScrollV{ state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} } ] } ] }
Root{ contents:[ Columns{ contents:[ Button{ label:"Long label", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} }, Button{ label:"Short", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} }, Button{ label:"Hey this is long", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20} }, Button{ label:"wide", state:"idle",idle:{r:128,g:128,b:128}, hover:{r:200,g:200,b:200}, active:{r:250,g:250,b:20}, columnSpan:2 } ], nColumns:3, gutter:20 } ] }