tracklist: Create a FavoriteButton TrackRow
This button shows an ImageToggle button connected to the "favorite" property of the Track. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
915a59a46b
commit
bed518cd77
|
@ -5,6 +5,7 @@ import dateutil.tz
|
|||
import pathlib
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gtk
|
||||
from .. import buttons
|
||||
from .. import factory
|
||||
|
||||
|
||||
|
@ -157,3 +158,20 @@ class PathString(InscriptionRow):
|
|||
def path(self, newval: pathlib.Path) -> None:
|
||||
self.__path = newval
|
||||
self.child.set_text(str(newval))
|
||||
|
||||
|
||||
class FavoriteButton(TrackRow):
|
||||
"""A TrackRow with an toggle to set Track favorite status."""
|
||||
|
||||
def __init__(self, listitem: Gtk.ListItem, property: str) -> None:
|
||||
"""Initialize a Favorite Button."""
|
||||
super().__init__(listitem, property=property)
|
||||
self.child = buttons.ImageToggle("heart-filled", "heart-outline-thick",
|
||||
icon_size=Gtk.IconSize.NORMAL,
|
||||
valign=Gtk.Align.CENTER,
|
||||
has_frame=False)
|
||||
|
||||
def do_bind(self):
|
||||
"""Bind a track property to the Toggle Button."""
|
||||
super().do_bind()
|
||||
self.bind_and_set_property(self.property, "active", bidirectional=True)
|
||||
|
|
|
@ -28,6 +28,8 @@ class TrackView(Gtk.Frame):
|
|||
model=self._selection)
|
||||
self._scrollwin = Gtk.ScrolledWindow(child=self._columnview)
|
||||
|
||||
self.__append_column("Fav", "favorite", row.FavoriteButton,
|
||||
resizable=False)
|
||||
self.__append_column("Title", "title", row.TrackString, width=300)
|
||||
self.__append_column("Length", "length", row.LengthString,
|
||||
xalign=1.0, numeric=True)
|
||||
|
@ -51,10 +53,10 @@ class TrackView(Gtk.Frame):
|
|||
|
||||
def __append_column(self, title: str, property: str, row_type: type,
|
||||
*, width: int = -1, visible: bool = True,
|
||||
**kwargs) -> None:
|
||||
resizable: bool = True, **kwargs) -> None:
|
||||
fctry = factory.Factory(row_type=row_type, property=property, **kwargs)
|
||||
col = Gtk.ColumnViewColumn(title=title, factory=fctry, visible=visible,
|
||||
resizable=True, fixed_width=width)
|
||||
resizable=resizable, fixed_width=width)
|
||||
self._columnview.append_column(col)
|
||||
|
||||
def __runtime_changed(self, selection: Gtk.MultiSelection,
|
||||
|
|
|
@ -121,6 +121,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.title.size"], 300)
|
||||
self.assertEqual(self.settings["tracklist.length.size"], -1)
|
||||
self.assertEqual(self.settings["tracklist.artist.size"], 250)
|
||||
|
@ -132,6 +133,7 @@ class TestSettings(unittest.TestCase):
|
|||
for column in self.win.tracklist.columns:
|
||||
column.set_fixed_width(123)
|
||||
|
||||
self.assertEqual(self.settings["tracklist.fav.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)
|
||||
|
@ -142,6 +144,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.title.visible"])
|
||||
self.assertTrue(self.settings["tracklist.length.visible"])
|
||||
self.assertTrue(self.settings["tracklist.artist.visible"])
|
||||
|
@ -153,6 +156,7 @@ class TestSettings(unittest.TestCase):
|
|||
for column in self.win.tracklist.columns:
|
||||
column.set_visible(not column.get_visible())
|
||||
|
||||
self.assertFalse(self.settings["tracklist.fav.visible"])
|
||||
self.assertFalse(self.settings["tracklist.title.visible"])
|
||||
self.assertFalse(self.settings["tracklist.length.visible"])
|
||||
self.assertFalse(self.settings["tracklist.artist.visible"])
|
||||
|
|
|
@ -17,7 +17,7 @@ class TestTrackRowWidgets(tests.util.TestCase):
|
|||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
super().setUp()
|
||||
self.sql.playlists.load()
|
||||
self.sql.playlists.load(now=True)
|
||||
self.library = self.sql.libraries.create(pathlib.Path("/a/b"))
|
||||
self.album = self.sql.albums.create("Test Album", "Artist", "2023")
|
||||
self.medium = self.sql.media.create(self.album, "", number=1)
|
||||
|
@ -102,23 +102,6 @@ class TestTrackRowWidgets(tests.util.TestCase):
|
|||
self.track.length = 123.84
|
||||
self.assertEqual(row.child.get_text(), "2:04")
|
||||
|
||||
def test_playcount_string(self):
|
||||
"""Test the PlayCountString widget."""
|
||||
row = emmental.tracklist.row.PlayCountString(self.listitem,
|
||||
"playcount")
|
||||
self.assertIsInstance(row, emmental.tracklist.row.InscriptionRow)
|
||||
self.assertEqual(row.property, "playcount")
|
||||
self.assertEqual(row.playcount, 0)
|
||||
|
||||
row.bind()
|
||||
self.assertEqual(row.child.get_text(), "Unplayed")
|
||||
self.track.playcount = 1
|
||||
self.assertEqual(row.child.get_text(), "Played 1 time")
|
||||
self.track.playcount = 2
|
||||
self.assertEqual(row.child.get_text(), "Played 2 times")
|
||||
self.track.playcount = 3
|
||||
self.assertEqual(row.child.get_text(), "Played 3 times")
|
||||
|
||||
def test_timestamp_string(self):
|
||||
"""Test the TimestampString widget."""
|
||||
row = emmental.tracklist.row.TimestampString(self.listitem,
|
||||
|
@ -145,3 +128,25 @@ class TestTrackRowWidgets(tests.util.TestCase):
|
|||
|
||||
row.bind()
|
||||
self.assertEqual(row.child.get_text(), str(pathlib.Path("/a/b/1.ogg")))
|
||||
|
||||
def test_favorite_button(self):
|
||||
"""Test the Favorite Button widget."""
|
||||
row = emmental.tracklist.row.FavoriteButton(self.listitem, "favorite")
|
||||
self.assertIsInstance(row, emmental.tracklist.row.TrackRow)
|
||||
self.assertIsInstance(row.child, emmental.buttons.ImageToggle)
|
||||
|
||||
self.assertEqual(row.property, "favorite")
|
||||
self.assertEqual(row.child.active_icon_name, "heart-filled")
|
||||
self.assertEqual(row.child.inactive_icon_name, "heart-outline-thick")
|
||||
self.assertEqual(row.child.icon_size, Gtk.IconSize.NORMAL)
|
||||
self.assertEqual(row.child.get_valign(), Gtk.Align.CENTER)
|
||||
self.assertFalse(row.child.get_has_frame())
|
||||
|
||||
self.track.favorite = True
|
||||
row.bind()
|
||||
self.assertTrue(row.child.active)
|
||||
|
||||
self.track.favorite = False
|
||||
self.assertFalse(row.child.active)
|
||||
row.child.active = True
|
||||
self.assertTrue(self.track.favorite)
|
||||
|
|
|
@ -93,7 +93,22 @@ class TestTrackViewColumns(tests.util.TestCase):
|
|||
self.columns = self.trackview.columns
|
||||
self.listitem = Gtk.ListItem()
|
||||
|
||||
def test_title_column(self, i: int = 0):
|
||||
def test_favorite_column(self, i: int = 0):
|
||||
"""Test the favorite column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Fav")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), -1)
|
||||
self.assertFalse(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.FavoriteButton)
|
||||
|
||||
factory.emit("setup", self.listitem)
|
||||
self.assertEqual(self.listitem.listrow.property, "favorite")
|
||||
|
||||
def test_title_column(self, i: int = 1):
|
||||
"""Test the title column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Title")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), 300)
|
||||
|
@ -109,7 +124,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 = 1):
|
||||
def test_length_column(self, i: int = 2):
|
||||
"""Test the length column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Length")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), -1)
|
||||
|
@ -125,7 +140,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 = 2):
|
||||
def test_artist_column(self, i: int = 3):
|
||||
"""Test the artist column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Artist")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), 250)
|
||||
|
@ -141,7 +156,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 = 3):
|
||||
def test_playcount_column(self, i: int = 4):
|
||||
"""Test the play count column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Play Count")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), 135)
|
||||
|
@ -158,7 +173,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 = 4):
|
||||
def test_last_started_column(self, i: int = 5):
|
||||
"""Test the last started column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Last Started")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), 250)
|
||||
|
@ -175,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_played_column(self, i: int = 5):
|
||||
def test_last_played_column(self, i: int = 6):
|
||||
"""Test the last played column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Last Played")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), 250)
|
||||
|
@ -192,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_filepath_column(self, i: int = 6):
|
||||
def test_filepath_column(self, i: int = 7):
|
||||
"""Test the last played column."""
|
||||
self.assertEqual(self.columns[i].get_title(), "Filepath")
|
||||
self.assertEqual(self.columns[i].get_fixed_width(), -1)
|
||||
|
|
Loading…
Reference in New Issue