sproutcore/sproutcore — pull request #1227 by mirion (2014-05-05 14:12:57+00:00)
Title: Horizontal and vertical stack layouts should let any child fill the available space

The current implementation of HORIZONTAL_STACK and VERTICAL_STACK allows the last child to fill the empty space. This is very restrictive and we often need to resize some other the children. For example, a layout like an window title bar: buttons, title, buttons. The title, at the middle of the bar should display as much text as possible, but in the same time the buttons are mandatory having fixed width. Another example, a vertical layout: some section title, master list (table), children list, footer. In this case, the available space should be shared by the two lists preserving also a proportion between their heights.

This pull request introduces another parameter, "fillAvailableSpaceRatio" that is used to define the proportion of empty, not provisioned space that is taken by the child view. Of course, this parameter is only used when the container view is not configured with resizeToFit.

The layout algorithm:
Step 1. Pass through all child views and verify that there is a width/maxWidth defined or fillAvailableSpaceRatio.
+ if width defined, this is just counted so we know exactly what is provisioned
+ otherwise, if fillAvailableSpaceRatio is defined, we add it to a total ratio variable so in the end we are able to know for each child the proportion of empty space that should be allocated
+ otherwise, if minWidth is defined, handle it as width
+ otherwise, log an error and exit

At the end of step 1, we have:
+ the provisioned space
+ the available space (not yet provisioned: autoFillAvailableSpace)
+ the cumulative value of fillAvailableSpaceRatio (totalFillAvailableSpaceRatio)

Step 2. Pass again through all children and:
+ if width defined, position as in the previous algorithm, left
+ otherwise, if fillAvailableSpaceRatio defined, calculate the width using a simple formula: autoFillAvailableSpace * fillAvailableSpaceRatio / totalFillAvailableSpaceRatio, then position left/right
+ otherwise, if minWidth defined, use it as width and position left

The code is commented and easy to understand. Of course, we could bring refinements like mixing the minimum dimensions and fillAvailableSpaceRatio, but let's avoid the mission creep. Will bring it probably later, into another commit.