StretchableLayoutManager stretches last element beyond its max size

If you add items to a StretchableLayoutManager, it will stretch the last element beyond its maximum size. I find that in most cases, if all components have reached their maximum size, I would prefer there to be empty space beyond the last element. This can be achieved by commenting out the following:

void StretchableLayoutManager::layOutComponents (Component** const components,
                                                 int numComponents,
                                                 int x, int y, int w, int h,
                                                 const bool vertically,
                                                 const bool resizeOtherDimension)
{
    setTotalSize (vertically ? h : w);
    int pos = vertically ? y : x;
    for (int i = 0; i < numComponents; ++i)
    {
        if (const ItemLayoutProperties* const layout = getInfoFor (i))
        {
            if (Component* const c = components[i])
            {
//                if (i == numComponents - 1)
//                {
//                    // if it's the last item, crop it to exactly fit the available space..
//                    if (resizeOtherDimension)
//                    {
//                        if (vertically)
//                            c->setBounds (x, pos, w, jmax (layout->currentSize, h - pos));
//                        else
//                            c->setBounds (pos, y, jmax (layout->currentSize, w - pos), h);
//                    }
//                    else
//                    {
//                        if (vertically)
//                            c->setBounds (c->getX(), pos, c->getWidth(), jmax (layout->currentSize, h - pos));
//                        else
//                            c->setBounds (pos, c->getY(), jmax (layout->currentSize, w - pos), c->getHeight());
//                    }
//                }
//                else
                {
                    if (resizeOtherDimension)
                    {
                        if (vertically)
                            c->setBounds (x, pos, w, layout->currentSize);
                        else
                            c->setBounds (pos, y, layout->currentSize, h);
                    }
                    else
                    {
                        if (vertically)
                            c->setBounds (c->getX(), pos, c->getWidth(), layout->currentSize);
                        else
                            c->setBounds (pos, c->getY(), layout->currentSize, c->getHeight());
                    }
                }
            }
            pos += layout->currentSize;
        }
    }
}

It would also be nice to have some control over the space inbetween the components, although I'm aware that this could be achieved with blank components.

Joe.

Well that might work for you, but a change like that would of course break all the existing code that uses that class!

(TBH that's an old class that I rarely use nowadays, and I'm planning to replace it with something better, so I'm not planning to spend much time worrying about the details of its implementation at the moment)

Fair enough, it's a preference thing really. I look forward to the 'something better'!

Why not just pass just a empty component, as last object.

Actually, the last element can get stretched past its maximum size even when other elements are not at their maximum. I made a GUI project using IntroJucer on v3.2.0. Here's my code:

main.cpp: I made the window resizable

        MainWindow (String name)  : DocumentWindow (name,
                                                    Colours::lightgrey,
                                                    DocumentWindow::allButtons)
        {
            setUsingNativeTitleBar (true);
            setResizable(true, false);     // Added this line, rest is Introjucer-generated
            setContentOwned (new MainContentComponent(), true);

            centreWithSize (getWidth(), getHeight());
            setVisible (true);
        }

MainComponent.h:

class MainContentComponent   : public Component
{
public:
    //==============================================================================
    MainContentComponent();
    ~MainContentComponent();

    void resized();

private:
    ScopedPointer<DocumentWindow>    m_window1;
    ScopedPointer<DocumentWindow>    m_window2;
    ScopedPointer<StretchableLayoutResizerBar>        m_bar;
    StretchableLayoutManager        m_manager;

    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

MainComponent.cpp

MainContentComponent::MainContentComponent()
{
    setSize (600, 400);
    
    m_window1 = new DocumentWindow("Doc 1", Colours::red, 0, false);
    m_window2 = new DocumentWindow("Doc 2", Colours::green, 0, false);
    
    m_window1->setBounds(0, 0, 290, getHeight());
    addAndMakeVisible(m_window1);

    m_window2->setBounds(310, 0, 290, getHeight());
    addAndMakeVisible(m_window2);
    
    m_bar = new StretchableLayoutResizerBar(&m_manager, 1, true);
    m_bar->setBounds(290, 0, 20, getHeight());
    addAndMakeVisible(m_bar);
    
    m_manager.setItemLayout(0, 100, 5000, 290);
    m_manager.setItemLayout(1, 20, 20, 20);
    m_manager.setItemLayout(2, 100, 300, 290);
}

MainContentComponent::~MainContentComponent()
{
}

void MainContentComponent::resized()
{
    Component* comps[] = {m_window1, m_bar, m_window2};
    m_manager.layOutComponents(comps, 3, 0, 0, getWidth(), getHeight(), false, true);
}

The first embedded window has essentially no limit on its size, while the second is limited to a max of 300. I run the app, widen the main window, and both embedded windows get wider when only the first should. Then I drag the divider bar and it snaps to the right, where it should have been.

-Marc