From 0c1e5fcacee82cba075f8d66920dc8a7826519cf Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Sun, 4 Jun 2023 10:29:28 -0400 Subject: [PATCH] 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 --- emmental/__init__.py | 2 ++ emmental/header/__init__.py | 16 ++++++++++++++++ tests/header/test_header.py | 24 ++++++++++++++++++++++++ tests/test_emmental.py | 17 +++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/emmental/__init__.py b/emmental/__init__.py index 2e570d7..6bc3b10 100644 --- a/emmental/__init__.py +++ b/emmental/__init__.py @@ -142,6 +142,8 @@ class Application(Adw.Application): ("audio.replaygain.mode", "rg-mode")]: 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-mode", self.__set_replaygain) hdr.connect("track-requested", self.__load_path) diff --git a/emmental/header/__init__.py b/emmental/header/__init__.py index 773455e..cdf23b0 100644 --- a/emmental/header/__init__.py +++ b/emmental/header/__init__.py @@ -5,6 +5,7 @@ import typing from gi.repository import GObject from gi.repository import Gtk from gi.repository import Adw +from ..action import ActionEntry from .. import db from .. import buttons from .. import gsetup @@ -118,6 +119,21 @@ class Header(Gtk.HeaderBar): path: pathlib.Path) -> None: 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, "o"), + ActionEntry("decrease-volume", self._volume.decrement, + "Down"), + ActionEntry("increase-volume", self._volume.increment, + "Up"), + ActionEntry("toggle-bg-mode", self._background.activate, + "b")] + if __debug__: + res.append(ActionEntry("edit-settings", self._settings.activate, + "s")) + return res + @GObject.Signal(arg_types=(GObject.TYPE_PYOBJECT,)) def track_requested(self, path: pathlib.Path) -> None: """Signal that a track has been requested.""" diff --git a/tests/header/test_header.py b/tests/header/test_header.py index 97ae9d0..acf67b7 100644 --- a/tests/header/test_header.py +++ b/tests/header/test_header.py @@ -180,3 +180,27 @@ class TestHeader(tests.util.TestCase): self.header._background) self.assertEqual(self.header._box.get_row_at_index(2), self.header._replaygain) + + def test_accelerators(self): + """Check that the accelerators list is set up properly.""" + entries = [("open-file", self.header._open.activate, "o"), + ("decrease-volume", self.header._volume.decrement, + "Down"), + ("increase-volume", self.header._volume.increment, + "Up"), + ("toggle-bg-mode", self.header._background.activate, + "b"), + ("edit-settings", self.header._settings.activate, + "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) diff --git a/tests/test_emmental.py b/tests/test_emmental.py index 5806093..a856c1a 100644 --- a/tests/test_emmental.py +++ b/tests/test_emmental.py @@ -118,6 +118,23 @@ class TestEmmental(unittest.TestCase): self.assertEqual(self.application.get_accels_for_action( "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", "o"), + ("app.decrease-volume", "Down"), + ("app.increase-volume", "Up"), + ("app.toggle-bg-mode", "b"), + ("app.edit-settings", "s")]: + self.assertEqual(self.application.get_accels_for_action(action), + [accel]) + @unittest.mock.patch("emmental.audio.Player.pause") @unittest.mock.patch("emmental.audio.Player.play") @unittest.mock.patch("sys.stdout", new_callable=io.StringIO)