playlist: Have the Factory create an active Playlist
And add some special handling for setting the active playlist and visible playlist to the same db playlist. I also add active-loop and active-shuffle properties that are wired up to the MPRIS2 "Shuffle" and "LoopStatus" player properties. Implements: #7 (Add MPRIS2 Support) Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
b0734a41d0
commit
820eda4c46
|
@ -155,6 +155,10 @@ class Application(Adw.Application):
|
|||
("status", "PlaybackStatus"),
|
||||
("position", "Position")]:
|
||||
self.player.bind_property(prop, self.mpris.player, mpris_prop)
|
||||
for (prop, mpris_prop) in [("active-shuffle", "Shuffle"),
|
||||
("active-loop", "LoopStatus")]:
|
||||
self.factory.bind_property(prop, self.mpris.player, mpris_prop,
|
||||
GObject.BindingFlags.BIDIRECTIONAL)
|
||||
self.mpris.player.link_property("Volume", self.win.header, "volume")
|
||||
self.mpris.player.connect("OpenPath", self.__load_path)
|
||||
self.mpris.player.connect("Pause", self.player.pause)
|
||||
|
|
|
@ -14,6 +14,7 @@ class Factory(GObject.GObject):
|
|||
db_previous = GObject.Property(type=db.playlist.Playlist)
|
||||
db_visible = GObject.Property(type=db.playlist.Playlist)
|
||||
|
||||
active_playlist = GObject.Property(type=playlist.Playlist)
|
||||
visible_playlist = GObject.Property(type=playlist.Playlist)
|
||||
|
||||
def __init__(self, sql: db.Connection):
|
||||
|
@ -22,6 +23,16 @@ class Factory(GObject.GObject):
|
|||
self.sql.bind_property("active-playlist", self, "db-active")
|
||||
self.connect("notify", self.__notify_db_playlists)
|
||||
|
||||
def __get_playlists(self) -> list[playlist.Playlist]:
|
||||
plists = [self.active_playlist, self.visible_playlist]
|
||||
return [p for p in plists if p is not None]
|
||||
|
||||
def __search_playlists(self, db_plist: db.playlist.Playlist) \
|
||||
-> playlist.Playlist:
|
||||
for plist in self.__get_playlists():
|
||||
if plist.playlist == db_plist:
|
||||
return plist
|
||||
|
||||
def __run_factory(self, label: str) -> None:
|
||||
db_plist = self.get_property(f"db-{label}")
|
||||
plist = self.get_property(f"{label}-playlist")
|
||||
|
@ -30,21 +41,59 @@ class Factory(GObject.GObject):
|
|||
"<None>" if db_plist is None else db_plist.name)
|
||||
|
||||
if db_plist is None:
|
||||
plist.playlist = None
|
||||
if self.__get_playlists().count(plist) == 1:
|
||||
plist.playlist = None
|
||||
new = None
|
||||
elif plist is None:
|
||||
new = playlist.Playlist(self.sql, db_plist)
|
||||
else:
|
||||
elif plist is None or self.__get_playlists().count(plist) > 1:
|
||||
if (new := self.__search_playlists(db_plist)) is None:
|
||||
new = playlist.Playlist(self.sql, db_plist)
|
||||
elif (new := self.__search_playlists(db_plist)) is None:
|
||||
plist.playlist = db_plist
|
||||
return
|
||||
else:
|
||||
plist.playlist = None
|
||||
|
||||
self.set_property(f"{label}-playlist", new)
|
||||
|
||||
def __notify_db_playlists(self, factory: GObject.GObject, param) -> None:
|
||||
match param.name:
|
||||
case "db-active" | "db-previous":
|
||||
case "db-active":
|
||||
self.__run_factory("active")
|
||||
self.notify("active-loop")
|
||||
self.notify("active-shuffle")
|
||||
case "db-previous":
|
||||
plist = self.get_property(param.name)
|
||||
name = "<None>" if plist is None else plist.name
|
||||
print(f"factory: {param.name[3:]} playlist is:", name)
|
||||
case "db-visible":
|
||||
self.__run_factory("visible")
|
||||
|
||||
@GObject.Property(type=str, flags=playlist.FLAGS)
|
||||
def active_loop(self) -> str:
|
||||
"""Get the loop state of the active playlist."""
|
||||
if self.active_playlist is not None:
|
||||
return self.active_playlist.loop
|
||||
return "None"
|
||||
|
||||
@active_loop.setter
|
||||
def active_loop(self, newval: str) -> None:
|
||||
"""Set the loop state of the active playlist."""
|
||||
if self.active_playlist is not None:
|
||||
if self.active_playlist.loop != newval:
|
||||
self.active_playlist.loop = newval
|
||||
self.notify("active-loop")
|
||||
|
||||
@GObject.Property(type=bool, default=False, flags=playlist.FLAGS)
|
||||
def active_shuffle(self) -> bool:
|
||||
"""Get the shuffle state of the active playlist."""
|
||||
if self.active_playlist is not None:
|
||||
return self.active_playlist.shuffle
|
||||
return False
|
||||
|
||||
@active_shuffle.setter
|
||||
def active_shuffle(self, newval: bool) -> None:
|
||||
"""Set the shuffle state of the active playlist."""
|
||||
if self.active_playlist is not None:
|
||||
if self.active_playlist.shuffle != newval:
|
||||
self.active_playlist.shuffle = newval
|
||||
self.notify("active-shuffle")
|
||||
|
|
|
@ -36,6 +36,102 @@ class TestFactory(tests.util.TestCase):
|
|||
self.assertIsNone(self.factory.db_active)
|
||||
self.assertRegex(mock_stdout.getvalue(), "active playlist is: <None>")
|
||||
|
||||
def test_active_playlist(self, mock_stdout: io.StringIO):
|
||||
"""Test creating a Playlist when setting the dv_visible property."""
|
||||
self.assertIsNone(self.factory.active_playlist)
|
||||
|
||||
self.factory.db_active = self.user_plist
|
||||
self.assertIsInstance(self.factory.active_playlist,
|
||||
emmental.playlist.playlist.Playlist)
|
||||
self.assertEqual(self.factory.active_playlist.sql, self.sql)
|
||||
self.assertEqual(self.factory.active_playlist.playlist,
|
||||
self.user_plist)
|
||||
|
||||
orig_id = id(self.factory.active_playlist)
|
||||
self.factory.db_active = self.sql.playlists.collection
|
||||
self.assertEqual(id(self.factory.active_playlist), orig_id)
|
||||
self.assertEqual(self.factory.active_playlist.playlist,
|
||||
self.sql.playlists.collection)
|
||||
|
||||
active = self.factory.active_playlist
|
||||
self.factory.db_active = None
|
||||
self.assertIsNone(self.factory.active_playlist)
|
||||
self.assertIsNone(active.playlist)
|
||||
|
||||
def test_active_visible_playlist(self, mock_stdout: io.StringIO):
|
||||
"""Test setting the active playlist to the visible playlist."""
|
||||
self.factory.db_visible = self.user_plist
|
||||
self.factory.db_active = self.user_plist
|
||||
self.assertEqual(id(self.factory.active_playlist),
|
||||
id(self.factory.visible_playlist))
|
||||
|
||||
self.factory.db_active = self.user_plist
|
||||
self.assertEqual(id(self.factory.active_playlist),
|
||||
id(self.factory.visible_playlist))
|
||||
|
||||
self.factory.db_active = self.sql.playlists.collection
|
||||
self.assertNotEqual(id(self.factory.active_playlist),
|
||||
id(self.factory.visible_playlist))
|
||||
|
||||
active = self.factory.active_playlist
|
||||
self.factory.db_active = self.user_plist
|
||||
self.assertEqual(id(self.factory.active_playlist),
|
||||
id(self.factory.visible_playlist))
|
||||
self.assertIsNone(active.playlist)
|
||||
|
||||
active = self.factory.active_playlist
|
||||
self.factory.db_active = None
|
||||
self.assertEqual(active.playlist, self.user_plist)
|
||||
self.assertIsNone(self.factory.active_playlist)
|
||||
|
||||
def test_active_loop(self, mock_stdout: io.StringIO):
|
||||
"""Test changing the loop property of the active playlist."""
|
||||
notify = unittest.mock.Mock()
|
||||
self.factory.connect("notify::active-loop", notify)
|
||||
|
||||
self.assertEqual(self.factory.active_loop, "None")
|
||||
self.factory.active_loop = "Playlist"
|
||||
self.assertEqual(self.factory.active_loop, "None")
|
||||
notify.assert_not_called()
|
||||
|
||||
self.factory.db_active = self.user_plist
|
||||
self.assertEqual(self.factory.active_loop, "None")
|
||||
notify.assert_called()
|
||||
|
||||
notify.reset_mock()
|
||||
self.factory.active_loop = "Playlist"
|
||||
self.assertEqual(self.user_plist.loop, "Playlist")
|
||||
self.assertEqual(self.factory.active_loop, "Playlist")
|
||||
notify.assert_called()
|
||||
|
||||
notify.reset_mock()
|
||||
self.factory.active_loop = "Playlist"
|
||||
notify.assert_not_called()
|
||||
|
||||
def test_active_shuffle(self, mock_stdout: io.StringIO):
|
||||
"""Test changing the shuffle property of the active playlist."""
|
||||
notify = unittest.mock.Mock()
|
||||
self.factory.connect("notify::active-shuffle", notify)
|
||||
|
||||
self.assertFalse(self.factory.active_shuffle)
|
||||
self.factory.active_shuffle = True
|
||||
self.assertFalse(self.factory.active_shuffle)
|
||||
notify.assert_not_called()
|
||||
|
||||
self.factory.db_active = self.user_plist
|
||||
self.assertFalse(self.factory.active_shuffle)
|
||||
notify.assert_called()
|
||||
|
||||
notify.reset_mock()
|
||||
self.factory.active_shuffle = True
|
||||
self.assertTrue(self.user_plist.shuffle)
|
||||
self.assertTrue(self.factory.active_shuffle)
|
||||
notify.assert_called()
|
||||
|
||||
notify.reset_mock()
|
||||
self.factory.active_shuffle = True
|
||||
notify.assert_not_called()
|
||||
|
||||
def test_previous(self, mock_stdout: io.StringIO):
|
||||
"""Test the previous playlist property."""
|
||||
self.assertIsNone(self.factory.db_previous)
|
||||
|
@ -83,3 +179,29 @@ class TestFactory(tests.util.TestCase):
|
|||
self.factory.db_visible = None
|
||||
self.assertIsNone(self.factory.visible_playlist)
|
||||
self.assertIsNone(visible.playlist)
|
||||
|
||||
def test_visible_active_playlist(self, mock_stdout: io.StringIO):
|
||||
"""Test setting the visible playlist to the active playlist."""
|
||||
self.factory.db_active = self.user_plist
|
||||
self.factory.db_visible = self.user_plist
|
||||
self.assertEqual(id(self.factory.visible_playlist),
|
||||
id(self.factory.active_playlist))
|
||||
|
||||
self.factory.db_visible = self.user_plist
|
||||
self.assertEqual(id(self.factory.visible_playlist),
|
||||
id(self.factory.active_playlist))
|
||||
|
||||
self.factory.db_visible = self.sql.playlists.collection
|
||||
self.assertNotEqual(id(self.factory.visible_playlist),
|
||||
id(self.factory.active_playlist))
|
||||
|
||||
visible = self.factory.visible_playlist
|
||||
self.factory.db_visible = self.user_plist
|
||||
self.assertEqual(id(self.factory.visible_playlist),
|
||||
id(self.factory.active_playlist))
|
||||
self.assertIsNone(visible.playlist)
|
||||
|
||||
visible = self.factory.visible_playlist
|
||||
self.factory.db_visible = None
|
||||
self.assertEqual(visible.playlist, self.user_plist)
|
||||
self.assertIsNone(self.factory.visible_playlist)
|
||||
|
|
Loading…
Reference in New Issue