From 0fd391a9fdf01db92f9431bd09cf6118c35727f4 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Sun, 25 Jun 2023 22:18:38 -0400 Subject: [PATCH] sidebar: Add keyboard shortcuts The following shortcuts are implemented: - ? (/) to focus the "filter playlists" entry - g to go to the current playlist - p to open the Playlists section - a to open the Artists section - g to open the Genres section - d to open the Decades section - l to open the Libraries section Signed-off-by: Anna Schumaker --- emmental/__init__.py | 1 + emmental/sidebar/__init__.py | 19 +++++++++++++++++++ tests/sidebar/test_sidebar.py | 34 ++++++++++++++++++++++++++++++++++ tests/test_emmental.py | 11 +++++++++++ 4 files changed, 65 insertions(+) diff --git a/emmental/__init__.py b/emmental/__init__.py index 303cb42..2853a41 100644 --- a/emmental/__init__.py +++ b/emmental/__init__.py @@ -182,6 +182,7 @@ class Application(Adw.Application): side_bar = sidebar.Card(sql=self.db) self.db.settings.bind_setting("sidebar.artists.show-all", side_bar, "show-all-artists") + self.__add_accelerators(side_bar.accelerators) return side_bar def build_tracklist(self) -> tracklist.Card: diff --git a/emmental/sidebar/__init__.py b/emmental/sidebar/__init__.py index c79bc36..f460fb1 100644 --- a/emmental/sidebar/__init__.py +++ b/emmental/sidebar/__init__.py @@ -8,6 +8,7 @@ from . import genre from . import library from . import playlist from . import section +from ..action import ActionEntry from .. import db from .. import entry @@ -86,3 +87,21 @@ class Card(Gtk.Box): section.active = True section.select_playlist(playlist) + + @property + def accelerators(self) -> list[ActionEntry]: + """Get a list of accelerators for the Sidebar.""" + return [ActionEntry("focus-search-playlist", self._filter.grab_focus, + "question", enabled=(self, "sensitive")), + ActionEntry("goto-active-playlist", self._jump.activate, + "g", enabled=(self, "sensitive")), + ActionEntry("goto-playlists", self._playlists.activate, + "p", enabled=(self, "sensitive")), + ActionEntry("goto-artists", self._artists.activate, + "a", enabled=(self, "sensitive")), + ActionEntry("goto-genres", self._genres.activate, + "g", enabled=(self, "sensitive")), + ActionEntry("goto-decades", self._decades.activate, + "d", enabled=(self, "sensitive")), + ActionEntry("goto-libraries", self._libraries.activate, + "l", enabled=(self, "sensitive"))] diff --git a/tests/sidebar/test_sidebar.py b/tests/sidebar/test_sidebar.py index 207b716..4ba75fd 100644 --- a/tests/sidebar/test_sidebar.py +++ b/tests/sidebar/test_sidebar.py @@ -186,3 +186,37 @@ class TestSidebar(tests.util.TestCase): self.sidebar.select_playlist(library) self.assertTrue(self.sidebar._libraries.active) self.assertEqual(self.sidebar.selected_playlist, library) + + def test_accelerators(self): + """Check that the accelerators list is set up properly.""" + entries = [("focus-search-playlist", self.sidebar._filter.grab_focus, + ["question"]), + ("goto-active-playlist", self.sidebar._jump.activate, + ["g"]), + ("goto-playlists", self.sidebar._playlists.activate, + ["p"]), + ("goto-artists", self.sidebar._artists.activate, + ["a"]), + ("goto-genres", self.sidebar._genres.activate, + ["g"]), + ("goto-decades", self.sidebar._decades.activate, + ["d"]), + ("goto-libraries", self.sidebar._libraries.activate, + ["l"])] + + accels = self.sidebar.accelerators + self.assertIsInstance(accels, list) + + for i, (name, func, accel) in enumerate(entries): + with self.subTest(action=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) + + enabled = self.sidebar.get_sensitive() + self.assertEqual(accels[i].enabled, enabled) + self.sidebar.set_sensitive(not enabled) + self.assertEqual(accels[i].enabled, not enabled) + + self.assertEqual(len(accels), i + 1) diff --git a/tests/test_emmental.py b/tests/test_emmental.py index ae88ad3..81f72b7 100644 --- a/tests/test_emmental.py +++ b/tests/test_emmental.py @@ -205,6 +205,17 @@ class TestEmmental(unittest.TestCase): self.application.player = emmental.audio.Player() win = self.application.build_window() + for action, accel in [("app.focus-search-playlist", + "question"), + ("app.goto-active-playlist", "g"), + ("app.goto-playlists", "p"), + ("app.goto-artists", "a"), + ("app.goto-genres", "g"), + ("app.goto-decades", "d"), + ("app.goto-libraries", "l")]: + self.assertEqual(self.application.get_accels_for_action(action), + [accel]) + self.assertEqual(win.sidebar.sql, self.application.db) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO)