5
5
from pyglet .math import Vec2
6
6
7
7
import arcade
8
- from arcade import MOUSE_BUTTON_LEFT
8
+ from arcade import LBWH , MOUSE_BUTTON_LEFT
9
9
from arcade .gui .events import (
10
10
UIEvent ,
11
11
UIKeyPressEvent ,
@@ -57,6 +57,36 @@ def ui(self) -> UIManager | None:
57
57
w = self .parent
58
58
return None
59
59
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
+
60
90
61
91
class UIFocusMixin (UIWidget ):
62
92
"""A group of widgets that can be focused.
@@ -154,6 +184,18 @@ def on_event(self, event: UIEvent) -> Optional[bool]:
154
184
155
185
return EVENT_UNHANDLED
156
186
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
+
157
199
def _get_focused_widget (self ) -> UIWidget | None :
158
200
if len (self ._focusable_widgets ) == 0 :
159
201
return None
@@ -278,6 +320,8 @@ def end_interaction(self):
278
320
)
279
321
280
322
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
+
281
325
# TODO: add a post child render hook to UIWidget
282
326
rendered = super ()._do_render (surface , force )
283
327
@@ -290,40 +334,46 @@ def do_post_render(self, surface: Surface):
290
334
surface .limit (None )
291
335
292
336
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 :
294
344
arcade .draw_rect_outline (
295
345
rect = widget .rect ,
296
346
color = arcade .color .WHITE ,
297
347
border_width = 2 ,
298
348
)
299
349
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
+ )
327
377
328
378
def _draw_indicator (self , start : Vec2 , end : Vec2 , color = arcade .color .WHITE ):
329
379
arcade .draw_line (start .x , start .y , end .x , end .y , color , 2 )
0 commit comments