StretchableLayoutManager misbehaves with 0-sized layouts


#1

Hi there,

I’m experimenting with the StretchableLayoutManager component on a simple layout, made of two vertical cells and a resizer bar (StretchableLayoutResizerBar) in the middle.

During the initial setup, If I try to initialize the layout with an invisible cell, like that:
... layout.setItemLayout(0, 20, -1, -0.3); // left cell, preferred size = 30% layout.setItemLayout(1, 20, 20, 20); // resizer bar, preferred size = 20px layout.setItemLayout(2, 0, 0, 0); // right cell, initially invisible ...

The right cell is still visible on startup (and it shouldn’t) and then the left one can’t fill up the entire space as supposed. Dragging the resizer bar around fixes the issue, so I guess It’s a matter of how elements’ widths are computed internally in setItemLayout().

Having a 0-sized layout would be useful when you want to programmatically show or hide some cells, but maybe I’m on the wrong track. Any ideas on that?

Here is small project that reproduces the issue (just remove the .txt extension): NewProject.zip.txt (4.5 KB)


#2

Hey!

I initialized the layout in your project in the following way and it worked:

layout.setItemLayout(0, 1, -1, -1); layout.setItemLayout(1, 20, 20, 20); layout.setItemLayout(2, 1, -1, 0);

The first cell’s preferred size is 100% and the second cell’s preferred size is 0 so this will achieve the initial setup you had in mind. I also set the minimum for both cell’s to 1 and the maximum to 100% so that you can drag them around freely (it behaves weirdly if the minimum is set to 0, I’ll look more into it to find out why)


#3

Hi luigisambuy,

Thanks for your feedback, your suggestion worked like a charm! However in my opinion it would be really great to use any other percentage (< 100%) for the visible cell and let it fill up the space anyway, in case the other one has preferred size == 0. Why? E.g. when you want to hide a cell through a button press, and the other one is obviously not set to 100%. Sure, in case of a simple 2-cell layout you could manually set the width of the other cell to 100%, but things get quite hard with more complex layouts, where you have more than 2 cell to manage…

I’ve updated the test project to show what I mean. NewProject.zip.txt (4.3 KB)

Thanks again for your time :slight_smile:


#4

I think it’s a good idea to explicitly set the suggested widths for every elements then. I noticed that if the sum of all suggested widths doesn’t add up properly the StretchableLayoutManager will workout an average rather than move your single cell in the position where you thought it would.

How many cells do you plan to use? I re-wrote MainComponent for a scenario where you have 3 cells and 2 bars, if you press the button the right cell then gets minimized. I wrote a initialize function that is called on the constructor and on the buttonClicked callback. Does this help?

int APP_WIDTH = 600;


MainContentComponent::MainContentComponent()
  : bar(&layout, 1, true), barTwo(&layout, 3, true)
{
    addAndMakeVisible(left);
    addAndMakeVisible(bar);
    addAndMakeVisible(center);
    addAndMakeVisible(barTwo);
    addAndMakeVisible(right);
    
    addAndMakeVisible(button);
    button.addListener(this);
    
    initialize();

    setSize (APP_WIDTH, 400);
}

MainContentComponent::~MainContentComponent()
{
}

void MainContentComponent::resized()
{
    Component* comps[] = {
        &left,
        &bar,
        &center,
        &barTwo,
        &right
    };
    layout.layOutComponents(comps, 5, 0, 0, getWidth(), getHeight()-40, false, true);
    
    button.setBounds(getWidth()-40, getHeight()-40, 40, 40);
}

void MainContentComponent::buttonClicked(Button* button)
{
    initialize();
    resized();
}

void MainContentComponent::initialize()
{
    layout.setItemLayout(0, 1, -1, (APP_WIDTH - 40) / 2);
    layout.setItemLayout(1, 20, 20, 20);
    layout.setItemLayout(2, 1, -1, (APP_WIDTH - 40) / 2);
    layout.setItemLayout(3, 20, 20, 20);
    layout.setItemLayout(4, 1, -1, -0); // Right cell is minimized
}

#5

Great, it definitely helped. So the trick here is to compute the widths of other layouts (as you did with (APP_WIDTH - 40) / 2) when one is hidden. Thanks for the hint!