Recent Posts

Pages: [1] 2 3 ... 10
1
Help requests / Re: Menubar overlap with layout.
« Last post by texus on Yesterday at 23:06:50 »
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.

Quote
I 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).
2
Help requests / Re: Menubar overlap with layout.
« Last post by Kvaz1r on Yesterday at 19:37:48 »
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.   
3
Help requests / Re: Menubar overlap with layout.
« Last post by texus on Yesterday at 18:17:34 »
Simply add all widgets other than the menu bar to a group.

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

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

And replace them with adding them to the group:
group->add(grid);
group->add(topLayout);
4
Help requests / Menubar overlap with layout.
« Last post by Kvaz1r on Yesterday at 12:58:33 »
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:

Code: [Select]
#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();
}
}
5
Feature requests / Re: DateTime Selector
« Last post by texus on 19 August 2019, 17:54:25 »
It is a pretty complex widget. I'll add it to the todo list, but unless someone else implements it, it won't be added anywhere soon.
6
Feature requests / DateTime Selector
« Last post by ertanataman on 19 August 2019, 11:34:18 »
A datetime selector seems missing. May seem compilcated for current level but is something really required.
7
Help requests / Re: Best practice for rendering specific widgets
« Last post by Hexade on 18 August 2019, 22:52:31 »
Alright, thanks for clearing it up.
8
Help requests / Re: Best practice for rendering specific widgets
« Last post by texus on 18 August 2019, 22:40:58 »
The Group::draw function is not supposed to be called directly. With the current design of the gui, you cannot draw widgets directly, all drawing has to happen via gui.draw().
What you are trying to do isn't supported, the gui always draws everything at once, the only solutions that I can provide are workarounds.

The code that you need looks more like this:
#include "TGUI/TGUI.hpp"

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600), "Group Test");
        tgui::Gui gui(window);

        tgui::Button::Ptr button_1 = tgui::Button::create("Button 1");
        button_1->setPosition(5, 5);

        tgui::Button::Ptr button_2 = tgui::Button::create("Button 2");
        button_2->setPosition(5, 30);

        tgui::Group::Ptr group = tgui::Group::create();
        group->setSize(400, 300);
        group->add(button_1);
        gui.add(group);

        tgui::Group::Ptr group2 = tgui::Group::create();
        group2->add(button_2);
        gui.add(group2);

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }

                        gui.handleEvent(event);
                }

                window.clear();
                       
                group->setVisible(true);
                group2->setVisible(false);
                gui.draw();

                // SFML rendering here will be between group and group2

                group->setVisible(false);
                group2->setVisible(true);
                gui.draw();
                       
                window.display();
        }
}

Alternatively, using a canvas:
#include "TGUI/TGUI.hpp"

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600), "Group Test");
        tgui::Gui gui(window);

        tgui::Button::Ptr button_1 = tgui::Button::create("Button 1");
        button_1->setPosition(5, 5);

        tgui::Button::Ptr button_2 = tgui::Button::create("Button 2");
        button_2->setPosition(5, 30);

        tgui::Group::Ptr group = tgui::Group::create();
        group->setSize(400, 300);
        group->add(button_1);
        gui.add(group);

        // Warning: the default canvas size is (100%,100%) to fill the screen which can cause performance overhead when changing the gui view.
        // Set a static size (by passing size to create function or calling setSize) if you don't want it to resize itself when resizing the gui.
        tgui::Canvas canvas = tgui::Canvas::create();
        gui.add(canvas);

        tgui::Group::Ptr group2 = tgui::Group::create();
        group2->add(button_2);
        gui.add(group2);

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }

                        gui.handleEvent(event);
                }

                // This clear/draw/display code can be called anywhere, if the contents is static you could even do it before the main loop
                canvas->clear(sf::Color::Transparent);
                // SFML rendering here will be between group and group2
                canvas->display();

                window.clear();
                gui.draw();
                window.display();
        }
}
9
Help requests / Re: Best practice for rendering specific widgets
« Last post by Hexade on 18 August 2019, 22:02:05 »
Alright, after playing around with tgui::Group for a while it seemed as though Group::draw() is just drawing the stored widgets to the group rather than the window. And it is still the Gui::draw() function that controls when the widgets are actually drawn to the screen. So I created a small demo to test how tgui::Group works a bit and ended up with this:
Code: [Select]
#include "TGUI/TGUI.hpp"

int main() {

sf::RenderWindow window(sf::VideoMode(800, 600), "Group Test");
tgui::Gui gui(window);

tgui::Button::Ptr button_1 = tgui::Button::create("Button 1");
button_1->setPosition(5, 5);

tgui::Button::Ptr button_2 = tgui::Button::create("Button 2");
button_2->setPosition(5, 30);

tgui::Group::Ptr group = tgui::Group::create();
group->setSize(400, 300);
group->add(button_1);
group->add(button_2);

while (window.isOpen()) {

sf::Event event;

while (window.pollEvent(event)) {

switch (event.type) {

case sf::Event::Closed:
window.close();
break;

}

gui.handleEvent(event);

window.clear();

group->draw(window, sf::RenderStates::Default);
                        gui.draw();

window.display();

}

}

}

Now the main part that I'd like to point your attention to are these two lines:
Code: [Select]
group->draw(window, sf::RenderStates::Default);
gui.draw();

In their current order the buttons get rendered to the screen as you would expect, changing the order so that Gui::draw() is called before Group::draw() also causes them to be rendered as normal. Commenting out the call to Group::draw() will cause nothing to be drawn to the screen as expected. But if we comment out the call to Gui::draw() whilst leaving in the call to Group::draw(), it will render the buttons to the screen but they are squashed and somewhat distorted.

Based on my first tests when trying to implement tgui::Group I thought that the call to Group::draw() was just drawing the widgets to some texture that is stored by the Group. And that it is not rendered to the screen until we call Gui::draw(). However this little demo shows the buttons are being drawn to the screen by Group::draw(), however they are not being drawn correctly.

So now I am a bit confused as to what happens when we call Group::draw()? And just to be clear I get the squashed buttons when commenting out the Gui::draw() call like so:
Code: [Select]
group->draw(window, sf::RenderStates::Default);
//gui.draw();
10
Help requests / Re: Best practice for rendering specific widgets
« Last post by Hexade on 18 August 2019, 20:44:22 »
tgui::Group definitely seems to be more along the lines of what I am looking for. I have just tried quickly implementing it but I am getting some unusual behaviour that is probably caused by things unrelated to the tgui::Group. I'll play around with it for a while and get back to you if it works out or not. Thanks.
Pages: [1] 2 3 ... 10