Skip to content

Commit 539dd7e

Browse files
authored
UIBoxLayout ignores widgets with visible=None (#2761)
* UIBoxLayout ignores widgets with `visible=None`
1 parent 3ce025a commit 539dd7e

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page.
99
- Fix a bug, where the caret of UIInputText was misplaced after resizing the widget
1010
- Use incremental layout for UIScrollArea to improve performance of changing text
1111
- Refactored and improved focus handling
12+
- UIBoxLayout ignores widgets with `visible=None`
1213

1314
## 3.3.2
1415

arcade/context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ def bind_window_block(self) -> None:
330330
gl.GL_UNIFORM_BUFFER,
331331
0,
332332
self._window_block.buffer.id,
333-
0,
334-
128, # 32 x 32bit floats (two mat4)
333+
0, # type: ignore
334+
128, # 32 x 32bit floats (two mat4) # type: ignore
335335
)
336336

337337
@property

arcade/gui/widgets/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ class UIWidget(EventDispatcher, ABC):
127127
"""A weak reference to the parent UIManager or UIWidget,
128128
which does not prevent garbage collection of the parent."""
129129
rect = Property(LBWH(0, 0, 1, 1))
130-
visible = Property(True)
130+
visible = Property[bool | None](True)
131+
"""If True, the widget is visible and will be rendered. If None,
132+
the widget should also be skipped by layouts."""
131133
focused = Property(False)
132134
focus_mode: FocusMode = FocusMode.NONE
133135

arcade/gui/widgets/layout.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,9 @@ def _update_size_hints(self):
315315
self._size_hint_requires_update = False
316316

317317
required_space_between = max(0, len(self.children) - 1) * self._space_between
318-
min_child_sizes = [UILayout.min_size_of(child) for child in self.children]
318+
min_child_sizes = [
319+
UILayout.min_size_of(child) for child in self.children if child.visible is not None
320+
]
319321

320322
if len(self.children) == 0:
321323
width = 0
@@ -360,10 +362,14 @@ def do_layout(self):
360362
if not self.children:
361363
return
362364

365+
children_to_render = [
366+
(child, data) for child, data in self._children if child.visible is not None
367+
]
368+
363369
# main axis
364370
constraints = [
365371
_C.from_widget_height(child) if self.vertical else _C.from_widget_width(child)
366-
for child, _ in self._children
372+
for child, _ in children_to_render
367373
]
368374

369375
available_space = (
@@ -374,14 +380,14 @@ def do_layout(self):
374380
# orthogonal axis
375381
constraints = [
376382
_C.from_widget_width(child) if self.vertical else _C.from_widget_height(child)
377-
for child, _ in self._children
383+
for child, _ in children_to_render
378384
]
379385
orthogonal_sizes = _box_orthogonal_algorithm(
380386
constraints, self.content_width if self.vertical else self.content_height
381387
)
382388

383389
for (child, data), main_size, ortho_size in zip(
384-
self._children, main_sizes, orthogonal_sizes
390+
children_to_render, main_sizes, orthogonal_sizes
385391
):
386392
# apply calculated sizes, condition regarding existing size_hint
387393
# are already covered in calculation input

tests/unit/gui/test_layouting_boxlayout.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,28 @@ def test_do_layout_vertical_space_between(window):
128128
assert element_2.top == 300
129129

130130

131+
def test_do_layout_ignores_child_with_visible_None(window):
132+
# add two 100x100 Dummy widgets
133+
element_1 = UIDummy()
134+
element_1.visible = None
135+
element_2 = UIDummy()
136+
137+
group = UIBoxLayout(vertical=True, children=[element_1, element_2])
138+
assert group.size_hint_min == (100, 100)
139+
group.rect = LBWH(100, 200, 100, 100)
140+
141+
group._do_layout()
142+
143+
# element 1 in initial position
144+
assert element_1.bottom == 0
145+
assert element_1.left == 0
146+
147+
# element 2 fills the group
148+
assert element_2.top == 300
149+
assert element_2.bottom == 200
150+
assert element_2.left == 100
151+
152+
131153
# Horizontal
132154
def test_do_layout_horizontal_with_initial_children(window):
133155
# add two 100x100 Dummy widgets

0 commit comments

Comments
 (0)