Grid and scrollbar

Started by Kvaz1r, 15 June 2021, 12:54:02

Kvaz1r

I have some widgets in grid and not all of them fit inside usual panel. I want to use scrollbar to provide access to widgets so put grid into ScrollablePanel panel. But even with scrollbar policy Always it can't change grid appearance. Does it bug or am I missing something?

MCVE:

#include <TGUI/TGUI.hpp>

class MyFrame
{
public:
    MyFrame(sf::RenderWindow& w, tgui::Gui& g);
    void main();

protected:
    tgui::Grid::Ptr m_grid;
    tgui::TextArea::Ptr m_log;

private:
    void updateLayout();

    sf::RenderWindow& window;
    tgui::Gui& gui;
};

MyFrame::MyFrame(sf::RenderWindow& w, tgui::Gui& g) : window(w), gui(g)
{
    auto panel = tgui::ScrollablePanel::create();
    panel->getRenderer()->setBackgroundColor(sf::Color(200, 200, 200, 255));

    m_grid = tgui::Grid::create();

    for (std::size_t i = 0; i < 20; i++)
    {
        m_grid->addWidget(tgui::Label::create(tgui::String(i)), i, 0, tgui::Grid::Alignment::Center, { 0,10,0,0 });

        auto widget = tgui::EditBox::create();
        widget->setText(tgui::String(i));
        m_grid->addWidget(widget, i, 1, tgui::Grid::Alignment::Center, { 0,10,0,0 });
    }

    panel->add(m_grid);

    m_log = tgui::TextArea::create();
    panel->add(m_log);
    gui.add(panel);
   
    updateLayout();
    panel->setVerticalScrollbarPolicy(tgui::Scrollbar::Policy::Always);
}

void MyFrame::updateLayout()
{
    m_grid->setSize({ "50%","100%" });
    m_log->setSize({ "50%","100%" });

    auto size = window.getSize();
    m_grid->setPosition(0, 0);
    m_log->setPosition(size.x - 0.5 * size.x, 0);
}

void MyFrame::main()
{
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            if (event.type == sf::Event::Resized)
            {
                updateLayout();
            }
            gui.handleEvent(event);
        }

        window.clear();
        gui.draw();
        window.display();
    }
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "MCVE");
    window.setFramerateLimit(60);
    tgui::Gui gui(window);
    MyFrame(window, gui).main();

    return EXIT_SUCCESS;
}

texus

#1
This is because the inner size of the ScrollablePanel never changes when scrollbars are visible or not.
I agree that this isn't ideal and it should probably be changed, but right now it is the expected behavior.

Implementing this properly is a bit tricky: whether scrollbars are shown could depends on the widgets inside the panel, but the size of those widgets would depend on whether there are scrollbars.
So when writing the ScrollablePanel widget I decided to just keep it simple and ignored this case.

Edit: Maybe I could change the inner size when Policy::Always is specified and leave the more difficult case for later.

texus

I think I might even be talking about a different issue, I though the problem was that the horizontal scrollbar appeared and your 50% width wasn't working correctly.

The vertical scrollbar isn't going to work when you set the grid size to 100%. The size of the grid should depend on its contents or be a chosen size, you shouldn't limit it to the viewable area of the scrollable panel (which is what 100% does). You'll want the grid size to be larger than 100%, because otherwise there will never be anything to scroll to. If you don't call m_grid->setSize then you will see that the vertical scrollbar works as intended (the columns in the grid need to be given a different width in that case though as auto-sizing puts the columns too close to each other). If you call "m_grid->setSize({ "50%","150%" });" for example then the vertical scrollbar can scroll to all contents (but you would have to set the policy of the horizontal scrollbar to Never to not overlap with the last edit box due to the issue I described in my previous post). There is no space below the last widget in the grid, but this could be solved by either specifying a bottom margin when adding it to the grid or manually setting the content size to something larger than the grid size (maybe setting a padding in the scrollable panel might also work, I haven't checked).

Issues like this really expose how TGUI started with having everything at fixed coordinates and where relative positions/sizes are just hacked on top of that instead of the library being designed with dynamic sizes in mind.

Kvaz1r

Quote from: texus on 15 June 2021, 19:30:51
The vertical scrollbar isn't going to work when you set the grid size to 100%. The size of the grid should depend on its contents or be a chosen size, you shouldn't limit it to the viewable area of the scrollable panel (which is what 100% does). You'll want the grid size to be larger than 100%, because otherwise there will never be anything to scroll to. If you don't call m_grid->setSize then you will see that the vertical scrollbar works as intended (the columns in the grid need to be given a different width in that case though as auto-sizing puts the columns too close to each other).
Aha, I got it, thanks for the detailed explanation.
For some reason I thought that "100%" it's about relative virtual size and not about real viewable, so expected that container will grows with it's content. Now everything makes sense.