|
@@ -1,39 +1,44 @@
|
|
#!./bin/python3
|
|
#!./bin/python3
|
|
|
|
|
|
|
|
+import os
|
|
|
|
+
|
|
import yaml
|
|
import yaml
|
|
import pygame # type: ignore
|
|
import pygame # type: ignore
|
|
from typing import Dict
|
|
from typing import Dict
|
|
|
|
+import random
|
|
|
|
|
|
# Color constants
|
|
# Color constants
|
|
|
|
|
|
-BLACK = (0, 0, 0)
|
|
|
|
-GREEN = (0, 255, 0)
|
|
|
|
|
|
+BLACK = (0, 0, 0)
|
|
|
|
+GREEN = (0, 255, 0)
|
|
|
|
+WHITE = (255, 255, 255)
|
|
|
|
|
|
class Display:
|
|
class Display:
|
|
'''
|
|
'''
|
|
Display object
|
|
Display object
|
|
'''
|
|
'''
|
|
def __init__(self, config, pydsp):
|
|
def __init__(self, config, pydsp):
|
|
-
|
|
|
|
|
|
+
|
|
# Set config values
|
|
# Set config values
|
|
-
|
|
|
|
|
|
+
|
|
self._dx = config.get("dimx", 128) # Drawing dimensions
|
|
self._dx = config.get("dimx", 128) # Drawing dimensions
|
|
self._dy = config.get("dimy", 160)
|
|
self._dy = config.get("dimy", 160)
|
|
self._playlistFile = config.get("playlist", "music.yml") # Playlist data
|
|
self._playlistFile = config.get("playlist", "music.yml") # Playlist data
|
|
self._pydsp = pydsp # Pygame display object
|
|
self._pydsp = pydsp # Pygame display object
|
|
self._fontsize = config.get("fontsize", 12) # Fontsize to use
|
|
self._fontsize = config.get("fontsize", 12) # Fontsize to use
|
|
- self._drawlines = int(self._dy / 12) - 1 # Max number of drawn lines
|
|
|
|
|
|
+ self._drawlines = int(self._dy / 12) - 5 # Max number of drawn lines
|
|
|
|
|
|
# Set initialisation values
|
|
# Set initialisation values
|
|
|
|
|
|
self._selection_pointer = 0 # Current selected value
|
|
self._selection_pointer = 0 # Current selected value
|
|
self._line_offset = 0 # Drawing offset in playlist
|
|
self._line_offset = 0 # Drawing offset in playlist
|
|
self._current_item = None
|
|
self._current_item = None
|
|
|
|
+ self._bgImg = None
|
|
|
|
|
|
|
|
|
|
- def loadPlaylist(self) -> Dict:
|
|
|
|
|
|
+ def getPlaylist(self) -> Dict:
|
|
'''
|
|
'''
|
|
- Load the playlist.
|
|
|
|
|
|
+ Return the playlist for this display.
|
|
'''
|
|
'''
|
|
return yaml.safe_load(open(self._playlistFile)).get("playlist", [])
|
|
return yaml.safe_load(open(self._playlistFile)).get("playlist", [])
|
|
|
|
|
|
@@ -43,7 +48,7 @@ class Display:
|
|
Load the data from the given playlist file and draw it according to the current state.
|
|
Load the data from the given playlist file and draw it according to the current state.
|
|
'''
|
|
'''
|
|
self._pydsp.fill((0,0,0))
|
|
self._pydsp.fill((0,0,0))
|
|
- playlist = self.loadPlaylist()
|
|
|
|
|
|
+ playlist = self.getPlaylist()
|
|
|
|
|
|
# Correct offset and selection pointer
|
|
# Correct offset and selection pointer
|
|
|
|
|
|
@@ -55,7 +60,7 @@ class Display:
|
|
self._selection_pointer = self._drawlines # Move the line offset up if possible
|
|
self._selection_pointer = self._drawlines # Move the line offset up if possible
|
|
if self._line_offset < len(playlist) - self._drawlines - 1:
|
|
if self._line_offset < len(playlist) - self._drawlines - 1:
|
|
self._line_offset+=1
|
|
self._line_offset+=1
|
|
-
|
|
|
|
|
|
+
|
|
# Draw lines
|
|
# Draw lines
|
|
|
|
|
|
font = pygame.font.Font('freesansbold.ttf', self._fontsize)
|
|
font = pygame.font.Font('freesansbold.ttf', self._fontsize)
|
|
@@ -72,18 +77,57 @@ class Display:
|
|
|
|
|
|
if drawline == self._selection_pointer:
|
|
if drawline == self._selection_pointer:
|
|
text = font.render(item["name"], True, BLACK, GREEN)
|
|
text = font.render(item["name"], True, BLACK, GREEN)
|
|
|
|
+
|
|
|
|
+ pygame.draw.rect(self._pydsp, BLACK, (0,0,self._dx,50))
|
|
|
|
+ try:
|
|
|
|
+ self.drawArt(item)
|
|
|
|
+ except Exception as e:
|
|
|
|
+ print("Error while drawing art:", e)
|
|
|
|
+
|
|
self._current_item = item
|
|
self._current_item = item
|
|
else:
|
|
else:
|
|
text = font.render(item["name"], True, GREEN, BLACK)
|
|
text = font.render(item["name"], True, GREEN, BLACK)
|
|
-
|
|
|
|
- self._pydsp.blit(text, (0, drawline * self._fontsize))
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ self._pydsp.blit(text, (0, drawline * self._fontsize+50))
|
|
|
|
+
|
|
# Increase number of drawn lines - stop when the maximum is reached
|
|
# Increase number of drawn lines - stop when the maximum is reached
|
|
|
|
|
|
drawline += 1
|
|
drawline += 1
|
|
if drawline > self._drawlines:
|
|
if drawline > self._drawlines:
|
|
break
|
|
break
|
|
|
|
|
|
|
|
+ def drawArt(self, item):
|
|
|
|
+ '''
|
|
|
|
+ Beautify the display.
|
|
|
|
+ '''
|
|
|
|
+ font = pygame.font.Font('freesansbold.ttf', self._fontsize)
|
|
|
|
+
|
|
|
|
+ # Draw a background image
|
|
|
|
+
|
|
|
|
+ if self._bgImg is None:
|
|
|
|
+ bg = os.listdir("web/background")
|
|
|
|
+ bg = bg[random.randint(0, len(bg)-1)]
|
|
|
|
+ self._bgImg = pygame.image.load(os.path.join("web/background", bg))
|
|
|
|
+ pygame.transform.scale(self._bgImg, (self._dx, 50))
|
|
|
|
+
|
|
|
|
+ self._pydsp.blit(self._bgImg, (0,0), (0, 0, self._dx, 50))
|
|
|
|
+
|
|
|
|
+ path = item.get("path")
|
|
|
|
+ title = item.get("name", "")
|
|
|
|
+ artist = item.get("artist", "")
|
|
|
|
+
|
|
|
|
+ # Try to extract meta data
|
|
|
|
+
|
|
|
|
+ if path is not None:
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
+ s = title
|
|
|
|
+ if artist != "":
|
|
|
|
+ s = "%s (%s)" % (s, artist)
|
|
|
|
+
|
|
|
|
+ text = font.render(s, True, WHITE, BLACK)
|
|
|
|
+ self._pydsp.blit(text, (0, 38))
|
|
|
|
+
|
|
|
|
|
|
def currentItem(self) -> Dict:
|
|
def currentItem(self) -> Dict:
|
|
'''
|
|
'''
|
|
@@ -100,5 +144,5 @@ class Display:
|
|
self._selection_pointer-=1
|
|
self._selection_pointer-=1
|
|
elif action == "down":
|
|
elif action == "down":
|
|
self._selection_pointer+=1
|
|
self._selection_pointer+=1
|
|
-
|
|
|
|
|
|
+
|
|
self.update()
|
|
self.update()
|