Skip to content

Instantly share code, notes, and snippets.

@tjpeden
Created January 13, 2019 21:11
Show Gist options
  • Save tjpeden/eebb85001aee98489723453510246fa9 to your computer and use it in GitHub Desktop.
Save tjpeden/eebb85001aee98489723453510246fa9 to your computer and use it in GitHub Desktop.
My journey with CircuitPython on the Feather M4 Express with the 2.4" TFT FeatherWing
from board import SCK, MOSI, MISO, D5, D6, D9, D10
from busio import SPI
from digitalio import DigitalInOut
import storage
from storage import VfsFat
from adafruit_sdcard import SDCard
from adafruit_stmpe610 import Adafruit_STMPE610_SPI
from adafruit_rgb_display import color565
from adafruit_rgb_display.ili9341 import ILI9341
from widgets import SceneManager, Scene, Image, Button
spi = SPI(clock=SCK, MOSI=MOSI, MISO=MISO)
display = ILI9341(spi, cs=DigitalInOut(D9), dc=DigitalInOut(D10))
sdcard = SDCard(spi, DigitalInOut(D5))
screen = Adafruit_STMPE610_SPI(spi, DigitalInOut(D6))
vfs = VfsFat(sdcard)
storage.mount(vfs, '/sd')
manager = SceneManager(display)
def splash_scene():
scene = Scene()
splash_button = Button(0, 0, 240, 320, '/sd/images/splash.bin')
splash_button.action = start_scene
scene.add(splash_button)
manager.transition_to(scene)
def start_scene():
scene = Scene()
blinka_image = Image(0, 0, 240, 246, '/sd/images/blinka.bin')
next_button = Button(130, 288, 110, 31, '/sd/images/next.bin')
next_button.action = next_scene
scene.add(blinka_image)
scene.add(next_button)
manager.transition_to(scene)
def next_scene():
scene = Scene()
back_button = Button(0, 288, 110, 31, '/sd/images/back.bin')
back_button.action = start_scene
scene.add(back_button)
manager.transition_to(scene)
splash_scene()
while True:
if screen.touched:
(x, y, pressure) = screen.read_data()
if x == 0 or y == 0: continue
x = 2 * (4096 - x) // 30
y = 8 * y // 90
manager.touch(x, y)
while screen.touched:
if not screen.buffer_empty:
screen.read_data()
# from abc import ABC, abstractmethod
class Widget:
def __init__(self, x, y, width, height):
self.dma_size = 256
self.x = x
self.y = y
self.width = width
self.height = height
# @abstractmethod
def render(self, display):
pass
class Touchable(Widget):
def touched(self, x, y):
return self.x < x and x < self.x + self.width and self.y < y and y < self.y + self.height
def action():
pass
class Image(Widget):
def __init__(self, x, y, width, height, file):
self.dma_size = 256
self.file = file
super().__init__(x, y, width, height)
def render(self, display):
with open(self.file, 'rb') as pixels:
display._block(
self.x,
self.y,
self.x + self.width - 1,
self.y + self.height - 1,
b''
)
chunks, rest = divmod(self.width * self.height, self.dma_size)
if chunks:
for _ in range(chunks):
display.write(None, pixels.read(self.dma_size * 2))
display.write(None, pixels.read(rest * 2))
class Button(Image, Touchable):
pass
class Scene:
def __init__(self):
self.widgets = []
def add(self, widget):
self.widgets.append(widget)
def render(self, display):
for widget in self.widgets:
widget.render(display)
def touch(self, x, y):
for widget in self.widgets:
if isinstance(widget, Touchable) and widget.touched(x, y):
widget.action()
class SceneManager:
def __init__(self, display):
self.display = display
self.scene = None
def transition_to(self, scene):
self.scene = scene
self.display.fill(0)
scene.render(self.display)
def touch(self, x, y):
if self.scene:
self.scene.touch(x, y)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment