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