Skip to content
This repository has been archived by the owner on Dec 23, 2021. It is now read-only.

Commit

Permalink
moved tarball files to clue dir (#333)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreamah authored Apr 16, 2020
1 parent 19ce7da commit 9a1adc9
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 1 deletion.
Binary file not shown.
2 changes: 2 additions & 0 deletions src/base_circuitpython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
import sys

abs_path = pathlib.Path(__file__).parent.absolute()
clue_path = os.path.join(abs_path, "../clue")
sys.path.insert(0, os.path.join(abs_path))
sys.path.insert(0, os.path.join(clue_path))
280 changes: 280 additions & 0 deletions src/clue/adafruit_display_text/label.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
# The MIT License (MIT)
#
# Copyright (c) 2019 Scott Shawcroft for Adafruit Industries LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""
`adafruit_display_text.label`
====================================================
Displays text labels using CircuitPython's displayio.
* Author(s): Scott Shawcroft
Implementation Notes
--------------------
**Hardware:**
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
"""

import displayio

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git"


class Label(displayio.Group):
"""A label displaying a string of text. The origin point set by ``x`` and ``y``
properties will be the left edge of the bounding box, and in the center of a M
glyph (if its one line), or the (number of lines * linespacing + M)/2. That is,
it will try to have it be center-left as close as possible.
:param Font font: A font class that has ``get_bounding_box`` and ``get_glyph``.
Must include a capital M for measuring character size.
:param str text: Text to display
:param int max_glyphs: The largest quantity of glyphs we will display
:param int color: Color of all text in RGB hex
:param double line_spacing: Line spacing of text to display"""

def __init__(
self,
font,
*,
x=0,
y=0,
text=None,
max_glyphs=None,
color=0xFFFFFF,
background_color=None,
line_spacing=1.25,
**kwargs
):
if not max_glyphs and not text:
raise RuntimeError("Please provide a max size, or initial text")
if not max_glyphs:
max_glyphs = len(text)
super().__init__(max_size=max_glyphs, auto_write=False, **kwargs)
self.width = max_glyphs
self.font = font
self._text = None
self._anchor_point = (0, 0)
self.x = x
self.y = y

self.palette = displayio.Palette(2)
if background_color is not None:
self.palette[0] = background_color
self.palette.make_opaque(0)
self._transparent_background = False
else:
self.palette[0] = 0
self.palette.make_transparent(0)
self._transparent_background = True
self.palette[1] = color

bounds = self.font.get_bounding_box()
self.height = bounds[1]
self._line_spacing = line_spacing
self._boundingbox = None

if text is not None:
self._update_text(str(text))

def _update_text(self, new_text): # pylint: disable=too-many-locals
x = 0
y = 0
i = 0
old_c = 0
y_offset = int(
(
self.font.get_glyph(ord("M")).height
- new_text.count("\n") * self.height * self.line_spacing
)
/ 2
)
# print("y offset from baseline", y_offset)
left = right = top = bottom = 0
for character in new_text:
if character == "\n":
y += int(self.height * self._line_spacing)
x = 0
continue
glyph = self.font.get_glyph(ord(character))
if not glyph:
continue
right = max(right, x + glyph.width)
if y == 0: # first line, find the Ascender height
top = min(top, -glyph.height + y_offset)
bottom = max(bottom, y - glyph.dy + y_offset)
position_y = y - glyph.height - glyph.dy + y_offset
position_x = x + glyph.dx
if (
not self._text
or old_c >= len(self._text)
or character != self._text[old_c]
):
try:
face = displayio.TileGrid(
glyph.bitmap,
pixel_shader=self.palette,
default_tile=glyph.tile_index,
tile_width=glyph.width,
tile_height=glyph.height,
position=(position_x, position_y),
)
except TypeError:
face = displayio.TileGrid(
glyph.bitmap,
pixel_shader=self.palette,
default_tile=glyph.tile_index,
tile_width=glyph.width,
tile_height=glyph.height,
x=position_x,
y=position_y,
)
if i < len(self):
self[i] = face
else:
self.append(face)
elif self._text and character == self._text[old_c]:
try:
self[i].position = (position_x, position_y)
except AttributeError:
self[i].x = position_x
self[i].y = position_y

x += glyph.shift_x

# TODO skip this for control sequences or non-printables.
i += 1
old_c += 1
# skip all non-prinables in the old string
while (
self._text
and old_c < len(self._text)
and (
self._text[old_c] == "\n"
or not self.font.get_glyph(ord(self._text[old_c]))
)
):
old_c += 1
# Remove the rest
while len(self) > i:
self.pop()
self._text = new_text
self._boundingbox = (left, top, left + right, bottom - top)

@property
def bounding_box(self):
"""An (x, y, w, h) tuple that completely covers all glyphs. The
first two numbers are offset from the x, y origin of this group"""
return tuple(self._boundingbox)

@property
def line_spacing(self):
"""The amount of space between lines of text, in multiples of the font's
bounding-box height. (E.g. 1.0 is the bounding-box height)"""
return self._line_spacing

@line_spacing.setter
def line_spacing(self, spacing):
if self._line_spacing != spacing:
self._line_spacing = spacing
self._Group__trigger_draw()

@property
def color(self):
"""Color of the text as an RGB hex number."""
return self.palette[1]

@color.setter
def color(self, new_color):
self.palette[1] = new_color
self._Group__trigger_draw()

@property
def background_color(self):
"""Color of the background as an RGB hex number."""
if not self._transparent_background:
return self.palette[0]
return None

@background_color.setter
def background_color(self, new_color):
if new_color is not None:
self.palette[0] = new_color
self.palette.make_opaque(0)
self._transparent_background = False
else:
self.palette[0] = 0
self.palette.make_transparent(0)
self._transparent_background = True

self._Group__trigger_draw()

@property
def text(self):
"""Text to display."""
return self._text

@text.setter
def text(self, new_text):
# APR 2, 2O2O ->
# Added manual trigger to update text since
# on-screen text updating is a lot faster this way.

# Previously, the group was set to auto_write=True
# and each letter in the group was individually
# drawn and sent to the front-end display.
if new_text != self._text:
self._update_text(str(new_text))
self._Group__trigger_draw()

@property
def anchor_point(self):
"""Point that anchored_position moves relative to.
Tuple with decimal percentage of width and height.
(E.g. (0,0) is top left, (1.0, 0.5): is middle right.)"""
return self._anchor_point

@anchor_point.setter
def anchor_point(self, new_anchor_point):
if self._anchor_point != new_anchor_point:
self._Group__trigger_draw()

@property
def anchored_position(self):
"""Position relative to the anchor_point. Tuple containing x,y
pixel coordinates."""
return (
self.x - self._boundingbox[2] * self._anchor_point[0],
self.y - self._boundingbox[3] * self._anchor_point[1],
)

@anchored_position.setter
def anchored_position(self, new_position):
self.x = int(new_position[0] - (self._boundingbox[2] * self._anchor_point[0]))
self.y = int(new_position[1] - (self._boundingbox[3] * self._anchor_point[1]))
self._Group__trigger_draw()
1 change: 0 additions & 1 deletion src/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ PyObjC; platform_system == "darwin"
uflash==1.3.0
adafruit-circuitpython-fancyled==1.3.3
Pillow==7.0.0
adafruit-circuitpython-display-text-DSX_CUSTOM_MAR172020.tar.gz
adafruit-circuitpython-bitmap_font==1.1.0
adafruit-circuitpython-display-shapes==1.2.0
adafruit-circuitpython-neopixel==5.0.0

0 comments on commit 9a1adc9

Please sign in to comment.