Headers, timer colours, all looking good

This commit is contained in:
Keith Edmunds 2021-04-04 19:49:33 +01:00
parent ba9b9cc936
commit 233cce7800
5 changed files with 163 additions and 99 deletions

View File

@ -7,11 +7,13 @@ class Config(object):
COLOUR_CURRENT_HEADER = "#d4edda"
COLOUR_CURRENT_PLAYLIST = "#28a745"
COLOUR_ODD_PLAYLIST = "#f2f2f2"
COLOUR_ENDING_TIMER = "#dc3545"
COLOUR_EVEN_PLAYLIST = "#d9d9d9"
COLOUR_NEXT_HEADER = "#fff3cd"
COLOUR_NEXT_PLAYLIST = "#ffc107"
COLOUR_NOTES_PLAYLIST = "#802020"
COLOUR_NOTES_PLAYLIST = "#dc3545"
COLOUR_PREVIOUS_HEADER = "#f8d7da"
COLOUR_WARNING_TIMER = "#ffc107"
DBFS_FADE = -12
DBFS_SILENCE = -50
DISPLAY_SQL = False

View File

@ -22,7 +22,7 @@ class Music:
"""
Fade the currently playing track.
Return the current track path and position.
Return the current track position.
The actual management of fading runs in its own thread so as not
to hold up the UI during the fade.
@ -31,15 +31,14 @@ class Music:
DEBUG("fade()")
if not self.playing():
return (None, None)
return None
path = self.track_path
position = self.player.get_position()
thread = threading.Thread(target=self._fade)
thread.start()
return (path, position)
return position
def _fade(self):
"""

View File

@ -31,6 +31,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.timer = QTimer()
self.even_tick = True
self.music = music.Music()
self.playing = False
self.playlist.music = self.music
self.connect_signals_slots()
self.disable_play_next_controls()
@ -47,6 +48,7 @@ class Window(QMainWindow, Ui_MainWindow):
# Hard code to the only playlist we have for now
if self.playlist.load_playlist("Default"):
self.update_headers()
self.enable_play_next_controls()
self.timer.start(Config.TIMER_MS)
@ -91,7 +93,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.actionSearch_database.triggered.connect(self.search_database)
self.btnPrevious.clicked.connect(self.play_previous)
self.btnSearchDatabase.clicked.connect(self.search_database)
self.btnSetNextTrack.clicked.connect(self.playlist.set_next_track)
self.btnSetNextTrack.clicked.connect(self.set_next_track)
self.btnSkipNext.clicked.connect(self.play_next)
self.btnStop.clicked.connect(self.fade)
@ -109,18 +111,7 @@ class Window(QMainWindow, Ui_MainWindow):
def play_next(self):
self.playlist.play_next()
self.disable_play_next_controls()
self.previous_track.setText(
f"{self.playlist.get_previous_title()} - "
f"{self.playlist.get_previous_artist()}"
)
self.current_track.setText(
f"{self.playlist.get_current_title()} - "
f"{self.playlist.get_current_artist()}"
)
self.next_track.setText(
f"{self.playlist.get_next_title()} - "
f"{self.playlist.get_next_artist()}"
)
self.update_headers()
# Set time clocks
now = datetime.now()
@ -142,8 +133,10 @@ class Window(QMainWindow, Ui_MainWindow):
dlg.exec()
def set_next_track(self):
# TODO
pass
"Set selected track as next"
self.playlist.set_selected_as_next()
self.update_headers()
def tick(self):
"""
@ -166,28 +159,69 @@ class Window(QMainWindow, Ui_MainWindow):
return
if self.music.playing():
self.playing = True
playtime = self.music.get_playtime()
self.label_elapsed_timer.setText(helpers.ms_to_mmss(playtime))
self.label_fade_timer.setText(
helpers.ms_to_mmss(
self.playlist.get_current_fade_at() - playtime)
)
time_to_fade = (self.playlist.get_current_fade_at() - playtime)
time_to_silence = (
self.playlist.get_current_silence_at() - playtime
)
if time_to_silence < 500:
self.label_silent_timer.setText("00:00")
time_to_end = (self.playlist.get_current_duration() - playtime)
# Elapsed time
if time_to_end < 500:
self.label_elapsed_timer.setText(
helpers.ms_to_mmss(self.playlist.get_current_duration())
)
else:
self.label_elapsed_timer.setText(helpers.ms_to_mmss(playtime))
# Time to fade
self.label_fade_timer.setText(helpers.ms_to_mmss(time_to_fade))
# Time to silence
if time_to_silence < 5000:
self.frame_silent.setStyleSheet(
f"background: {Config.COLOUR_ENDING_TIMER}"
)
self.enable_play_next_controls()
elif time_to_fade < 500:
self.frame_silent.setStyleSheet(
f"background: {Config.COLOUR_WARNING_TIMER}"
)
self.enable_play_next_controls()
else:
self.frame_silent.setStyleSheet("")
self.label_silent_timer.setText(
helpers.ms_to_mmss(time_to_silence)
)
self.label_end_timer.setText(
helpers.ms_to_mmss(
self.playlist.get_current_duration() - playtime))
# Time to end
self.label_end_timer.setText(helpers.ms_to_mmss(time_to_end))
else:
# When music ends, update playlist display
self.playlist.update_playlist_colours()
if self.playing:
self.label_end_timer.setText("00:00")
self.frame_silent.setStyleSheet("")
self.playing = False
self.playlist.music_ended()
self.update_headers()
def update_headers(self):
"Update last / current / next track headers"
self.previous_track.setText(
f"{self.playlist.get_previous_title()} - "
f"{self.playlist.get_previous_artist()}"
)
self.current_track.setText(
f"{self.playlist.get_current_title()} - "
f"{self.playlist.get_current_artist()}"
)
self.next_track.setText(
f"{self.playlist.get_next_title()} - "
f"{self.playlist.get_next_artist()}"
)
class DbDialog(QDialog):

View File

@ -42,7 +42,7 @@ class Playlist(QTableWidget):
self.current_track = None
self.next_track = None
self.previous_track_path = None
self.previous_track = None
self.previous_track_position = None
self.played_tracks = []
@ -66,10 +66,11 @@ class Playlist(QTableWidget):
"Save column widths"
for column in range(self.columnCount()):
width = self.columnWidth(column)
name = f"playlist_col_{str(column)}_width"
record = Settings.get_int(name)
if record.f_int != self.columnWidth(column):
record.update({'f_int': self.columnWidth(column)})
record.update({'f_int': width})
def add_to_playlist(self, track):
"""
@ -133,7 +134,7 @@ class Playlist(QTableWidget):
DEBUG(f"Moved row(s) {rows} to become row {drop_row}")
self.clearSelection()
self.update_playlist_colours()
self.repaint()
def fade(self):
self.music.fade()
@ -225,17 +226,18 @@ class Playlist(QTableWidget):
Return True if successful else False.
"""
DEBUG(f"load_playlist({name})")
for track in Playlists.get_playlist_by_name(name).get_tracks():
self.add_to_playlist(track)
# Set the first playable track as next to play
for row in range(self.rowCount()):
if self.set_row_as_next_track(row):
if self.item(row, self.COL_INDEX):
self.meta_set_next(row)
self.tracks_changed()
return True
self.update_playlist_colours()
return False
def meta_clear(self, row):
@ -295,11 +297,21 @@ class Playlist(QTableWidget):
def meta_set_current(self, row):
"Mark row as current track"
DEBUG(f"meta_set_current({row})")
old_current = self.meta_get_current()
if old_current is not None:
self.meta_clear(old_current)
self.meta_set(row, "current")
def meta_set_next(self, row):
"Mark row as next track"
DEBUG(f"meta_set_next({row})")
old_next = self.meta_get_next()
if old_next is not None:
self.meta_clear(old_next)
self.meta_set(row, "next")
def meta_set_note(self, row):
@ -322,10 +334,9 @@ class Playlist(QTableWidget):
Play (new) current.
Update playlist "current track" metadata
Cue up next track in playlist if there is one.
Update playlist "next track" metadata
Tell database to record it as played
Remember it was played for this session
Update playlist appearance.
Update metadata and headers, and repaint
"""
# If there is no next track set, return.
@ -334,43 +345,30 @@ class Playlist(QTableWidget):
# If there's currently a track playing, fade it.
if self.music.playing():
path, position = self.music.fade()
self.previous_track_path = path
self.previous_track_position = position
self.previous_track_position = self.music.fade()
self.previous_track = self.current_track
# Move next track to current track.
# Shuffle tracks along
self.current_track = self.next_track
self.next_track = None
# Play (new) current.
self.music.play(self.current_track.path)
# Update playlist "current track" metadata
old_current = self.meta_get_current()
if old_current is not None:
self.meta_clear(old_current)
current = self.meta_get_next()
if current is not None:
self.meta_set_current(current)
# Update metadata
self.meta_set_current(self.meta_get_next())
# Cue up next track in playlist if there is one.
track_id = 0
next_row = 0
if current is not None:
start = current + 1
# Set up metadata for next track in playlist if there is one.
current_row = self.meta_get_current()
if current_row is not None:
start = current_row + 1
else:
start = 0
for row in range(start, self.rowCount()):
if self.item(row, self.COL_INDEX):
if int(self.item(row, self.COL_INDEX).text()) > 0:
track_id = int(self.item(row, self.COL_INDEX).text())
next_row = row
self.meta_set_next(row)
break
if track_id:
self.next_track = Tracks.get_track(track_id)
# Update playlist "next track" metadata
if next_row:
self.meta_set_next(next_row)
# Tell database to record it as played
self.current_track.update_lastplayed()
@ -379,33 +377,15 @@ class Playlist(QTableWidget):
# Remember it was played for this session
self.played_tracks.append(self.current_track.id)
# Update playlist appearance.
self.update_playlist_colours()
# Update display
self.tracks_changed()
def set_next_track(self):
def set_selected_as_next(self):
"""
Sets the selected track as the next track.
"""
# TODO
pass
# if self.selectionModel().hasSelection():
# self.set_next_track_row(self.playlist.currentRow())
# if self.selectionModel().hasSelection():
# row = self.currentRow()
# track_id = int(self.item(row, 0).text())
# DEBUG(f"play_selected: track_id={track_id}")
# # TODO: get_path may raise exception
# music.play_track(track_id)
# track = Tracks.get_track(id)
# if not track:
# ERROR(f"set_next_track({id}): can't find track")
# return None
# # self.next_track['player'] = vlc.MediaPlayer(track.path)
# self.next_track = track
# return track.id
self.set_row_as_next_track(self.currentRow())
def set_row_as_next_track(self, row):
"""
@ -415,16 +395,21 @@ class Playlist(QTableWidget):
"""
if self.item(row, self.COL_INDEX):
track_id = int(self.item(row, self.COL_INDEX).text())
DEBUG(f"set_row_as_next_track: track_id={track_id}")
self.next_track = Tracks.get_track(track_id)
# Mark row as next track
self.meta_set_next(row)
self.meta_set_current(row)
self.tracks_changed()
return True
return False
def update_playlist_colours(self):
def music_ended(self):
"Update display"
self.previous_track = self.current_track
self.previous_track_position = 0
self.meta_clear(self.meta_get_current())
self.tracks_changed()
def repaint(self):
"Set row colours, fonts, etc"
self.clearSelection()
@ -481,6 +466,50 @@ class Playlist(QTableWidget):
if self.item(row, j):
self.item(row, j).setFont(normal)
def tracks_changed(self):
"""
One or more of current or next track has changed.
The row metadata is definitive because the same track may appear
more than once in the playlist, but only one track may be marked
as current or next.
Update self.current_track and self.next_track.
"""
# Update instance variables
current_row = self.meta_get_current()
if current_row is not None:
track_id = int(self.item(current_row, self.COL_INDEX).text())
if not self.current_track or self.current_track.id != track_id:
self.current_track = Tracks.get_track(track_id)
else:
self.current_track = None
next_row = self.meta_get_next()
if next_row is not None:
track_id = int(self.item(next_row, self.COL_INDEX).text())
if not self.next_track or self.next_track.id != track_id:
self.next_track = Tracks.get_track(track_id)
else:
self.next_track = None
try:
DEBUG(f"tracks_changed() previous={self.previous_track.id}")
except AttributeError:
DEBUG("tracks_changed() previous=None")
try:
DEBUG(f"tracks_changed() current={self.current_track.id}")
except AttributeError:
DEBUG("tracks_changed() current=None")
try:
DEBUG(f"tracks_changed() next={self.next_track.id}")
except AttributeError:
DEBUG("tracks_changed() next=None")
# Update display
self.repaint()
class Window(QWidget):
def __init__(self):

View File

@ -491,7 +491,7 @@ border: 1px solid rgb(85, 87, 83);</string>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed_2">
<widget class="QFrame" name="frame_fade">
<property name="styleSheet">
<string notr="true"/>
</property>
@ -547,7 +547,7 @@ border: 1px solid rgb(85, 87, 83);</string>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed_3">
<widget class="QFrame" name="frame_silent">
<property name="styleSheet">
<string notr="true"/>
</property>
@ -603,7 +603,7 @@ border: 1px solid rgb(85, 87, 83);</string>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed_4">
<widget class="QFrame" name="frame_end">
<property name="styleSheet">
<string notr="true"/>
</property>