99Enhanced: Dave Erickson
1010"""
1111
12- import logging
1312import math
1413import weakref
1514from collections .abc import Iterator
16- from typing import TYPE_CHECKING , Any , Optional
15+ from typing import TYPE_CHECKING , Any , Dict , List , Optional , Tuple , Union
1716
18- from ._bindings import CanvasBindings , DEFAULT_BINDINGS
17+ from ._bindings import DEFAULT_BINDINGS , CanvasBindings
1918from ._history import saves_history
2019from ._keyboard import KeyboardStateManager
2120from ._units import mm_to_px , px_to_mm
@@ -57,7 +56,7 @@ class DraggableRectangle:
5756 - Class methods for alignment and distribution
5857 """
5958
60- _instances : list [weakref .ref ] = []
59+ _instances : List [weakref .ref ] = []
6160 ALIGN_MODES = ["top" , "middle" , "bottom" , "start" , "center" , "end" ]
6261 DISTRIBUTE_MODES = ["horizontal" , "vertical" ]
6362
@@ -99,7 +98,7 @@ def __init__(
9998
10099 # Canvas items attached to this rectangle (e.g. text labels) that move
101100 # with it during drags. Declared here so mypy always sees the attribute.
102- self ._attached_items : list [int ] = []
101+ self ._attached_items : List [int ] = []
103102
104103 self .rect = canvas .create_rectangle (x1 , y1 , x2 , y2 , width = width , ** kwargs )
105104 self .resize_handle = canvas .create_aa_circle (x2 , y2 , radius = radius , fill = "#00497b" )
@@ -207,7 +206,7 @@ def __len__(self) -> int:
207206 """
208207 return 4
209208
210- def __getitem__ (self , index : int | slice ) -> float | list [float ]:
209+ def __getitem__ (self , index : Union [ int , slice ] ) -> Union [ float , List [float ] ]:
211210 """
212211 Access coordinates by index or slice.
213212
@@ -226,7 +225,7 @@ def __getitem__(self, index: int | slice) -> float | list[float]:
226225 IndexError: If index is out of range.
227226 """
228227 coords_tuple = self .canvas .coords (self .rect )
229- coords : list [float ] = [float (c ) for c in coords_tuple ]
228+ coords : List [float ] = [float (c ) for c in coords_tuple ]
230229 if isinstance (index , slice ):
231230 return coords [index ]
232231 if not isinstance (index , int ):
@@ -273,7 +272,7 @@ def __iter__(self) -> Iterator[float]:
273272 """
274273 return iter (self .canvas .coords (self .rect ))
275274
276- def __contains__ (self , point : list [ float ] | tuple [float , float ]) -> bool :
275+ def __contains__ (self , point : Union [ List [ float ], Tuple [float , float ] ]) -> bool :
277276 """
278277 Check if a point is inside the rectangle.
279278
@@ -394,7 +393,7 @@ def __hash__(self) -> int:
394393 return hash (coords )
395394
396395 @saves_history
397- def __add__ (self , offset : list [ float ] | tuple [float , float ]) -> "DraggableRectangle" :
396+ def __add__ (self , offset : Union [ List [ float ], Tuple [float , float ] ]) -> "DraggableRectangle" :
398397 """
399398 Translate rectangle by offset (returns new rectangle).
400399
@@ -424,7 +423,7 @@ def __add__(self, offset: list[float] | tuple[float, float]) -> "DraggableRectan
424423 )
425424 return new_rect
426425
427- def __radd__ (self , offset : list [ float ] | tuple [float , float ]) -> "DraggableRectangle" :
426+ def __radd__ (self , offset : Union [ List [ float ], Tuple [float , float ] ]) -> "DraggableRectangle" :
428427 """
429428 Right-hand addition (commutative).
430429
@@ -436,7 +435,7 @@ def __radd__(self, offset: list[float] | tuple[float, float]) -> "DraggableRecta
436435 """
437436 return self .__add__ (offset )
438437
439- def __sub__ (self , offset : list [ float ] | tuple [float , float ]) -> "DraggableRectangle" :
438+ def __sub__ (self , offset : Union [ List [ float ], Tuple [float , float ] ]) -> "DraggableRectangle" :
440439 """
441440 Translate rectangle by negative offset (returns new rectangle).
442441
@@ -456,7 +455,7 @@ def __sub__(self, offset: list[float] | tuple[float, float]) -> "DraggableRectan
456455 return self .__add__ ([- dx , - dy ])
457456
458457 @saves_history
459- def __rsub__ (self , offset : list [ float ] | tuple [float , float ]) -> "DraggableRectangle" :
458+ def __rsub__ (self , offset : Union [ List [ float ], Tuple [float , float ] ]) -> "DraggableRectangle" :
460459 """
461460 Right-hand subtraction (offset - rect).
462461
@@ -487,7 +486,7 @@ def __rsub__(self, offset: list[float] | tuple[float, float]) -> "DraggableRecta
487486 return new_rect
488487
489488 @saves_history
490- def __mul__ (self , scalar : int | float ) -> "DraggableRectangle" :
489+ def __mul__ (self , scalar : Union [ int , float ] ) -> "DraggableRectangle" :
491490 """
492491 Scale rectangle size from center (returns new rectangle).
493492
@@ -526,7 +525,7 @@ def __mul__(self, scalar: int | float) -> "DraggableRectangle":
526525 )
527526 return new_rect
528527
529- def __rmul__ (self , scalar : int | float ) -> "DraggableRectangle" :
528+ def __rmul__ (self , scalar : Union [ int , float ] ) -> "DraggableRectangle" :
530529 """
531530 Right-hand multiplication (commutative).
532531
@@ -538,7 +537,7 @@ def __rmul__(self, scalar: int | float) -> "DraggableRectangle":
538537 """
539538 return self .__mul__ (scalar )
540539
541- def __truediv__ (self , scalar : int | float ) -> "DraggableRectangle" :
540+ def __truediv__ (self , scalar : Union [ int , float ] ) -> "DraggableRectangle" :
542541 """
543542 Scale rectangle size down (divide) from center.
544543
@@ -564,7 +563,7 @@ def __truediv__(self, scalar: int | float) -> "DraggableRectangle":
564563
565564 return self .__mul__ (1 / scalar )
566565
567- def __floordiv__ (self , scalar : int | float ) -> "DraggableRectangle" :
566+ def __floordiv__ (self , scalar : Union [ int , float ] ) -> "DraggableRectangle" :
568567 """
569568 Integer division scaling from center.
570569
@@ -591,7 +590,7 @@ def __floordiv__(self, scalar: int | float) -> "DraggableRectangle":
591590 return self .__mul__ (1 // scalar if isinstance (scalar , int ) else int (1 / scalar ))
592591
593592 @saves_history
594- def __iadd__ (self , offset : list [ float ] | tuple [float , float ]) -> "DraggableRectangle" :
593+ def __iadd__ (self , offset : Union [ List [ float ], Tuple [float , float ] ]) -> "DraggableRectangle" :
595594 """
596595 Translate rectangle in-place (modifies this rectangle).
597596
@@ -612,7 +611,7 @@ def __iadd__(self, offset: list[float] | tuple[float, float]) -> "DraggableRecta
612611 self .canvas .move (self .resize_handle , dx , dy )
613612 return self
614613
615- def __isub__ (self , offset : list [ float ] | tuple [float , float ]) -> "DraggableRectangle" :
614+ def __isub__ (self , offset : Union [ List [ float ], Tuple [float , float ] ]) -> "DraggableRectangle" :
616615 """
617616 Translate rectangle in-place by negative offset.
618617
@@ -632,7 +631,7 @@ def __isub__(self, offset: list[float] | tuple[float, float]) -> "DraggableRecta
632631 return self .__iadd__ ([- dx , - dy ])
633632
634633 @saves_history
635- def __imul__ (self , scalar : int | float ) -> "DraggableRectangle" :
634+ def __imul__ (self , scalar : Union [ int , float ] ) -> "DraggableRectangle" :
636635 """
637636 Scale rectangle in-place from center.
638637
@@ -669,7 +668,7 @@ def __imul__(self, scalar: int | float) -> "DraggableRectangle":
669668 self .canvas .coords (self .resize_handle , new_x1 , new_y1 )
670669 return self
671670
672- def __itruediv__ (self , scalar : int | float ) -> "DraggableRectangle" :
671+ def __itruediv__ (self , scalar : Union [ int , float ] ) -> "DraggableRectangle" :
673672 """
674673 Scale rectangle in-place (divide size).
675674
@@ -851,10 +850,10 @@ def _save_history(self) -> None:
851850 canvas .save_state ()
852851
853852 @classmethod
854- def get_instances (cls ) -> list ["DraggableRectangle" ]:
853+ def get_instances (cls ) -> List ["DraggableRectangle" ]:
855854 """Get all currently alive DraggableRectangle instances."""
856- alive : list [ " DraggableRectangle" ] = []
857- new_refs : list [weakref .ref ] = []
855+ alive : List [ DraggableRectangle ] = []
856+ new_refs : List [weakref .ref ] = []
858857 for ref in cls ._instances :
859858 obj = ref ()
860859 if obj is not None :
@@ -865,10 +864,10 @@ def get_instances(cls) -> list["DraggableRectangle"]:
865864
866865 def set_topleft_pos (
867866 self ,
868- new_pos : list [float ],
869- relative_pos : list [ float ] | None = None ,
867+ new_pos : List [float ],
868+ relative_pos : Optional [ List [ float ]] = None ,
870869 in_mm : bool = False ,
871- dpi : int | None = None ,
870+ dpi : Optional [ int ] = None ,
872871 ) -> None :
873872 """
874873 Set the top-left position of the rectangle.
@@ -904,10 +903,10 @@ def set_topleft_pos(
904903
905904 def set_bottomright_pos (
906905 self ,
907- new_pos : list [float ],
908- relative_pos : list [ float ] | None = None ,
906+ new_pos : List [float ],
907+ relative_pos : Optional [ List [ float ]] = None ,
909908 in_mm : bool = False ,
910- dpi : int | None = None ,
909+ dpi : Optional [ int ] = None ,
911910 ) -> None :
912911 """
913912 Set the bottom-right position of the rectangle (resize operation).
@@ -936,7 +935,9 @@ def set_bottomright_pos(
936935 self .canvas .coords (self .rect , x0 , y0 , new_pos [0 ], new_pos [1 ])
937936 self .canvas .coords (self .resize_handle , new_pos [0 ], new_pos [1 ])
938937
939- def set_size (self , new_size : list [float ], in_mm : bool = False , dpi : int | None = None ) -> None :
938+ def set_size (
939+ self , new_size : List [float ], in_mm : bool = False , dpi : Optional [int ] = None
940+ ) -> None :
940941 """
941942 Set the size of the rectangle.
942943
@@ -962,10 +963,10 @@ def set_size(self, new_size: list[float], in_mm: bool = False, dpi: int | None =
962963
963964 def get_topleft_pos (
964965 self ,
965- relative_pos : list [ float ] | None = None ,
966+ relative_pos : Optional [ List [ float ]] = None ,
966967 in_mm : bool = False ,
967- dpi : int | None = None ,
968- ) -> list [float ]:
968+ dpi : Optional [ int ] = None ,
969+ ) -> List [float ]:
969970 """
970971 Get the top-left position of the rectangle.
971972
@@ -999,10 +1000,10 @@ def get_topleft_pos(
9991000
10001001 def get_bottomright_pos (
10011002 self ,
1002- relative_pos : list [ float ] | None = None ,
1003+ relative_pos : Optional [ List [ float ]] = None ,
10031004 in_mm : bool = False ,
1004- dpi : int | None = None ,
1005- ) -> list [float ]:
1005+ dpi : Optional [ int ] = None ,
1006+ ) -> List [float ]:
10061007 """
10071008 Get the bottom-right position of the rectangle.
10081009
@@ -1034,7 +1035,7 @@ def get_bottomright_pos(
10341035
10351036 return [x1 , y1 ]
10361037
1037- def get_size (self , in_mm : bool = False , dpi : int | None = None ) -> list [float ]:
1038+ def get_size (self , in_mm : bool = False , dpi : Optional [ int ] = None ) -> List [float ]:
10381039 """
10391040 Get the size of the rectangle.
10401041
@@ -1116,9 +1117,9 @@ def safe_rotate(self, angle: int, anchor: str = "topleft") -> None:
11161117 @saves_history
11171118 def align (
11181119 cls ,
1119- rectangles : list ["DraggableRectangle" ],
1120+ rectangles : List ["DraggableRectangle" ],
11201121 mode : str ,
1121- relative_pos : list [ float ] | None = None ,
1122+ relative_pos : Optional [ List [ float ]] = None ,
11221123 ) -> None :
11231124 """
11241125 Align multiple rectangles relative to the first rectangle.
@@ -1170,9 +1171,9 @@ def align(
11701171 @saves_history
11711172 def distribute (
11721173 cls ,
1173- rectangles : list ["DraggableRectangle" ],
1174+ rectangles : List ["DraggableRectangle" ],
11741175 mode : str ,
1175- relative_pos : list [ float ] | None = None ,
1176+ relative_pos : Optional [ List [ float ]] = None ,
11761177 ) -> None :
11771178 """
11781179 Distribute multiple rectangles evenly with equal spacing.
@@ -1228,7 +1229,7 @@ def distribute(
12281229 rect .set_topleft_pos ([current_x , y ], relative_pos = [ox , oy ])
12291230 y += (rc [3 ] - rc [1 ]) + space_between
12301231
1231- def copy_ (self , offset : list [ float ] | None = None , ** kwargs : Any ) -> "DraggableRectangle" :
1232+ def copy_ (self , offset : Optional [ List [ float ]] = None , ** kwargs : Any ) -> "DraggableRectangle" :
12321233 """
12331234 Create a copy of this rectangle at an offset position.
12341235
@@ -1272,7 +1273,7 @@ def copy_(self, offset: list[float] | None = None, **kwargs: Any) -> "DraggableR
12721273 )
12731274
12741275 @classmethod
1275- def compare (cls , rect1 : "DraggableRectangle" , rect2 : "DraggableRectangle" ) -> tuple [bool , dict ]:
1276+ def compare (cls , rect1 : "DraggableRectangle" , rect2 : "DraggableRectangle" ) -> Tuple [bool , Dict ]:
12761277 """
12771278 Compare two rectangles for equality with detailed information.
12781279
@@ -1474,7 +1475,7 @@ def _builtin_on_resize_end(self, event: "Event") -> None:
14741475 if hasattr (self .canvas , "_on_objects_changed" ):
14751476 self .canvas ._on_objects_changed ()
14761477
1477- def convert_mm_to_px (self , millimeters : float , dpi : int | None = None ) -> int :
1478+ def convert_mm_to_px (self , millimeters : float , dpi : Optional [ int ] = None ) -> int :
14781479 """
14791480 Convert millimeters to pixels using DPI.
14801481
@@ -1490,7 +1491,7 @@ def convert_mm_to_px(self, millimeters: float, dpi: int | None = None) -> int:
14901491 """
14911492 return mm_to_px (millimeters , dpi if dpi is not None else self .dpi )
14921493
1493- def convert_px_to_mm (self , pixels : float , dpi : int | None = None ) -> float :
1494+ def convert_px_to_mm (self , pixels : float , dpi : Optional [ int ] = None ) -> float :
14941495 """
14951496 Convert pixels to millimeters using DPI.
14961497
0 commit comments