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:
parent
ed1d990e74
commit
0c77e509c3
|
@ -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())
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue