diff options
| author | Wolfgang Ginolas <wolfgang.ginolas@gwif.eu> | 2020-12-31 16:18:13 (GMT) |
|---|---|---|
| committer | Daniel Thompson <daniel@redfelineninja.org.uk> | 2021-01-10 16:02:35 (GMT) |
| commit | 5b74c45e58eedddf3432b595822989afba8bf3a4 (patch) | |
| tree | f524373a333b23210273f57a2acfdca4bba09fa5 | |
| parent | 4e9a576a2df3476a19522df177f845fade7b1fa6 (diff) | |
apps: timer: Add a countdown timer application
Signed-off-by: Wolfgang Ginolas <wolfgang.ginolas@gwif.eu>
[daniel@redfelineninja.org.uk: squashed into a single commit, rebase to
latest master, integrate with the Software application and rename the
screenshots to match the application name]
Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
| -rw-r--r-- | README.rst | 6 | ||||
| -rw-r--r-- | docs/apps.rst | 2 | ||||
| -rw-r--r-- | res/StopclockApp.png | bin | 0 -> 7386 bytes | |||
| -rw-r--r-- | res/TimerApp.png | bin | 6904 -> 15666 bytes | |||
| -rw-r--r-- | res/timer_icon.png | bin | 0 -> 1066 bytes | |||
| -rw-r--r-- | wasp/apps/software.py | 1 | ||||
| -rw-r--r-- | wasp/apps/stopwatch.py | 5 | ||||
| -rw-r--r-- | wasp/apps/timer.py | 173 | ||||
| -rw-r--r-- | wasp/boards/manifest_240x240.py | 1 |
9 files changed, 185 insertions, 3 deletions
@@ -137,7 +137,7 @@ simulator (the "blank" screen is the torch application): :alt: Heart rate application running on the wasp-os simulator :width: 179 -.. image:: res/TimerApp.png +.. image:: res/StopclockApp.png :alt: Stop watch application running on the wasp-os simulator :width: 179 @@ -192,3 +192,7 @@ using one of the techniques is the Application Writer's guide. .. image:: res/SnakeApp.png :alt: Snake Game running in the wasp-os simulator :width: 179 + +.. image:: res/TimerApp.png + :alt: Countdown timer application running in the wasp-os simulator + :width: 179 diff --git a/docs/apps.rst b/docs/apps.rst index ae9fb15..5cadd94 100644 --- a/docs/apps.rst +++ b/docs/apps.rst @@ -40,3 +40,5 @@ Integration .. automodule:: apps.alarm .. automodule:: apps.musicplayer + +.. automodule:: apps.timer diff --git a/res/StopclockApp.png b/res/StopclockApp.png Binary files differnew file mode 100644 index 0000000..3c14c74 --- /dev/null +++ b/res/StopclockApp.png diff --git a/res/TimerApp.png b/res/TimerApp.png Binary files differindex eaa91de..8edb17e 100644 --- a/res/TimerApp.png +++ b/res/TimerApp.png diff --git a/res/timer_icon.png b/res/timer_icon.png Binary files differnew file mode 100644 index 0000000..6493f8d --- /dev/null +++ b/res/timer_icon.png diff --git a/wasp/apps/software.py b/wasp/apps/software.py index a39cce0..b8bea2c 100644 --- a/wasp/apps/software.py +++ b/wasp/apps/software.py @@ -22,6 +22,7 @@ class SoftwareApp(): ('snake', wasp.widgets.Checkbox(0, 40, 'Snake Game')), ('flashlight', wasp.widgets.Checkbox(0, 80, 'Torch')), ('testapp', wasp.widgets.Checkbox(0, 120, 'Test')), + ('timer', wasp.widgets.Checkbox(0, 160, 'Timer')), ) self.si = wasp.widgets.ScrollIndicator() self.page = 0 diff --git a/wasp/apps/stopwatch.py b/wasp/apps/stopwatch.py index 0d572af..f46baa0 100644 --- a/wasp/apps/stopwatch.py +++ b/wasp/apps/stopwatch.py @@ -8,12 +8,13 @@ import fonts class StopwatchApp(): """Stopwatch application. - .. figure:: res/TimerApp.png + .. figure:: res/StopclockApp.png :width: 179 Screenshot of the stopwatch application """ - NAME = 'Timer' + # Stopwatch requires too many pixels to fit into the launcher + NAME = 'Stopclock' ICON = icons.app def __init__(self): diff --git a/wasp/apps/timer.py b/wasp/apps/timer.py new file mode 100644 index 0000000..f1543f8 --- /dev/null +++ b/wasp/apps/timer.py @@ -0,0 +1,173 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2020 Wolfgang Ginolas +"""Timer Application +~~~~~~~~~~~~~~~~~~~~ + +An application to set a vibration in a specified amount of time. Like a kitchen timer. + + .. figure:: res/TimerApp.png + :width: 179 + + Screenshot of the Timer Application + +""" + +import wasp +import fonts +import time +import widgets +import math +from micropython import const + +# 2-bit RLE, generated from res/timer_icon.png, 345 bytes +icon = ( + b'\x02' + b'`@' + b'?\xff\r@\xb4I?\x14Q?\rW?\x08[?' + b'\x04_?\x00c<Q\x80\xd0\x83Q:L\x87\x01\x87' + b'L8K\x89\x01\x89K6J\x8b\x01\x8bJ4I\x8d' + b'\x01\x8dI2I\x9dI0I\x83\x01\x97\x01\x83I.' + b'H\x86\x01\x95\x01\x86H-H\xa3H,H\x92\x01\x92' + b'H+G\x92\x03\x92G*G\x92\x05\x92G)G\x92' + b"\x05\x92G(G\x82\x01\x8f\x07\x8f\x01\x82G'G\x83" + b"\x01\x8e\x07\x8e\x01\x83G'F\x93\x07\x93F&G\x93" + b'\x07\x93G%F\x94\x07\x94F%F\x94\x07\x94F%' + b'F\x94\x07\x94F$G\x94\x07\x94G#G\x94\x07\x94' + b'G#G\x94\x07\x94G#F\x95\x07\x95F#F\x81' + b'\x04\x90\x07\x90\x04\x81F#F\x95\x07\x95F#G\x94' + b'\x07\x94G#G\x94\x07\x94G#G\x94\x07\x94G$' + b'F\x94\x07\x94F%F\x94\x07\x94F%F\x94\x07\x94' + b"F%G\x93\x07\x93G%G\x93\x07\x93F'G\x83" + b"\x01\x8e\x07\x8e\x01\x83G'G\x82\x01\x8f\x07\x8f\x01\x82" + b'G(G\x92\x05\x92G)G\x93\x03\x93G*G\xa7' + b'G+H\xa5H,G\xa5G-H\x86\x01\x9cH.' + b'H\x84\x01\x96\x01\x85H0I\x9a\x01\x82I1J\x8d' + b'\x01\x8dJ2K\x8b\x01\x8bK4K\x8a\x01\x89L5' + b'N\x87\x01\x87N5S\x85S5k5k5k5' + b'k5k5k\x1b' +) + +_STOPPED = const(0) +_RUNNING = const(1) +_RINGING = const(2) + +_BUTTON_Y = const(200) + +class TimerApp(): + """Allows the user to set a vibration alarm. + """ + NAME = 'Timer' + ICON = icon + + def __init__(self): + """Initialize the application.""" + self.minutes = widgets.Spinner(50, 60, 0, 99, 2) + self.seconds = widgets.Spinner(130, 60, 0, 60, 2) + self.current_alarm = None + + self.minutes.value = 10 + self.state = _STOPPED + + def foreground(self): + """Activate the application.""" + self._draw() + wasp.system.request_event(wasp.EventMask.TOUCH) + wasp.system.request_tick(1000) + + def background(self): + """De-activate the application.""" + if self.state == _RINGING: + self.state = _STOPPED + + def tick(self, ticks): + """Notify the application that its periodic tick is due.""" + if self.state == _RINGING: + wasp.watch.vibrator.pulse(duty=50, ms=500) + wasp.system.keep_awake() + self._update() + + def touch(self, event): + """Notify the application of a touchscreen touch event.""" + if self.state == _RINGING: + mute = wasp.watch.display.mute + mute(True) + self._stop() + mute(False) + elif self.state == _RUNNING: + self._stop() + else: # _STOPPED + if self.minutes.touch(event) or self.seconds.touch(event): + pass + else: + y = event[2] + if y >= _BUTTON_Y: + self._start() + + + def _start(self): + self.state = _RUNNING + now = wasp.watch.rtc.time() + self.current_alarm = now + self.minutes.value * 60 + self.seconds.value + wasp.system.set_alarm(self.current_alarm, self._alert) + self._draw() + + def _stop(self): + self.state = _STOPPED + wasp.system.cancel_alarm(self.current_alarm, self._alert) + self._draw() + + def _draw(self): + """Draw the display from scratch.""" + draw = wasp.watch.drawable + draw.fill() + sbar = wasp.system.bar + sbar.clock = True + sbar.draw() + + if self.state == _RINGING: + draw.set_font(fonts.sans24) + draw.string(self.NAME, 0, 150, width=240) + draw.blit(icon, 73, 50) + elif self.state == _RUNNING: + self._draw_stop(104, _BUTTON_Y) + draw.string(':', 110, 120-14, width=20) + self._update() + else: # _STOPPED + draw.set_font(fonts.sans28) + draw.string(':', 110, 120-14, width=20) + + self.minutes.draw() + self.seconds.draw() + + self._draw_play(114, _BUTTON_Y) + + def _update(self): + wasp.system.bar.update() + draw = wasp.watch.drawable + if self.state == _RUNNING: + now = wasp.watch.rtc.time() + s = self.current_alarm - now + if s<0: + s = 0 + m = str(math.floor(s // 60)) + s = str(math.floor(s) % 60) + if len(m) < 2: + m = '0' + m + if len(s) < 2: + s = '0' + s + draw.set_font(fonts.sans28) + draw.string(m, 50, 120-14, width=60) + draw.string(s, 130, 120-14, width=60) + + def _draw_play(self, x, y): + draw = wasp.watch.drawable + for i in range(0,20): + draw.fill(0xffff, x+i, y+i, 1, 40 - 2*i) + + def _draw_stop(self, x, y): + wasp.watch.drawable.fill(0xffff, x, y, 40, 40) + + def _alert(self): + self.state = _RINGING + wasp.system.wake() + wasp.system.switch(self) diff --git a/wasp/boards/manifest_240x240.py b/wasp/boards/manifest_240x240.py index 4d91566..ed3a692 100644 --- a/wasp/boards/manifest_240x240.py +++ b/wasp/boards/manifest_240x240.py @@ -21,6 +21,7 @@ manifest = ( 'apps/stopwatch.py', 'apps/snake.py', 'apps/testapp.py', + 'apps/timer.py', 'fonts/__init__.py', 'fonts/clock.py', 'fonts/sans24.py', |
