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

arcade.gui.UIBoxLayout.height value is incorrect at init #2068

Closed
ksetrae opened this issue Apr 20, 2024 · 3 comments
Closed

arcade.gui.UIBoxLayout.height value is incorrect at init #2068

ksetrae opened this issue Apr 20, 2024 · 3 comments
Assignees
Labels
gui Related to arcade GUI (sub module arcade.gui)

Comments

@ksetrae
Copy link

ksetrae commented Apr 20, 2024

Bug Report

System Info

Arcade 3.0.0.dev20

vendor: NVIDIA Corporation
renderer: GeForce GTX 1660 SUPER/PCIe/SSE2
version: (3, 3)
python: 3.10.10 (tags/v3.10.10:aad5f6a, Feb 7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)]
platform: win32
pyglet version: 2.0.5
PIL version: 9.4.0

Actual behavior:

arcade.gui.UIBoxLayout.height is not set immediatly after adding children to the box. It remains at 0, despite children having non-zero height.

What is also weird, it changes to a correct value during runtime after several frames, but I wonder why exactly after that number of frames.

This is the output of the code below. You can see attribute being set on frame 3:

v_box height after init: 0
v_box children heights after init: [50]

v_box height after frame 1: 0
v_box children heights after frame 1: [50]

v_box height after frame 2: 0
v_box children heights after frame 2: [50]

v_box height after frame 3: 50
v_box children heights after frame 3: [50]

v_box height after frame 4: 50
v_box children heights after frame 4: [50]

v_box height after frame 5: 50
v_box children heights after frame 5: [50]

Expected behavior:

height attribute is set to a correct value after adding elements to the layout.

Steps to reproduce/example code:

import arcade
import arcade.gui


class MyView(arcade.View):
    def __init__(self):
        super().__init__()

        self.ui = arcade.gui.UIManager()
        self.ui.enable()

        self.v_box = arcade.gui.UIBoxLayout(space_between=20)

        start_button = arcade.gui.UIFlatButton(text="Start Game", width=200)
        self.v_box.add(start_button)

        self.ui.add(self.v_box)

        self.frame_count = 0

        print(f'v_box height after init: {self.v_box.height}')
        print(f'v_box children heights after init: {[child.height for child in self.v_box.children]}')
        print()

    def on_draw(self):
        self.clear()
        self.ui.draw()

    def on_update(self, delta_time: float):
        self.frame_count += 1
        if self.frame_count in (1, 2, 3, 4, 5):
            print(f'v_box height after frame {self.frame_count}: {self.v_box.height}')
            print(f'v_box children heights after frame {self.frame_count}: {[child.height for child in self.v_box.children]}')
            print()


if __name__ == '__main__':
    window = arcade.Window(800, 600)
    window.show_view(MyView())
    window.run()
@eruvanos eruvanos added the gui Related to arcade GUI (sub module arcade.gui) label May 10, 2024
@eruvanos eruvanos self-assigned this May 21, 2024
@eruvanos
Copy link
Member

Hi,

UIWidgets live within the GUI lifecycle. The docs contain some description regarding that behaviour: GUI Concept

UILayouts change their size depending on the space they get. The steps to calculate all of this is executed before drawing on screen.

In your code the on_update is executed before the first draw call. Which explains, why the height is changed after the second on_update call. In between the ui.draw() was executed, ensured a up-to-date layouting, which actually sets the size.

If you want, use self.ui.execute_layout() after you added the box to the UIManager.

class MyView(arcade.View):
    def __init__(self):
        super().__init__()

        self.ui = arcade.gui.UIManager()
        self.ui.enable()

        self.v_box = arcade.gui.UIBoxLayout(space_between=20)

        start_button = arcade.gui.UIFlatButton(text="Start Game", width=200)
        self.v_box.add(start_button)

        self.ui.add(self.v_box)
        self.ui.execute_layout()

        self.frame_count = 0

        print(f'v_box height after init: {self.v_box.height}')
        print(f'v_box children heights after init: {[child.height for child in self.v_box.children]}')
        print()

...

That should lead to your expected result.

@eruvanos
Copy link
Member

Please close the issue, in case your question is answered.

@ksetrae
Copy link
Author

ksetrae commented May 22, 2024

Thanks for the explanation.

@ksetrae ksetrae closed this as completed May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gui Related to arcade GUI (sub module arcade.gui)
Projects
None yet
Development

No branches or pull requests

2 participants