1
0
Fork 0

wasp: draw565: Refactor to allow apps to focus on the drawable.

This commit is contained in:
Daniel Thompson 2020-03-09 00:00:13 +00:00
parent 5413d826d7
commit 031d139b7c
6 changed files with 67 additions and 55 deletions

View file

@ -56,10 +56,10 @@ class ClockApp(object):
def draw(self, effect=None): def draw(self, effect=None):
"""Redraw the display from scratch.""" """Redraw the display from scratch."""
display = watch.display draw = watch.drawable
display.fill(0) draw.fill()
display.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6) draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6)
self.on_screen = ( -1, -1, -1, -1, -1, -1 ) self.on_screen = ( -1, -1, -1, -1, -1, -1 )
self.update() self.update()
self.meter.draw() self.meter.draw()
@ -77,14 +77,13 @@ class ClockApp(object):
self.on_screen = now self.on_screen = now
return False return False
display = watch.display draw = watch.drawable
display.rleblit(DIGITS[now[4] % 10], pos=(4*48, 80)) draw.rleblit(DIGITS[now[4] % 10], pos=(4*48, 80))
display.rleblit(DIGITS[now[4] // 10], pos=(3*48, 80), fg=0xbdb6) draw.rleblit(DIGITS[now[4] // 10], pos=(3*48, 80), fg=0xbdb6)
display.rleblit(DIGITS[now[3] % 10], pos=(1*48, 80)) draw.rleblit(DIGITS[now[3] % 10], pos=(1*48, 80))
display.rleblit(DIGITS[now[3] // 10], pos=(0*48, 80), fg=0xbdb6) draw.rleblit(DIGITS[now[3] // 10], pos=(0*48, 80), fg=0xbdb6)
self.on_screen = now self.on_screen = now
draw = watch.drawable
month = now[1] - 1 month = now[1] - 1
month = MONTH[month*3:(month+1)*3] month = MONTH[month*3:(month+1)*3]
draw.string('{} {} {}'.format(now[2], month, now[0]), draw.string('{} {} {}'.format(now[2], month, now[0]),

View file

@ -38,7 +38,7 @@ class TestApp():
draw.string('({}, {})'.format(event[1], event[2]), draw.string('({}, {})'.format(event[1], event[2]),
0, 108, width=240) 0, 108, width=240)
elif self.test == 'String': elif self.test == 'String':
watch.display.fill(0, 0, 30, 240, 240-30) draw.fill(0, 0, 30, 240, 240-30)
t = machine.Timer(id=1, period=8000000) t = machine.Timer(id=1, period=8000000)
t.start() t.start()
draw.string("The quick brown", 12, 24+24) draw.string("The quick brown", 12, 24+24)
@ -56,7 +56,7 @@ class TestApp():
def draw(self, effect=None): def draw(self, effect=None):
"""Redraw the display from scratch.""" """Redraw the display from scratch."""
watch.display.mute(True) watch.display.mute(True)
watch.display.fill(0) watch.drawable.fill()
watch.drawable.string('{} test'.format(self.test), watch.drawable.string('{} test'.format(self.test),
0, 6, width=240) 0, 6, width=240)
watch.display.mute(False) watch.display.mute(False)

View file

@ -7,7 +7,7 @@
# len(colors) is not a multiple of 5 ;-) ). # len(colors) is not a multiple of 5 ;-) ).
# #
import watch, logo, time, gc, draw565 import watch, logo, time, gc
colors = ( colors = (
0xffff, 0xffff,
@ -24,10 +24,9 @@ colors = (
0xf81f, # magenta 0xf81f, # magenta
) )
draw = draw565.Draw565(watch.display)
def textdemo(): def textdemo():
watch.display.fill(0) watch.display.fill(0)
draw = watch.drawable
draw.string("The quick brown", 12, 24) draw.string("The quick brown", 12, 24)
draw.string("fox jumped over", 12, 48) draw.string("fox jumped over", 12, 48)
draw.string("the lazy dog.", 12, 72) draw.string("the lazy dog.", 12, 72)
@ -57,7 +56,7 @@ def run():
l = logo.pine64 l = logo.pine64
watch.display.fill(0) watch.display.fill(0)
watch.display.rleblit(l, fg=c) watch.drawable.rleblit(l, fg=c)
time.sleep(2) time.sleep(2)
gc.collect() gc.collect()

View file

@ -29,6 +29,16 @@ def _bitblit(bitbuf, pixels, bgfg: int, count: int):
bitselect = 0x80 bitselect = 0x80
pxp += 1 pxp += 1
@micropython.viper
def _fill(mv, color: int, count: int, offset: int):
p = ptr8(mv)
colorhi = color >> 8
colorlo = color & 0xff
for x in range(count):
p[2*(x+offset) ] = colorhi
p[2*(x+offset) + 1] = colorlo
def _bounding_box(s, font): def _bounding_box(s, font):
w = 0 w = 0
for ch in s: for ch in s:
@ -66,6 +76,44 @@ class Draw565(object):
self.set_color(0xffff) self.set_color(0xffff)
self.set_font(fonts.sans24) self.set_font(fonts.sans24)
def fill(self, bg=None, x=0, y=0, w=None, h=None):
"""Draw a solid color rectangle.
If no arguments a provided the whole display will be filled with
the background color.
"""
if bg is None:
bg = self._bgfg >> 16
self._display.fill(bg, x, y, w, h)
@micropython.native
def rleblit(self, image, pos=(0, 0), fg=0xffff, bg=0):
"""Decode and draw a 1-bit RLE image."""
display = self._display
(sx, sy, rle) = image
display.set_window(pos[0], pos[1], sx, sy)
buf = memoryview(display.linebuffer)[0:2*sx]
bp = 0
color = bg
for rl in rle:
while rl:
count = min(sx - bp, rl)
_fill(buf, color, count, bp)
bp += count
rl -= count
if bp >= sx:
display.write_data(buf)
bp = 0
if color == bg:
color = fg
else:
color = bg
def set_color(self, color, bg=0): def set_color(self, color, bg=0):
"""Set the foreground (color) and background (bg) color. """Set the foreground (color) and background (bg) color.

View file

@ -25,16 +25,6 @@ _RAMWR = const(0x2c)
_COLMOD = const(0x3a) _COLMOD = const(0x3a)
_MADCTL = const(0x36) _MADCTL = const(0x36)
@micropython.viper
def fastfill(mv, color: int, count: int, offset: int):
p = ptr8(mv)
colorhi = color >> 8
colorlo = color & 0xff
for x in range(count):
p[2*(x+offset) ] = colorhi
p[2*(x+offset) + 1] = colorlo
class ST7789(object): class ST7789(object):
def __init__(self, width, height): def __init__(self, width, height):
self.width = width self.width = width
@ -126,31 +116,6 @@ class ST7789(object):
for yi in range(h): for yi in range(h):
self.write_data(buf) self.write_data(buf)
@micropython.native
def rleblit(self, image, pos=(0, 0), fg=0xffff, bg=0):
(sx, sy, rle) = image
self.set_window(pos[0], pos[1], sx, sy)
buf = memoryview(self.linebuffer)[0:2*sx]
bp = 0
color = bg
for rl in rle:
while rl:
count = min(sx - bp, rl)
fastfill(buf, color, count, bp)
bp += count
rl -= count
if bp >= sx:
self.write_data(buf)
bp = 0
if color == bg:
color = fg
else:
color = bg
class ST7789_SPI(ST7789): class ST7789_SPI(ST7789):
def __init__(self, width, height, spi, cs, dc, res=None, rate=8000000): def __init__(self, width, height, spi, cs, dc, res=None, rate=8000000):
self.spi = spi self.spi = spi

View file

@ -11,10 +11,11 @@ class BatteryMeter(object):
def update(self): def update(self):
icon = icons.battery icon = icons.battery
draw = watch.drawable
if watch.battery.charging(): if watch.battery.charging():
if self.level != -1: if self.level != -1:
watch.display.rleblit(icon, pos=(239-icon[0], 0), fg=0x7bef) draw.rleblit(icon, pos=(239-icon[0], 0), fg=0x7bef)
self.level = -1 self.level = -1
else: else:
level = watch.battery.level() level = watch.battery.level()
@ -33,16 +34,16 @@ class BatteryMeter(object):
if (level > 5) ^ (self.level > 5): if (level > 5) ^ (self.level > 5):
if level > 5: if level > 5:
watch.display.rleblit(icon, pos=(239-icon[0], 0), fg=0x7bef) draw.rleblit(icon, pos=(239-icon[0], 0), fg=0x7bef)
else: else:
rgb = 0xf800 rgb = 0xf800
watch.display.rleblit(icon, pos=(239-icon[0], 0), fg=0xf800) draw.rleblit(icon, pos=(239-icon[0], 0), fg=0xf800)
x = 239 - 30 x = 239 - 30
w = 16 w = 16
if 24 - h: if 24 - h:
watch.display.fill(0, x, 14, w, 24 - h) draw.fill(0, x, 14, w, 24 - h)
if h: if h:
watch.display.fill(rgb, x, 38 - h, w, h) draw.fill(rgb, x, 38 - h, w, h)
self.level = level self.level = level