33from PIL import Image
44import adafruit_display_text
55
6- from .tile_grid import TileGrid , bmp_img , img
6+ from .tile_grid import TileGrid
77from . import constants as CONSTANTS
88
99import common
10+ import board
1011
1112# Group implementation loosely based on the
1213# displayio.Group class in Adafruit CircuitPython
1617
1718
1819class Group :
19- def __init__ (self , max_size , scale = 1 , auto_write = True ):
20+ def __init__ (self , max_size , scale = 1 , check_active_group_ref = True , auto_write = True ):
21+ self .__check_active_group_ref = check_active_group_ref
22+ self .__auto_write = auto_write
2023 self .__contents = []
2124 self .max_size = max_size
2225 self .scale = scale
23- self .auto_write = auto_write
24- self .in_group = False
26+ self .parent = None
27+
28+ @property
29+ def in_group (self ):
30+ return self .parent != None
2531
2632 def append (self , item ):
2733 if len (self .__contents ) == self .max_size :
@@ -32,19 +38,47 @@ def append(self, item):
3238 raise ValueError (CONSTANTS .LAYER_ALREADY_IN_GROUP )
3339
3440 self .__contents .append (item )
35- item .in_group = True
36- if self .auto_write :
37- self .draw (show = True )
41+ item .parent = self
42+
43+ self .__elem_changed ()
44+
45+ def __elem_changed (self ):
46+ # Ensure that this group is what the board is currently showing.
47+ # Otherwise, don't bother to draw it.
48+ if (
49+ self .__auto_write
50+ and self .__check_active_group_ref
51+ and board .DISPLAY .active_group == self
52+ ):
53+ self .draw ()
54+
55+ elif self .in_group :
56+
57+ # If a sub-group is modified, propagate to top level to
58+ # see if one of the parents are the current active group.
59+ self .parent .__elem_changed ()
3860
3961 def __getitem__ (self , index ):
4062 return self .__contents [index ]
4163
4264 def __setitem__ (self , index , val ):
65+ old_val = self .__contents [index ]
66+
4367 self .__contents [index ] = val
4468
45- def draw (self , x = 0 , y = 0 , scale = None , show = False ):
69+ if old_val != val :
70+ self .__elem_changed ()
71+
72+ def draw (self , img = None , x = 0 , y = 0 , scale = None , show = True ):
4673 # this function is not a part of the orignal implementation
47- # it is what prints itself and its children to the frontend
74+ # it is what draws itself and its children and potentially shows it to the
75+ # frontend
76+ if img == None :
77+ img = Image .new (
78+ "RGBA" ,
79+ (CONSTANTS .SCREEN_HEIGHT_WIDTH , CONSTANTS .SCREEN_HEIGHT_WIDTH ),
80+ (0 , 0 , 0 , 0 ),
81+ )
4882 if scale is None :
4983 scale = self .scale
5084 else :
@@ -55,11 +89,11 @@ def draw(self, x=0, y=0, scale=None, show=False):
5589 # adafruit_display_text has some positioning considerations
5690 # that need to be handled.
5791
58- # found manually, display must be positioned upwards
92+ # This was found manually, display must be positioned upwards
5993 # 1 unit (1 unit * scale = scale)
6094 y -= scale
6195
62- # group is positioned against anchored_position (default (0,0)),
96+ # Group is positioned against anchored_position (default (0,0)),
6397 # which is positioned against anchor_point
6498
6599 x += self ._anchor_point [0 ]
@@ -72,15 +106,19 @@ def draw(self, x=0, y=0, scale=None, show=False):
72106
73107 for elem in self .__contents :
74108 if isinstance (elem , Group ):
75- elem .draw (x , y , scale , False )
109+ img = elem .draw (img = img , x = x , y = y , scale = scale , show = False , )
76110 else :
77- elem .draw (x , y , scale )
111+ img = elem .draw (img = img , x = x , y = y , scale = scale )
78112
113+ # show should only be true to the highest parent group
79114 if show :
80- self .show ()
115+ self .show (img )
116+
117+ # return value only used if this is within another group
118+ return img
81119
82- def show (self ):
83- # sends current bmp_img to the frontend
120+ def show (self , img ):
121+ # sends current img to the frontend
84122 buffered = BytesIO ()
85123 img .save (buffered , format = "BMP" )
86124 byte_base64 = base64 .b64encode (buffered .getvalue ())
@@ -102,4 +140,7 @@ def __len__(self):
102140 return len (self .__contents )
103141
104142 def pop (self , i = - 1 ):
105- return self .__contents .pop (i )
143+ item = self .__contents .pop (i )
144+ item .parent = None
145+ self .__elem_changed ()
146+ return item
0 commit comments