diff --git a/emmental/nowplaying/tags.py b/emmental/nowplaying/tags.py new file mode 100644 index 0000000..d58cdba --- /dev/null +++ b/emmental/nowplaying/tags.py @@ -0,0 +1,53 @@ +# Copyright 2022 (c) Anna Schumaker. +"""Widgets for information about the current track.""" +from gi.repository import GObject +from gi.repository import GLib +from gi.repository import Gtk +from . import label + + +class TagInfo(Gtk.ScrolledWindow): + """A widget for displaying information about the current track.""" + + title = GObject.Property(type=str) + album = GObject.Property(type=str) + artist = GObject.Property(type=str) + album_artist = GObject.Property(type=str) + prefer_artist = GObject.Property(type=bool, default=True) + + def __init__(self): + """Initialize the TagInfo widget.""" + super().__init__(hexpand=True, vexpand=True) + self._box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) + self._title = label.Label() + self._album = label.Label(prefix="from ") + self._artist = label.ArtistLabel(prefix="by ") + self._saved_height = 0 + self._idle_id = None + + self.bind_property("title", self._title, "text") + self.bind_property("album", self._album, "text") + self.bind_property("artist", self._artist, "artist") + self.bind_property("album-artist", self._artist, "album-artist") + self.bind_property("prefer-artist", self._artist, "prefer-artist", + GObject.BindingFlags.BIDIRECTIONAL) + + self._box.append(self._title) + self._box.append(self._album) + self._box.append(self._artist) + self.set_child(self._box) + + def __set_label_size(self): + self._title.size = self._saved_height / 2.5 + for tag in [self._album, self._artist]: + tag.size = self._saved_height / 5 + self._idle_id = None + return GLib.SOURCE_REMOVE + + def do_size_allocate(self, width, height, baseline) -> None: + """Monitor for size changes.""" + Gtk.ScrolledWindow.do_size_allocate(self, width, height, baseline) + if height != self._saved_height: + self._saved_height = height + if not self._idle_id: + self._idle_id = GLib.idle_add(self.__set_label_size) diff --git a/tests/nowplaying/test_tags.py b/tests/nowplaying/test_tags.py new file mode 100644 index 0000000..dd43aec --- /dev/null +++ b/tests/nowplaying/test_tags.py @@ -0,0 +1,82 @@ +# Copyright 2022 (c) Anna Schumaker. +"""Tests our TagInfo widget.""" +import unittest +import emmental.nowplaying.label +import emmental.nowplaying.tags +from gi.repository import Gtk + + +class TestTagInfo(unittest.TestCase): + """Tests the tags.Info widget.""" + + def setUp(self): + """Set up common variables.""" + self.info = emmental.nowplaying.tags.TagInfo() + + def test_init(self): + """Test that the TagInfo widget is set up correctly.""" + self.assertIsInstance(self.info, Gtk.ScrolledWindow) + self.assertIsInstance(self.info.get_child(), Gtk.Viewport) + self.assertIsInstance(self.info._box, Gtk.Box) + + self.assertTrue(self.info.get_hexpand()) + self.assertTrue(self.info.get_vexpand()) + self.assertEqual(self.info._saved_height, 0) + self.assertIsNone(self.info._idle_id) + + self.assertEqual(self.info.get_child().get_child(), self.info._box) + self.assertEqual(self.info._box.get_orientation(), + Gtk.Orientation.VERTICAL) + self.assertEqual(self.info._box.get_spacing(), 0) + + def test_title(self): + """Test the title label.""" + self.assertIsInstance(self.info._title, + emmental.nowplaying.label.Label) + self.assertEqual(self.info._box.get_first_child(), self.info._title) + + self.assertEqual(self.info.title, "") + self.assertEqual(self.info._title.prefix, "") + self.info.title = "Test Title" + self.assertEqual(self.info.title, "Test Title") + self.assertEqual(self.info._title.get_text(), "Test Title") + + def test_album(self): + """Test the album label.""" + self.assertIsInstance(self.info._album, + emmental.nowplaying.label.Label) + self.assertEqual(self.info._title.get_next_sibling(), + self.info._album) + + self.assertEqual(self.info.album, "") + self.assertEqual(self.info._album.prefix, "from ") + self.info.album = "Test Album" + self.assertEqual(self.info.album, "Test Album") + self.assertEqual(self.info._album.get_text(), "from Test Album") + + def test_artist(self): + """Test the artist label.""" + self.assertIsInstance(self.info._artist, + emmental.nowplaying.label.ArtistLabel) + self.assertEqual(self.info._album.get_next_sibling(), + self.info._artist) + + self.assertEqual(self.info.artist, "") + self.assertEqual(self.info._artist.prefix, "by ") + self.assertTrue(self.info.prefer_artist) + + self.info.artist = "Test Artist" + self.assertEqual(self.info.artist, "Test Artist") + self.assertEqual(self.info._artist.artist, "Test Artist") + + self.info.album_artist = "Test Album Artist" + self.assertEqual(self.info.album_artist, "Test Album Artist") + self.assertEqual(self.info._artist.album_artist, "Test Album Artist") + + self.info.prefer_artist = False + self.assertFalse(self.info._artist.prefer_artist) + self.assertEqual(self.info._artist.get_text(), "by Test Album Artist") + + self.info._artist.prefer_artist = True + self.assertTrue(self.info.prefer_artist) + self.assertEqual(self.info._artist.get_text(), "by Test Artist")