FlexBox required size


#1

Is it possible to add a method like FlexBox::getRequiredSize?

I could really use a method that predicts if the laid out components will overflow the available bounds. Currently I just perform the layout, and then compute the bounding box of the components once their bounds are already changed. Then I extend the bounding box based on the margins of the items on the layout periphery. I feel this procedure really belongs as a FlexBox method. One should be able to check the layout requirements without actually modifying the component bounds.


#2

With FlexBox the idea is that you give the area of the bounding box and the elements inside will adjust their sizes to fit that box, not the other way round.


#3

Thanks, leehu. To clarify, my use case involves a FlexBox component that is also a FlexItem in a parent. It has some bounds to work within, but can request more area by setting the minWidth and minHeight of its FlexItem. You can get some snazzy dynamic layouts like this.

If this should not be encouraged, then I agree it doesn’t belong as a FlexBox method. But here is what I’m doing in case it’s useful to anyone:

// Calling code:
auto newMinimumSize = computeMinimumSize (flexBox, 50, 50);

if (newMinimumSize.x != flexItem.minWidth || newMinimumSize.y != flexItem.minHeight)
{
    flexItem.minWidth  = newMinimumSize.x;
    flexItem.minHeight = newMinimumSize.y;
    layoutCallback (DisplayItemType::Flex); // signal indicating the flex item changed
}

/**
    Computes the size needed to avoid an overflow, but not smaller than the
    given absolute minimums.
*/
Point<float> computeMinimumSize (FlexBox box, float absoluteMinWidth, float absoluteMinHeight)
{
    for (auto& item : box.items)
    {
        item.associatedComponent = nullptr; // no side effects
        item.associatedFlexBox = nullptr;
    }
    box.performLayout (Rectangle<float>()); // squeezes things

    RectangleList<float> layout;

    for (auto& item : box.items)
    {
        layout.add (item.currentBounds
                    .withTrimmedLeft   (-item.margin.left)
                    .withTrimmedRight  (-item.margin.right)
                    .withTrimmedTop    (-item.margin.top)
                    .withTrimmedBottom (-item.margin.bottom));
    }
    auto boundingBox = layout.getBounds();

    return Point<float> (jmax (absoluteMinWidth, boundingBox.getWidth()),
                          jmax (absoluteMinHeight, boundingBox.getHeight()));
}

#4

If using minwidth/minheight it’s best to leave some items to “flex” and therefore they fill up the remaining space available so you can still specify a bounding box and be happy it won’t overflow. this applies to any nested flexboxes.


#5

Whether or not your items include one that flexes, you can still overflow your available area.


#7

yes you can, but that’s more of a trying to cram too much stuff into a space that can’t contain it maybe? If ultimately your top level bounding box is the screen and you can’t fit everything in then something has to give. At that point, calculating the bounds of your stuff isn’t going to help as it’s larger than the screen.

I think I don’t really understand what you’re requirements are as you seem to be approaching things opposite to how I deal with them as i ask “given this area (i.e. the screen) layout everything in it” and you’re asking “given these elements, how much screen estate do I need”. Can’t really suggest anything there :slight_smile: