Skip to content

Commit c31c0ef

Browse files
authored
Merge pull request #154 from lesamouraipourpre/refactor
Refactor the classes
2 parents 5b0c5fe + b3acf4f commit c31c0ef

6 files changed

+294
-353
lines changed

adafruit_display_text/__init__.py

Lines changed: 83 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
def wrap_text_to_pixels(
1818
string: str, max_width: int, font=None, indent0: str = "", indent1: str = ""
1919
) -> List[str]:
20+
# pylint: disable=too-many-branches, too-many-locals
21+
2022
"""wrap_text_to_pixels function
2123
A helper that will return a list of lines with word-break wrapping.
2224
Leading and trailing whitespace in your string will be removed. If
@@ -34,18 +36,17 @@ def wrap_text_to_pixels(
3436
:rtype: List[str]
3537
3638
"""
37-
# pylint: disable=too-many-locals, too-many-branches
3839
if font is None:
3940

40-
def measure(string):
41-
return len(string)
41+
def measure(text):
42+
return len(text)
4243

4344
else:
4445
if hasattr(font, "load_glyphs"):
4546
font.load_glyphs(string)
4647

47-
def measure(string):
48-
return sum(font.get_glyph(ord(c)).shift_x for c in string)
48+
def measure(text):
49+
return sum(font.get_glyph(ord(c)).shift_x for c in text)
4950

5051
lines = []
5152
partial = [indent0]
@@ -153,6 +154,8 @@ def chunks(lst, n):
153154

154155

155156
class LabelBase(Group):
157+
# pylint: disable=too-many-instance-attributes
158+
156159
"""Superclass that all other types of labels will extend. This contains
157160
all of the properties and functions that work the same way in all labels.
158161
@@ -164,8 +167,6 @@ class LabelBase(Group):
164167
:param Font font: A font class that has ``get_bounding_box`` and ``get_glyph``.
165168
Must include a capital M for measuring character size.
166169
:param str text: Text to display
167-
:param int max_glyphs: Unnecessary parameter (provided only for direct compability
168-
with :py:func:`~adafruit_display_text.label.Label`)
169170
:param int color: Color of all text in RGB hex
170171
:param int background_color: Color of the background, use `None` for transparent
171172
:param float line_spacing: Line spacing of text to display
@@ -181,25 +182,20 @@ class LabelBase(Group):
181182
:param (int,int) anchored_position: Position relative to the anchor_point. Tuple
182183
containing x,y pixel coordinates.
183184
:param int scale: Integer value of the pixel scaling
184-
:param bool save_text: Set True to save the text string as a constant in the
185-
label structure. Set False to reduce memory use.
186185
:param bool base_alignment: when True allows to align text label to the baseline.
187186
This is helpful when two or more labels need to be aligned to the same baseline
188187
:param (int,str) tab_replacement: tuple with tab character replace information. When
189188
(4, " ") will indicate a tab replacement of 4 spaces, defaults to 4 spaces by
190189
tab character
191-
:param str label_direction: string defining the label text orientation. There are 5
192-
configurations possibles ``LTR``-Left-To-Right ``RTL``-Right-To-Left
193-
``TTB``-Top-To-Bottom ``UPR``-Upwards ``DWR``-Downwards. It defaults to ``LTR``"""
190+
:param str label_direction: string defining the label text orientation. See the
191+
subclass documentation for the possible values."""
194192

195-
# pylint: disable=unused-argument, too-many-instance-attributes, too-many-locals, too-many-arguments
196193
def __init__(
197194
self,
198195
font,
199196
x: int = 0,
200197
y: int = 0,
201198
text: str = "",
202-
max_glyphs: int = None,
203199
color: int = 0xFFFFFF,
204200
background_color: int = None,
205201
line_spacing: float = 1.25,
@@ -210,46 +206,59 @@ def __init__(
210206
padding_right: int = 0,
211207
anchor_point: Tuple[float, float] = None,
212208
anchored_position: Tuple[int, int] = None,
213-
save_text: bool = True, # can reduce memory use if save_text = False
214209
scale: int = 1,
215210
base_alignment: bool = False,
216211
tab_replacement: Tuple[int, str] = (4, " "),
217212
label_direction: str = "LTR",
218-
**kwargs,
213+
**kwargs, # pylint: disable=unused-argument
219214
) -> None:
215+
# pylint: disable=too-many-arguments, too-many-locals
216+
220217
super().__init__(x=x, y=y, scale=1)
221218

222219
self._font = font
223-
self._ascent, self._descent = self._get_ascent_descent()
224-
self.palette = Palette(2)
225-
self._color = color
226-
self._background_color = background_color
227-
228-
self._bounding_box = None
220+
self._text = text
221+
self._palette = Palette(2)
222+
self._color = 0xFFFFFF
223+
self._background_color = None
224+
self._line_spacing = line_spacing
225+
self._background_tight = background_tight
226+
self._padding_top = padding_top
227+
self._padding_bottom = padding_bottom
228+
self._padding_left = padding_left
229+
self._padding_right = padding_right
229230
self._anchor_point = anchor_point
230231
self._anchored_position = anchored_position
232+
self._base_alignment = base_alignment
233+
self._label_direction = label_direction
234+
self._tab_replacement = tab_replacement
235+
self._tab_text = self._tab_replacement[1] * self._tab_replacement[0]
231236

232-
# local group will hold background and text
233-
# the self group scale should always remain at 1, the self.local_group will
234-
# be used to set the scale of the label
235-
self.local_group = None
237+
if "max_glyphs" in kwargs:
238+
print("Please update your code: 'max_glyphs' is not needed anymore.")
236239

237-
self._text = text
240+
self._ascent, self._descent = self._get_ascent_descent()
241+
self._bounding_box = None
238242

239-
self._label_direction = label_direction
243+
self.color = color
244+
self.background_color = background_color
240245

241-
self.baseline = -1.0
246+
# local group will hold background and text
247+
# the self group scale should always remain at 1, the self._local_group will
248+
# be used to set the scale of the label
249+
self._local_group = Group(scale=scale)
250+
self.append(self._local_group)
242251

243-
self.base_alignment = base_alignment
252+
self._baseline = -1.0
244253

245-
if self.base_alignment:
254+
if self._base_alignment:
246255
self._y_offset = 0
247256
else:
248257
self._y_offset = self._ascent // 2
249258

250259
def _get_ascent_descent(self) -> Tuple[int, int]:
251260
""" Private function to calculate ascent and descent font values """
252-
if hasattr(self.font, "ascent"):
261+
if hasattr(self.font, "ascent") and hasattr(self.font, "descent"):
253262
return self.font.ascent, self.font.descent
254263

255264
# check a few glyphs for maximum ascender and descender height
@@ -274,8 +283,7 @@ def font(self) -> None:
274283
return self._font
275284

276285
def _set_font(self, new_font) -> None:
277-
# subclasses should override this
278-
pass
286+
raise NotImplementedError("{} MUST override '_set_font'".format(type(self)))
279287

280288
@font.setter
281289
def font(self, new_font) -> None:
@@ -290,20 +298,21 @@ def color(self) -> int:
290298
def color(self, new_color: int):
291299
self._color = new_color
292300
if new_color is not None:
293-
self.palette[1] = new_color
294-
self.palette.make_opaque(1)
301+
self._palette[1] = new_color
302+
self._palette.make_opaque(1)
295303
else:
296-
self.palette[1] = 0
297-
self.palette.make_transparent(1)
304+
self._palette[1] = 0
305+
self._palette.make_transparent(1)
298306

299307
@property
300308
def background_color(self) -> int:
301309
"""Color of the background as an RGB hex number."""
302310
return self._background_color
303311

304312
def _set_background_color(self, new_color):
305-
# subclasses should override this
306-
pass
313+
raise NotImplementedError(
314+
"{} MUST override '_set_background_color'".format(type(self))
315+
)
307316

308317
@background_color.setter
309318
def background_color(self, new_color: int) -> None:
@@ -318,13 +327,13 @@ def anchor_point(self) -> Tuple[float, float]:
318327

319328
@anchor_point.setter
320329
def anchor_point(self, new_anchor_point: Tuple[float, float]) -> None:
321-
if new_anchor_point[1] == self.baseline:
330+
if new_anchor_point[1] == self._baseline:
322331
self._anchor_point = (new_anchor_point[0], -1.0)
323332
else:
324333
self._anchor_point = new_anchor_point
325-
self.anchored_position = (
326-
self._anchored_position
327-
) # update the anchored_position using setter
334+
335+
# update the anchored_position using setter
336+
self.anchored_position = self._anchored_position
328337

329338
@property
330339
def anchored_position(self) -> Tuple[int, int]:
@@ -335,14 +344,14 @@ def anchored_position(self) -> Tuple[int, int]:
335344
@anchored_position.setter
336345
def anchored_position(self, new_position: Tuple[int, int]) -> None:
337346
self._anchored_position = new_position
338-
# Set anchored_position
347+
# Calculate (x,y) position
339348
if (self._anchor_point is not None) and (self._anchored_position is not None):
340349
self.x = int(
341350
new_position[0]
342351
- (self._bounding_box[0] * self.scale)
343352
- round(self._anchor_point[0] * (self._bounding_box[2] * self.scale))
344353
)
345-
if self._anchor_point[1] == self.baseline:
354+
if self._anchor_point[1] == self._baseline:
346355
self.y = int(new_position[1] - (self._y_offset * self.scale))
347356
else:
348357
self.y = int(
@@ -354,16 +363,15 @@ def anchored_position(self, new_position: Tuple[int, int]) -> None:
354363
@property
355364
def scale(self) -> int:
356365
"""Set the scaling of the label, in integer values"""
357-
return self.local_group.scale
366+
return self._local_group.scale
358367

359368
@scale.setter
360369
def scale(self, new_scale: int) -> None:
361-
self.local_group.scale = new_scale
370+
self._local_group.scale = new_scale
362371
self.anchored_position = self._anchored_position # update the anchored_position
363372

364373
def _set_text(self, new_text: str, scale: int) -> None:
365-
# subclasses should override this
366-
pass
374+
raise NotImplementedError("{} MUST override '_set_text'".format(type(self)))
367375

368376
@property
369377
def text(self) -> str:
@@ -380,15 +388,26 @@ def bounding_box(self) -> Tuple[int, int]:
380388
first two numbers are offset from the x, y origin of this group"""
381389
return tuple(self._bounding_box)
382390

391+
@property
392+
def height(self) -> int:
393+
"""The height of the label determined from the bounding box."""
394+
return self._bounding_box[3] - self._bounding_box[1]
395+
396+
@property
397+
def width(self) -> int:
398+
"""The width of the label determined from the bounding box."""
399+
return self._bounding_box[2] - self._bounding_box[0]
400+
383401
@property
384402
def line_spacing(self) -> float:
385403
"""The amount of space between lines of text, in multiples of the font's
386404
bounding-box height. (E.g. 1.0 is the bounding-box height)"""
387405
return self._line_spacing
388406

389407
def _set_line_spacing(self, new_line_spacing: float) -> None:
390-
# subclass should override this.
391-
pass
408+
raise NotImplementedError(
409+
"{} MUST override '_set_line_spacing'".format(type(self))
410+
)
392411

393412
@line_spacing.setter
394413
def line_spacing(self, new_line_spacing: float) -> None:
@@ -400,12 +419,21 @@ def label_direction(self) -> str:
400419
return self._label_direction
401420

402421
def _set_label_direction(self, new_label_direction: str) -> None:
403-
# subclass should override this.
404-
pass
422+
raise NotImplementedError(
423+
"{} MUST override '_set_label_direction'".format(type(self))
424+
)
425+
426+
def _get_valid_label_directions(self) -> Tuple[str, ...]:
427+
raise NotImplementedError(
428+
"{} MUST override '_get_valid_label_direction'".format(type(self))
429+
)
405430

406431
@label_direction.setter
407432
def label_direction(self, new_label_direction: str) -> None:
408433
"""Set the text direction of the label"""
409-
if new_label_direction not in ["LTR", "RTL", "UPR", "DWR", "TTB"]:
434+
if new_label_direction not in self._get_valid_label_directions():
410435
raise RuntimeError("Please provide a valid text direction")
411436
self._set_label_direction(new_label_direction)
437+
438+
def _replace_tabs(self, text):
439+
return self._tab_text.join(text.split("\t"))

0 commit comments

Comments
 (0)