tracklist: Add a ShuffleButton

This is an ImageToggle button that adjusts its opacity based on if it is
active or not.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2022-10-26 11:05:30 -04:00
parent ed1d990e74
commit 0c77e509c3
4 changed files with 72 additions and 0 deletions

View File

@ -33,11 +33,13 @@ class Card(Gtk.Box):
self._unselect = Gtk.Button(icon_name="edit-select-none-symbolic",
has_frame=False, sensitive=False)
self._loop = buttons.LoopButton()
self._shuffle = buttons.ShuffleButton()
self._top_left.append(self._visible_cols)
self._top_left.append(self._unselect)
self._top_right.append(self._loop)
self._top_right.append(self._shuffle)
self._top_box.set_start_widget(self._top_left)
self._top_box.set_center_widget(self._filter)
@ -52,6 +54,7 @@ class Card(Gtk.Box):
self._filter.connect("search-changed", self.__search_changed)
self._unselect.connect("clicked", self.__clear_selection)
self._loop.connect("notify::state", self.__update_loop_state)
self._shuffle.connect("notify::active", self.__update_shuffle_state)
self.add_css_class("card")
@ -64,16 +67,24 @@ class Card(Gtk.Box):
self._loop.state = playlist.loop
case "playlist":
self.__set_button_state()
case "shuffle":
self._shuffle.active = playlist.shuffle
def __set_button_state(self) -> None:
can_disable = self.playlist.playlist != self.sql.playlists.collection
self._loop.can_disable = can_disable
self._loop.state = self.playlist.loop
self._shuffle.active = self.playlist.shuffle
def __update_loop_state(self, loop: buttons.LoopButton, param) -> None:
if self.playlist.loop != loop.state:
self.playlist.loop = loop.state
def __update_shuffle_state(self, shuffle: buttons.ShuffleButton,
param) -> None:
if self.playlist.shuffle != shuffle.active:
self.playlist.shuffle = shuffle.active
def __search_changed(self, filter: entry.Filter) -> None:
self.sql.tracks.filter(filter.get_query())

View File

@ -84,3 +84,18 @@ class LoopButton(buttons.ImageToggle):
case ("Track", _):
self.active = True
self.icon_opacity = 1.0
class ShuffleButton(buttons.ImageToggle):
"""A button for setting Shuffle state of a Playlist."""
def __init__(self, **kwargs):
"""Initialize a Shuffle Button."""
super().__init__(active_icon_name="media-playlist-shuffle",
inactive_icon_name="media-playlist-consecutive",
icon_size=Gtk.IconSize.NORMAL, icon_opacity=0.5,
has_frame=False, **kwargs)
def do_toggled(self):
"""Adjust opacity when active state toggles."""
self.icon_opacity = 1.0 if self.active else 0.5

View File

@ -131,3 +131,29 @@ class TestLoopButton(unittest.TestCase):
self.assertEqual(self.loop.state, "Track")
self.loop.emit("clicked")
self.assertEqual(self.loop.state, "Playlist")
class TestShuffleButtons(unittest.TestCase):
"""Test the Shuffle button."""
def setUp(self):
"""Set up common variables."""
self.shuffle = emmental.tracklist.buttons.ShuffleButton()
def test_init(self):
"""Test that the shuffle button is configured correctly."""
self.assertIsInstance(self.shuffle, emmental.buttons.ImageToggle)
self.assertEqual(self.shuffle.icon_size, Gtk.IconSize.NORMAL)
self.assertEqual(self.shuffle.active_icon_name,
"media-playlist-shuffle")
self.assertEqual(self.shuffle.inactive_icon_name,
"media-playlist-consecutive")
self.assertAlmostEqual(self.shuffle.icon_opacity, 0.5, delta=0.005)
self.assertFalse(self.shuffle.get_has_frame())
def test_opacity(self):
"""Test adjusting the opacity based on active state."""
self.shuffle.active = True
self.assertEqual(self.shuffle.icon_opacity, 1.0)
self.shuffle.active = False
self.assertEqual(self.shuffle.icon_opacity, 0.5)

View File

@ -116,6 +116,26 @@ class TestTracklist(tests.util.TestCase):
self.tracklist._loop.state = "Playlist"
self.assertEqual(self.playlist.loop, "Playlist")
def test_shuffle_button(self):
"""Test the shuffle button."""
self.assertIsInstance(self.tracklist._shuffle,
emmental.tracklist.buttons.ShuffleButton)
self.assertEqual(self.tracklist._loop.get_next_sibling(),
self.tracklist._shuffle)
self.playlist.shuffle = True
self.tracklist.playlist = self.playlist
self.assertTrue(self.tracklist._shuffle.active)
self.playlist.playlist = self.sql.playlists.collection
self.assertFalse(self.tracklist._shuffle.active)
self.playlist.shuffle = True
self.assertTrue(self.tracklist._shuffle.active)
self.tracklist._shuffle.active = False
self.assertFalse(self.playlist.shuffle)
def test_trackview(self):
"""Test the Trackview widget."""
self.assertIsInstance(self.tracklist._trackview,