Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page.
- Upgraded Pillow to 12.0.0 for Python 3.14 support.
- Adds a new `arcade.NoAracdeWindowError` exception type. This is raised when certain window operations are performed and there is no valid Arcade window found. Previously where this error would be raised, we raised a standard `RuntimeError`, this made it harder to properly catch and act accordingly. This new exception subclasses `RuntimeError`, so you can still catch this error the same way as before. The `arcade.get_window()` function will now raise this if there is no window.
- Along with the new exception type, is a new `arcade.windows_exists()` function which will return True or False based on if there is currently an active window.
- GUI
- `UIManager` did not apply size hint of (0,0). Mainly an issue with `UIBoxLayout`.
- Allow multiple children in `UIScrollArea`.
- Fix `UIDropdown Overlay` positioning within a `UIScrollArea`.

## 3.3.3

Expand Down
3 changes: 0 additions & 3 deletions arcade/gui/experimental/scroll_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,6 @@ def __init__(

def add(self, child: W, **kwargs) -> W:
"""Add a child to the widget."""
if self._children:
raise ValueError("UIScrollArea can only have one child")

super().add(child, **kwargs)
self.trigger_full_render()

Expand Down
4 changes: 2 additions & 2 deletions arcade/gui/ui_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ def _do_layout(self):
# actual layout
if child.size_hint:
sh_x, sh_y = child.size_hint
nw = surface_width * sh_x if sh_x else None
nh = surface_height * sh_y if sh_y else None
nw = surface_width * sh_x if sh_x is not None else None
nh = surface_height * sh_y if sh_y is not None else None
child.rect = child.rect.resize(nw, nh, anchor=AnchorPoint.BOTTOM_LEFT)

if child.size_hint_min:
Expand Down
21 changes: 15 additions & 6 deletions arcade/gui/widgets/dropdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from arcade import uicolor
from arcade.gui import UIEvent, UIMousePressEvent
from arcade.gui.events import UIControllerButtonPressEvent, UIOnChangeEvent, UIOnClickEvent
from arcade.gui.experimental import UIScrollArea
from arcade.gui.experimental.focus import UIFocusMixin
from arcade.gui.ui_manager import UIManager
from arcade.gui.widgets import UILayout, UIWidget
Expand All @@ -21,7 +22,7 @@ class _UIDropdownOverlay(UIFocusMixin, UIBoxLayout):

# TODO move also options logic to this class

def show(self, manager: UIManager):
def show(self, manager: UIManager | UIScrollArea):
manager.add(self, layer=UIManager.OVERLAY_LAYER)

def hide(self):
Expand Down Expand Up @@ -197,11 +198,19 @@ def _update_options(self):
self._overlay.detect_focusable_widgets()

def _show_overlay(self):
manager = self.get_ui_manager()
if manager is None:
raise Exception("UIDropdown could not find UIManager in its parents.")

self._overlay.show(manager)
# traverse parents until UIManager or UIScrollArea is found
parent = self.parent
while parent is not None:
if isinstance(parent, UIManager):
break
if isinstance(parent, UIScrollArea):
break
parent = parent.parent

if parent is None:
raise Exception("UIDropdown could not find a valid parent for the overlay.")

self._overlay.show(parent)

def _on_button_click(self, _: UIOnClickEvent):
self._show_overlay()
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/gui/test_uimanager_layouting.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,21 @@ def test_supports_size_hint(window):
widget3 = UIDummy()
widget3.size_hint = (1, None)

widget4 = UIDummy()
widget4.size_hint = (0, 0)

manager.add(widget1)
manager.add(widget2)
manager.add(widget3)
manager.add(widget4)

with sized(window, 200, 300):
manager.draw()

assert widget1.size == Vec2(200, 300)
assert widget2.size == Vec2(100, 75)
assert widget3.size == Vec2(200, 100)
assert widget4.size == Vec2(0, 0)


def test_supports_size_hint_min(window):
Expand Down
Loading