audio: Rework the Artwork widget

It now sets artwork based on the signals sent by the player, allowing us
to move it out of the Player class and create instances based on the
global Player instead.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-09-07 10:54:49 -04:00
parent f55377cc69
commit 3a50235c38
9 changed files with 42 additions and 46 deletions

View File

@ -15,6 +15,9 @@ tagdb.Stack.Counter = Player.Autopause
def AudioControls():
return controls.AudioControls(Player, Player.Autopause)
def Artwork():
return artwork.Artwork(Player)
def NowPlaying():
return nowplaying.NowPlaying(Player)

View File

@ -2,10 +2,9 @@
from gi.repository import Gtk, GdkPixbuf, Gst
class Artwork(Gtk.AspectFrame):
def __init__(self):
def __init__(self, player):
Gtk.AspectFrame.__init__(self)
self.picture = Gtk.Picture()
self.frame = Gtk.Frame()
self.frame.set_child(self.picture)
@ -16,31 +15,32 @@ class Artwork(Gtk.AspectFrame):
self.set_margin_top(5)
self.set_margin_bottom(5)
self.set_ratio(1.0)
self.reset()
def get_default_path(self):
display = self.picture.get_display()
theme = Gtk.IconTheme.get_for_display(display)
icon = theme.lookup_icon("emmental", [ ], 1024, 1, 0, 0)
return icon.get_file().get_path()
self.player = player
self.player.connect("artwork", self.on_artwork)
self.player.connect("track-changed", self.on_track_changed)
self.on_track_changed(player, None, player.track)
def set_from_data(self, data):
loader = GdkPixbuf.PixbufLoader()
loader.write(data)
def __set_from_cover_jpg__(self, track):
cover = track.filepath().parent / "cover.jpg"
if cover.exists():
self.picture.set_filename(str(cover))
return True
return False
pixbuf = loader.get_pixbuf()
self.picture.set_pixbuf(pixbuf)
loader.close()
def set_from_sample(self, sample):
def on_artwork(self, player, sample):
buffer = sample.get_buffer()
(res, map) = buffer.map(Gst.MapFlags.READ)
if res == True:
self.set_from_data(map.data)
buffer.unmap(map)
else:
self.reset()
if res:
loader = GdkPixbuf.PixbufLoader()
loader.write(map.data)
self.picture.set_pixbuf(loader.get_pixbuf())
loader.close()
buffer.unmap(map)
def reset(self):
self.picture.set_filename(self.get_default_path())
def on_track_changed(self, player, prev, new):
if not (new and self.__set_from_cover_jpg__(new)):
display = self.picture.get_display()
theme = Gtk.IconTheme.get_for_display(display)
icon = theme.lookup_icon("emmental", [ ], 1024, 1, 0, 0)
self.picture.set_file(icon.get_file())

View File

@ -17,9 +17,6 @@ class Player(bass.BassPlayer):
self.track = None
self.bus.connect("message::eos", self.next)
self.bus.connect("message::tag", self.on_tag)
self.Artwork = artwork.Artwork()
self.load_track(tagdb.Tracks[settings.get_int("audio.trackid")])
if self.track:
@ -34,14 +31,6 @@ class Player(bass.BassPlayer):
self.load_track(track)
self.playing = cont
def on_tag(self, bus, message):
taglist = message.parse_tag()
(res, sample) = taglist.get_sample("image")
if res == True:
self.Artwork.set_from_sample(sample)
else:
self.Artwork.reset()
def play(self): self.playing = True
def pause(self): self.playing = False
def playpause(self, *args): self.playing = not self.playing

View File

@ -1,19 +1,23 @@
# Copyright 2021 (c) Anna Schumaker.
from . import artwork
from gi.repository import Gtk
import pathlib
import unittest
from gi.repository import Gtk
from . import artwork
Path = pathlib.Path("./data/hicolor/scalable/apps/emmental.svg")
class FakePlayer:
def __init__(self):
self.track = None
def connect(self, name, cb): pass
class TestAudioArtwork(unittest.TestCase):
def test_audio_artwork_init(self):
art = artwork.Artwork()
fake = FakePlayer()
art = artwork.Artwork(fake)
self.assertIsInstance(art, Gtk.AspectFrame)
self.assertIsInstance(art.frame, Gtk.Frame)
self.assertIsInstance(art.picture, Gtk.Picture)
self.assertEqual(art.player, fake)
self.assertEqual(art.get_child(), art.frame)
self.assertEqual(art.frame.get_child(), art.picture)
self.assertEqual(art.get_obey_child(), False)
@ -23,5 +27,3 @@ class TestAudioArtwork(unittest.TestCase):
self.assertEqual(art.get_margin_end(), 5)
self.assertEqual(art.get_margin_top(), 5)
self.assertEqual(art.get_margin_bottom(), 5)
self.assertIsNotNone(art.get_default_path())

View File

@ -23,6 +23,10 @@ class TestAudio(unittest.TestCase):
def test_audio_widgets(self):
seeker = audio.SeekControl()
self.assertIsInstance(audio.AudioControls(),
audio.controls.AudioControls)
self.assertIsInstance(audio.Artwork(),
audio.artwork.Artwork)
self.assertIsInstance(audio.NowPlaying(),
audio.nowplaying.NowPlaying)
self.assertIsInstance(seeker, audio.scale.ScaleButtonBox)

View File

@ -43,7 +43,6 @@ class TestPlayer(unittest.TestCase):
play = player.Player()
self.assertIsInstance(play, bass.BassPlayer)
self.assertIsInstance(play.bus, Gst.Bus)
self.assertIsInstance(play.Artwork, artwork.Artwork)
self.assertIsInstance(play.Autopause, scale.AutoPauseScale)
self.assertIsNone(play.track)

View File

@ -59,7 +59,7 @@ add_stack_page("Decades", tagbox.ParentTagBox(tagdb.tags.Decade, "x-office-cal
add_stack_page("Libraries", library.Box)
Box.append(audio.Player.Artwork)
Box.append(audio.Artwork())
Box.append(Gtk.Separator.new(Gtk.Orientation.HORIZONTAL))
Box.append(Stack)
Box.append(Gtk.Separator.new(Gtk.Orientation.HORIZONTAL))

View File

@ -14,7 +14,7 @@ class TestSidebar(unittest.TestCase):
self.assertIsInstance(sidebar.Stack, Gtk.Stack)
self.assertIsInstance(sidebar.Box, Gtk.Box)
self.assertIn(audio.Player.Artwork, sidebar.Box)
#self.assertIn(audio.Player.Artwork, sidebar.Box)
self.assertIn(sidebar.Stack, sidebar.Box)
self.assertIn(sidebar.pulser.Box, sidebar.Box)

View File

@ -14,6 +14,5 @@ class EmmentalApplication(Gtk.Application):
def do_startup(self):
Gtk.Application.do_startup(self)
self.add_window(window.Window)
audio.Player.Artwork.reset()
Application = EmmentalApplication()