2
2
The base classes.
3
3
"""
4
4
5
- __all__ = [ "BaseLoop" , "BaseRenderCanvas" , "WrapperRenderCanvas" ]
5
+ from __future__ import annotations
6
6
7
7
import sys
8
8
import weakref
9
9
import importlib
10
- from typing import Optional , Tuple
10
+ from typing import TYPE_CHECKING
11
11
12
12
from ._events import EventEmitter , EventType # noqa: F401
13
13
from ._loop import BaseLoop
14
14
from ._scheduler import Scheduler , UpdateMode
15
15
from ._coreutils import logger , log_exception , BaseEnum
16
16
17
+ if TYPE_CHECKING :
18
+ from typing import Callable , List , Optional , Tuple
19
+
20
+ EventHandlerFunction = Callable [[dict ], None ]
21
+ DrawFunction = Callable [[], None ]
22
+
23
+
24
+ __all__ = ["BaseLoop" , "BaseRenderCanvas" , "WrapperRenderCanvas" ]
25
+
17
26
18
27
# Notes on naming and prefixes:
19
28
#
@@ -61,7 +70,7 @@ def _register_canvas(self, canvas, task):
61
70
loop ._register_canvas_group (self )
62
71
loop .add_task (task , name = "scheduler-task" )
63
72
64
- def select_loop (self , loop ) :
73
+ def select_loop (self , loop : BaseLoop ) -> None :
65
74
"""Select the loop to use for this group of canvases."""
66
75
if not (loop is None or isinstance (loop , BaseLoop )):
67
76
raise TypeError ("select_loop() requires a loop instance or None." )
@@ -74,11 +83,11 @@ def select_loop(self, loop):
74
83
self ._loop ._unregister_canvas_group (self )
75
84
self ._loop = loop
76
85
77
- def get_loop (self ):
86
+ def get_loop (self ) -> BaseLoop :
78
87
"""Get the currently associated loop (can be None for canvases that don't run a scheduler)."""
79
88
return self ._loop
80
89
81
- def get_canvases (self ):
90
+ def get_canvases (self ) -> List [ BaseRenderCanvas ] :
82
91
"""Get a list of currently active (not-closed) canvases for this group."""
83
92
return [canvas for canvas in self ._canvases if not canvas .get_closed ()]
84
93
@@ -112,7 +121,7 @@ class BaseRenderCanvas:
112
121
"""
113
122
114
123
@classmethod
115
- def select_loop (cls , loop ) :
124
+ def select_loop (cls , loop : BaseLoop ) -> None :
116
125
"""Select the loop to run newly created canvases with.
117
126
Can only be called when there are no live canvases of this class.
118
127
"""
@@ -213,11 +222,11 @@ def __del__(self):
213
222
214
223
_canvas_context = None # set in get_context()
215
224
216
- def get_physical_size (self ):
225
+ def get_physical_size (self ) -> Tuple [ int ] :
217
226
"""Get the physical size of the canvas in integer pixels."""
218
227
return self ._rc_get_physical_size ()
219
228
220
- def get_context (self , context_type ) :
229
+ def get_context (self , context_type : str ) -> object :
221
230
"""Get a context object that can be used to render to this canvas.
222
231
223
232
The context takes care of presenting the rendered result to the canvas.
@@ -292,13 +301,15 @@ def get_context(self, context_type):
292
301
293
302
# %% Events
294
303
295
- def add_event_handler (self , * args , ** kwargs ):
296
- return self ._events .add_handler (* args , ** kwargs )
304
+ def add_event_handler (
305
+ self , * args : str | EventHandlerFunction , order : float = 0
306
+ ) -> None :
307
+ return self ._events .add_handler (* args , order = order )
297
308
298
- def remove_event_handler (self , * args , ** kwargs ) :
299
- return self ._events .remove_handler (* args , ** kwargs )
309
+ def remove_event_handler (self , callback : EventHandlerFunction , * types : str ) -> None :
310
+ return self ._events .remove_handler (callback , * types )
300
311
301
- def submit_event (self , event ) :
312
+ def submit_event (self , event : dict ) -> None :
302
313
# Not strictly necessary for normal use-cases, but this allows
303
314
# the ._event to be an implementation detail to subclasses, and it
304
315
# allows users to e.g. emulate events in tests.
@@ -354,7 +365,13 @@ def _draw_frame(self):
354
365
"""
355
366
pass
356
367
357
- def set_update_mode (self , update_mode , * , min_fps = None , max_fps = None ):
368
+ def set_update_mode (
369
+ self ,
370
+ update_mode : UpdateMode ,
371
+ * ,
372
+ min_fps : Optional [float ] = None ,
373
+ max_fps : Optional [float ] = None ,
374
+ ) -> None :
358
375
"""Set the update mode for scheduling draws.
359
376
360
377
Arguments:
@@ -365,7 +382,7 @@ def set_update_mode(self, update_mode, *, min_fps=None, max_fps=None):
365
382
"""
366
383
self .__scheduler .set_update_mode (update_mode , min_fps = min_fps , max_fps = max_fps )
367
384
368
- def request_draw (self , draw_function = None ):
385
+ def request_draw (self , draw_function : Optional [ DrawFunction ] = None ) -> None :
369
386
"""Schedule a new draw event.
370
387
371
388
This function does not perform a draw directly, but schedules a draw at
@@ -388,7 +405,7 @@ def request_draw(self, draw_function=None):
388
405
# storing it here, the gc can detect this case, and its fine. However,
389
406
# this fails if we'd store _draw_frame on the scheduler!
390
407
391
- def force_draw (self ):
408
+ def force_draw (self ) -> None :
392
409
"""Perform a draw right now.
393
410
394
411
In most cases you want to use ``request_draw()``. If you find yourself using
@@ -458,15 +475,15 @@ def _draw_frame_and_present(self):
458
475
459
476
# %% Primary canvas management methods
460
477
461
- def get_logical_size (self ):
478
+ def get_logical_size (self ) -> Tuple [ float ] :
462
479
"""Get the logical size (width, height) in float pixels."""
463
480
return self ._rc_get_logical_size ()
464
481
465
- def get_pixel_ratio (self ):
482
+ def get_pixel_ratio (self ) -> float :
466
483
"""Get the float ratio between logical and physical pixels."""
467
484
return self ._rc_get_pixel_ratio ()
468
485
469
- def close (self ):
486
+ def close (self ) -> None :
470
487
"""Close the canvas."""
471
488
# Clear the draw-function, to avoid it holding onto e.g. wgpu objects.
472
489
self ._draw_frame = None
@@ -483,7 +500,7 @@ def close(self):
483
500
# Let the subclass clean up.
484
501
self ._rc_close ()
485
502
486
- def get_closed (self ):
503
+ def get_closed (self ) -> bool :
487
504
"""Get whether the window is closed."""
488
505
return self ._rc_get_closed ()
489
506
@@ -498,14 +515,14 @@ def is_closed(self):
498
515
# These methods provide extra control over the canvas. Subclasses should
499
516
# implement the methods they can, but these features are likely not critical.
500
517
501
- def set_logical_size (self , width , height ) :
518
+ def set_logical_size (self , width : float , height : float ) -> None :
502
519
"""Set the window size (in logical pixels)."""
503
520
width , height = float (width ), float (height )
504
521
if width < 0 or height < 0 :
505
522
raise ValueError ("Canvas width and height must not be negative" )
506
523
self ._rc_set_logical_size (width , height )
507
524
508
- def set_title (self , title ) :
525
+ def set_title (self , title : str ) -> None :
509
526
"""Set the window title.
510
527
511
528
The words "$backend", "$loop", and "$fps" can be used as variables that
@@ -516,7 +533,7 @@ def set_title(self, title):
516
533
title = title .replace ("$" + k , v )
517
534
self ._rc_set_title (title )
518
535
519
- def set_cursor (self , cursor ) :
536
+ def set_cursor (self , cursor : CursorShape ) -> None :
520
537
"""Set the cursor shape for the mouse pointer.
521
538
522
539
See :obj:`rendercanvas.CursorShape`:
@@ -658,50 +675,52 @@ class WrapperRenderCanvas(BaseRenderCanvas):
658
675
_rc_canvas_group = None # No grouping for these wrappers
659
676
660
677
@classmethod
661
- def select_loop (cls , loop ) :
678
+ def select_loop (cls , loop : BaseLoop ) -> None :
662
679
m = sys .modules [cls .__module__ ]
663
680
return m .RenderWidget .select_loop (loop )
664
681
665
- def add_event_handler (self , * args , ** kwargs ):
666
- return self ._subwidget ._events .add_handler (* args , ** kwargs )
682
+ def add_event_handler (
683
+ self , * args : str | EventHandlerFunction , order : float = 0
684
+ ) -> None :
685
+ return self ._subwidget ._events .add_handler (* args , order = order )
667
686
668
- def remove_event_handler (self , * args , ** kwargs ) :
669
- return self ._subwidget ._events .remove_handler (* args , ** kwargs )
687
+ def remove_event_handler (self , callback : EventHandlerFunction , * types : str ) -> None :
688
+ return self ._subwidget ._events .remove_handler (callback , * types )
670
689
671
- def submit_event (self , event ) :
690
+ def submit_event (self , event : dict ) -> None :
672
691
return self ._subwidget ._events .submit (event )
673
692
674
- def get_context (self , * args , ** kwargs ) :
675
- return self ._subwidget .get_context (* args , ** kwargs )
693
+ def get_context (self , context_type : str ) -> object :
694
+ return self ._subwidget .get_context (context_type )
676
695
677
- def request_draw (self , * args , ** kwargs ) :
678
- return self ._subwidget .request_draw (* args , ** kwargs )
696
+ def request_draw (self , draw_function : Optional [ DrawFunction ] = None ) -> None :
697
+ return self ._subwidget .request_draw (draw_function )
679
698
680
- def force_draw (self ):
699
+ def force_draw (self ) -> None :
681
700
self ._subwidget .force_draw ()
682
701
683
- def get_physical_size (self ):
702
+ def get_physical_size (self ) -> Tuple [ int ] :
684
703
return self ._subwidget .get_physical_size ()
685
704
686
- def get_logical_size (self ):
705
+ def get_logical_size (self ) -> Tuple [ float ] :
687
706
return self ._subwidget .get_logical_size ()
688
707
689
- def get_pixel_ratio (self ):
708
+ def get_pixel_ratio (self ) -> float :
690
709
return self ._subwidget .get_pixel_ratio ()
691
710
692
- def set_logical_size (self , width , height ) :
711
+ def set_logical_size (self , width : float , height : float ) -> None :
693
712
self ._subwidget .set_logical_size (width , height )
694
713
695
- def set_title (self , * args ) :
696
- self ._subwidget .set_title (* args )
714
+ def set_title (self , title : str ) -> None :
715
+ self ._subwidget .set_title (title )
697
716
698
- def set_cursor (self , * args ) :
699
- self ._subwidget .set_cursor (* args )
717
+ def set_cursor (self , cursor : CursorShape ) -> None :
718
+ self ._subwidget .set_cursor (cursor )
700
719
701
- def close (self ):
720
+ def close (self ) -> None :
702
721
self ._subwidget .close ()
703
722
704
- def get_closed (self ):
723
+ def get_closed (self ) -> bool :
705
724
return self ._subwidget .get_closed ()
706
725
707
726
def is_closed (self ):
0 commit comments