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:
parent
dd9d6268ff
commit
5b0a0f54e4
|
@ -1,11 +1,13 @@
|
||||||
# Copyright 2022 (c) Anna Schumaker.
|
# Copyright 2022 (c) Anna Schumaker.
|
||||||
"""A custom Gtk.HeaderBar configured for our application."""
|
"""A custom Gtk.HeaderBar configured for our application."""
|
||||||
import pathlib
|
import pathlib
|
||||||
|
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 .. import db
|
from .. import db
|
||||||
from .. import buttons
|
from .. import buttons
|
||||||
|
from .. import gsetup
|
||||||
from . import open
|
from . import open
|
||||||
from . import replaygain
|
from . import replaygain
|
||||||
from . import volume
|
from . import volume
|
||||||
|
@ -39,7 +41,8 @@ class Header(Gtk.HeaderBar):
|
||||||
"""Initialize the HeaderBar."""
|
"""Initialize the HeaderBar."""
|
||||||
super().__init__(title=title, subtitle=SUBTITLE, sql=sql)
|
super().__init__(title=title, subtitle=SUBTITLE, sql=sql)
|
||||||
self._open = open.Button()
|
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._volume = volume.Controls()
|
||||||
self._replaygain = replaygain.Selector()
|
self._replaygain = replaygain.Selector()
|
||||||
|
|
||||||
|
@ -64,7 +67,8 @@ class Header(Gtk.HeaderBar):
|
||||||
self.pack_start(self._open)
|
self.pack_start(self._open)
|
||||||
if __debug__:
|
if __debug__:
|
||||||
self._window = settings.Window(sql)
|
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._settings.connect("clicked", self.__run_settings)
|
||||||
self.pack_start(self._settings)
|
self.pack_start(self._settings)
|
||||||
|
|
||||||
|
@ -72,14 +76,21 @@ class Header(Gtk.HeaderBar):
|
||||||
self.set_title_widget(self._title)
|
self.set_title_widget(self._title)
|
||||||
|
|
||||||
self._open.connect("track-requested", self.__track_requested)
|
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:
|
def __run_settings(self, button: Gtk.Button) -> None:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
self._window.present()
|
self._window.present()
|
||||||
|
|
||||||
def __notify_volume(self, header, param) -> None:
|
def __notify(self, header: typing.Self, param: GObject.ParamSpec) -> None:
|
||||||
self._button.set_icon_name(_volume_icon(self.volume))
|
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,
|
def __track_requested(self, button: open.Button,
|
||||||
path: pathlib.Path) -> None:
|
path: pathlib.Path) -> None:
|
||||||
|
|
|
@ -12,7 +12,8 @@ class Button(Gtk.Button):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initialize our open button."""
|
"""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._filters = Gio.ListStore()
|
||||||
self._filter = Gtk.FileFilter(name="Audio Files",
|
self._filter = Gtk.FileFilter(name="Audio Files",
|
||||||
mime_types=["inode/directory",
|
mime_types=["inode/directory",
|
||||||
|
|
|
@ -33,6 +33,9 @@ class TestHeader(tests.util.TestCase):
|
||||||
self.assertEqual(self.header._title.get_subtitle(),
|
self.assertEqual(self.header._title.get_subtitle(),
|
||||||
emmental.header.SUBTITLE)
|
emmental.header.SUBTITLE)
|
||||||
|
|
||||||
|
self.assertEqual(self.header._title.get_tooltip_text(),
|
||||||
|
emmental.gsetup.env_string())
|
||||||
|
|
||||||
def test_open(self):
|
def test_open(self):
|
||||||
"""Check that the Open button works as expected."""
|
"""Check that the Open button works as expected."""
|
||||||
self.assertIsInstance(self.header._open, emmental.header.open.Button)
|
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.sql, self.sql)
|
||||||
self.assertEqual(self.header._settings.get_icon_name(),
|
self.assertEqual(self.header._settings.get_icon_name(),
|
||||||
"settings-symbolic")
|
"settings-symbolic")
|
||||||
|
self.assertEqual(self.header._settings.get_tooltip_text(),
|
||||||
|
"open settings editor")
|
||||||
|
|
||||||
with unittest.mock.patch.object(self.header._window,
|
with unittest.mock.patch.object(self.header._window,
|
||||||
"present") as mock_present:
|
"present") as mock_present:
|
||||||
|
@ -77,6 +82,8 @@ class TestHeader(tests.util.TestCase):
|
||||||
self.assertEqual(self.header._volume.volume, vol)
|
self.assertEqual(self.header._volume.volume, vol)
|
||||||
self.assertEqual(self.header._button.get_icon_name(),
|
self.assertEqual(self.header._button.get_icon_name(),
|
||||||
f"audio-volume-{icon}-symbolic")
|
f"audio-volume-{icon}-symbolic")
|
||||||
|
self.assertEqual(self.header._button.get_tooltip_text(),
|
||||||
|
f"volume: {i*10}%\nnormalizing: off")
|
||||||
|
|
||||||
def test_replaygain(self):
|
def test_replaygain(self):
|
||||||
"""Test that we can configure ReplayGain as expected."""
|
"""Test that we can configure ReplayGain as expected."""
|
||||||
|
@ -89,11 +96,15 @@ class TestHeader(tests.util.TestCase):
|
||||||
self.header.rg_mode = "track"
|
self.header.rg_mode = "track"
|
||||||
self.assertTrue(self.header._replaygain.enabled)
|
self.assertTrue(self.header._replaygain.enabled)
|
||||||
self.assertEqual(self.header._replaygain.mode, "track")
|
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.enabled = False
|
||||||
self.header._replaygain.mode = "album"
|
self.header._replaygain.mode = "album"
|
||||||
self.assertFalse(self.header.rg_enabled)
|
self.assertFalse(self.header.rg_enabled)
|
||||||
self.assertEqual(self.header.rg_mode, "album")
|
self.assertEqual(self.header.rg_mode, "album")
|
||||||
|
self.assertEqual(self.header._button.get_tooltip_text(),
|
||||||
|
"volume: 100%\nnormalizing: off")
|
||||||
|
|
||||||
def test_popover(self):
|
def test_popover(self):
|
||||||
"""Check that the menu popover was set up correctly."""
|
"""Check that the menu popover was set up correctly."""
|
||||||
|
|
|
@ -18,6 +18,8 @@ class TestButton(unittest.TestCase):
|
||||||
"""Check that the button was set up properly."""
|
"""Check that the button was set up properly."""
|
||||||
self.assertIsInstance(self.button, Gtk.Button)
|
self.assertIsInstance(self.button, Gtk.Button)
|
||||||
self.assertEqual(self.button.get_icon_name(), "document-open-symbolic")
|
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):
|
def test_filter(self):
|
||||||
"""Check that the file filter is set up properly."""
|
"""Check that the file filter is set up properly."""
|
||||||
|
|
Loading…
Reference in New Issue