Original Post
hi there, I'm trying to build a basic layout manager that arranges components in a grid and takes into account there maximum and minimum widths so that there size can be determined from thier containers size. they way I currently do this is by calculating the preferred size of the column i.e. containerWidth / nColumns, so if the container width was 100 and there were 2 columns then the preferred size for each of them would be 50, but because the components can have a maximum and minimum width it makes things more complex. I now loop through each column and check if its minimum width is greater than the preferred size, ifso then I calculate the new preferred size for the rest of the columns, by: (containerWidth - columnMinWidth) / (nColumns-1) and call the function recursively: this function takes an array of the columns minimum width(minWidths), and distributes the space evenly taking this array into account, the main problem is its inefficiency, using unessesary recursive calls - eg. if the column min widths were: 100, 50, 50 resp. and the container size was 200:
void arrangeSizes(std::vector<unsigned>& finalSizes, const
std::vector<unsigned>& minSizes, std::vector<bool>& hasSpace, unsigned&
remainingUnits, unsigned& remainingSize, unsigned& preferredSize)
{
// for all columns
for(unsigned i = 0; i < hasSpace.size(); ++i)
{
if(!hasSpace)
continue;
if(minSizes > preferredSize)
{
// if this columns min width is greater than the preferred size
// then need to adjust the preferred size for the rest of the
// columns and call this function again
// this column no longer has space available
hasSpace = false;
// one less column
--remainingUnits;
finalSizes = minSizes;
//
remainingSize -= minSizes;
if(remainingUnits != 0)
preferredSize = remainingSize / remainingUnits;
arrangeSizes(finalSizes, minSizes, hasSpace, remainingUnits, remainingSize, preferredSize);
}
else
{
finalSizes = preferredSize;
}
}
unsigned preferredWidth = containerWidth / nColumns = 200 / 3 = 66
arrangeSizes({0, 0, 0}, {100, 50, 50}, {true, true, true}, 3, 200, 66);
// first recursive call:
arrangeSizes({100, 0, 0}, {100, 50, 50}, {false, true, true}, 2, 100, 50);
when the second function call above^ returns it will set the values 50 and 50 of the last two columns again when they have already been set. Anyway, I was looking for a more efficient way of doing this, I think there could be an eaiser way involving assigning weights to each column and just normalizing but I haven't found it yet, if anyone has any experience in building layout managers I'd greatly appreciate your help.