diff --git a/emmental/header/__init__.py b/emmental/header/__init__.py index dd0df9d..ff32647 100644 --- a/emmental/header/__init__.py +++ b/emmental/header/__init__.py @@ -1,11 +1,13 @@ # Copyright 2022 (c) Anna Schumaker. """A custom Gtk.HeaderBar configured for our application.""" import pathlib +import typing from gi.repository import GObject from gi.repository import Gtk from gi.repository import Adw from .. import db from .. import buttons +from .. import gsetup from . import open from . import replaygain from . import volume @@ -39,7 +41,8 @@ class Header(Gtk.HeaderBar): """Initialize the HeaderBar.""" super().__init__(title=title, subtitle=SUBTITLE, sql=sql) self._open = open.Button() - self._title = Adw.WindowTitle(title=self.title, subtitle=self.subtitle) + self._title = Adw.WindowTitle(title=self.title, subtitle=self.subtitle, + tooltip_text=gsetup.env_string()) self._volume = volume.Controls() self._replaygain = replaygain.Selector() @@ -64,7 +67,8 @@ class Header(Gtk.HeaderBar): self.pack_start(self._open) if __debug__: self._window = settings.Window(sql) - self._settings = Gtk.Button.new_from_icon_name("settings-symbolic") + self._settings = Gtk.Button(icon_name="settings-symbolic", + tooltip_text="open settings editor") self._settings.connect("clicked", self.__run_settings) self.pack_start(self._settings) @@ -72,14 +76,21 @@ class Header(Gtk.HeaderBar): self.set_title_widget(self._title) self._open.connect("track-requested", self.__track_requested) - self.connect("notify::volume", self.__notify_volume) + self.connect("notify", self.__notify) def __run_settings(self, button: Gtk.Button) -> None: if __debug__: self._window.present() - def __notify_volume(self, header, param) -> None: - self._button.set_icon_name(_volume_icon(self.volume)) + def __notify(self, header: typing.Self, param: GObject.ParamSpec) -> None: + match param.name: + case "volume": + self._button.set_icon_name(_volume_icon(self.volume)) + + rg_status = f"{self.rg_mode} mode" if self.rg_enabled else "off" + status = (f"volume: {round(self.volume * 100)}%\n" + f"normalizing: {rg_status}") + self._button.set_tooltip_text(status) def __track_requested(self, button: open.Button, path: pathlib.Path) -> None: diff --git a/emmental/header/open.py b/emmental/header/open.py index abdc558..2e9efd4 100644 --- a/emmental/header/open.py +++ b/emmental/header/open.py @@ -12,7 +12,8 @@ class Button(Gtk.Button): def __init__(self): """Initialize our open button.""" - super().__init__(icon_name="document-open-symbolic") + super().__init__(icon_name="document-open-symbolic", + tooltip_text="open a file for playback") self._filters = Gio.ListStore() self._filter = Gtk.FileFilter(name="Audio Files", mime_types=["inode/directory", diff --git a/tests/header/test_header.py b/tests/header/test_header.py index 733e6d0..ff684c6 100644 --- a/tests/header/test_header.py +++ b/tests/header/test_header.py @@ -33,6 +33,9 @@ class TestHeader(tests.util.TestCase): self.assertEqual(self.header._title.get_subtitle(), emmental.header.SUBTITLE) + self.assertEqual(self.header._title.get_tooltip_text(), + emmental.gsetup.env_string()) + def test_open(self): """Check that the Open button works as expected.""" self.assertIsInstance(self.header._open, emmental.header.open.Button) @@ -51,6 +54,8 @@ class TestHeader(tests.util.TestCase): self.assertEqual(self.header.sql, self.sql) self.assertEqual(self.header._settings.get_icon_name(), "settings-symbolic") + self.assertEqual(self.header._settings.get_tooltip_text(), + "open settings editor") with unittest.mock.patch.object(self.header._window, "present") as mock_present: @@ -77,6 +82,8 @@ class TestHeader(tests.util.TestCase): self.assertEqual(self.header._volume.volume, vol) self.assertEqual(self.header._button.get_icon_name(), f"audio-volume-{icon}-symbolic") + self.assertEqual(self.header._button.get_tooltip_text(), + f"volume: {i*10}%\nnormalizing: off") def test_replaygain(self): """Test that we can configure ReplayGain as expected.""" @@ -89,11 +96,15 @@ class TestHeader(tests.util.TestCase): self.header.rg_mode = "track" self.assertTrue(self.header._replaygain.enabled) self.assertEqual(self.header._replaygain.mode, "track") + self.assertEqual(self.header._button.get_tooltip_text(), + "volume: 100%\nnormalizing: track mode") self.header._replaygain.enabled = False self.header._replaygain.mode = "album" self.assertFalse(self.header.rg_enabled) self.assertEqual(self.header.rg_mode, "album") + self.assertEqual(self.header._button.get_tooltip_text(), + "volume: 100%\nnormalizing: off") def test_popover(self): """Check that the menu popover was set up correctly.""" diff --git a/tests/header/test_open.py b/tests/header/test_open.py index 4184938..c6bca1e 100644 --- a/tests/header/test_open.py +++ b/tests/header/test_open.py @@ -18,6 +18,8 @@ class TestButton(unittest.TestCase): """Check that the button was set up properly.""" self.assertIsInstance(self.button, Gtk.Button) self.assertEqual(self.button.get_icon_name(), "document-open-symbolic") + self.assertEqual(self.button.get_tooltip_text(), + "open a file for playback") def test_filter(self): """Check that the file filter is set up properly."""