Skip to content

Commit 8db8913

Browse files
committed
adding more workarounds to handle scrollarea setups, set focused on widget
1 parent 7dc467d commit 8db8913

File tree

1 file changed

+79
-29
lines changed

1 file changed

+79
-29
lines changed

arcade/gui/experimental/focus.py

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pyglet.math import Vec2
66

77
import arcade
8-
from arcade import MOUSE_BUTTON_LEFT
8+
from arcade import LBWH, MOUSE_BUTTON_LEFT
99
from arcade.gui.events import (
1010
UIEvent,
1111
UIKeyPressEvent,
@@ -57,6 +57,36 @@ def ui(self) -> UIManager | None:
5757
w = self.parent
5858
return None
5959

60+
def _render_focus(self, surface: Surface):
61+
# this will be properly integrated into widget
62+
self.prepare_render(surface)
63+
arcade.draw_rect_outline(
64+
rect=LBWH(0, 0, self.content_width, self.content_height),
65+
color=arcade.color.WHITE,
66+
border_width=4,
67+
)
68+
69+
def _do_render(self, surface: Surface, force=False) -> bool:
70+
rendered = False
71+
72+
should_render = force or self._requires_render
73+
if should_render and self.visible:
74+
rendered = True
75+
self.do_render_base(surface)
76+
self.do_render(surface)
77+
78+
if self.focused:
79+
self._render_focus(surface)
80+
81+
self._requires_render = False
82+
83+
# only render children if self is visible
84+
if self.visible:
85+
for child in self.children:
86+
rendered |= child._do_render(surface, should_render)
87+
88+
return rendered
89+
6090

6191
class UIFocusMixin(UIWidget):
6292
"""A group of widgets that can be focused.
@@ -154,6 +184,18 @@ def on_event(self, event: UIEvent) -> Optional[bool]:
154184

155185
return EVENT_UNHANDLED
156186

187+
def _ensure_focused_property(self):
188+
# TODO this is a hack, to set the focused property on the focused widget
189+
# this should be properly handled in a property or so
190+
191+
focused = self._get_focused_widget()
192+
193+
for widget in self._focusable_widgets:
194+
if widget == focused:
195+
widget.focused = True
196+
else:
197+
widget.focused = False
198+
157199
def _get_focused_widget(self) -> UIWidget | None:
158200
if len(self._focusable_widgets) == 0:
159201
return None
@@ -278,6 +320,8 @@ def end_interaction(self):
278320
)
279321

280322
def _do_render(self, surface: Surface, force=False) -> bool:
323+
self._ensure_focused_property() # TODO this is a hack, to set the focused property on the focused widget
324+
281325
# TODO: add a post child render hook to UIWidget
282326
rendered = super()._do_render(surface, force)
283327

@@ -290,40 +334,46 @@ def do_post_render(self, surface: Surface):
290334
surface.limit(None)
291335

292336
widget = self._get_focused_widget()
293-
if widget:
337+
if not widget:
338+
return
339+
340+
if isinstance(widget, Focusable):
341+
# Focusable widgets care about focus themselves
342+
pass
343+
else:
294344
arcade.draw_rect_outline(
295345
rect=widget.rect,
296346
color=arcade.color.WHITE,
297347
border_width=2,
298348
)
299349

300-
if self._debug:
301-
# debugging
302-
if isinstance(widget, Focusable):
303-
if widget.neighbor_up:
304-
self._draw_indicator(
305-
widget.rect.top_center,
306-
widget.neighbor_up.rect.bottom_center,
307-
color=arcade.color.RED,
308-
)
309-
if widget.neighbor_down:
310-
self._draw_indicator(
311-
widget.rect.bottom_center,
312-
widget.neighbor_down.rect.top_center,
313-
color=arcade.color.GREEN,
314-
)
315-
if widget.neighbor_left:
316-
self._draw_indicator(
317-
widget.rect.center_left,
318-
widget.neighbor_left.rect.center_right,
319-
color=arcade.color.BLUE,
320-
)
321-
if widget.neighbor_right:
322-
self._draw_indicator(
323-
widget.rect.center_right,
324-
widget.neighbor_right.rect.center_left,
325-
color=arcade.color.ORANGE,
326-
)
350+
if self._debug:
351+
# debugging
352+
if isinstance(widget, Focusable):
353+
if widget.neighbor_up:
354+
self._draw_indicator(
355+
widget.rect.top_center,
356+
widget.neighbor_up.rect.bottom_center,
357+
color=arcade.color.RED,
358+
)
359+
if widget.neighbor_down:
360+
self._draw_indicator(
361+
widget.rect.bottom_center,
362+
widget.neighbor_down.rect.top_center,
363+
color=arcade.color.GREEN,
364+
)
365+
if widget.neighbor_left:
366+
self._draw_indicator(
367+
widget.rect.center_left,
368+
widget.neighbor_left.rect.center_right,
369+
color=arcade.color.BLUE,
370+
)
371+
if widget.neighbor_right:
372+
self._draw_indicator(
373+
widget.rect.center_right,
374+
widget.neighbor_right.rect.center_left,
375+
color=arcade.color.ORANGE,
376+
)
327377

328378
def _draw_indicator(self, start: Vec2, end: Vec2, color=arcade.color.WHITE):
329379
arcade.draw_line(start.x, start.y, end.x, end.y, color, 2)

0 commit comments

Comments
 (0)