diff options
Diffstat (limited to 'wasp/apps')
| -rw-r--r-- | wasp/apps/pager.py | 119 | ||||
| -rw-r--r-- | wasp/apps/testapp.py | 22 |
2 files changed, 140 insertions, 1 deletions
diff --git a/wasp/apps/pager.py b/wasp/apps/pager.py new file mode 100644 index 0000000..7da8f5a --- /dev/null +++ b/wasp/apps/pager.py @@ -0,0 +1,119 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2020 Daniel Thompson + +import wasp +import icons + +import io +import sys + + +class PagerApp(): + """Show long text in a pager. + + This is used to present text based information to the user. It is primarily + intended for notifications but is also used to provide debugging + information when applications crash. + """ + NAME = 'Pager' + ICON = icons.app + + def __init__(self, msg): + self._msg = msg + self._scroll = wasp.widgets.ScrollIndicator() + + def foreground(self): + """Activate the application.""" + self._page = 0 + self._chunks = wasp.watch.drawable.wrap(self._msg, 240) + self._numpages = (len(self._chunks) - 2) // 9 + wasp.system.request_event(wasp.EventMask.SWIPE_UPDOWN) + self._draw() + + def background(self): + del self._chunks + del self._numpages + + def swipe(self, event): + mute = wasp.watch.display.mute + + if event[0] == wasp.EventType.UP: + if self._page >= self._numpages: + wasp.system.navigate(wasp.EventType.BACK) + return + self._page += 1 + else: + if self._page <= 0: + wasp.watch.vibrator.pulse() + return + self._page -= 1 + mute(True) + self._draw() + mute(False) + + def _draw(self): + """Draw the display from scratch.""" + draw = wasp.watch.drawable + draw.fill() + + page = self._page + i = page * 9 + j = i + 11 + chunks = self._chunks[i:j] + for i in range(len(chunks)-1): + sub = self._msg[chunks[i]:chunks[i+1]].rstrip() + draw.string(sub, 0, 24*i) + + scroll = self._scroll + scroll.up = page > 0 + scroll.down = page < self._numpages + scroll.draw() + +class CrashApp(): + """Crash handler application. + + This application is launched automatically whenever another + application crashes. Our main job it to indicate as loudly as + possible that the system is no longer running correctly. This + app deliberately enables inverted video mode in order to deliver + that message as strongly as possible. + """ + def __init__(self, exc): + """Capture the exception information. + + This app does not actually display the exception information + but we need to capture the exception info before we leave + the except block. + """ + msg = io.StringIO() + sys.print_exception(exc, msg) + self._msg = msg.getvalue() + msg.close() + + def foreground(self): + """Indicate the system has crashed by drawing a couple of bomb icons. + + If you owned an Atari ST back in the mid-eighties then I hope you + recognise this as a tribute a long forgotten home computer! + """ + wasp.watch.display.invert(False) + draw = wasp.watch.drawable + draw.blit(icons.bomb, 0, 104) + draw.blit(icons.bomb, 32, 104) + + wasp.system.request_event(wasp.EventMask.SWIPE_UPDOWN | + wasp.EventMask.SWIPE_LEFTRIGHT) + + def background(self): + """Restore a normal display mode. + + Conceal the display before the transition otherwise the inverted + bombs get noticed by the user. + """ + wasp.watch.display.mute(True) + wasp.watch.display.invert(True) + + def swipe(self, event): + """Show the exception message in a pager. + """ + wasp.system.switch(PagerApp(self._msg)) diff --git a/wasp/apps/testapp.py b/wasp/apps/testapp.py index 789454f..0df4ee7 100644 --- a/wasp/apps/testapp.py +++ b/wasp/apps/testapp.py @@ -12,7 +12,7 @@ class TestApp(): ICON = icons.app def __init__(self): - self.tests = ('Touch', 'String', 'Button', 'Crash', 'RLE') + self.tests = ('Touch', 'String', 'Wrap', 'Button', 'Crash', 'RLE') self.test = self.tests[0] self.scroll = wasp.widgets.ScrollIndicator() @@ -56,6 +56,8 @@ class TestApp(): event[1], event[2]), 0, 108, width=240) elif self.test == 'String': self.benchmark_string() + elif self.test == 'Wrap': + self.benchmark_wrap() elif self.test == 'RLE': self.benchmark_rle() @@ -88,6 +90,24 @@ class TestApp(): del t draw.string('{}s'.format(elapsed / 1000000), 12, 24+192) + def benchmark_wrap(self): + draw = wasp.watch.drawable + draw.fill(0, 0, 30, 240, 240-30) + self.scroll.draw() + t = machine.Timer(id=1, period=8000000) + t.start() + draw = wasp.watch.drawable + s = 'This\nis a very long string that will need to be wrappedinmultipledifferentways!' + chunks = draw.wrap(s, 240) + + for i in range(len(chunks)-1): + sub = s[chunks[i]:chunks[i+1]].rstrip() + draw.string(sub, 0, 48+24*i) + elapsed = t.time() + t.stop() + del t + draw.string('{}s'.format(elapsed / 1000000), 12, 24+192) + def draw(self): """Redraw the display from scratch.""" wasp.watch.display.mute(True) |
