Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting a widget's index in a layout doesn't seem to update it until the layout is resized #202

Closed
CasualYT31 opened this issue Aug 26, 2023 · 1 comment

Comments

@CasualYT31
Copy link
Contributor

CasualYT31 commented Aug 26, 2023

I've come across an issue with updating widget indices whilst developing my game, and I have been able to replicate it in isolation with the following code:

#include <TGUI/TGUI.hpp>
#include <TGUI/Backend/SFML-Graphics.hpp>
#include <iostream>

using namespace tgui;

int main() {
    sf::RenderWindow window{ {800, 600}, "TGUI example - SFML_GRAPHICS backend" };
    Gui gui{ window };

    auto layout = VerticalLayout::create();
    gui.add(layout);

    auto button1 = Button::create("Button1");
    button1->setPosition("50px", "50px");
    button1->setSize("50px", "50px");
    layout->add(button1);

    auto button2 = Button::create("Button2");
    button2->setPosition("75px", "75px");
    button2->setSize("50px", "50px");
    layout->add(button2);

    auto button3 = Button::create("Button3");
    button3->setPosition("100px", "100px");
    button3->setSize("50px", "50px");
    layout->add(button3);

    layout->setWidgetIndex(button3, 0);

    // Adding a new widget to the layout updates it.
    //auto button4 = Button::create("Button4");
    //layout->add(button4);

    // As does resizing the layout.
    //layout->setSize("50%", "50%");

    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            gui.handleEvent(event);

            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.clear();
        gui.draw();
        window.display();
    }
}

The expected outcome is that the buttons will be displayed in the following order, from top to bottom:

  1. Button3
  2. Button1
  3. Button2

However, the buttons are instead displayed in their original order:

  1. Button1
  2. Button2
  3. Button3

That is, until the layout is resized, either by manually resizing the window, resizing the layout itself programmatically (e.g. setSize()), or adding a widget to the layout to invoke a resize.

I can also replicate this issue with a HorizontalLayout and HorizontalWrap, but I cannot replicate it with any other container type. You can see that if you change VerticalLayout to Group, for example, Button2 will appear on top of the other two buttons, which is the intended outcome.

Can replicate using the latest changes on the 1.x branch (currently commit 6c4879e). Seems like this could be a simple fix so I'll do some digging now and report any findings and/or make a PR if I make any progress.

@CasualYT31 CasualYT31 changed the title Setting a widget's index in a container doesn't seem to update it until later Setting a widget's index in a container doesn't seem to update it until resized Aug 26, 2023
@CasualYT31 CasualYT31 changed the title Setting a widget's index in a container doesn't seem to update it until resized Setting a widget's index in a layout doesn't seem to update it until the layout is resized Aug 26, 2023
@CasualYT31
Copy link
Contributor Author

CasualYT31 commented Aug 26, 2023

I have a solution but I'm not sure if it's the right way to go.

We could make Container::setWidgetIndex() virtual. Then, in BoxLayout, we can override it, invoke Container's setWidgetIndex(), and if it returns true, we can then invoke updateWidgets().

I was not able to replicate the problem with any layout widget after making those changes. Here's a patch:

diff --git a/include/TGUI/Container.hpp b/include/TGUI/Container.hpp
index 748e3914..c88e626d 100644
--- a/include/TGUI/Container.hpp
+++ b/include/TGUI/Container.hpp
@@ -345,7 +345,7 @@ TGUI_MODULE_EXPORT namespace tgui
         ///
         /// @return True when the index was changed, false if widget wasn't found in the container or index was too high
         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-        bool setWidgetIndex(const Widget::Ptr& widget, std::size_t index);
+        virtual bool setWidgetIndex(const Widget::Ptr& widget, std::size_t index);


         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/include/TGUI/Widgets/BoxLayout.hpp b/include/TGUI/Widgets/BoxLayout.hpp
index 95faa3cc..f6082f69 100644
--- a/include/TGUI/Widgets/BoxLayout.hpp
+++ b/include/TGUI/Widgets/BoxLayout.hpp
@@ -137,6 +137,9 @@ TGUI_MODULE_EXPORT namespace tgui
         using Container::get;


+        bool setWidgetIndex(const Widget::Ptr& widget, std::size_t index) override;
+
+
         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     protected:

diff --git a/src/Widgets/BoxLayout.cpp b/src/Widgets/BoxLayout.cpp
index 5d781ebf..244e794b 100644
--- a/src/Widgets/BoxLayout.cpp
+++ b/src/Widgets/BoxLayout.cpp
@@ -129,6 +129,12 @@ namespace tgui
             return nullptr;
     }

+    bool BoxLayout::setWidgetIndex(const Widget::Ptr& widget, std::size_t index) {
+        const auto ret = Container::setWidgetIndex(widget, index);
+        if (ret) updateWidgets();
+        return ret;
+    }
+
     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

     void BoxLayout::rendererChanged(const String& property)

It doesn't follow the style of the rest of the library's code yet, but I will create a proper PR that addresses that. Let me know what you think.

CasualYT31 added a commit to CasualYT31/TGUI that referenced this issue Aug 26, 2023
@texus texus closed this as completed in e778c38 Aug 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant