Menubar overlap with layout.

Started by Kvaz1r, 21 August 2019, 12:58:33

Kvaz1r

I can't found a way to insert space between menu bar and panel with other widgets because without it they overlapped. How to do it correctly?

MCVE:

#include <TGUI/TGUI.hpp>

static auto File = "File";

int main()
{
sf::RenderWindow window(sf::VideoMode(400, 300), "TGUI window");
tgui::Gui gui(window);
auto topLayout = tgui::VerticalLayout::create();
auto panel = tgui::ScrollablePanel::create();
auto grid = tgui::Grid::create();

tgui::MenuBar::Ptr menuBar = tgui::MenuBar::create();
menuBar->addMenu(File);
menuBar->addMenuItem(File, L"New");
menuBar->addMenuItem(File, L"Open");
gui.add(menuBar);
auto box = tgui::CheckBox::create("0");
grid->addWidget(box, 0, 0);
auto box2 = tgui::CheckBox::create("1");
grid->addWidget(box2, 1, 0);
panel->add(grid);
gui.add(grid);
topLayout->add(panel);
gui.add(topLayout);
menuBar->moveToFront();
// Main loop
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();

gui.handleEvent(event); // Pass the event to the widgets
}
window.clear();
gui.draw(); // Draw all widgets
window.display();
}
}

texus

Simply add all widgets other than the menu bar to a group.

Create a group and position it below the menu bar:
Code (cpp) Select
auto group = tgui::Group::create();
group->setPosition(0, menuBar->getSize().y);
gui.add(group);


Remove the lines that add the widgets to the gui
Code (cpp) Select
gui.add(grid);
gui.add(topLayout);


And replace them with adding them to the group:
Code (cpp) Select
group->add(grid);
group->add(topLayout);

Kvaz1r

Thanks it works, I didn't know about group. I looking through tutorials and examples but didn't found anything related to it. When one should use group and not just layouts?

I tried set position only for layout without using group and this works too.   

texus

The Group widget is the most basic container widget (a widget that can contain other widgets). Originally this was the Panel widget but it got split up in Group and Panel where the main difference between the two is that Group has no background color. Despite not calling setSize in my example, the group actually has a size and child widgets that would fall outside the group would be clipped.
The default size of the group is to fill the parent widget 100%, so the code that I gave actually makes the bottom part of the group fall outside of the window (as the group was positioned down a bit to start below the menu bar). This doesn't matter in this case, but if you want to rely on bottom padding then you might want to manually call setSize() on the group as well.

VerticalLayout and HorizontalLayout were contributed by someone who found them useful. They are definitely useful for positioning widgets next to each other or below each other, but I would personally only use them for simple cases like having a couple buttons below each other. The gui mostly relies on manually positioning and sizing widgets (either absolute or relative), but these layout widgets are an exception to this. These widgets try to resize and reposition the widgets that you put inside them automatically. This doesn't always perform ideally and some widgets may not work properly when placed inside a layout widget.

So if you need a container of widgets, which you are going to manually give a position, then use Group. It is useful for e.g. creating multiple screens in your program (with each screen being in a group and only one group shown), position a set of widgets relative to some point (like in your case), etc.
If you have a certain amount of space that you want to divide by a couple of widgets, then you can try to use a layout widget.

QuoteI tried set position only for layout without using group and this works too.
You can choose. You either add menuBar->getSize().y to the position of all widgets added to the gui or you create a new group widget that has this offset and add all widgets to that group. The outcome will be the same (as long as the group is large enough to fill the screen, which it is by default).