Bug with alignItems in FlexBox -- incorrect resize behavior


#1

NOTE: It seems new users can only post one screenshot. I left the descriptions, and removed the other two screenshots. It should be sufficient.

EDIT: I guess with this screenshot alone it is hard to see, but there should be four items in there. The demo is not modified.

Hello,
I am working on a product that uses JUCE. We rely on the FlexBox component, and I found an odd behavior that I believe is a bug. It seems to happen with the demo, so I will just use that for my description.

The issue is with alignItems. To reproduce, you have to set all items to alignSelf::autoAlign. For the FlexBox itself, you can see the options I defined in each screenshot. Note that the issue only occurs with column as direction.

In the first screenshot, if I set align-items to ‘stretch’, the items don’t stretch as they should. (note that they do stretch if the direction is ‘row’.

In the second screenshot, align-items is set to flex-end, and the items just get spaced vertically (and some items disappear). If I resize the window vertically, the items don’t move, but if I resize it horizontally, the spacing vertically contracts/expands (opposite of what it should be).

The third screenshot just shows center, which also behaves as in the second screenshot.

It seems to me that somewhere in the resize function the wrong axis is being used for the calculation, but I don’t know that I can spend the time to debug this right now. I wanted to see if this was a known issue, and if people could reproduce it (just apply the same settings to the flexbox demo.

Please let me know if anyone experiences the same behavior, and whether it is indeed a bug. Thank you in advance.


#2

Hey guys, I didn’t get a reply so I don’t really know if anybody is bothered by this, but I did fix it in juce. Please see the code below (I did it quickly, so I don’t know if it breaks something–I will double-check Tomorrow. It does fix all of the broken behaviors. Basically, I just had to fix cases with isRowDirection…I am not sure if that was the way to do it, but it does work ™.

Hopefully this can be fixed in juce. I will apply this fix in our own builds in the meantime. Cheers.

void alignItemsInCrossAxisInLinesPerAlignItems() noexcept
{
    for (int row = 0; row < numberOfRows; ++row)
    {
        const auto numColumns = lineInfo[row].numItems;
        const auto lineSize = lineInfo[row].crossSize;

        for (int column = 0; column < numColumns; ++column)
        {
            auto& item = getItem (column, row);

            if (item.item->alignSelf == FlexItem::AlignSelf::autoAlign)
            {
                if (owner.alignItems == FlexBox::AlignItems::stretch)
                {
                    item.lockedMarginTop = item.item->margin.top;

                    if (isRowDirection)
                    {
                      item.setHeightChecked(lineSize - item.item->margin.top - item.item->margin.bottom);
                    }
                    else
                    {
                      item.setWidthChecked(lineSize - item.item->margin.left - item.item->margin.right);
                    }
                }
                else if (owner.alignItems == FlexBox::AlignItems::flexStart)
                {
                    item.lockedMarginTop = item.item->margin.top;
                }
                else if (owner.alignItems == FlexBox::AlignItems::flexEnd)
                {
                  if (isRowDirection)
                  {
                    item.lockedMarginTop = lineSize - item.lockedHeight - item.item->margin.bottom;
                  }
                  else
                  {
                    item.lockedMarginLeft = lineSize - item.lockedWidth - item.item->margin.right;
                  }
                }
                else if (owner.alignItems == FlexBox::AlignItems::center)
                {
                  if (isRowDirection)
                  {
                    item.lockedMarginTop = (lineSize - item.lockedHeight - item.item->margin.top - item.item->margin.bottom) / 2;
                  }
                  else
                  {
                    item.lockedMarginLeft = (lineSize - item.lockedWidth - item.item->margin.left - item.item->margin.right) / 2;
                  }
                }
            }
        }
    }

#3

Thanks for the heads-up - we’d seen this but hadn’t got around to investigating yet. I’ll take a look at your suggestion shortly!


#4

Sounds good. I’m just glad it’s working now :wink: