tracklist: Create a TracknoString TrackRow

This is an InscriptionRow that combines a Track's number with its
Medium's number.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-01-13 14:34:26 -05:00
parent bed518cd77
commit 1ffc300eda
5 changed files with 79 additions and 7 deletions

View File

@ -13,6 +13,7 @@ class TrackRow(factory.ListRow):
"""Base class for Track Row widgets."""
property = GObject.Property(type=str)
mediumid = GObject.Property(type=int)
def __init__(self, listitem: Gtk.ListItem, property: str):
"""Initialize a TrackRow."""
@ -25,6 +26,10 @@ class TrackRow(factory.ListRow):
self.bind_and_set(library, "online", self, "online")
self.bind_active("active")
def bind_to_self(self, item_prop: str, child_prop: str) -> None:
"""Bind an item property directly to a TrackRow property."""
self.bind_and_set(self.item, item_prop, self, child_prop)
@GObject.Property(type=bool, default=False)
def active(self) -> bool:
"""Get the active state of this Row."""
@ -160,6 +165,31 @@ class PathString(InscriptionRow):
self.child.set_text(str(newval))
class TracknoString(InscriptionRow):
"""A FormatString that combines medium and track numbers."""
number = GObject.Property(type=int)
def __init__(self, *args, **kwargs):
"""Initialize a TracknoString."""
super().__init__(*args, **kwargs)
self.connect("notify", self.__update_trackno)
def __update_trackno(self, row: InscriptionRow, param) -> None:
"""Update the trackno string when properties change."""
match param.name:
case "mediumid": self.notify("number")
case "number":
mediumno = self.item.get_medium().number
self.child.set_text("{}-{:02d}".format(mediumno, self.number))
def do_bind(self) -> None:
"""Bind track and medium numbers to the Track Inscription."""
super().do_bind()
self.bind_to_self("mediumid", "mediumid")
self.bind_to_self("number", "number")
class FavoriteButton(TrackRow):
"""A TrackRow with an toggle to set Track favorite status."""

View File

@ -30,6 +30,8 @@ class TrackView(Gtk.Frame):
self.__append_column("Fav", "favorite", row.FavoriteButton,
resizable=False)
self.__append_column("Track", "number", row.TracknoString,
width=55, xalign=1.0, numeric=True)
self.__append_column("Title", "title", row.TrackString, width=300)
self.__append_column("Length", "length", row.LengthString,
xalign=1.0, numeric=True)

View File

@ -122,6 +122,7 @@ class TestSettings(unittest.TestCase):
def test_save_tracklist_column_width(self, mock_stdout: io.StringIO):
"""Test saving tracklist column widths."""
self.assertEqual(self.settings["tracklist.fav.size"], -1)
self.assertEqual(self.settings["tracklist.track.size"], 55)
self.assertEqual(self.settings["tracklist.title.size"], 300)
self.assertEqual(self.settings["tracklist.length.size"], -1)
self.assertEqual(self.settings["tracklist.artist.size"], 250)
@ -134,6 +135,7 @@ class TestSettings(unittest.TestCase):
column.set_fixed_width(123)
self.assertEqual(self.settings["tracklist.fav.size"], 123)
self.assertEqual(self.settings["tracklist.track.size"], 123)
self.assertEqual(self.settings["tracklist.title.size"], 123)
self.assertEqual(self.settings["tracklist.length.size"], 123)
self.assertEqual(self.settings["tracklist.artist.size"], 123)
@ -145,6 +147,7 @@ class TestSettings(unittest.TestCase):
def test_save_tracklist_column_visible(self, mock_stdout: io.StringIO):
"""Test saving tracklist column visibility."""
self.assertTrue(self.settings["tracklist.fav.visible"])
self.assertTrue(self.settings["tracklist.track.visible"])
self.assertTrue(self.settings["tracklist.title.visible"])
self.assertTrue(self.settings["tracklist.length.visible"])
self.assertTrue(self.settings["tracklist.artist.visible"])
@ -157,6 +160,7 @@ class TestSettings(unittest.TestCase):
column.set_visible(not column.get_visible())
self.assertFalse(self.settings["tracklist.fav.visible"])
self.assertFalse(self.settings["tracklist.track.visible"])
self.assertFalse(self.settings["tracklist.title.visible"])
self.assertFalse(self.settings["tracklist.length.visible"])
self.assertFalse(self.settings["tracklist.artist.visible"])

View File

@ -38,6 +38,7 @@ class TestTrackRowWidgets(tests.util.TestCase):
row = emmental.tracklist.row.TrackRow(self.listitem, "property")
self.assertIsInstance(row, emmental.factory.ListRow)
self.assertEqual(row.property, "property")
self.assertEqual(row.mediumid, 0)
row.child = Gtk.Label()
self.columnrow.set_child(row.child)
@ -129,6 +130,24 @@ class TestTrackRowWidgets(tests.util.TestCase):
row.bind()
self.assertEqual(row.child.get_text(), str(pathlib.Path("/a/b/1.ogg")))
def test_trackno_label(self):
"""Test the Track Number Label widget."""
row = emmental.tracklist.row.TracknoString(self.listitem, "number")
self.assertIsInstance(row, emmental.tracklist.row.InscriptionRow)
self.assertEqual(row.property, "number")
self.assertEqual(row.number, 0)
row.bind()
self.assertEqual(row.mediumid, self.medium.mediumid)
self.assertEqual(row.child.get_text(), "1-00")
self.track.number = 3
self.assertEqual(row.child.get_text(), "1-03")
medium = self.sql.media.create(self.album, "", number=3)
self.track.mediumid = medium.mediumid
self.assertEqual(row.child.get_text(), "3-03")
def test_favorite_button(self):
"""Test the Favorite Button widget."""
row = emmental.tracklist.row.FavoriteButton(self.listitem, "favorite")

View File

@ -108,7 +108,24 @@ class TestTrackViewColumns(tests.util.TestCase):
factory.emit("setup", self.listitem)
self.assertEqual(self.listitem.listrow.property, "favorite")
def test_title_column(self, i: int = 1):
def test_trackno_column(self, i: int = 1):
"""Test the track number column."""
self.assertEqual(self.columns[i].get_title(), "Track")
self.assertEqual(self.columns[i].get_fixed_width(), 55)
self.assertTrue(self.columns[i].get_resizable())
self.assertTrue(self.columns[i].get_visible())
factory = self.columns[i].get_factory()
self.assertIsInstance(factory, emmental.factory.Factory)
self.assertEqual(factory.row_type,
emmental.tracklist.row.TracknoString)
factory.emit("setup", self.listitem)
self.assertEqual(self.listitem.listrow.property, "number")
self.assertEqual(self.listitem.listrow.child.get_xalign(), 1.0)
self.assertTrue(self.listitem.listrow.child.has_css_class("numeric"))
def test_title_column(self, i: int = 2):
"""Test the title column."""
self.assertEqual(self.columns[i].get_title(), "Title")
self.assertEqual(self.columns[i].get_fixed_width(), 300)
@ -124,7 +141,7 @@ class TestTrackViewColumns(tests.util.TestCase):
self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0)
self.assertFalse(self.listitem.listrow.child.has_css_class("numeric"))
def test_length_column(self, i: int = 2):
def test_length_column(self, i: int = 3):
"""Test the length column."""
self.assertEqual(self.columns[i].get_title(), "Length")
self.assertEqual(self.columns[i].get_fixed_width(), -1)
@ -140,7 +157,7 @@ class TestTrackViewColumns(tests.util.TestCase):
self.assertEqual(self.listitem.listrow.child.get_xalign(), 1.0)
self.assertTrue(self.listitem.listrow.child.has_css_class("numeric"))
def test_artist_column(self, i: int = 3):
def test_artist_column(self, i: int = 4):
"""Test the artist column."""
self.assertEqual(self.columns[i].get_title(), "Artist")
self.assertEqual(self.columns[i].get_fixed_width(), 250)
@ -156,7 +173,7 @@ class TestTrackViewColumns(tests.util.TestCase):
self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0)
self.assertFalse(self.listitem.listrow.child.has_css_class("numeric"))
def test_playcount_column(self, i: int = 4):
def test_playcount_column(self, i: int = 5):
"""Test the play count column."""
self.assertEqual(self.columns[i].get_title(), "Play Count")
self.assertEqual(self.columns[i].get_fixed_width(), 135)
@ -173,7 +190,7 @@ class TestTrackViewColumns(tests.util.TestCase):
self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0)
self.assertTrue(self.listitem.listrow.child.has_css_class("numeric"))
def test_last_started_column(self, i: int = 5):
def test_last_started_column(self, i: int = 6):
"""Test the last started column."""
self.assertEqual(self.columns[i].get_title(), "Last Started")
self.assertEqual(self.columns[i].get_fixed_width(), 250)
@ -190,7 +207,7 @@ class TestTrackViewColumns(tests.util.TestCase):
self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0)
self.assertTrue(self.listitem.listrow.child.has_css_class("numeric"))
def test_last_played_column(self, i: int = 6):
def test_last_played_column(self, i: int = 7):
"""Test the last played column."""
self.assertEqual(self.columns[i].get_title(), "Last Played")
self.assertEqual(self.columns[i].get_fixed_width(), 250)
@ -207,7 +224,7 @@ class TestTrackViewColumns(tests.util.TestCase):
self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0)
self.assertTrue(self.listitem.listrow.child.has_css_class("numeric"))
def test_filepath_column(self, i: int = 7):
def test_filepath_column(self, i: int = 8):
"""Test the last played column."""
self.assertEqual(self.columns[i].get_title(), "Filepath")
self.assertEqual(self.columns[i].get_fixed_width(), -1)