Example #1
0
def popup_text(grp, text, show_time=2,
               *,
               font=default_font, font_scale=default_font_scale):
    grp.append(Label(font, scale=font_scale,
                     anchor_point=(0.5, 0.5),
                     anchored_position=(G_ORIGIN_X, G_ORIGIN_Y),
                     text=text,
                     color=WHITE, background_color=BLUE,
                     padding_left=6, padding_right=6
                     ))
    time.sleep(show_time)
    _ = grp.pop()


gc.collect()
main_group = displayio.Group()
display.show(main_group)

### Show empty word grid
##grid = WordGrid(font=default_font, font_scale=default_font_scale)
gc.collect()
grid = WordGrid()
gc.collect()
d_print(3, "GC after WordGrid", gc.mem_free())
main_group.append(grid.group)

### Create keyboard and add to displayio displayed group but the
### keyboard will not be visible at this stage
gc.collect()
keyboard = Keyboard(keyboard_device, cb=grid_set_char,
                    max_width=DISPLAY_WIDTH, max_height=DISPLAY_HEIGHT)
today_humidity.anchor_point = (0, 0.5)
today_humidity.anchored_position = (105, 95)

today_wind = label.Label(terminalio.FONT, text="99m/s", color=0x000000)
today_wind.anchor_point = (0, 0.5)
today_wind.anchored_position = (155, 95)

today_sunrise = label.Label(terminalio.FONT, text="12:12 PM", color=0x000000)
today_sunrise.anchor_point = (0, 0.5)
today_sunrise.anchored_position = (45, 117)

today_sunset = label.Label(terminalio.FONT, text="12:12 PM", color=0x000000)
today_sunset.anchor_point = (0, 0.5)
today_sunset.anchored_position = (130, 117)

today_banner = displayio.Group(max_size=10)
today_banner.append(today_date)
today_banner.append(city_name)
today_banner.append(today_icon)
today_banner.append(today_morn_temp)
today_banner.append(today_day_temp)
today_banner.append(today_night_temp)
today_banner.append(today_humidity)
today_banner.append(today_wind)
today_banner.append(today_sunrise)
today_banner.append(today_sunset)

future_banners = [
    make_banner(x=210, y=18),
    make_banner(x=210, y=39),
    make_banner(x=210, y=60),
    def __init__(
        self,
        *,
        url=None,
        headers=None,
        json_path=None,
        regexp_path=None,
        default_bg=0x000000,
        status_neopixel=None,
        text_font=None,
        text_position=None,
        text_color=0x808080,
        text_wrap=False,
        text_maxlen=0,
        text_transform=None,
        json_transform=None,
        image_json_path=None,
        image_resize=None,
        image_position=None,
        image_dim_json_path=None,
        caption_text=None,
        caption_font=None,
        caption_position=None,
        caption_color=0x808080,
        image_url_path=None,
        success_callback=None,
        esp=None,
        external_spi=None,
        debug=False
    ):

        self._debug = debug

        try:
            if hasattr(board, "TFT_BACKLIGHT"):
                self._backlight = pulseio.PWMOut(
                    board.TFT_BACKLIGHT
                )  # pylint: disable=no-member
            elif hasattr(board, "TFT_LITE"):
                self._backlight = pulseio.PWMOut(
                    board.TFT_LITE
                )  # pylint: disable=no-member
        except ValueError:
            self._backlight = None
        self.set_backlight(1.0)  # turn on backlight

        self._url = url
        self._headers = headers
        if json_path:
            if isinstance(json_path[0], (list, tuple)):
                self._json_path = json_path
            else:
                self._json_path = (json_path,)
        else:
            self._json_path = None

        self._regexp_path = regexp_path
        self._success_callback = success_callback

        if status_neopixel:
            self.neopix = neopixel.NeoPixel(status_neopixel, 1, brightness=0.2)
        else:
            self.neopix = None
        self.neo_status(0)

        try:
            os.stat(LOCALFILE)
            self._uselocal = True
        except OSError:
            self._uselocal = False

        if self._debug:
            print("Init display")
        self.splash = displayio.Group(max_size=15)

        if self._debug:
            print("Init background")
        self._bg_group = displayio.Group(max_size=1)
        self._bg_file = None
        self._default_bg = default_bg
        self.splash.append(self._bg_group)

        # show thank you and bootup file if available
        for bootscreen in ("/thankyou.bmp", "/pyportal_startup.bmp"):
            try:
                os.stat(bootscreen)
                board.DISPLAY.show(self.splash)
                for i in range(100, -1, -1):  # dim down
                    self.set_backlight(i / 100)
                    time.sleep(0.005)
                self.set_background(bootscreen)
                try:
                    board.DISPLAY.refresh(target_frames_per_second=60)
                except AttributeError:
                    board.DISPLAY.wait_for_frame()
                for i in range(100):  # dim up
                    self.set_backlight(i / 100)
                    time.sleep(0.005)
                time.sleep(2)
            except OSError:
                pass  # they removed it, skip!

        self._speaker_enable = DigitalInOut(board.SPEAKER_ENABLE)
        self._speaker_enable.switch_to_output(False)
        if hasattr(board, "AUDIO_OUT"):
            self.audio = audioio.AudioOut(board.AUDIO_OUT)
        elif hasattr(board, "SPEAKER"):
            self.audio = audioio.AudioOut(board.SPEAKER)
        else:
            raise AttributeError("Board does not have a builtin speaker!")
        try:
            self.play_file("pyportal_startup.wav")
        except OSError:
            pass  # they deleted the file, no biggie!

        if esp:  # If there was a passed ESP Object
            if self._debug:
                print("Passed ESP32 to PyPortal")
            self._esp = esp
            if external_spi:  # If SPI Object Passed
                spi = external_spi
            else:  # Else: Make ESP32 connection
                spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
        else:
            if self._debug:
                print("Init ESP32")
            esp32_ready = DigitalInOut(board.ESP_BUSY)
            esp32_gpio0 = DigitalInOut(board.ESP_GPIO0)
            esp32_reset = DigitalInOut(board.ESP_RESET)
            esp32_cs = DigitalInOut(board.ESP_CS)
            spi = busio.SPI(board.SCK, board.MOSI, board.MISO)

            self._esp = adafruit_esp32spi.ESP_SPIcontrol(
                spi, esp32_cs, esp32_ready, esp32_reset, esp32_gpio0
            )
        # self._esp._debug = 1
        for _ in range(3):  # retries
            try:
                print("ESP firmware:", self._esp.firmware_version)
                break
            except RuntimeError:
                print("Retrying ESP32 connection")
                time.sleep(1)
                self._esp.reset()
        else:
            raise RuntimeError("Was not able to find ESP32")
        requests.set_socket(socket, self._esp)

        if url and not self._uselocal:
            self._connect_esp()

        if self._debug:
            print("My IP address is", self._esp.pretty_ip(self._esp.ip_address))

        # set the default background
        self.set_background(self._default_bg)
        board.DISPLAY.show(self.splash)

        if self._debug:
            print("Init SD Card")
        sd_cs = DigitalInOut(board.SD_CS)
        self._sdcard = None
        try:
            self._sdcard = adafruit_sdcard.SDCard(spi, sd_cs)
            vfs = storage.VfsFat(self._sdcard)
            storage.mount(vfs, "/sd")
        except OSError as error:
            print("No SD card found:", error)

        self._qr_group = None
        # Tracks whether we've hidden the background when we showed the QR code.
        self._qr_only = False

        if self._debug:
            print("Init caption")
        self._caption = None
        if caption_font:
            self._caption_font = bitmap_font.load_font(caption_font)
        self.set_caption(caption_text, caption_position, caption_color)

        if text_font:
            if isinstance(text_position[0], (list, tuple)):
                num = len(text_position)
                if not text_wrap:
                    text_wrap = [0] * num
                if not text_maxlen:
                    text_maxlen = [0] * num
                if not text_transform:
                    text_transform = [None] * num
            else:
                num = 1
                text_position = (text_position,)
                text_color = (text_color,)
                text_wrap = (text_wrap,)
                text_maxlen = (text_maxlen,)
                text_transform = (text_transform,)
            self._text = [None] * num
            self._text_color = [None] * num
            self._text_position = [None] * num
            self._text_wrap = [None] * num
            self._text_maxlen = [None] * num
            self._text_transform = [None] * num
            self._text_font = bitmap_font.load_font(text_font)
            if self._debug:
                print("Loading font glyphs")
            # self._text_font.load_glyphs(b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
            #                             b'0123456789:/-_,. ')
            gc.collect()

            for i in range(num):
                if self._debug:
                    print("Init text area", i)
                self._text[i] = None
                self._text_color[i] = text_color[i]
                self._text_position[i] = text_position[i]
                self._text_wrap[i] = text_wrap[i]
                self._text_maxlen[i] = text_maxlen[i]
                self._text_transform[i] = text_transform[i]
        else:
            self._text_font = None
            self._text = None

        # Add any JSON translators
        self._json_transform = []
        if json_transform:
            if callable(json_transform):
                self._json_transform.append(json_transform)
            else:
                self._json_transform.extend(filter(callable, json_transform))

        self._image_json_path = image_json_path
        self._image_url_path = image_url_path
        self._image_resize = image_resize
        self._image_position = image_position
        self._image_dim_json_path = image_dim_json_path
        if image_json_path or image_url_path:
            if self._debug:
                print("Init image path")
            if not self._image_position:
                self._image_position = (0, 0)  # default to top corner
            if not self._image_resize:
                self._image_resize = (
                    board.DISPLAY.width,
                    board.DISPLAY.height,
                )  # default to full screen
        if hasattr(board, "TOUCH_XL"):
            if self._debug:
                print("Init touchscreen")
            # pylint: disable=no-member
            self.touchscreen = adafruit_touchscreen.Touchscreen(
                board.TOUCH_XL,
                board.TOUCH_XR,
                board.TOUCH_YD,
                board.TOUCH_YU,
                calibration=((5200, 59000), (5800, 57000)),
                size=(board.DISPLAY.width, board.DISPLAY.height),
            )
            # pylint: enable=no-member

            self.set_backlight(1.0)  # turn on backlight
        elif hasattr(board, "BUTTON_CLOCK"):
            if self._debug:
                print("Init cursor")
            self.mouse_cursor = Cursor(
                board.DISPLAY, display_group=self.splash, cursor_speed=8
            )
            self.mouse_cursor.hide()
            self.cursor = CursorManager(self.mouse_cursor)
        else:
            raise AttributeError(
                "PyPortal module requires either a touchscreen or gamepad."
            )

        gc.collect()
                                 reset=epd_reset,
                                 baudrate=1000000)
time.sleep(1)  # Wait a bit

DISPLAY_WIDTH = 212
DISPLAY_HEIGHT = 104
# Create the display object - the third color is red (0xff0000)
display = adafruit_il0373.IL0373(display_bus,
                                 width=DISPLAY_WIDTH,
                                 height=DISPLAY_HEIGHT,
                                 rotation=90,
                                 busy_pin=epd_busy,
                                 highlight_color=0xff0000)

# Create a display group for our screen objects
g = displayio.Group()

# Set a background
background_bitmap = displayio.Bitmap(DISPLAY_WIDTH, DISPLAY_HEIGHT, 1)
# Map colors in a palette
palette = displayio.Palette(1)
palette[0] = BACKGROUND_COLOR

# Put the background into the display group
bg_sprite = displayio.TileGrid(background_bitmap,
                               pixel_shader=palette,
                               x=0,
                               y=0)
g.append(bg_sprite)

# Display a picture from the root directory of the CIRCUITPY drive
                                      text="R")
B = adafruit_display_text.label.Label(terminalio.FONT,
                                      color=0x0000ff,
                                      scale=3,
                                      x=24,
                                      y=13,
                                      text="B")
G = adafruit_display_text.label.Label(terminalio.FONT,
                                      color=0x00ff00,
                                      scale=3,
                                      x=46,
                                      y=13,
                                      text="G")

# Put each line of text into a Group, then show that group.
g = displayio.Group()
g.append(R)
g.append(B)
g.append(G)
display.show(g)
display.auto_refresh = True

# CircuitPython 6 & 7 compatible
bitmap_file = open("/rbg.bmp", "rb")
# Setup the file as the bitmap data source
bitmap = displayio.OnDiskBitmap(bitmap_file)
# Create a TileGrid to hold the bitmap
tile_grid = displayio.TileGrid(bitmap,
                               pixel_shader=getattr(
                                   bitmap, 'pixel_shader',
                                   displayio.ColorConverter()))
    def show_badge(self,
                   *,
                   background_color=0xFF0000,
                   foreground_color=0xFFFFFF,
                   background_text_color=0xFFFFFF,
                   foreground_text_color=0x000000,
                   hello_font=terminalio.FONT,
                   hello_scale=1,
                   hello_string="HELLO",
                   my_name_is_font=terminalio.FONT,
                   my_name_is_scale=1,
                   my_name_is_string="MY NAME IS",
                   name_font=terminalio.FONT,
                   name_scale=1,
                   name_string="Blinka"):
        """Create a "Hello My Name is"-style badge.

        :param background_color: The color of the background. Defaults to 0xFF0000.
        :param foreground_color: The color of the foreground rectangle. Defaults to 0xFFFFFF.
        :param background_text_color: The color of the "HELLO MY NAME IS" text. Defaults to
                                      0xFFFFFF.
        :param foreground_text_color: The color of the name text. Defaults to 0x000000.
        :param hello_font: The font for the "HELLO" string. Defaults to ``terminalio.FONT``.
        :param hello_scale: The size scale of the "HELLO" string. Defaults to 1.
        :param hello_string: The first string of the badge. Defaults to "HELLO".
        :param my_name_is_font: The font for the "MY NAME IS" string. Defaults to
                                ``terminalio.FONT``.
        :param my_name_is_scale: The size scale of the "MY NAME IS" string. Defaults to 1.
        :param my_name_is_string: The second string of the badge. Defaults to "MY NAME IS".
        :param name_font: The font for the name string. Defaults to ``terminalio.FONT``.
        :param name_scale: The size scale of the name string. Defaults to 1.
        :param name_string: The third string of the badge - change to be your name. Defaults to
                            "Blinka".

        """
        splash = displayio.Group(max_size=20)

        color_bitmap = displayio.Bitmap(self.display.width,
                                        self.display.height, 1)
        color_palette = displayio.Palette(1)
        color_palette[0] = background_color

        bg_sprite = displayio.TileGrid(color_bitmap,
                                       pixel_shader=color_palette,
                                       x=0,
                                       y=0)
        splash.append(bg_sprite)

        rect = Rect(0, (int(self.display.height * 0.4)),
                    self.display.width, (int(self.display.height * 0.5)),
                    fill=foreground_color)
        splash.append(rect)

        hello_scale = hello_scale
        hello_group = displayio.Group(scale=hello_scale)
        hello_label = Label(font=hello_font, text=hello_string)
        (_, _, width, height) = hello_label.bounding_box
        hello_label.x = ((self.display.width // (2 * hello_scale)) -
                         width // 2)
        hello_label.y = int(height // (1.2 * hello_scale))
        hello_label.color = background_text_color
        hello_group.append(hello_label)

        my_name_is_scale = my_name_is_scale
        my_name_is_group = displayio.Group(scale=my_name_is_scale)
        my_name_is_label = Label(font=my_name_is_font, text=my_name_is_string)
        (_, _, width, height) = my_name_is_label.bounding_box
        my_name_is_label.x = ((self.display.width // (2 * my_name_is_scale)) -
                              width // 2)
        my_name_is_label.y = int(height // (0.42 * my_name_is_scale))
        my_name_is_label.color = background_text_color
        my_name_is_group.append(my_name_is_label)

        name_scale = name_scale
        name_group = displayio.Group(scale=name_scale)
        name_label = Label(font=name_font, text=name_string)
        (_, _, width, height) = name_label.bounding_box
        name_label.x = ((self.display.width // (2 * name_scale)) - width // 2)
        name_label.y = int(height // (0.17 * name_scale))
        name_label.color = foreground_text_color
        name_group.append(name_label)

        group = displayio.Group()
        group.append(splash)
        group.append(hello_group)
        group.append(my_name_is_group)
        group.append(name_group)
        self.display.show(group)
Example #7
0
ORANGE = 0xFF8800
BLUE = 0x0088FF
WHITE = 0xFFFFFF
GRAY = 0x666666
LABEL_OFFSET = int(SCREEN_WIDTH - (SCREEN_WIDTH / 7))

ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL,
                                      board.TOUCH_XR,
                                      board.TOUCH_YD,
                                      board.TOUCH_YU,
                                      calibration=((5200, 59000), (5800,
                                                                   57000)),
                                      size=(SCREEN_WIDTH, SCREEN_HEIGHT))

# Make the display context
calc_group = displayio.Group()
board.DISPLAY.show(calc_group)

# Make a background color fill
color_bitmap = displayio.Bitmap(SCREEN_WIDTH, SCREEN_HEIGHT, 1)
color_palette = displayio.Palette(1)
color_palette[0] = GRAY
bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette,
                               x=0,
                               y=0)
calc_group.append(bg_sprite)

# Load the font
if SCREEN_WIDTH < 480:
    font = bitmap_font.load_font("/fonts/Arial-12.bdf")
    pass
spi.configure(baudrate=24000000)  # Configure SPI for 24MHz
spi.unlock()
tft_cs = board.D5
tft_dc = board.D6

displayio.release_displays()
display_bus = displayio.FourWire(spi,
                                 command=tft_dc,
                                 chip_select=tft_cs,
                                 reset=board.D9)

display = ST7789(display_bus, width=240, height=240, rowstart=80)

# Make the display context
splash = displayio.Group(max_size=10)
display.show(splash)

color_bitmap = displayio.Bitmap(240, 240, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00  # Bright Green

bg_sprite = displayio.TileGrid(color_bitmap,
                               pixel_shader=color_palette,
                               x=0,
                               y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(200, 200, 1)
inner_palette = displayio.Palette(1)
    def __init__(self, root_group, *, am_pm=True):
        super().__init__(max_size=2)
        self.am_pm = am_pm
        root_group.append(self)
        self._icon_group = displayio.Group(max_size=1)
        self.append(self._icon_group)
        self._text_group = displayio.Group(max_size=8)
        self.append(self._text_group)

        self._icon_sprite = None
        self._icon_file = None
        self.set_icon(cwd + "/icons/sarscov2.bmp")

        self.small_font = bitmap_font.load_font(small_font)
        self.medium_font = bitmap_font.load_font(medium_font)
        self.large_font = bitmap_font.load_font(large_font)
        glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
        self.small_font.load_glyphs(glyphs)
        self.medium_font.load_glyphs(glyphs)
        self.large_font.load_glyphs(glyphs)
        self.large_font.load_glyphs(
            ('°', ))  # a non-ascii character we need for sure
        self.country_text = None

        self.time_text = Label(self.medium_font, max_glyphs=8)
        self.time_text.x = 200
        self.time_text.y = 12
        self.time_text.color = 0xFFFFFF
        self._text_group.append(self.time_text)

        self.country_text = Label(self.medium_font, max_glyphs=60)
        self.country_text.x = 10
        self.country_text.y = 12
        self.country_text.color = 0xFFFFFF
        self._text_group.append(self.country_text)

        self.deaths_text = Label(self.small_font, max_glyphs=25)
        self.deaths_text.x = 10
        self.deaths_text.y = 75
        self.deaths_text.color = 0xFF0000
        self._text_group.append(self.deaths_text)

        self.critical_text = Label(self.small_font, max_glyphs=25)
        self.critical_text.x = 10
        self.critical_text.y = 105
        self.critical_text.color = 0xFFFF00
        self._text_group.append(self.critical_text)

        self.recovered_text = Label(self.small_font, max_glyphs=25)
        self.recovered_text.x = 10
        self.recovered_text.y = 135
        self.recovered_text.color = 0x00FF00
        self._text_group.append(self.recovered_text)

        self.today_cases_text = Label(self.small_font, max_glyphs=25)
        self.today_cases_text.x = 10
        self.today_cases_text.y = 165
        self.today_cases_text.color = 0xFFFFFF
        self._text_group.append(self.today_cases_text)

        self.cases_text = Label(self.medium_font, max_glyphs=25)
        self.cases_text.x = 10
        self.cases_text.y = 195
        self.cases_text.color = 0xFFFFFF
        self._text_group.append(self.cases_text)

        self.cases_million_text = Label(self.small_font, max_glyphs=60)
        self.cases_million_text.x = 10
        self.cases_million_text.y = 225
        self.cases_million_text.color = 0xFFFFFF
        self._text_group.append(self.cases_million_text)
Example #10
0
# Set this to your LIFX personal access token in secrets.py
# (to obtain a token, visit: https://cloud.lifx.com/settings)
lifx_token = secrets['lifx_token']

# Initialize the LIFX API Helper
lifx = adafruit_lifx.LIFX(wifi, lifx_token)

# Set these to your LIFX light selector (https://api.developer.lifx.com/docs/selectors)
lifx_lights = ['label:Lamp', 'label:Bedroom']
# set default light properties
current_light = lifx_lights[0]
light_brightness = 1.0

# Make the display context
button_group = displayio.Group(max_size=20)
board.DISPLAY.show(button_group)
# preload the font
print('loading font...')
font = bitmap_font.load_font("/fonts/Arial-12.bdf")
glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
font.load_glyphs(glyphs)
# button properties
BUTTON_WIDTH = 60
BUTTON_HEIGHT = 60
buttons = []

# button fill colors (from https://api.developer.lifx.com/docs/colors)
button_colors = {
    'red': 0xFF0000,
    'white': 0xFFFFFF,
    "/vo/pathfnd_54.wav",
    "/vo/pathfnd_55.wav",
    "/vo/pathfnd_56.wav",
]

pyportal = PyPortal(status_neopixel=board.NEOPIXEL)

# Open the file
with open(emote_img[0], "rb") as bitmap_file:
    # Setup the file as the bitmap data source
    bitmap = displayio.OnDiskBitmap(bitmap_file)
    # Create a TileGrid to hold the bitmap
    tile_grid = displayio.TileGrid(bitmap,
                                   pixel_shader=displayio.ColorConverter())
    # Create a Group to hold the TileGrid
    group = displayio.Group()
    # Add the TileGrid to the Group
    group.append(tile_grid)
    # Add the Group to the Display
    display.show(group)
    if sound_mode is not 0:
        # play a sound file
        pyportal.play_file(vo_sound[10])
    else:
        pyportal.play_file(
            "/vo/pathfnd_silent.wav")  # hack to deal w no mute method

while True:
    if pyportal.touchscreen.touch_point:
        i = (i + 1) % 11
        pixel.fill(colors[i])
# Release any resources currently in use for the displays
displayio.release_displays()

spi = board.SPI()
tft_cs = board.D5
tft_dc = board.D6

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=board.D9
)

display = ST7735R(display_bus, width=160, height=128, rotation=90, bgr=True)

# Make the display context
splash = displayio.Group(max_size=10)
display.show(splash)

color_bitmap = displayio.Bitmap(160, 128, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00  # Bright Green

bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(150, 118, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0xAA0088  # Purple
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=5, y=5)
splash.append(inner_sprite)
Example #13
0
displayio.release_displays()
display_bus = displayio.FourWire(spi,
                                 command=tft_dc,
                                 chip_select=tft_cs,
                                 reset=board.D9)

display = ST7789(display_bus, width=320, height=240, rotation=90)

# Make the display context
with open("/blinka.bmp", "rb") as bitmap_file:

    color_bitmap = displayio.Bitmap(320, 240, 1)
    color_palette = displayio.Palette(1)
    color_palette[0] = 0x00FF00  # Bright Green
    # Create a Group to hold the TileGrid
    group = displayio.Group()

    bg_sprite = displayio.TileGrid(color_bitmap,
                                   pixel_shader=color_palette,
                                   x=0,
                                   y=0)
    group.append(bg_sprite)

    # Setup the file as the bitmap data source
    bitmap = displayio.OnDiskBitmap(bitmap_file)

    # Create a TileGrid to hold the bitmap
    tile_grid = displayio.TileGrid(bitmap,
                                   pixel_shader=displayio.ColorConverter(),
                                   x=20,
                                   y=20)
Example #14
0
    def __init__(self,
                 input_device,
                 layout="QUERTY",
                 numbers=False,
                 keycaps_upper=True, shift=False, control=False, symbols=False,
                 enter=True, backspace=True, space=False,
                 keycap_fg=0xd0d0d0,
                 keycap_bg=0x404040,
                 keycap_font=terminalio.FONT,
                 min_press_time=0.08,  ### 80ms plus library delay required for a press
                 max_width=None,
                 max_height=None,
                 cb=None,
                 cb_kwargs={},
                 blank_char=" "
                 ):
        self._keys = []
        self._dio_keyboard = displayio.Group()
        ### TODO - sizing code still needs some cleaning
        self._dio_keyboard.x = int(max_width / 40) if max_width else 8
        self._dio_keyboard.y = 132   ### TODO set this properly
        self._key_width = int(max_width / 12) if max_width else 26
        self._key_height = int(max_width / 12) if max_width else 26
        self._key_x_space = int(self._key_width / 5)
        self._key_y_space = self._key_x_space + 2
        
        self._keycap_fg = keycap_fg
        self._keycap_bg = keycap_bg
        self._keycap_font = keycap_font
        self._initKeys(layout,
                       enter=enter, backspace=backspace, space=space,
                       numbers=numbers, keycaps_upper=keycaps_upper,
                       shift=shift, control=control, symbols=False)
        self._dio_group = displayio.Group()

        self._touch_screen = None
        self._off_time = 0.05

        self._accel = None
        self._accel_lr_ud = None
        self._button = None
        self._keycursor_home = (1, 4)  ### row, column
        self._keycursor = None

        self._min_press_time = min_press_time
        self._cb = cb
        self._cb_kwargs = cb_kwargs
        self._blank_char = blank_char
        try:
            _ = input_device.touch_point
            self._touch_screen = input_device
        except AttributeError:
            pass

        try:
            _ = input_device[0].acceleration
            _ = input_device[1]()
            _ = input_device[2][:2]
            self._accel = input_device[0]
            self._button = input_device[1]
            self._accel_lr_ud = input_device[2][:2]
        except (AttributeError, TypeError):
            pass

        if self._touch_screen is None and self._accel is None:
            raise ValueError("Need an input_device which supports touch_point"
                             "or array with accelerometer, callable button and axis spec")
    label_title.text = secret_name
    # format and display the OTP
    label_secret.text = "{} {}".format(str(secret_otp)[0:3], str(secret_otp)[3:6])
    print("OTP Name: {}\nOTP Key: {}".format(secret_name, secret_otp))

print("===========================================")

# GFX Font
font = terminalio.FONT

# Initialize new PyPortal object
pyportal = PyPortal(esp=esp,
                    external_spi=spi)

# Root DisplayIO
root_group = displayio.Group()
display.show(root_group)

BACKGROUND = BACKGROUND if isinstance(BACKGROUND, int) else 0x0
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = BACKGROUND
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)

# Create a new DisplayIO group
splash = displayio.Group()

splash.append(background)

key_group = displayio.Group(scale=5)
# We'll use a default text placeholder for this label
Example #16
0
    def __init__(self, celsius=True, usa_date=False):
        """Creates a Thermometer_GFX object.
        :param bool celsius: Temperature displayed as F or C
        :param bool usa_date: Use mon/day/year date-time formatting.
        """
        # root displayio group
        root_group = displayio.Group(max_size=20)
        board.DISPLAY.show(root_group)
        super().__init__(max_size=20)

        self._celsius = celsius
        self._usa_date = usa_date
     
        # create background icon group
        self._icon_group = displayio.Group(max_size=1)
        self.append(self._icon_group)
        board.DISPLAY.show(self._icon_group)

        # create text object group
        self._text_group = displayio.Group(max_size=20)
        self.append(self._text_group)

        self._icon_sprite = None
        self._icon_file = None
        self._cwd = cwd
        self.set_icon(self._cwd+"/icons/pyportal_splash.bmp")
  
        print('loading fonts...')
        self.info_font = bitmap_font.load_font(info_font)
        self.info_font.load_glyphs(glyphs)

        self.small_font = bitmap_font.load_font(small_font)
        self.small_font.load_glyphs(glyphs)

        self.c_font = bitmap_font.load_font(temperature_font)
        self.c_font.load_glyphs(glyphs)
        self.c_font.load_glyphs(('°',)) # extra glyph for temperature font

        print('setting up labels...')

        self.date_text = Label(self.info_font, max_glyphs=40)
        self.date_text.x = 10
        self.date_text.y = 15
        self._text_group.append(self.date_text)

        self.time_text = Label(self.info_font, max_glyphs=40)
        self.time_text.x = 120
        self.time_text.y = 15
        self._text_group.append(self.time_text)

        self.city1_name = Label(self.small_font, max_glyphs=40)
        self.city1_name.x = 10
        self.city1_name.y = 80
        self._text_group.append(self.city1_name)

        self.city1_temp = Label(self.small_font, max_glyphs=40)
        self.city1_temp.x = 10
        self.city1_temp.y = 100
        self._text_group.append(self.city1_temp)

        self.city1_desc = Label(self.small_font, max_glyphs=40)
        self.city1_desc.x = 10
        self.city1_desc.y = 120
        self._text_group.append(self.city1_desc)

        self.city1_additional_desc = Label(self.small_font, max_glyphs=40)
        self.city1_additional_desc.x = 10
        self.city1_additional_desc.y = 140
        self._text_group.append(self.city1_additional_desc)

        self.city1_humid = Label(self.small_font, max_glyphs=40)
        self.city1_humid.x = 10
        self.city1_humid.y = 160
        self._text_group.append(self.city1_humid)

        self.city1_wind = Label(self.small_font, max_glyphs=40)
        self.city1_wind.x = 10
        self.city1_wind.y = 180
        self._text_group.append(self.city1_wind)

        self.city1_sunrise = Label(self.small_font, max_glyphs=40)
        self.city1_sunrise.x = 10
        self.city1_sunrise.y = 200
        self._text_group.append(self.city1_sunrise)


        self.city2_name = Label(self.small_font, max_glyphs=40)
        self.city2_name.x = 170
        self.city2_name.y = 80
        self._text_group.append(self.city2_name)

        self.city2_temp = Label(self.small_font, max_glyphs=40)
        self.city2_temp.x = 170
        self.city2_temp.y = 100
        self._text_group.append(self.city2_temp)

        self.city2_desc = Label(self.small_font, max_glyphs=40)
        self.city2_desc.x = 170
        self.city2_desc.y = 120
        self._text_group.append(self.city2_desc)

        self.city2_additional_desc = Label(self.small_font, max_glyphs=40)
        self.city2_additional_desc.x = 170
        self.city2_additional_desc.y = 140
        self._text_group.append(self.city2_additional_desc)

        self.city2_humid = Label(self.small_font, max_glyphs=40)
        self.city2_humid.x = 170
        self.city2_humid.y = 160
        self._text_group.append(self.city2_humid)

        self.city2_wind = Label(self.small_font, max_glyphs=40)
        self.city2_wind.x = 170
        self.city2_wind.y = 180
        self._text_group.append(self.city2_wind)

        self.city2_sunrise = Label(self.small_font, max_glyphs=40)
        self.city2_sunrise.x = 170
        self.city2_sunrise.y = 200
        self._text_group.append(self.city2_sunrise)

        # add flag images to the text group
        self.add_flag("/icons/brit.bmp", 10, 24)
        self.add_flag("/icons/finn.bmp", 170, 24)


        board.DISPLAY.show(self._text_group)
    def show_business_card(self,
                           *,
                           image_name=None,
                           name_string=None,
                           name_scale=1,
                           name_font=terminalio.FONT,
                           email_string_one=None,
                           email_scale_one=1,
                           email_font_one=terminalio.FONT,
                           email_string_two=None,
                           email_scale_two=1,
                           email_font_two=terminalio.FONT):
        """Display a bitmap image and a text string, such as a personal image and email address.

        :param str image_name: REQUIRED. The name of the bitmap image including .bmp, e.g.
                               ``"Blinka.bmp"``.
        :param str name_string: A name string to display along the bottom of the display, e.g.
                                 ``"Blinka"``.
        :param int name_scale: The scale of ``name_string``. Defaults to 1.
        :param name_font: The font for the name string. Defaults to ``terminalio.FONT``.
        :param str email_string_one: A string to display along the bottom of the display, e.g.
                                 ``"*****@*****.**"``.
        :param int email_scale_one: The scale of ``email_string_one``. Defaults to 1.
        :param email_font_one: The font for the first email string. Defaults to ``terminalio.FONT``.
        :param str email_string_two: A second string to display along the bottom of the display.
                                     Use if your email address is longer than one line or to add
                                     more space between the name and email address,
                                     e.g. (blinka@) ``"adafruit.com"``.
        :param int email_scale_two: The scale of ``email_string_two``. Defaults to 1.
        :param email_font_two: The font for the second email string. Defaults to
                               ``terminalio.FONT``.

        """
        business_card_splash = displayio.Group(max_size=30)
        self.display.show(business_card_splash)
        with open(image_name, "rb") as file_name:
            on_disk_bitmap = displayio.OnDiskBitmap(file_name)
            face_image = displayio.TileGrid(
                on_disk_bitmap, pixel_shader=displayio.ColorConverter())
            business_card_splash.append(face_image)
            self.display.wait_for_frame()
        if name_string:
            name_group = displayio.Group(scale=name_scale)
            name_label = Label(name_font, text=name_string)
            (_, _, width, height) = name_label.bounding_box
            name_label.x = ((self.display.width // (2 * name_scale)) -
                            width // 2)
            name_label.y = int(height // (0.15 * name_scale))
            name_label.color = 0xFFFFFF
            name_group.append(name_label)
            business_card_splash.append(name_group)
        if email_string_one:
            email_group_one = displayio.Group(scale=email_scale_one)
            email_label_one = Label(email_font_one, text=email_string_one)
            (_, _, width, height) = email_label_one.bounding_box
            email_label_one.width = self.display.width
            email_label_one.x = ((self.display.width //
                                  (2 * email_scale_one)) - width // 2)
            email_label_one.y = int(height // (0.13 * email_scale_one))
            email_label_one.color = 0xFFFFFF
            email_group_one.append(email_label_one)
            business_card_splash.append(email_group_one)
        if email_string_two:
            email_group_two = displayio.Group(scale=email_scale_two)
            email_label_two = Label(email_font_two, text=email_string_two)
            (_, _, width, height) = email_label_two.bounding_box
            email_label_two.width = self.display.width
            email_label_two.x = ((self.display.width //
                                  (2 * email_scale_two)) - width // 2)
            email_label_two.y = int(height // (0.12 * email_scale_two))
            email_label_two.color = 0xFFFFFF
            email_group_two.append(email_label_two)
            business_card_splash.append(email_group_two)
Example #18
0
from digitalio import DigitalInOut, Pull
from adafruit_matrixportal.matrix import Matrix
from adafruit_debouncer import Debouncer

SPRITESHEET_FOLDER = "/bmps"
DEFAULT_FRAME_DURATION = 0.1  # 100ms
AUTO_ADVANCE_LOOPS = 3
FRAME_DURATION_OVERRIDES = {
    "three_rings1-sheet.bmp": 0.15,
    "hop1-sheet.bmp": 0.05,
    "firework1-sheet.bmp": 0.03,
}

# --- Display setup ---
matrix = Matrix(bit_depth=4)
sprite_group = displayio.Group()
matrix.display.show(sprite_group)

# --- Button setup ---
pin_down = DigitalInOut(board.BUTTON_DOWN)
pin_down.switch_to_input(pull=Pull.UP)
button_down = Debouncer(pin_down)
pin_up = DigitalInOut(board.BUTTON_UP)
pin_up.switch_to_input(pull=Pull.UP)
button_up = Debouncer(pin_up)

auto_advance = True

file_list = sorted(
    [
        f
                            \n\t"bridge_ip":"{0}", \
                            \n\t"hue_username":"******"'.format(ip, username))
    raise

# These pins are used as both analog and digital! XL, XR and YU must be analog
# and digital capable. YD just need to be digital
ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL,
                                      board.TOUCH_XR,
                                      board.TOUCH_YD,
                                      board.TOUCH_YU,
                                      calibration=((5200, 59000), (5800,
                                                                   57000)),
                                      size=(320, 240))

# Make the display context
button_group = displayio.Group()
board.DISPLAY.show(button_group)
# preload the font
print('loading font...')
font = bitmap_font.load_font("/fonts/Arial-12.bdf")
glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
font.load_glyphs(glyphs)
# button properties
BUTTON_WIDTH = 60
BUTTON_HEIGHT = 60
buttons = []

print('loading colors...')
# color conversions (RGB to Philips Hue-compatible HSB)
red = my_bridge.rgb_to_hsb([255, 0, 0])
white = my_bridge.rgb_to_hsb([255, 255, 255])
Example #20
0
# Release any resources currently in use for the displays
displayio.release_displays()

spi = board.SPI()
tft_cs = board.D5
tft_dc = board.D6

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=board.D9
)

display = ST7789(display_bus, width=320, height=240, rotation=90)

# Make the display context
splash = displayio.Group()
display.show(splash)

color_bitmap = displayio.Bitmap(320, 240, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00  # Bright Green

bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(280, 200, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0xAA0088  # Purple
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=20, y=20)
splash.append(inner_sprite)
                            width=1,
                            height=1,
                            tile_width=16,
                            tile_height=16,
                            default_tile=0)

# Create the castle TileGrid
castle = displayio.TileGrid(sprite_sheet,
                            pixel_shader=palette,
                            width=6,
                            height=5,
                            tile_width=16,
                            tile_height=16)

# Create a Group to hold the sprite and add it
sprite_group = displayio.Group()
sprite_group.append(sprite)

# Create a Group to hold the castle and add it
castle_group = displayio.Group(scale=3)
castle_group.append(castle)

# Create a Group to hold the sprite and castle
group = displayio.Group()

# Add the sprite and castle to the group
group.append(castle_group)
group.append(sprite_group)

# Castle tile assignments
# corners
import displayio
import json
import terminalio
from adafruit_display_text import label
from blinka_displayio_pygamedisplay import PyGameDisplay
import adafruit_imageload

f = open("good_map_0.json", "r")
map_obj = json.loads(f.read())
f.close()

# Make the display context. Change size if you want
display = PyGameDisplay(width=160 * 2, height=128 * 2)

# Make the display context
main_group = displayio.Group(max_size=10)
display.show(main_group)

# Load the sprite sheet (bitmap)
sprite_sheet, palette = adafruit_imageload.load("sprite_sheet_new.bmp",
                                                bitmap=displayio.Bitmap,
                                                palette=displayio.Palette)

sprite_sheet2, palette2 = adafruit_imageload.load("sprite_sheet_new.bmp",
                                                  bitmap=displayio.Bitmap,
                                                  palette=displayio.Palette)

palette.make_transparent(0)
palette2.make_transparent(0)
# Create the sprite TileGrid
"""
Example #23
0
import board
import busio
import audioio
import displayio
import digitalio
from adafruit_pyportal import PyPortal
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text import label
from adafruit_display_shapes.circle import Circle
from adafruit_button import Button
import adafruit_touchscreen
from adafruit_mcp9600 import MCP9600

VERSION = "0.1"

display_group = displayio.Group(max_size=20)
board.DISPLAY.show(display_group)

PLOT_SIZE = 2  # plot thickness
PLOT_COLOR = 0x00FF55  # plot color
GRID_SIZE = 2
GRID_COLOR = 0x2020FF
GRID_STYLE = 3
TEMP_SIZE = 2
TEMP_COLOR = 0xFFFF00
LABEL_COLOR = 0x8080FF

WIDTH = board.DISPLAY.width
HEIGHT = board.DISPLAY.height

pyportal = PyPortal()
I2C = busio.I2C(board.SCL, board.SDA)
if IS_HALLOWING_M4:
    import adafruit_msa301
    ACCEL = adafruit_msa301.MSA301(I2C)
else:
    import adafruit_lis3dh
    try:
        ACCEL = adafruit_lis3dh.LIS3DH_I2C(I2C, address=0x18) # Production board
    except ValueError:
        ACCEL = adafruit_lis3dh.LIS3DH_I2C(I2C, address=0x19) # Beta hardware
    ACCEL.range = adafruit_lis3dh.RANGE_4_G

try:
    import displayio
    board.DISPLAY.brightness = 0
    SCREEN = displayio.Group()
    board.DISPLAY.show(SCREEN)
    BITMAP = displayio.OnDiskBitmap(open(IMAGEFILE, 'rb'))
    SCREEN.append(
        displayio.TileGrid(BITMAP,
                           pixel_shader=displayio.ColorConverter(),
                           x=0, y=0))
    board.DISPLAY.brightness = 1.0
except (ImportError, NameError, AttributeError) as err:
    pass # Probably earlier CircuitPython; no displayio support

# If everything has initialized correctly, turn off the onboard NeoPixel:
PIXEL = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0)
PIXEL.show()

while True:
Example #25
0
import audioio
import pulseio
import touchio
import digitalio
import analogio
import os

#-------------------------------------------
# Graphics Setup
#-------------------------------------------
# Display brightness now controlled with DISPLAY
# In the beta versions fo CircuitPython

board.DISPLAY.auto_brightness = False
board.DISPLAY.brightness = 0
splash = displayio.Group()
board.DISPLAY.show(splash)

# Image Database
#Image database, all images can be referenced from this list
images_db = list(filter(lambda x: x.endswith("bmp"), sorted(os.listdir("/media"))))
print(images_db)

#Global Fade Timer
fade_timer = 0.01

#Light Threshold
light_threshold = 15000

#---------------------------------------------------
# Audio Setup
    bg_bitmap = displayio.Bitmap(WIDTH, HEIGHT, 1)
    bg_palette = displayio.Palette(1)
    bg_palette[0] = BACKGROUND
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)

# Snowflake setup
flake_bitmap, flake_palette = adafruit_imageload.load(
    FLAKE_SHEET, bitmap=displayio.Bitmap, palette=displayio.Palette)
if FLAKE_TRAN_COLOR is not None:
    for i, color in enumerate(flake_palette):
        if color == FLAKE_TRAN_COLOR:
            flake_palette.make_transparent(i)
            break
NUM_SPRITES = flake_bitmap.width // FLAKE_WIDTH * flake_bitmap.height // FLAKE_HEIGHT
flake_pos = [0.0] * NUM_FLAKES
flakes = displayio.Group(max_size=NUM_FLAKES)
for _ in range(NUM_FLAKES):
    flakes.append(
        displayio.TileGrid(flake_bitmap,
                           pixel_shader=flake_palette,
                           width=1,
                           height=1,
                           tile_width=FLAKE_WIDTH,
                           tile_height=FLAKE_HEIGHT,
                           x=randrange(0, WIDTH),
                           default_tile=randrange(0, NUM_SPRITES)))

# Snowfield setup
snow_depth = [HEIGHT] * WIDTH
snow_palette = displayio.Palette(2)
snow_palette[0] = 0xADAF00  # transparent color
Example #27
0
clue._pressure.mode = 0x03  # normal
clue._pressure.overscan_pressure = 0x05  # x16
clue._pressure.overscan_temperature = 0x02  # x2
clue._pressure.iir_filter = 0x02  # 4
clue._pressure.standby_period = 0x01  # 62.5 ms

# restore saved sea level pressure from NVM
slp = struct.unpack("f", nvm[0:4])[0]
clue.sea_level_pressure = slp if 0 < slp < 2000 else STD_SLP

# --------------------------------------------------------------------
# D I S P L A Y    S E T U P
# --------------------------------------------------------------------

# create main display group
splash = displayio.Group()
clue.display.show(splash)

# background
bg_bmp, bg_pal = adafruit_imageload.load("/network23.bmp",
                                         bitmap=displayio.Bitmap,
                                         palette=displayio.Palette)
for i, color in enumerate(bg_pal):
    if color == 0xFF0000:
        bg_pal.make_transparent(i)
        break
background = displayio.TileGrid(bg_bmp, pixel_shader=bg_pal)

# a group for both altitude readouts
alti_readouts = displayio.Group(scale=6)
Example #28
0
# width and height variables used to check the edges
SCREEN_WIDTH = 160
SCREEN_HEIGHT = 128

# FPS setting raise or lower this to make the game faster or slower
FPS = 60

# what fraction of a second to wait in order to achieve FPS setting
FPS_DELAY = 1 / FPS

# Badger object for easy button handling
badger = PyBadger()

# Make the display context
splash = displayio.Group(max_size=10)
board.DISPLAY.show(splash)

# Make a background color fill
color_bitmap = displayio.Bitmap(SCREEN_WIDTH, SCREEN_HEIGHT, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF
bg_sprite = displayio.TileGrid(color_bitmap,
                               x=0,
                               y=0,
                               pixel_shader=color_palette)
splash.append(bg_sprite)

# hold the time we last updated the game state
last_update_time = 0
import time
import math
import board
from digitalio import DigitalInOut, Direction, Pull
import pwmio
from adafruit_lsm6ds.lsm6ds33 import LSM6DS33
from adafruit_lsm6ds import AccelRange, AccelHPF, Rate
from adafruit_display_text import label
import displayio
import terminalio

button_a = DigitalInOut(board.BUTTON_A)
button_a.direction = Direction.INPUT
button_a.pull = Pull.UP

splash = displayio.Group(max_size=3)

# draw the bad egg!
begg_file = open("broken_egg.bmp", "rb")
begg_bmp = displayio.OnDiskBitmap(begg_file)
begg_sprite = displayio.TileGrid(begg_bmp,
                                 pixel_shader=displayio.ColorConverter())
splash.append(begg_sprite)

# draw the good egg on top
gegg_file = open("good_egg.bmp", "rb")
gegg_bmp = displayio.OnDiskBitmap(gegg_file)
gegg_sprite = displayio.TileGrid(gegg_bmp,
                                 pixel_shader=displayio.ColorConverter())
splash.append(gegg_sprite)
    def __init__(self, display=board.DISPLAY):
        self._logger = logging.getLogger("Paint")
        self._logger.setLevel(logging.DEBUG)
        self._display = display
        self._w = self._display.width
        self._h = self._display.height
        self._x = self._w // 2
        self._y = self._h // 2

        self._splash = displayio.Group(max_size=5)

        self._bg_bitmap = displayio.Bitmap(self._w, self._h, 1)
        self._bg_palette = displayio.Palette(1)
        self._bg_palette[0] = Color.BLACK
        self._bg_sprite = displayio.TileGrid(self._bg_bitmap,
                                             pixel_shader=self._bg_palette,
                                             x=0,
                                             y=0)
        self._splash.append(self._bg_sprite)

        self._palette_bitmap = displayio.Bitmap(self._w, self._h, 5)
        self._palette_palette = displayio.Palette(len(Color.colors))
        for i, c in enumerate(Color.colors):
            self._palette_palette[i] = c
        self._palette_sprite = displayio.TileGrid(
            self._palette_bitmap, pixel_shader=self._palette_palette, x=0, y=0)
        self._splash.append(self._palette_sprite)

        self._fg_bitmap = displayio.Bitmap(self._w, self._h, 5)
        self._fg_palette = displayio.Palette(len(Color.colors))
        for i, c in enumerate(Color.colors):
            self._fg_palette[i] = c
        self._fg_sprite = displayio.TileGrid(self._fg_bitmap,
                                             pixel_shader=self._fg_palette,
                                             x=0,
                                             y=0)
        self._splash.append(self._fg_sprite)

        self._number_of_palette_options = len(Color.colors) + 2
        self._swatch_height = self._h // self._number_of_palette_options
        self._swatch_width = self._w // 10
        self._logger.debug('Height: %d', self._h)
        self._logger.debug('Swatch height: %d', self._swatch_height)

        self._palette = self._make_palette()
        self._splash.append(self._palette)

        self._display.show(self._splash)
        self._display.refresh_soon()
        gc.collect()
        self._display.wait_for_frame()

        self._brush = 0
        self._cursor_bitmaps = [
            self._cursor_bitmap_1(),
            self._cursor_bitmap_3()
        ]
        if hasattr(board, 'TOUCH_XL'):
            self._poller = TouchscreenPoller(self._splash,
                                             self._cursor_bitmaps[0])
        elif hasattr(board, 'BUTTON_CLOCK'):
            self._poller = CursorPoller(self._splash, self._cursor_bitmaps[0])
        else:
            raise AttributeError('PyPaint requires a touchscreen or cursor.')

        self._a_pressed = False
        self._last_a_pressed = False
        self._location = None
        self._last_location = None

        self._pencolor = 7