This commit is contained in:
Andrew Dunai 2018-01-22 16:03:29 +02:00
parent 55c6bb1227
commit 3a20268e01
2 changed files with 113 additions and 62 deletions

View file

@ -34,6 +34,13 @@ PALETTE = [
('progress', '', '', '', '#FFF', '#F54'), ('progress', '', '', '', '#FFF', '#F54'),
('progress_remaining', '', '', '', '#FFF', '#444'), ('progress_remaining', '', '', '', '#FFF', '#444'),
('progressbar_done', '', '', '', '#F54', ''),
('progressbar_done_paused', '', '', '', '#AAA', ''),
('progressbar_remaining', '', '', '', '#444', ''),
('title-idle', '', '', '', '', ''),
('title-playing', '', '', '', '#F54', ''),
('panel', '', '', '', '#FFF', '#222'), ('panel', '', '', '', '#FFF', '#222'),
('panel_focus', '', '', '', '#FFF', '#F54'), ('panel_focus', '', '', '', '#FFF', '#F54'),
('panel_divider', '', '', '', '#444', '#222'), ('panel_divider', '', '', '', '#444', '#222'),
@ -122,6 +129,8 @@ class AppWidget(urwid.Frame):
] ]
self.current_page = None self.current_page = None
self.loop = None
NotificationArea.set_app(self) NotificationArea.set_app(self)
self._login_notification = None self._login_notification = None
@ -137,12 +146,7 @@ class AppWidget(urwid.Frame):
NotificationArea.get() NotificationArea.get()
# urwid.Divider('\u2500') # urwid.Divider('\u2500')
]) ])
self.playbar = PlayBar( self.playbar = PlayBar(self)
'progress_remaining',
'progress',
current=0,
done=100
)
self.shuffle_el = urwid.AttrWrap(urwid.Text(u' \u22cd SHUF '), 'flag') self.shuffle_el = urwid.AttrWrap(urwid.Text(u' \u22cd SHUF '), 'flag')
self.repeat_el = urwid.AttrWrap(urwid.Text(u' \u27f2 REP '), 'flag') self.repeat_el = urwid.AttrWrap(urwid.Text(u' \u27f2 REP '), 'flag')
self.panel = urwid.Pile([ self.panel = urwid.Pile([
@ -162,12 +166,7 @@ class AppWidget(urwid.Frame):
) )
# self.current_page.activate() # self.current_page.activate()
self.loop = None
player = Player.get() player = Player.get()
player.media_position_changed += self.media_position_changed
player.media_state_changed += self.media_state_changed
player.track_changed += self.track_changed
player.playback_flags_changed += self.playback_flags_changed player.playback_flags_changed += self.playback_flags_changed
self.set_page('MyLibraryPage') self.set_page('MyLibraryPage')
@ -251,33 +250,6 @@ class AppWidget(urwid.Frame):
""" """
self.loop = loop self.loop = loop
def media_position_changed(self, progress):
"""
Update slider in playbar.
Called when current play position changes.
"""
if progress < 0:
progress = 0
self.playbar.set_completion(progress * 100)
self.playbar.tick()
self.loop.draw_screen()
def media_state_changed(self, *_):
"""
Update playbar.
Called when playback is paused/unpaused.
"""
self.playbar.update()
self.loop.draw_screen()
def track_changed(self, track):
"""
Update displayed track in playbar.
Called when current track changes.
"""
self.playbar.set_track(track)
self.loop.draw_screen()
def playback_flags_changed(self): def playback_flags_changed(self):
""" """
Update playbar flags. Update playbar flags.
@ -290,7 +262,6 @@ class AppWidget(urwid.Frame):
self.repeat_el.attr = 'flag-active' \ self.repeat_el.attr = 'flag-active' \
if player.get_is_repeat_one() \ if player.get_is_repeat_one() \
else 'flag' else 'flag'
self.playbar.update()
self.loop.draw_screen() self.loop.draw_screen()
def set_page(self, classname): def set_page(self, classname):

View file

@ -6,18 +6,86 @@ import urwid
from clay.player import Player from clay.player import Player
class PlayBar(urwid.ProgressBar): class ProgressBar(urwid.Widget):
"""
Thin progress bar.
"""
_sizing = frozenset([urwid.FLOW])
CHARS = u'\u2580'
def __init__(self):
self.value = 0
self.done_style = 'progressbar_done'
super(ProgressBar, self).__init__()
def render(self, size, focus=False):
"""
Render canvas.
"""
(width,) = size
text = urwid.Text('foo', urwid.LEFT, urwid.CLIP)
frac = width * self.value
whole = int(frac)
text.set_text([
(
self.done_style,
whole * ProgressBar.CHARS[-1]
# + ProgressBar.CHARS[partial]
),
(
'progressbar_remaining',
(width - whole) * ProgressBar.CHARS[-1]
)
])
return text.render(size, focus)
@staticmethod
def rows(*_):
"""
Return number of rows required for rendering.
"""
return 1
def set_progress(self, value):
"""
Set progress value in range [0..1].
"""
self.value = value
self._invalidate()
def set_done_style(self, done_style):
"""
Set style for "done" part.
"""
self.done_style = done_style
class PlayBar(urwid.Pile):
""" """
A widget that shows currently played track, playback progress and flags. A widget that shows currently played track, playback progress and flags.
""" """
ROTATING = u'|' u'/' u'\u2014' u'\\' ROTATING = u'|' u'/' u'\u2014' u'\\'
def __init__(self, *args, **kwargs): def __init__(self, app):
super(PlayBar, self).__init__(*args, **kwargs) # super(PlayBar, self).__init__(*args, **kwargs)
self.track = None self.app = app
self.player = Player.get()
self.rotating_index = 0 self.rotating_index = 0
self.text = urwid.Text('', align=urwid.CENTER)
self.progressbar = ProgressBar()
super(PlayBar, self).__init__([
('pack', self.text),
('pack', self.progressbar),
])
self.update()
player = Player.get()
player.media_position_changed += self.update
player.media_state_changed += self.update
player.track_changed += self.update
def get_rotating_bar(self): def get_rotating_bar(self):
""" """
@ -25,42 +93,54 @@ class PlayBar(urwid.ProgressBar):
""" """
return PlayBar.ROTATING[self.rotating_index % len(PlayBar.ROTATING)] return PlayBar.ROTATING[self.rotating_index % len(PlayBar.ROTATING)]
@staticmethod
def get_style():
"""
Return the style for current playback state.
"""
player = Player.get()
if player.is_loading or player.is_playing:
return 'title-playing'
return 'title-idle'
def get_text(self): def get_text(self):
""" """
Return text for display in this bar. Return text for display in this bar.
""" """
if self.track is None: player = Player.get()
track = player.get_current_track()
if track is None:
return u'Idle' return u'Idle'
progress = self.player.get_play_progress_seconds() progress = player.get_play_progress_seconds()
total = self.player.get_length_seconds() total = player.get_length_seconds()
return u' {} {} - {} [{:02d}:{:02d} / {:02d}:{:02d}]'.format( return (self.get_style(), u' {} {} - {} [{:02d}:{:02d} / {:02d}:{:02d}]'.format(
# u'|>' if player.is_playing else u'||', # u'|>' if player.is_playing else u'||',
# self.get_rotating_bar(), # self.get_rotating_bar(),
u'\u2505' if self.player.is_loading u'\u2505' if player.is_loading
else u'\u25B6' if self.player.is_playing else u'\u25B6' if player.is_playing
else u'\u25A0', else u'\u25A0',
self.track.artist, track.artist,
self.track.title, track.title,
progress // 60, progress // 60,
progress % 60, progress % 60,
total // 60, total // 60,
total % 60, total % 60,
) ))
def set_track(self, track): def update(self, *_):
"""
Set displayed track.
"""
self.track = track
# TODO: Call ``self.update()``?
def update(self):
""" """
Force update of this widget. Force update of this widget.
Called when something unrelated to completion value changes, Called when something unrelated to completion value changes,
e.g. current track or playback flags. e.g. current track or playback flags.
""" """
self._invalidate() self.text.set_text(self.get_text())
self.progressbar.set_progress(Player.get().get_play_progress())
self.progressbar.set_done_style(
'progressbar_done'
if Player.get().is_playing
else 'progressbar_done_paused'
)
self.app.redraw()
def tick(self): def tick(self):
""" """