apps: musicplayer: Adopt GfxButton and use it for trace fwd/back
Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
2
TODO.rst
|
@ -62,7 +62,7 @@ Wasp-os
|
||||||
|
|
||||||
* [X] Add a simple theming approach
|
* [X] Add a simple theming approach
|
||||||
* [X] Update icon for Music player
|
* [X] Update icon for Music player
|
||||||
* [ ] Introduce fwd/back/vol+/vol- buttons to the music player
|
* [X] Introduce fwd/back buttons to the music player
|
||||||
* [X] Update icon for Alarm app
|
* [X] Update icon for Alarm app
|
||||||
* [X] Update art work for buttons in Confirmation view
|
* [X] Update art work for buttons in Confirmation view
|
||||||
* [X] Reduce the size of the battery charge icon slightly (match bell)
|
* [X] Reduce the size of the battery charge icon slightly (match bell)
|
||||||
|
|
BIN
res/back.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
res/fwd.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
0
res/headset.png
Executable file → Normal file
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 8 KiB |
0
res/pause.png
Executable file → Normal file
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
BIN
res/play.png
Executable file → Normal file
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -22,6 +22,8 @@ import wasp
|
||||||
import icons
|
import icons
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from micropython import const
|
||||||
|
|
||||||
# 2-bit RLE, generated from res/music_icon.png, 358 bytes
|
# 2-bit RLE, generated from res/music_icon.png, 358 bytes
|
||||||
icon = (
|
icon = (
|
||||||
b'\x02'
|
b'\x02'
|
||||||
|
@ -51,20 +53,20 @@ icon = (
|
||||||
b'<\xa4\x1e'
|
b'<\xa4\x1e'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DISPLAY_WIDTH = const(240)
|
||||||
|
ICON_SIZE = const(72)
|
||||||
|
CENTER_AT = const((DISPLAY_WIDTH - ICON_SIZE) // 2)
|
||||||
|
|
||||||
class MusicPlayerApp(object):
|
class MusicPlayerApp(object):
|
||||||
""" Music Player Controller application."""
|
""" Music Player Controller application."""
|
||||||
NAME = 'Music'
|
NAME = 'Music'
|
||||||
ICON = icon
|
ICON = icon
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self._pauseplay = wasp.widgets.GfxButton(CENTER_AT, CENTER_AT, icons.play)
|
||||||
self._play_icon = icons.play
|
self._back = wasp.widgets.GfxButton(0, 120-12, icons.back)
|
||||||
self._pause_icon = icons.pause
|
self._fwd = wasp.widgets.GfxButton(240-48, 120-12, icons.fwd)
|
||||||
self._play_state = False
|
self._play_state = False
|
||||||
self._icon_state = self._play_icon
|
|
||||||
self._max_display = 240
|
|
||||||
self._icon_size = 72
|
|
||||||
self._center_at = int((self._max_display - self._icon_size)/2)
|
|
||||||
self._musicstate = 'pause'
|
self._musicstate = 'pause'
|
||||||
self._artist = ''
|
self._artist = ''
|
||||||
self._track = ''
|
self._track = ''
|
||||||
|
@ -84,14 +86,11 @@ class MusicPlayerApp(object):
|
||||||
def _fill_space(self, key):
|
def _fill_space(self, key):
|
||||||
if key == 'top':
|
if key == 'top':
|
||||||
wasp.watch.drawable.fill(
|
wasp.watch.drawable.fill(
|
||||||
x=0, y=0, w=self._max_display, h=self._center_at)
|
x=0, y=0, w=DISPLAY_WIDTH, h=CENTER_AT)
|
||||||
elif key == 'mid':
|
|
||||||
wasp.watch.drawable.fill(x=self._center_at, y=self._center_at,
|
|
||||||
w=self._icon_size, h=self._icon_size)
|
|
||||||
elif key == 'down':
|
elif key == 'down':
|
||||||
wasp.watch.drawable.fill(x=0, y=self._center_at + self._icon_size,
|
wasp.watch.drawable.fill(x=0, y=CENTER_AT + ICON_SIZE,
|
||||||
w=self._max_display,
|
w=DISPLAY_WIDTH,
|
||||||
h=self._max_display - (self._center_at + self._icon_size))
|
h=DISPLAY_WIDTH - (CENTER_AT + ICON_SIZE))
|
||||||
|
|
||||||
def foreground(self):
|
def foreground(self):
|
||||||
"""Activate the application."""
|
"""Activate the application."""
|
||||||
|
@ -102,10 +101,8 @@ class MusicPlayerApp(object):
|
||||||
self._musicstate = state
|
self._musicstate = state
|
||||||
if self._musicstate == 'play':
|
if self._musicstate == 'play':
|
||||||
self._play_state = True
|
self._play_state = True
|
||||||
self._icon_state = self._pause_icon
|
|
||||||
elif self._musicstate == 'pause':
|
elif self._musicstate == 'pause':
|
||||||
self._play_state = False
|
self._play_state = False
|
||||||
self._icon_state = self._play_icon
|
|
||||||
if artist:
|
if artist:
|
||||||
self._artist = artist
|
self._artist = artist
|
||||||
if track:
|
if track:
|
||||||
|
@ -113,8 +110,7 @@ class MusicPlayerApp(object):
|
||||||
wasp.watch.drawable.fill()
|
wasp.watch.drawable.fill()
|
||||||
self.draw()
|
self.draw()
|
||||||
wasp.system.request_tick(1000)
|
wasp.system.request_tick(1000)
|
||||||
wasp.system.request_event(wasp.EventMask.SWIPE_UPDOWN |
|
wasp.system.request_event(wasp.EventMask.SWIPE_LEFTRIGHT |
|
||||||
wasp.EventMask.SWIPE_LEFTRIGHT |
|
|
||||||
wasp.EventMask.TOUCH)
|
wasp.EventMask.TOUCH)
|
||||||
|
|
||||||
def background(self):
|
def background(self):
|
||||||
|
@ -158,23 +154,24 @@ class MusicPlayerApp(object):
|
||||||
self._send_cmd('{"t":"music", "n":"volumeup"} ')
|
self._send_cmd('{"t":"music", "n":"volumeup"} ')
|
||||||
elif event[0] == wasp.EventType.DOWN:
|
elif event[0] == wasp.EventType.DOWN:
|
||||||
self._send_cmd('{"t":"music", "n":"volumedown"} ')
|
self._send_cmd('{"t":"music", "n":"volumedown"} ')
|
||||||
elif event[0] == wasp.EventType.LEFT:
|
|
||||||
self._send_cmd('{"t":"music", "n":"next"} ')
|
|
||||||
elif event[0] == wasp.EventType.RIGHT:
|
|
||||||
self._send_cmd('{"t":"music", "n":"previous"} ')
|
|
||||||
|
|
||||||
def touch(self, event):
|
def touch(self, event):
|
||||||
self._play_state = not self._play_state
|
if self._pauseplay.touch(event):
|
||||||
if self._play_state:
|
self._play_state = not self._play_state
|
||||||
self._musicstate = 'play'
|
if self._play_state:
|
||||||
self._icon_state = self._pause_icon
|
self._musicstate = 'play'
|
||||||
self._draw_button()
|
self._pauseplay.gfx = icons.pause
|
||||||
self._send_cmd('{"t":"music", "n":"play"} ')
|
self._pauseplay.draw()
|
||||||
else:
|
self._send_cmd('{"t":"music", "n":"play"} ')
|
||||||
self._musicstate = 'pause'
|
else:
|
||||||
self._icon_state = self._play_icon
|
self._musicstate = 'pause'
|
||||||
self._draw_button()
|
self._pauseplay.gfx = icons.play
|
||||||
self._send_cmd('{"t":"music", "n":"pause"} ')
|
self._pauseplay.draw()
|
||||||
|
self._send_cmd('{"t":"music", "n":"pause"} ')
|
||||||
|
elif self._back.touch(event):
|
||||||
|
self._send_cmd('{"t":"music", "n":"previous"} ')
|
||||||
|
elif self._fwd.touch(event):
|
||||||
|
self._send_cmd('{"t":"music", "n":"next"} ')
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
"""Redraw the display from scratch."""
|
"""Redraw the display from scratch."""
|
||||||
|
@ -183,17 +180,13 @@ class MusicPlayerApp(object):
|
||||||
def _draw(self):
|
def _draw(self):
|
||||||
"""Redraw the updated zones."""
|
"""Redraw the updated zones."""
|
||||||
if self._state_changed:
|
if self._state_changed:
|
||||||
self._draw_button()
|
self._pauseplay.draw()
|
||||||
if self._track_changed:
|
if self._track_changed:
|
||||||
self._draw_label(self._track, 24 + 144)
|
self._draw_label(self._track, 24 + 144)
|
||||||
if self._artist_changed:
|
if self._artist_changed:
|
||||||
self._draw_label(self._artist, 12)
|
self._draw_label(self._artist, 12)
|
||||||
|
self._back.draw()
|
||||||
def _draw_button(self):
|
self._fwd.draw()
|
||||||
"""Redraw player button"""
|
|
||||||
self._fill_space('mid')
|
|
||||||
wasp.watch.drawable.blit(self._icon_state, self._center_at,
|
|
||||||
self._center_at)
|
|
||||||
|
|
||||||
def _draw_label(self, label, pos):
|
def _draw_label(self, label, pos):
|
||||||
"""Redraw label info"""
|
"""Redraw label info"""
|
||||||
|
@ -208,10 +201,10 @@ class MusicPlayerApp(object):
|
||||||
def _update(self):
|
def _update(self):
|
||||||
if self._musicstate == 'play':
|
if self._musicstate == 'play':
|
||||||
self._play_state = True
|
self._play_state = True
|
||||||
self._icon_state = self._pause_icon
|
self._pauseplay.gfx = icons.pause
|
||||||
elif self._musicstate == 'pause':
|
elif self._musicstate == 'pause':
|
||||||
self._play_state = False
|
self._play_state = False
|
||||||
self._icon_state = self._play_icon
|
self._pauseplay.gfx = icons.play
|
||||||
self._draw()
|
self._draw()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
|
|
@ -215,28 +215,29 @@ blestatus = (
|
||||||
b'\x13\xc2\x14\xc1\x0e'
|
b'\x13\xc2\x14\xc1\x0e'
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2-bit RLE, generated from res/play.png, 282 bytes
|
# 2-bit RLE, generated from res/play.png, 303 bytes
|
||||||
play = (
|
play = (
|
||||||
b'\x02'
|
b'\x02'
|
||||||
b'HH'
|
b'HH'
|
||||||
b'?\xff\x8f\xcd8\xd41\xd9.\xdc*\xe0&\xe4#\xd1'
|
b'?\xff\x8f\xcd8\xd41\xd9.\xdc*\xe0&\xe4#\xd1'
|
||||||
b'\x01\x02\xd2!\xcd\r\xce\x1f\xcb\x13\xcc\x1d\xca\x17\xcb\x1b'
|
b'\x01\x02\xd2!\xcd\r\xce\x1f\xcb\x13\xcc\x1d\xca\x17\xcb\x1b'
|
||||||
b'\xca\x1a\xca\x19\xc9\x1d\xca\x17\xc9 \xc9\x16\xc8"\xc8\x15'
|
b'\xca\x1a\xca\x19\xc9\x1d\xca\x17\xc9 \xc9\x16\xc8"\xc8\x15'
|
||||||
b'\xc8$\xc8\x14\xc7%\xc8\x13\xc8&\xc8\x11\xc8\x0e\xc2\x18'
|
b'\xc8$\xc8\x14\xc7%\xc8\x13\xc8&\xc8\x11\xc8\x0c\xc4\x11'
|
||||||
b'\xc7\x11\xc7\x0f\xc3\x17\xc8\x10\xc7\x0f\xc4\x17\xc7\x0f\xc7\x10'
|
b'\x07\xc7\x11\xc7\r\xc6\x0f\x07\xc8\x10\xc7\r\xc7\x0e\x08\xc7'
|
||||||
b'\xc6\x16\xc7\x0e\xc7\x10\xc7\x15\xc7\x0e\xc7\x10\xc8\x14\xc7\r'
|
b'\x0f\xc7\x0e\xc9\x0c\t\xc7\x0e\xc7\x0e\xcb\n\t\xc7\x0e\xc7'
|
||||||
b'\xc7\x11\xca\x13\xc6\r\xc7\x11\xcb\x12\xc7\x0c\xc7\x11\xcc\x11'
|
b'\x0e\xcc\t\t\xc7\r\xc7\x0f\xce\x07\n\xc6\r\xc7\x0f\xd0'
|
||||||
b'\xc7\x0c\xc7\x11\xce\x0f\xc7\x0c\xc7\x11\xcf\x0e\x01\xc6\x0c\xc6'
|
b'\x05\n\xc7\x0c\xc7\x0f\xd1\x04\n\xc7\x0c\xc7\x0f\xd3\x02\n'
|
||||||
b'\x12\xd0\r\x01\xc6\x0c\xc6\x12\xd1\x01\x0c\xc6\x0c\xc6\x12\xd2'
|
b'\xc7\x0c\xc7\x0f\xd4\x01\n\x01\xc6\x0c\xc6\x10\xd5\n\x01\xc6'
|
||||||
b'\x0c\xc6\x0c\xc6\x12\xd1\x0c\xc7\x0c\xc7\x11\xcf\x0e\xc7\x0c\xc7'
|
b'\x0c\xc6\x10\xd6\n\xc6\x0c\xc6\x10\xd6\n\xc6\x0c\xc6\x10\xd5'
|
||||||
b'\x11\xce\x0f\xc7\x0c\xc7\x11\xcd\x10\xc7\x0c\xc7\x11\xcb\x12\xc7'
|
b'\n\xc7\x0c\xc7\x0f\xd4\x01\n\xc7\x0c\xc7\x0f\xd3\x02\n\xc7'
|
||||||
b'\x0c\xc7\x11\xca\x13\xc7\r\xc7\x10\xc9\x13\xc7\x0e\xc7\x10\xc7'
|
b'\x0c\xc7\x0f\xd1\x04\n\xc7\x0c\xc7\x0f\xd0\x05\n\xc7\x0c\xc7'
|
||||||
b'\x15\xc7\x0e\xc7\x10\xc6\x16\xc7\x0f\xc7\x0f\xc5\x16\xc7\x10\xc7'
|
b'\x0f\xce\x07\n\xc7\r\xc7\x0e\xcc\t\t\xc7\x0e\xc7\x0e\xcb'
|
||||||
b'\x0f\xc3\x18\xc7\x10\xc8\x0e\xc2\x18\xc8\x11\xc7\x0e\xc1\x18\xc8'
|
b'\n\t\xc7\x0e\xc7\x0e\xc9\x0c\t\xc7\x0f\xc7\r\xc7\x0e\x08'
|
||||||
b'\x12\xc8&\xc7\x14\xc8$\xc8\x15\xc8"\xc8\x16\xc9 \xc9'
|
b'\xc7\x10\xc7\r\xc6\x0f\x08\xc7\x10\xc8\x0c\xc4\x11\x07\xc8\x11'
|
||||||
b'\x17\xc9\x1e\xc9\x19\xc9\x1b\xca\x1b\xca\x18\xca\x1d\xcb\x14\xcb'
|
b'\xc7\x0e\x02\x17\xc8\x12\xc8&\xc7\x14\xc8$\xc8\x15\xc8"'
|
||||||
b'\x1f\xcd\x0e\xcd!\xd1\x04\xd1#\xe4&\xe0)\xdd-\xda'
|
b'\xc8\x16\xc9 \xc9\x17\xc9\x1e\xc9\x19\xc9\x1b\xca\x1b\xca\x18'
|
||||||
b'1\xd47\xce?\xff\x8f'
|
b'\xca\x1d\xcb\x14\xcb\x1f\xcd\x0e\xcd!\xd1\x04\xd1#\xe4&'
|
||||||
|
b'\xe0)\xdd-\xda1\xd47\xce?\xff\x8f'
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2-bit RLE, generated from res/pause.png, 320 bytes
|
# 2-bit RLE, generated from res/pause.png, 320 bytes
|
||||||
|
@ -265,6 +266,30 @@ pause = (
|
||||||
b'&\xe0)\xdd-\xda1\xd47\xce?\xff\x8f'
|
b'&\xe0)\xdd-\xda1\xd47\xce?\xff\x8f'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 2-bit RLE, generated from res/fwd.png, 93 bytes
|
||||||
|
fwd = (
|
||||||
|
b'\x02'
|
||||||
|
b'0\x18'
|
||||||
|
b'\xc4\x11\xc4\x11\xcc\x0f\xc6\x0f\xcd\x0e\xc7\x0e\xcf\x0c\xc9\x0c'
|
||||||
|
b'\xd1\n\xcb\n\xd2\t\xcc\t\xd4\x07\xce\x07\xd6\x05\xd0\x05'
|
||||||
|
b'\xd7\x04\xd1\x04\xd9\x02\xd3\x02\xda\x01\xd4\x01\xff;\x01\xd4'
|
||||||
|
b'\x01\xd9\x02\xd3\x02\xd7\x04\xd1\x04\xd6\x05\xd0\x05\xd4\x07\xce'
|
||||||
|
b'\x07\xd2\t\xcc\t\xd1\n\xcb\n\xcf\x0c\xc9\x0c\xcd\x0e\xc7'
|
||||||
|
b'\x0e\xcc\x0f\xc6\x0f\xca\x11\xc4\x11\xc6'
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2-bit RLE, generated from res/back.png, 93 bytes
|
||||||
|
back = (
|
||||||
|
b'\x02'
|
||||||
|
b'0\x18'
|
||||||
|
b'\xc6\x11\xc4\x11\xca\x0f\xc6\x0f\xcc\x0e\xc7\x0e\xcd\x0c\xc9\x0c'
|
||||||
|
b'\xcf\n\xcb\n\xd1\t\xcc\t\xd2\x07\xce\x07\xd4\x05\xd0\x05'
|
||||||
|
b'\xd6\x04\xd1\x04\xd7\x02\xd3\x02\xd9\x01\xd4\x01\xff;\x01\xd4'
|
||||||
|
b'\x01\xda\x02\xd3\x02\xd9\x04\xd1\x04\xd7\x05\xd0\x05\xd6\x07\xce'
|
||||||
|
b'\x07\xd4\t\xcc\t\xd2\n\xcb\n\xd1\x0c\xc9\x0c\xcf\x0e\xc7'
|
||||||
|
b'\x0e\xcd\x0f\xc6\x0f\xcc\x11\xc4\x11\xc4'
|
||||||
|
)
|
||||||
|
|
||||||
# 2-bit RLE, generated from res/checkbox.png, 108 bytes
|
# 2-bit RLE, generated from res/checkbox.png, 108 bytes
|
||||||
checkbox = (
|
checkbox = (
|
||||||
b'\x02'
|
b'\x02'
|
||||||
|
@ -277,4 +302,3 @@ checkbox = (
|
||||||
b'F\x85O\xc6G\x83P\xc6H\x81Q\xc6Z\xc6Z\xc6'
|
b'F\x85O\xc6G\x83P\xc6H\x81Q\xc6Z\xc6Z\xc6'
|
||||||
b'Z\xc7X\xe4\x01\xde\x03\xdc\x02'
|
b'Z\xc7X\xe4\x01\xde\x03\xdc\x02'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|