display.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!./bin/python3
  2. import yaml
  3. import pygame # type: ignore
  4. from typing import Dict
  5. # Color constants
  6. BLACK = (0, 0, 0)
  7. GREEN = (0, 255, 0)
  8. class Display:
  9. '''
  10. Display object
  11. '''
  12. def __init__(self, config, pydsp):
  13. # Set config values
  14. self._dx = config.get("dimx", 128) # Drawing dimensions
  15. self._dy = config.get("dimy", 160)
  16. self._playlistFile = config.get("playlist", "music.yml") # Playlist data
  17. self._pydsp = pydsp # Pygame display object
  18. self._fontsize = config.get("fontsize", 12) # Fontsize to use
  19. self._drawlines = int(self._dy / 12) - 5 # Max number of drawn lines
  20. # Set initialisation values
  21. self._selection_pointer = 0 # Current selected value
  22. self._line_offset = 0 # Drawing offset in playlist
  23. self._current_item = None
  24. def getPlaylist(self) -> Dict:
  25. '''
  26. Return the playlist for this display.
  27. '''
  28. return yaml.safe_load(open(self._playlistFile)).get("playlist", [])
  29. def update(self):
  30. '''
  31. Load the data from the given playlist file and draw it according to the current state.
  32. '''
  33. self._pydsp.fill((0,0,0))
  34. playlist = self.getPlaylist()
  35. # Correct offset and selection pointer
  36. if self._selection_pointer < 0:
  37. self._selection_pointer = 0 # Make sure the selection is at least at pos 0
  38. if self._line_offset > 0: # Move the line offset down if possible
  39. self._line_offset-=1
  40. elif self._selection_pointer > self._drawlines: # Make sure sure selection does not exceed list
  41. self._selection_pointer = self._drawlines # Move the line offset up if possible
  42. if self._line_offset < len(playlist) - self._drawlines - 1:
  43. self._line_offset+=1
  44. # Draw lines
  45. font = pygame.font.Font('freesansbold.ttf', self._fontsize)
  46. drawline = 0 # Line currently drawm
  47. for i, item in enumerate(playlist):
  48. # Skip lines until we reached the offset
  49. if i < self._line_offset:
  50. continue
  51. # Draw the line
  52. if drawline == self._selection_pointer:
  53. text = font.render(item["name"], True, BLACK, GREEN)
  54. img = item.get("img")
  55. if img is not None:
  56. pass
  57. else:
  58. pygame.draw.rect(self._pydsp, GREEN, (0,0,self._dx,50))
  59. self._current_item = item
  60. else:
  61. text = font.render(item["name"], True, GREEN, BLACK)
  62. self._pydsp.blit(text, (0, drawline * self._fontsize+50))
  63. # Increase number of drawn lines - stop when the maximum is reached
  64. drawline += 1
  65. if drawline > self._drawlines:
  66. break
  67. def currentItem(self) -> Dict:
  68. '''
  69. Return the current selected item.
  70. '''
  71. return self._current_item
  72. def action(self, action: str):
  73. '''
  74. Perform an action to this display.
  75. '''
  76. if action == "up":
  77. self._selection_pointer-=1
  78. elif action == "down":
  79. self._selection_pointer+=1
  80. self.update()