header: Add keyboard accelerators

I add accelerators for opening files, changing the volume, toggling
background mode, and running the settings editor.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-06-04 10:29:28 -04:00
parent 9cb927aabb
commit 0c1e5fcace
4 changed files with 59 additions and 0 deletions

View File

@ -142,6 +142,8 @@ class Application(Adw.Application):
("audio.replaygain.mode", "rg-mode")]: ("audio.replaygain.mode", "rg-mode")]:
self.db.settings.bind_setting(setting, hdr, property) self.db.settings.bind_setting(setting, hdr, property)
self.__add_accelerators(hdr.accelerators)
hdr.connect("notify::rg-enabled", self.__set_replaygain) hdr.connect("notify::rg-enabled", self.__set_replaygain)
hdr.connect("notify::rg-mode", self.__set_replaygain) hdr.connect("notify::rg-mode", self.__set_replaygain)
hdr.connect("track-requested", self.__load_path) hdr.connect("track-requested", self.__load_path)

View File

@ -5,6 +5,7 @@ import typing
from gi.repository import GObject from gi.repository import GObject
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Adw from gi.repository import Adw
from ..action import ActionEntry
from .. import db from .. import db
from .. import buttons from .. import buttons
from .. import gsetup from .. import gsetup
@ -118,6 +119,21 @@ class Header(Gtk.HeaderBar):
path: pathlib.Path) -> None: path: pathlib.Path) -> None:
self.emit("track-requested", path) self.emit("track-requested", path)
@property
def accelerators(self) -> list[ActionEntry]:
"""Get a list of accelerators for the Header."""
res = [ActionEntry("open-file", self._open.activate, "<Control>o"),
ActionEntry("decrease-volume", self._volume.decrement,
"<Control>Down"),
ActionEntry("increase-volume", self._volume.increment,
"<Control>Up"),
ActionEntry("toggle-bg-mode", self._background.activate,
"<Shift><Control>b")]
if __debug__:
res.append(ActionEntry("edit-settings", self._settings.activate,
"<Shift><Control>s"))
return res
@GObject.Signal(arg_types=(GObject.TYPE_PYOBJECT,)) @GObject.Signal(arg_types=(GObject.TYPE_PYOBJECT,))
def track_requested(self, path: pathlib.Path) -> None: def track_requested(self, path: pathlib.Path) -> None:
"""Signal that a track has been requested.""" """Signal that a track has been requested."""

View File

@ -180,3 +180,27 @@ class TestHeader(tests.util.TestCase):
self.header._background) self.header._background)
self.assertEqual(self.header._box.get_row_at_index(2), self.assertEqual(self.header._box.get_row_at_index(2),
self.header._replaygain) self.header._replaygain)
def test_accelerators(self):
"""Check that the accelerators list is set up properly."""
entries = [("open-file", self.header._open.activate, "<Control>o"),
("decrease-volume", self.header._volume.decrement,
"<Control>Down"),
("increase-volume", self.header._volume.increment,
"<Control>Up"),
("toggle-bg-mode", self.header._background.activate,
"<Shift><Control>b"),
("edit-settings", self.header._settings.activate,
"<Shift><Control>s")]
accels = self.header.accelerators
self.assertIsInstance(accels, list)
for i, (name, func, accel) in enumerate(entries):
with self.subTest(name=name):
self.assertIsInstance(accels[i], emmental.action.ActionEntry)
self.assertEqual(accels[i].name, name)
self.assertEqual(accels[i].func, func)
self.assertListEqual(accels[i].accels, [accel])
self.assertEqual(len(accels), i + 1)

View File

@ -118,6 +118,23 @@ class TestEmmental(unittest.TestCase):
self.assertEqual(self.application.get_accels_for_action( self.assertEqual(self.application.get_accels_for_action(
"app.reset-focus"), ["Escape"]) "app.reset-focus"), ["Escape"])
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_header_accels(self, mock_stdout: io.StringIO):
"""Check that accelerators have been added for header actions."""
self.application.db = emmental.db.Connection()
self.application.factory = emmental.playlist.Factory(
self.application.db)
self.application.player = emmental.audio.Player()
self.application.build_window()
for action, accel in [("app.open-file", "<Control>o"),
("app.decrease-volume", "<Control>Down"),
("app.increase-volume", "<Control>Up"),
("app.toggle-bg-mode", "<Shift><Control>b"),
("app.edit-settings", "<Shift><Control>s")]:
self.assertEqual(self.application.get_accels_for_action(action),
[accel])
@unittest.mock.patch("emmental.audio.Player.pause") @unittest.mock.patch("emmental.audio.Player.pause")
@unittest.mock.patch("emmental.audio.Player.play") @unittest.mock.patch("emmental.audio.Player.play")
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO)