2020# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121# THE SOFTWARE.
2222"""
23- `adafruit_display_text`
23+ `adafruit_display_text.text_area `
2424====================================================
2525
2626Displays text using CircuitPython's displayio.
4444__version__ = "0.0.0-auto.0"
4545__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git"
4646
47+ class TextArea (displayio .Group ):
48+ """An area displaying a string of textself.
4749
48- class TextArea :
49- def __init__ (self , font , * , text = None , width = None , color = 0x0 , height = 1 ):
50+ :param Font font: A font class that has ``get_bounding_box`` and ``get_glyph``
51+ :param str text: Text to display
52+ :param int width: Area width in characters
53+ :param int height: Area height in characters
54+ :param int color: Color of all text in RGB hex"""
55+ def __init__ (self , font , * , text = None , width = None , height = 1 , color = 0xffffff ):
5056 if not width and not text :
5157 raise RuntimeError ("Please provide a width" )
5258 if not width :
5359 width = len (text )
60+ super ().__init__ (max_size = width * height )
5461 self .width = width
5562 self .font = font
5663 self ._text = None
5764
58- self .p = displayio .Palette (2 )
59- self .p .make_transparent (0 )
60- self .p [1 ] = color
61-
62- self .group = displayio .Group (max_size = width * height )
65+ self .palette = displayio .Palette (2 )
66+ self .palette .make_transparent (0 )
67+ self .palette [1 ] = color
6368
6469 bounds = self .font .get_bounding_box ()
6570 self .height = bounds [1 ]
6671
67- self .sprites = [None ] * (width * height )
68-
69- self ._x = 0
70- self ._y = 0
71-
7272 if text :
7373 self ._update_text (text )
7474
@@ -77,79 +77,56 @@ def _update_text(self, new_text):
7777 x = 0
7878 y = 0
7979 i = 0
80- first_different = self . _text is not None
81- for c in new_text :
82- if chr ( ord ( c )) == '\n ' :
80+ old_c = 0
81+ for character in new_text :
82+ if character == '\n ' :
8383 y += int (self .height * 1.25 )
8484 x = 0
8585 continue
86- glyph = self .font .get_glyph (ord (c ))
86+ glyph = self .font .get_glyph (ord (character ))
8787 if not glyph :
8888 continue
89- # Remove any characters that are different
90- if first_different and c != self ._text [i ]:
91- # TODO(tannewt): Make this smarter when we can remove and add things into the middle
92- # of a group.
93- for _ in range (len (self .sprites ) - i ):
94- try :
95- self .group .pop ()
96- except IndexError :
97- break
98- first_different = False
99- if not first_different :
100- position = (self ._x + x , self ._y + y + self .height - glyph ["bounds" ][1 ] - glyph ["bounds" ][3 ])
101- try :
102- face = displayio .TileGrid (glyph ["bitmap" ], pixel_shader = self .p , position = position )
103- except :
104- face = displayio .Sprite (glyph ["bitmap" ], pixel_shader = self .p , position = position )
105- self .group .append (face )
106- self .sprites [i ] = face
107- x += glyph ["shift" ][0 ]
89+ position_y = y + self .height - glyph .height - glyph .dy
90+ if not self ._text or old_c >= len (self ._text ) or character != self ._text [old_c ]:
91+ face = displayio .TileGrid (glyph .bitmap , pixel_shader = self .palette ,
92+ default_tile = glyph .tile_index ,
93+ tile_width = glyph .width , tile_height = glyph .height ,
94+ position = (x , position_y ))
95+ if i < len (self ):
96+ self [i ] = face
97+ else :
98+ self .append (face )
99+ elif self ._text and character == self ._text [old_c ]:
100+ self [i ].position = (x , position_y )
101+
102+ x += glyph .shift_x
108103
109104 # TODO skip this for control sequences or non-printables.
110105 i += 1
111-
112- # TODO: support multiple lines by adjusting y
106+ old_c += 1
107+ # skip all non-prinables in the old string
108+ while (self ._text and old_c < len (self ._text ) and
109+ (self ._text [old_c ] == '\n ' or not self .font .get_glyph (ord (self ._text [old_c ])))):
110+ old_c += 1
111+ # Remove the rest
112+ while len (self ) > i :
113+ self .pop ()
113114 self ._text = new_text
114115
115116 @property
116117 def color (self ):
117- return self .p [1 ]
118+ """Color of the text as an RGB hex number."""
119+ return self .palette [1 ]
118120
119121 @color .setter
120- def color (self , c ):
121- self .p [1 ] = c
122+ def color (self , new_color ):
123+ self .palette [1 ] = new_color
122124
123125 @property
124- def text (self , t ):
125- self ._text = t
126+ def text (self ):
127+ """Text to display."""
128+ return self ._text
126129
127130 @text .setter
128- def text (self , t ):
129- self ._update_text (t )
130-
131- @property
132- def y (self ):
133- return self ._y
134-
135- @y .setter
136- def y (self , new_y ):
137- for sprite in self .sprites :
138- if not sprite :
139- continue
140- pos = sprite .position
141- sprite .position = (pos [0 ], (pos [1 ] - self ._y ) + new_y )
142- self ._y = new_y
143-
144- @property
145- def x (self ):
146- return self ._x
147-
148- @x .setter
149- def x (self , new_x ):
150- for sprite in self .sprites :
151- if not sprite :
152- continue
153- pos = sprite .position
154- sprite .position = ((pos [0 ] - self ._x ) + new_x , pos [1 ])
155- self ._x = new_x
131+ def text (self , new_text ):
132+ self ._update_text (new_text )
0 commit comments