5
5
"""
6
6
Display Text module helper functions
7
7
"""
8
+ try :
9
+ from typing import Tuple
10
+ except ImportError :
11
+ pass
8
12
from displayio import Group , Palette
9
13
10
14
11
- def wrap_text_to_pixels (string , max_width , font = None , indent0 = "" , indent1 = "" ):
15
+ def wrap_text_to_pixels (
16
+ string : str , max_width : int , font = None , indent0 : str = "" , indent1 : str = ""
17
+ ) -> None :
12
18
"""wrap_text_to_pixels function
13
19
A helper that will return a list of lines with word-break wrapping.
14
20
Leading and trailing whitespace in your string will be removed. If
@@ -26,7 +32,7 @@ def wrap_text_to_pixels(string, max_width, font=None, indent0="", indent1=""):
26
32
input text at max_width pixels size
27
33
28
34
"""
29
- # pylint: disable=too-many-locals too-many-branches
35
+ # pylint: disable=too-many-locals, too-many-branches
30
36
if font is None :
31
37
32
38
def measure (string ):
@@ -173,37 +179,36 @@ class LabelBase(Group):
173
179
:param int scale: Integer value of the pixel scaling
174
180
:param bool save_text: Set True to save the text string as a constant in the
175
181
label structure. Set False to reduce memory use.
176
- :param: bool base_alignment: when True allows to align text label to the baseline.
182
+ :param bool base_alignment: when True allows to align text label to the baseline.
177
183
This is helpful when two or more labels need to be aligned to the same baseline
178
- :param: (int,str) tab_replacement: tuple with tab character replace information. When
184
+ :param (int,str) tab_replacement: tuple with tab character replace information. When
179
185
(4, " ") will indicate a tab replacement of 4 spaces, defaults to 4 spaces by
180
186
tab character"""
181
187
182
188
# pylint: disable=unused-argument, too-many-instance-attributes, too-many-locals, too-many-arguments
183
189
def __init__ (
184
190
self ,
185
191
font ,
186
- x = 0 ,
187
- y = 0 ,
188
- text = "" ,
189
- max_glyphs = None ,
190
- # with label.py
191
- color = 0xFFFFFF ,
192
- background_color = None ,
193
- line_spacing = 1.25 ,
194
- background_tight = False ,
195
- padding_top = 0 ,
196
- padding_bottom = 0 ,
197
- padding_left = 0 ,
198
- padding_right = 0 ,
199
- anchor_point = None ,
200
- anchored_position = None ,
201
- save_text = True , # can reduce memory use if save_text = False
202
- scale = 1 ,
203
- base_alignment = False ,
204
- tab_replacement = (4 , " " ),
192
+ x : int = 0 ,
193
+ y : int = 0 ,
194
+ text : str = "" ,
195
+ max_glyphs : int = None ,
196
+ color : int = 0xFFFFFF ,
197
+ background_color : int = None ,
198
+ line_spacing : float = 1.25 ,
199
+ background_tight : bool = False ,
200
+ padding_top : int = 0 ,
201
+ padding_bottom : int = 0 ,
202
+ padding_left : int = 0 ,
203
+ padding_right : int = 0 ,
204
+ anchor_point : Tuple [float , float ] = None ,
205
+ anchored_position : Tuple [int , int ] = None ,
206
+ save_text : bool = True , # can reduce memory use if save_text = False
207
+ scale : int = 1 ,
208
+ base_alignment : bool = False ,
209
+ tab_replacement : Tuple [int , str ] = (4 , " " ),
205
210
** kwargs ,
206
- ):
211
+ ) -> None :
207
212
super ().__init__ (max_size = 1 , x = x , y = y , scale = 1 )
208
213
209
214
self ._font = font
@@ -221,8 +226,16 @@ def __init__(
221
226
self .local_group = None
222
227
223
228
self ._text = text
229
+ self .baseline = - 1.0
224
230
225
- def _get_ascent_descent (self ):
231
+ self .base_alignment = base_alignment
232
+
233
+ if self .base_alignment :
234
+ self ._y_offset = 0
235
+ else :
236
+ self ._y_offset = self ._get_ascent () // 2
237
+
238
+ def _get_ascent_descent (self ) -> Tuple [int , int ]:
226
239
""" Private function to calculate ascent and descent font values """
227
240
if hasattr (self .font , "ascent" ):
228
241
return self .font .ascent , self .font .descent
@@ -243,29 +256,29 @@ def _get_ascent_descent(self):
243
256
descender_max = max (descender_max , - this_glyph .dy )
244
257
return ascender_max , descender_max
245
258
246
- def _get_ascent (self ):
259
+ def _get_ascent (self ) -> int :
247
260
return self ._get_ascent_descent ()[0 ]
248
261
249
262
@property
250
- def font (self ):
263
+ def font (self ) -> None :
251
264
"""Font to use for text display."""
252
265
return self ._font
253
266
254
- def _set_font (self , new_font ):
267
+ def _set_font (self , new_font ) -> None :
255
268
# subclasses should override this
256
269
pass
257
270
258
271
@font .setter
259
- def font (self , new_font ):
272
+ def font (self , new_font ) -> None :
260
273
self ._set_font (new_font )
261
274
262
275
@property
263
- def color (self ):
276
+ def color (self ) -> int :
264
277
"""Color of the text as an RGB hex number."""
265
278
return self ._color
266
279
267
280
@color .setter
268
- def color (self , new_color ):
281
+ def color (self , new_color : int ):
269
282
self ._color = new_color
270
283
if new_color is not None :
271
284
self .palette [1 ] = new_color
@@ -275,7 +288,7 @@ def color(self, new_color):
275
288
self .palette .make_transparent (1 )
276
289
277
290
@property
278
- def background_color (self ):
291
+ def background_color (self ) -> int :
279
292
"""Color of the background as an RGB hex number."""
280
293
return self ._background_color
281
294
@@ -284,31 +297,34 @@ def _set_background_color(self, new_color):
284
297
pass
285
298
286
299
@background_color .setter
287
- def background_color (self , new_color ) :
300
+ def background_color (self , new_color : int ) -> None :
288
301
self ._set_background_color (new_color )
289
302
290
303
@property
291
- def anchor_point (self ):
304
+ def anchor_point (self ) -> Tuple [ float , float ] :
292
305
"""Point that anchored_position moves relative to.
293
306
Tuple with decimal percentage of width and height.
294
307
(E.g. (0,0) is top left, (1.0, 0.5): is middle right.)"""
295
308
return self ._anchor_point
296
309
297
310
@anchor_point .setter
298
- def anchor_point (self , new_anchor_point ):
299
- self ._anchor_point = new_anchor_point
311
+ def anchor_point (self , new_anchor_point : Tuple [float , float ]) -> None :
312
+ if new_anchor_point [1 ] == self .baseline :
313
+ self ._anchor_point = (new_anchor_point [0 ], - 1.0 )
314
+ else :
315
+ self ._anchor_point = new_anchor_point
300
316
self .anchored_position = (
301
317
self ._anchored_position
302
318
) # update the anchored_position using setter
303
319
304
320
@property
305
- def anchored_position (self ):
321
+ def anchored_position (self ) -> Tuple [ int , int ] :
306
322
"""Position relative to the anchor_point. Tuple containing x,y
307
323
pixel coordinates."""
308
324
return self ._anchored_position
309
325
310
326
@anchored_position .setter
311
- def anchored_position (self , new_position ) :
327
+ def anchored_position (self , new_position : Tuple [ int , int ]) -> None :
312
328
self ._anchored_position = new_position
313
329
# Set anchored_position
314
330
if (self ._anchor_point is not None ) and (self ._anchored_position is not None ):
@@ -317,51 +333,54 @@ def anchored_position(self, new_position):
317
333
- (self ._bounding_box [0 ] * self .scale )
318
334
- round (self ._anchor_point [0 ] * (self ._bounding_box [2 ] * self .scale ))
319
335
)
320
- self .y = int (
321
- new_position [1 ]
322
- - (self ._bounding_box [1 ] * self .scale )
323
- - round (self ._anchor_point [1 ] * self ._bounding_box [3 ] * self .scale )
324
- )
336
+ if self ._anchor_point [1 ] == self .baseline :
337
+ self .y = int (new_position [1 ] - (self ._y_offset * self .scale ))
338
+ else :
339
+ self .y = int (
340
+ new_position [1 ]
341
+ - (self ._bounding_box [1 ] * self .scale )
342
+ - round (self ._anchor_point [1 ] * self ._bounding_box [3 ] * self .scale )
343
+ )
325
344
326
345
@property
327
- def scale (self ):
346
+ def scale (self ) -> int :
328
347
"""Set the scaling of the label, in integer values"""
329
348
return self .local_group .scale
330
349
331
350
@scale .setter
332
- def scale (self , new_scale ) :
351
+ def scale (self , new_scale : int ) -> None :
333
352
self .local_group .scale = new_scale
334
353
self .anchored_position = self ._anchored_position # update the anchored_position
335
354
336
- def _set_text (self , new_text , scale ) :
355
+ def _set_text (self , new_text : str , scale : int ) -> None :
337
356
# subclasses should override this
338
357
pass
339
358
340
359
@property
341
- def text (self ):
360
+ def text (self ) -> str :
342
361
"""Text to be displayed."""
343
362
return self ._text
344
363
345
364
@text .setter # Cannot set color or background color with text setter, use separate setter
346
- def text (self , new_text ) :
365
+ def text (self , new_text : str ) -> None :
347
366
self ._set_text (new_text , self .scale )
348
367
349
368
@property
350
- def bounding_box (self ):
369
+ def bounding_box (self ) -> Tuple [ int , int ] :
351
370
"""An (x, y, w, h) tuple that completely covers all glyphs. The
352
371
first two numbers are offset from the x, y origin of this group"""
353
372
return tuple (self ._bounding_box )
354
373
355
374
@property
356
- def line_spacing (self ):
375
+ def line_spacing (self ) -> float :
357
376
"""The amount of space between lines of text, in multiples of the font's
358
377
bounding-box height. (E.g. 1.0 is the bounding-box height)"""
359
378
return self ._line_spacing
360
379
361
- def _set_line_spacing (self , new_line_spacing ) :
380
+ def _set_line_spacing (self , new_line_spacing : float ) -> None :
362
381
# subclass should override this.
363
382
pass
364
383
365
384
@line_spacing .setter
366
- def line_spacing (self , new_line_spacing ) :
385
+ def line_spacing (self , new_line_spacing : float ) -> None :
367
386
self ._set_line_spacing (new_line_spacing )
0 commit comments