nowplaying: Give the Controls accelerator functions and properties
I create can-activate-* properties to indicate if a specific accelerator can be activated. At the same time, I introduce functions intended to be called by accelerators to activate each of our widgets. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
87b92ffc90
commit
8d72e1375f
|
@ -201,6 +201,7 @@ class Application(Adw.Application):
|
|||
now_playing=self.build_now_playing(),
|
||||
sidebar=self.build_sidebar(),
|
||||
tracklist=self.build_tracklist())
|
||||
win.bind_property("user-editing", win.now_playing, "editing")
|
||||
|
||||
for (setting, property) in [("window.width", "default-width"),
|
||||
("window.height", "default-height"),
|
||||
|
|
|
@ -28,6 +28,7 @@ class Card(Gtk.Box):
|
|||
have_previous = GObject.Property(type=bool, default=False)
|
||||
have_track = GObject.Property(type=bool, default=False)
|
||||
have_db_track = GObject.Property(type=bool, default=False)
|
||||
editing = GObject.Property(type=bool, default=False)
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize a Now Playing Card."""
|
||||
|
@ -55,7 +56,8 @@ class Card(Gtk.Box):
|
|||
self.bind_property(prop, self._tags, prop)
|
||||
self.bind_property("prefer-artist", self._tags, "prefer-artist",
|
||||
GObject.BindingFlags.BIDIRECTIONAL)
|
||||
for prop in ["playing", "have-next", "have-previous", "have-track"]:
|
||||
for prop in ["playing", "editing", "have-next",
|
||||
"have-previous", "have-track"]:
|
||||
self.bind_property(prop, self._controls, prop)
|
||||
self.bind_property("have-db-track", self._jump, "sensitive")
|
||||
self.bind_property("have-db-track", self._favorite, "sensitive")
|
||||
|
|
|
@ -28,6 +28,11 @@ class Controls(Gtk.Box):
|
|||
have_previous = GObject.Property(type=bool, default=False)
|
||||
have_track = GObject.Property(type=bool, default=False)
|
||||
|
||||
editing = GObject.Property(type=bool, default=False)
|
||||
can_activate_next = GObject.Property(type=bool, default=False)
|
||||
can_activate_prev = GObject.Property(type=bool, default=False)
|
||||
can_activate_play_pause = GObject.Property(type=bool, default=False)
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the Controls."""
|
||||
super().__init__(valign=Gtk.Align.START, homogeneous=True,
|
||||
|
@ -65,19 +70,59 @@ class Controls(Gtk.Box):
|
|||
self.bind_property("have-previous", self._prev, "sensitive")
|
||||
self.bind_property("have-track", self._play, "sensitive")
|
||||
self.bind_property("have-track", self._pause, "sensitive")
|
||||
self.connect("notify::playing", self.__notify_playing)
|
||||
self.connect("notify", self.__notify)
|
||||
|
||||
self.add_css_class("linked")
|
||||
|
||||
def __on_click(self, button: Gtk.Button, signal: str) -> None:
|
||||
self.emit(signal)
|
||||
|
||||
def __notify_playing(self, controls, param) -> None:
|
||||
def __notify_playing(self, controls: Gtk.Box, param) -> None:
|
||||
if not self.playing and self.autopause != -1:
|
||||
if win := self.get_ancestor(window.Window):
|
||||
win.post_toast("Autopause Cancelled")
|
||||
self.autopause = -1
|
||||
|
||||
def __notify(self, controls: Gtk.Box, param) -> None:
|
||||
match param.name:
|
||||
case "editing":
|
||||
allowed = not self.editing
|
||||
self.can_activate_next = self.have_next and allowed
|
||||
self.can_activate_prev = self.have_previous and allowed
|
||||
self.can_activate_play_pause = self.have_track and allowed
|
||||
case "playing": self.__notify_playing(controls, param)
|
||||
case "have-next":
|
||||
self.can_activate_next = self.have_next and not self.editing
|
||||
case "have-previous":
|
||||
can_activate = self.have_previous and not self.editing
|
||||
self.can_activate_prev = can_activate
|
||||
case "have-track":
|
||||
can_activate = self.have_track and not self.editing
|
||||
self.can_activate_play_pause = can_activate
|
||||
|
||||
def activate_next(self) -> None:
|
||||
"""Activate the Next button."""
|
||||
self._next.activate()
|
||||
|
||||
def activate_previous(self) -> None:
|
||||
"""Activate the Previous button."""
|
||||
self._prev.activate()
|
||||
|
||||
def activate_play_pause(self) -> None:
|
||||
"""Activate the Play or Pause button."""
|
||||
if self.playing:
|
||||
self._pause.activate()
|
||||
else:
|
||||
self._play.activate()
|
||||
|
||||
def decrease_autopause(self) -> None:
|
||||
"""Decrease the autopause count."""
|
||||
self._autopause.decrement()
|
||||
|
||||
def increase_autopause(self) -> None:
|
||||
"""Increase the autopause count."""
|
||||
self._autopause.increment()
|
||||
|
||||
@GObject.Signal
|
||||
def previous(self) -> None:
|
||||
"""Signals that the Previous button has been clicked."""
|
||||
|
|
|
@ -47,6 +47,8 @@ class TestControls(unittest.TestCase):
|
|||
self.assertEqual(self.controls.get_margin_end(),
|
||||
emmental.nowplaying.controls.MARGIN)
|
||||
|
||||
self.assertFalse(self.controls.editing)
|
||||
|
||||
def test_previous_button(self):
|
||||
"""Test the previous button."""
|
||||
self.assertIsInstance(self.controls._prev,
|
||||
|
@ -60,6 +62,19 @@ class TestControls(unittest.TestCase):
|
|||
self.controls._prev.emit("clicked")
|
||||
self.clicked.assert_called_with(self.controls._prev)
|
||||
|
||||
def test_activate_previous(self):
|
||||
"""Test can-activate-prev and the activate_previous() function."""
|
||||
self.assertFalse(self.controls.can_activate_prev)
|
||||
self.controls.have_previous = True
|
||||
self.assertTrue(self.controls.can_activate_prev)
|
||||
self.controls.editing = True
|
||||
self.assertFalse(self.controls.can_activate_prev)
|
||||
|
||||
activate = unittest.mock.Mock()
|
||||
self.controls._prev.connect("activate", activate)
|
||||
self.controls.activate_previous()
|
||||
activate.assert_called()
|
||||
|
||||
def test_play_button(self):
|
||||
"""Test the play button."""
|
||||
self.assertIsInstance(self.controls._play,
|
||||
|
@ -101,6 +116,25 @@ class TestControls(unittest.TestCase):
|
|||
self.controls._pause.emit("clicked")
|
||||
self.clicked.assert_called_with(self.controls._pause)
|
||||
|
||||
def test_activate_play_pause(self):
|
||||
"""Test can-activate-play-pause and the activate_play_pause() func."""
|
||||
self.assertFalse(self.controls.can_activate_play_pause)
|
||||
self.controls.have_track = True
|
||||
self.assertTrue(self.controls.can_activate_play_pause)
|
||||
self.controls.editing = True
|
||||
self.assertFalse(self.controls.can_activate_play_pause)
|
||||
|
||||
play = unittest.mock.Mock()
|
||||
self.controls._play.connect("activate", play)
|
||||
self.controls.activate_play_pause()
|
||||
play.assert_called()
|
||||
|
||||
self.controls.playing = True
|
||||
pause = unittest.mock.Mock()
|
||||
self.controls._pause.connect("activate-primary", pause)
|
||||
self.controls.activate_play_pause()
|
||||
pause.assert_called()
|
||||
|
||||
def test_autopause_button(self):
|
||||
"""Test the autopause button."""
|
||||
self.assertIsInstance(self.controls._autopause,
|
||||
|
@ -127,6 +161,33 @@ class TestControls(unittest.TestCase):
|
|||
self.controls._next.emit("clicked")
|
||||
self.clicked.assert_called_with(self.controls._next)
|
||||
|
||||
def test_activate_next(self):
|
||||
"""Test can-activate-next and the activate_next() function."""
|
||||
self.assertFalse(self.controls.can_activate_next)
|
||||
self.controls.have_next = True
|
||||
self.assertTrue(self.controls.can_activate_next)
|
||||
self.controls.editing = True
|
||||
self.assertFalse(self.controls.can_activate_next)
|
||||
|
||||
activate = unittest.mock.Mock()
|
||||
self.controls._next.connect("activate", activate)
|
||||
self.controls.activate_next()
|
||||
activate.assert_called()
|
||||
|
||||
def test_decrease_autopause(self):
|
||||
"""Test the decrease_autopause() function."""
|
||||
with unittest.mock.patch.object(self.controls._autopause,
|
||||
"decrement") as mock_decrement:
|
||||
self.controls.decrease_autopause()
|
||||
mock_decrement.assert_called()
|
||||
|
||||
def test_increase_autopause(self):
|
||||
"""Test the increase_autopause() function."""
|
||||
with unittest.mock.patch.object(self.controls._autopause,
|
||||
"increment") as mock_increment:
|
||||
self.controls.increase_autopause()
|
||||
mock_increment.assert_called()
|
||||
|
||||
def test_have_properties(self):
|
||||
"""Test the have_{next, previous, track} properties."""
|
||||
self.assertFalse(self.controls.have_next)
|
||||
|
|
|
@ -145,6 +145,14 @@ class TestNowPlaying(unittest.TestCase):
|
|||
self.card._seeker.emit("change-value", Gtk.ScrollType.JUMP, 10)
|
||||
handler.assert_called_with(self.card, 10)
|
||||
|
||||
def test_editing(self):
|
||||
"""Test the 'editing' property."""
|
||||
self.assertFalse(self.card.editing)
|
||||
self.card.editing = True
|
||||
self.assertTrue(self.card._controls.editing)
|
||||
self.card.editing = False
|
||||
self.assertFalse(self.card._controls.editing)
|
||||
|
||||
def test_playing(self):
|
||||
"""Test the 'playing' property."""
|
||||
self.assertFalse(self.card.playing)
|
||||
|
@ -154,7 +162,7 @@ class TestNowPlaying(unittest.TestCase):
|
|||
self.assertFalse(self.card._controls.playing)
|
||||
|
||||
def test_have_properties(self):
|
||||
"""Test the 'have-{next, previous, track} properties."""
|
||||
"""Test the 'have-{next, previous, track}' properties."""
|
||||
for property in ["have-next", "have-previous", "have-track"]:
|
||||
with self.subTest(property=property):
|
||||
self.assertFalse(self.card.get_property(property))
|
||||
|
|
|
@ -163,6 +163,9 @@ class TestEmmental(unittest.TestCase):
|
|||
self.application.factory.can_go_previous = True
|
||||
self.assertTrue(win.now_playing.have_previous)
|
||||
|
||||
win.user_editing = True
|
||||
self.assertTrue(win.now_playing.editing)
|
||||
|
||||
win.now_playing.emit("play")
|
||||
play_func.assert_called()
|
||||
win.now_playing.emit("pause")
|
||||
|
|
Loading…
Reference in New Issue