Listbox can trim text.

pull/8/head
Peter Hinch 2021-09-29 14:20:15 +01:00
rodzic 58dac4b6a0
commit fae4c5edc9
3 zmienionych plików z 61 dodań i 24 usunięć

Wyświetl plik

@ -1292,7 +1292,9 @@ Optional keyword only arguments:
scrolling is possible, one or two vertical bars will appear to the right of scrolling is possible, one or two vertical bars will appear to the right of
the list. the list.
* `width=None` Control width in pixels. By default this is calculated to * `width=None` Control width in pixels. By default this is calculated to
accommodate all elements. accommodate all elements. If a `width` is specified, and some elements are too
long to fit, they will be clipped. This is a visual effect only and does not
affect the value of that element.
* `value=0` Index of currently selected list item. If necessary the list will * `value=0` Index of currently selected list item. If necessary the list will
scroll to ensure the item is visible. scroll to ensure the item is visible.
* `fgcolor=None` Color of foreground (the control itself). If `None` the * `fgcolor=None` Color of foreground (the control itself). If `None` the

Wyświetl plik

@ -12,6 +12,8 @@ import pyb
# Do allocations early # Do allocations early
BUFSIZE = 1024*20 # 5.8ms/KiB BUFSIZE = 1024*20 # 5.8ms/KiB
root = "/sd/music" # Location of directories containing albums
pyb.Pin("EN_3V3").on() # provide 3.3V on 3V3 output pin pyb.Pin("EN_3V3").on() # provide 3.3V on 3V3 output pin
# ======= I2S CONFIGURATION ======= # ======= I2S CONFIGURATION =======
@ -52,19 +54,29 @@ from gui.core.colors import *
import os import os
import gc import gc
import uasyncio as asyncio import uasyncio as asyncio
import sys
# Initial check on ilesystem
try:
subdirs = [x[0] for x in os.ilistdir(root) if x[1] == 0x4000]
if len(subdirs):
subdirs.sort()
else:
print("No albums found in ", root)
sys.exit(1)
except OSError:
print(f"Expected {root} directory not found.")
sys.exit(1)
class SelectScreen(Screen): class SelectScreen(Screen):
songs = [] songs = []
album = "" album = ""
def __init__(self, wri): def __init__(self, wri):
super().__init__() super().__init__()
self.root = "/sd/music" Listbox(wri, 2, 2, elements = subdirs, dlines = 8, width=100, callback = self.lbcb)
subdirs = [x[0] for x in os.ilistdir(self.root) if x[1] == 0x4000]
subdirs.sort()
Listbox(wri, 2, 2, elements = subdirs, dlines = 8, callback = self.lbcb)
def lbcb(self, lb): # sort def lbcb(self, lb): # sort
directory = ''.join((self.root, '/', lb.textvalue())) directory = ''.join((root, '/', lb.textvalue()))
songs = [x[0] for x in os.ilistdir(directory) if x[1] != 0x4000] songs = [x[0] for x in os.ilistdir(directory) if x[1] != 0x4000]
songs.sort() songs.sort()
SelectScreen.songs = [''.join((directory, '/', x)) for x in songs] SelectScreen.songs = [''.join((directory, '/', x)) for x in songs]
@ -113,8 +125,8 @@ class BaseScreen(Screen):
row = 110 row = 110
col = 14 col = 14
HorizSlider(wri, row, col, callback=self.slider_cb, **args) HorizSlider(wri, row, col, callback=self.slider_cb, **args)
CloseButton(wri, callback=self.shutdown) # Quit the application CloseButton(wri) # Quit the application
self.reg_task(asyncio.create_task(self.report())) # self.reg_task(asyncio.create_task(self.report()))
async def report(self): async def report(self):
while True: while True:
@ -131,40 +143,54 @@ class BaseScreen(Screen):
def pause(self, _): def pause(self, _):
self.stop_play = True self.stop_play = True
self.paused = True self.paused = True
self.show_song()
def stop(self, _): # Abandon album def stop(self, _): # Abandon album
self.stop_play = True self.stop_play = True
self.paused = False self.paused = False
self.song_idx = 0 self.song_idx = 0
self.show_song()
def replay(self, _): def replay(self, _):
self.stop_play = True if self.stop_play:
self.song_idx = max(0, self.song_idx - 1)
else:
self.stop_play = True # Replay from start
self.paused = False self.paused = False
#self.play_album() # Play from same song_idx self.show_song()
#self.play_album()
def skip(self, _): def skip(self, _):
self.stop_play = True self.stop_play = True
self.paused = False self.paused = False
self.song_idx = min(self.song_idx + 1, len(self.songs) -1) self.song_idx = min(self.song_idx + 1, len(self.songs) -1)
self.show_song()
#self.play_album() #self.play_album()
def new(self, _, wri): def new(self, _, wri):
self.stop_play = True
self.paused = False
Screen.change(SelectScreen, args=[wri,]) Screen.change(SelectScreen, args=[wri,])
def play_album(self): def play_album(self):
self.reg_task(asyncio.create_task(self.album_task())) self.reg_task(asyncio.create_task(self.album_task()))
def shutdown(self, _):
audio_out.deinit()
print("========== CLOSE AUDIO ==========")
def after_open(self): def after_open(self):
self.songs = SelectScreen.songs self.songs = SelectScreen.songs
self.lbl.value(SelectScreen.album) self.lbl.value(SelectScreen.album)
if self.songs: if self.songs:
self.song_idx = 0 # Start on track 0 self.song_idx = 0 # Start on track 0
self.show_song()
#self.play_album() #self.play_album()
def show_song(self):
song = self.songs[self.song_idx]
print('refresh', song)
ns = song.find(SelectScreen.album)
ne = song[ns:].find('/') + 1
end = song[ns + ne:].find(".wav")
self.lblsong.value(song[ns + ne: ns + ne + end])
async def album_task(self): async def album_task(self):
# Must ensure that only one instance of album_task is running # Must ensure that only one instance of album_task is running
self.stop_play = True # Stop the running instance self.stop_play = True # Stop the running instance
@ -175,18 +201,12 @@ class BaseScreen(Screen):
# Leave paused status unchanged # Leave paused status unchanged
songs = self.songs[self.song_idx :] # Start from current index songs = self.songs[self.song_idx :] # Start from current index
for song in songs: for song in songs:
ns = song.find(SelectScreen.album) self.show_song()
ne = song[ns:].find('/') + 1
end = song[ns + ne:].find(".wav")
self.lblsong.value(song[ns + ne: ns + ne + end])
print(song[ns + ne: ns + ne + end])
await self.play_song(song) await self.play_song(song)
if self.stop_play: if self.stop_play:
break # A callback has stopped playback break # A callback has stopped playback
self.song_idx += 1 self.song_idx += 1
self.playing = False self.playing = False
self.lblsong.value("")
# Open and play a binary wav file # Open and play a binary wav file
async def play_song(self, song): async def play_song(self, song):
@ -208,6 +228,10 @@ class BaseScreen(Screen):
def test(): def test():
print('Audio demo.') print('Audio demo.')
Screen.change(BaseScreen) # A class is passed here, not an instance. try:
Screen.change(BaseScreen) # A class is passed here, not an instance.
finally:
audio_out.deinit()
print("========== CLOSE AUDIO ==========")
test() test()

Wyświetl plik

@ -81,11 +81,22 @@ class Listbox(Widget):
dlines = self.dlines dlines = self.dlines
nlines = min(dlines, len(self.elements)) # Displayable lines nlines = min(dlines, len(self.elements)) # Displayable lines
for n in range(ntop, ntop + nlines): for n in range(ntop, ntop + nlines):
text = self.elements[n]
if self.writer.stringlen(text) > self.width: # Clip
font = self.writer.font
pos = 0
nch = 0
for ch in text:
pos += font.get_ch(ch)[2] # width of current char
if pos > self.width:
break
nch += 1
text = text[: nch]
if n == self._value: if n == self._value:
display.fill_rect(x, y + 1, self.width, eh - 1, self.select_color) display.fill_rect(x, y + 1, self.width, eh - 1, self.select_color)
display.print_left(self.writer, x + 2, y + 1, self.elements[n], self.fontcolor, self.select_color) display.print_left(self.writer, x + 2, y + 1, text, self.fontcolor, self.select_color)
else: else:
display.print_left(self.writer, x + 2, y + 1, self.elements[n], self.fontcolor, self.bgcolor) display.print_left(self.writer, x + 2, y + 1, text, self.fontcolor, self.bgcolor)
y += eh y += eh
# Draw a vertical line to hint at scrolling # Draw a vertical line to hint at scrolling
x = self.col + self.width - 2 x = self.col + self.width - 2