header: Add tooltips to the Header widgets

This is nice to have so users know what to expect from each button. I do
take some liberties, such as putting version numbers of our dependencies
as the tooltip for the Title widget. I also display the current volume
level in the volume button tooltip.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-05-27 16:12:44 -04:00
parent dd9d6268ff
commit 5b0a0f54e4
4 changed files with 31 additions and 6 deletions

View File

@ -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:

View File

@ -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",

View File

@ -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."""

View File

@ -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."""