header: Convert the ReplayGain selector into an Adw.ExpanderRow
This will be added to a ListBox with the volume controls. Expanding the row will enable ReplayGain and give the user a menu to select ReplayGain mode. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
03e5b9ad1b
commit
dae588bfaf
|
@ -44,7 +44,7 @@ class Header(Gtk.HeaderBar):
|
|||
self._title = Adw.WindowTitle(title=self.title, subtitle=self.subtitle,
|
||||
tooltip_text=gsetup.env_string())
|
||||
self._volume = volume.VolumeRow()
|
||||
self._replaygain = replaygain.Selector()
|
||||
self._replaygain = replaygain.ReplayGainRow()
|
||||
|
||||
self._box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
|
||||
self._box.append(self._volume)
|
||||
|
|
|
@ -2,9 +2,36 @@
|
|||
"""A widget for selecting ReplayGain mode."""
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
||||
class Selector(Gtk.Grid):
|
||||
class CheckRow(Adw.ActionRow):
|
||||
"""A custom Adw.ActionRow displaying a Check Button."""
|
||||
|
||||
active = GObject.Property(type=bool, default=False)
|
||||
group = GObject.Property(type=Adw.ActionRow)
|
||||
mode = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, mode: str, active: bool = False,
|
||||
group: Adw.ActionRow | None = None, **kwargs):
|
||||
"""Initialize the Check Row."""
|
||||
super().__init__(mode=mode, active=active, group=group, **kwargs)
|
||||
self._prefix = Gtk.CheckButton(active=active,
|
||||
group=group._prefix if group else None)
|
||||
|
||||
self.bind_property("active", self._prefix, "active",
|
||||
GObject.BindingFlags.BIDIRECTIONAL)
|
||||
|
||||
self.set_activatable_widget(self._prefix)
|
||||
self.add_prefix(self._prefix)
|
||||
|
||||
def set_active(self, newval: bool) -> None:
|
||||
"""Set the active property."""
|
||||
if self.active != newval:
|
||||
self.active = newval
|
||||
|
||||
|
||||
class ReplayGainRow(Adw.ExpanderRow):
|
||||
"""Build up a widget for configuring ReplayGain settings."""
|
||||
|
||||
enabled = GObject.Property(type=bool, default=False)
|
||||
|
@ -12,42 +39,40 @@ class Selector(Gtk.Grid):
|
|||
|
||||
def __init__(self):
|
||||
"""Initialize the ReplayGain selector."""
|
||||
super().__init__(column_spacing=6, margin_top=8)
|
||||
self._title = Gtk.Label(label="Volume Normalization", yalign=0.8,
|
||||
hexpand=True, vexpand=True)
|
||||
self._switch = Gtk.Switch()
|
||||
self._auto = Gtk.CheckButton(label="Decide automatically",
|
||||
sensitive=False, active=True)
|
||||
self._album = Gtk.CheckButton(label="Albums have the same volume",
|
||||
sensitive=False, group=self._auto)
|
||||
self._track = Gtk.CheckButton(label="Tracks have the same volume",
|
||||
sensitive=False, group=self._auto)
|
||||
super().__init__(title="Volume Normalization",
|
||||
subtitle="Configure ReplayGain normalizing")
|
||||
self._switch = Gtk.Switch(valign=Gtk.Align.CENTER)
|
||||
self._automatic = CheckRow(title="Automatic Mode",
|
||||
subtitle="Emmental decides automatically",
|
||||
mode="auto", active=True)
|
||||
self._album = CheckRow(title="Album Mode",
|
||||
subtitle="Albums have the same volume",
|
||||
mode="album", group=self._automatic)
|
||||
self._track = CheckRow(title="Track Mode",
|
||||
subtitle="Tracks have the same volume",
|
||||
mode="track", group=self._automatic)
|
||||
|
||||
self.attach(self._title, 0, 0, 1, 1)
|
||||
self.attach(self._switch, 1, 0, 1, 1)
|
||||
self.attach(self._auto, 0, 1, 2, 1)
|
||||
self.attach(self._album, 0, 2, 2, 1)
|
||||
self.attach(self._track, 0, 3, 2, 1)
|
||||
self.add_prefix(self._switch)
|
||||
self.add_row(self._automatic)
|
||||
self.add_row(self._album)
|
||||
self.add_row(self._track)
|
||||
|
||||
self.connect("notify::mode", self.__notify_mode)
|
||||
self._auto.connect("toggled", self.__mode_toggled, "auto")
|
||||
self._album.connect("toggled", self.__mode_toggled, "album")
|
||||
self._track.connect("toggled", self.__mode_toggled, "track")
|
||||
self._automatic.connect("notify::active", self.__row_activated)
|
||||
self._album.connect("notify::active", self.__row_activated)
|
||||
self._track.connect("notify::active", self.__row_activated)
|
||||
|
||||
self._switch.bind_property("state", self._auto, "sensitive")
|
||||
self._switch.bind_property("state", self._album, "sensitive")
|
||||
self._switch.bind_property("state", self._track, "sensitive")
|
||||
self.bind_property("enabled", self._switch, "state",
|
||||
self._switch.bind_property("active", self, "expanded",
|
||||
GObject.BindingFlags.BIDIRECTIONAL)
|
||||
self.bind_property("enabled", self._switch, "active",
|
||||
GObject.BindingFlags.BIDIRECTIONAL)
|
||||
|
||||
self._title.add_css_class("title-4")
|
||||
|
||||
def __notify_mode(self, selector: Gtk.Grid, param) -> None:
|
||||
match selector.get_property("mode"):
|
||||
def __notify_mode(self, row: Adw.ExpanderRow, param) -> None:
|
||||
match self.mode:
|
||||
case "album": self._album.set_active(True)
|
||||
case "track": self._track.set_active(True)
|
||||
case _: self._auto.set_active(True)
|
||||
case _: self._automatic.set_active(True)
|
||||
|
||||
def __mode_toggled(self, check: Gtk.CheckButton, new_mode: str) -> None:
|
||||
if check.get_active():
|
||||
self.mode = new_mode
|
||||
def __row_activated(self, row: CheckRow, param: GObject.ParamSpec) -> None:
|
||||
if row.active:
|
||||
self.mode = row.mode
|
||||
|
|
|
@ -88,7 +88,7 @@ class TestHeader(tests.util.TestCase):
|
|||
def test_replaygain(self):
|
||||
"""Test that we can configure ReplayGain as expected."""
|
||||
self.assertIsInstance(self.header._replaygain,
|
||||
emmental.header.replaygain.Selector)
|
||||
emmental.header.replaygain.ReplayGainRow)
|
||||
self.assertFalse(self.header.rg_enabled)
|
||||
self.assertEqual(self.header.rg_mode, "auto")
|
||||
|
||||
|
|
|
@ -1,119 +1,159 @@
|
|||
# Copyright 2022 (c) Anna Schumaker
|
||||
"""Tests our ReplayGain selector."""
|
||||
import unittest
|
||||
import unittest.mock
|
||||
import emmental.header.replaygain
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
||||
class TestSelector(unittest.TestCase):
|
||||
"""Test case for our custom ReplayGain Selector."""
|
||||
class TestCheckRow(unittest.TestCase):
|
||||
"""Test case for our custom CheckRow ListBox row."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.selector = emmental.header.replaygain.Selector()
|
||||
self.checkrow = emmental.header.replaygain.CheckRow("test mode",
|
||||
title="My Title")
|
||||
|
||||
def test_selector(self):
|
||||
"""Check that the Selector is set up properly."""
|
||||
self.assertIsInstance(self.selector, Gtk.Grid)
|
||||
self.assertEqual(self.selector.get_column_spacing(), 6)
|
||||
self.assertEqual(self.selector.get_margin_top(), 8)
|
||||
def test_init(self):
|
||||
"""Test that the CheckRow is set up properly."""
|
||||
self.assertIsInstance(self.checkrow, Adw.ActionRow)
|
||||
self.assertIsInstance(self.checkrow._prefix, Gtk.CheckButton)
|
||||
|
||||
self.assertEqual(self.selector.mode, "auto")
|
||||
self.assertFalse(self.selector.enabled)
|
||||
self.assertEqual(self.checkrow.mode, "test mode")
|
||||
self.assertEqual(self.checkrow.get_title(), "My Title")
|
||||
self.assertEqual(self.checkrow.get_activatable_widget(),
|
||||
self.checkrow._prefix)
|
||||
|
||||
self.selector.enabled = True
|
||||
self.assertTrue(self.selector._switch.get_state())
|
||||
self.selector.enabled = False
|
||||
self.assertFalse(self.selector._switch.get_state())
|
||||
def test_active(self):
|
||||
"""Test the CheckRow active property."""
|
||||
self.assertFalse(self.checkrow.active)
|
||||
|
||||
def test_title(self):
|
||||
"""Check that the Selector title label is set up properly."""
|
||||
self.assertIsInstance(self.selector._title, Gtk.Label)
|
||||
self.assertEqual(self.selector.get_child_at(0, 0),
|
||||
self.selector._title)
|
||||
self.checkrow.active = True
|
||||
self.assertTrue(self.checkrow._prefix.get_active())
|
||||
self.checkrow._prefix.set_active(False)
|
||||
self.assertFalse(self.checkrow.active)
|
||||
|
||||
self.assertEqual(self.selector._title.get_text(),
|
||||
"Volume Normalization")
|
||||
self.assertAlmostEqual(self.selector._title.get_yalign(), 0.8)
|
||||
self.assertTrue(self.selector._title.has_css_class("title-4"))
|
||||
self.assertTrue(self.selector._title.get_hexpand())
|
||||
self.assertTrue(self.selector._title.get_vexpand())
|
||||
checkrow2 = emmental.header.replaygain.CheckRow("other", active=True)
|
||||
self.assertTrue(checkrow2.active)
|
||||
self.assertTrue(checkrow2._prefix.get_active())
|
||||
|
||||
def test_group(self):
|
||||
"""Test the CheckRow group property."""
|
||||
self.assertIsNone(self.checkrow.group)
|
||||
checkrow2 = emmental.header.replaygain.CheckRow("other",
|
||||
group=self.checkrow)
|
||||
self.assertEqual(checkrow2.group, self.checkrow)
|
||||
|
||||
def test_set_active(self):
|
||||
"""Test the set_active() property."""
|
||||
notify = unittest.mock.Mock()
|
||||
self.checkrow.connect("notify::active", notify)
|
||||
|
||||
self.checkrow.set_active(True)
|
||||
self.assertTrue(self.checkrow.active)
|
||||
notify.assert_called()
|
||||
|
||||
notify.reset_mock()
|
||||
self.checkrow.set_active(True)
|
||||
notify.assert_not_called()
|
||||
|
||||
|
||||
class TestReplayGainRow(unittest.TestCase):
|
||||
"""Test case for our custom ReplayGain ListBox row."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.replaygain = emmental.header.replaygain.ReplayGainRow()
|
||||
|
||||
def test_init(self):
|
||||
"""Check that the ReplayGainRow is set up properly."""
|
||||
self.assertIsInstance(self.replaygain, Adw.ExpanderRow)
|
||||
self.assertEqual(self.replaygain.get_title(), "Volume Normalization")
|
||||
self.assertEqual(self.replaygain.get_subtitle(),
|
||||
"Configure ReplayGain normalizing")
|
||||
|
||||
self.assertEqual(self.replaygain.mode, "auto")
|
||||
self.assertFalse(self.replaygain.enabled)
|
||||
|
||||
self.replaygain.set_expanded(True)
|
||||
self.assertTrue(self.replaygain._switch.get_active())
|
||||
self.replaygain.set_expanded(False)
|
||||
self.assertFalse(self.replaygain._switch.get_active())
|
||||
|
||||
def test_switch(self):
|
||||
"""Check that the Selector switch works as intended."""
|
||||
self.assertIsInstance(self.selector._switch, Gtk.Switch)
|
||||
self.assertEqual(self.selector.get_child_at(1, 0),
|
||||
self.selector._switch)
|
||||
self.assertFalse(self.selector._switch.get_active())
|
||||
"""Check that the ReplayGainRow switch works as intended."""
|
||||
self.assertIsInstance(self.replaygain._switch, Gtk.Switch)
|
||||
self.assertEqual(self.replaygain._switch.get_valign(),
|
||||
Gtk.Align.CENTER)
|
||||
self.assertFalse(self.replaygain._switch.get_active())
|
||||
|
||||
self.selector._switch.set_active(True)
|
||||
self.assertTrue(self.selector.enabled)
|
||||
self.assertTrue(self.selector._auto.get_sensitive())
|
||||
self.assertTrue(self.selector._album.get_sensitive())
|
||||
self.assertTrue(self.selector._track.get_sensitive())
|
||||
|
||||
self.selector._switch.set_active(False)
|
||||
self.assertFalse(self.selector.enabled)
|
||||
self.assertFalse(self.selector._auto.get_sensitive())
|
||||
self.assertFalse(self.selector._album.get_sensitive())
|
||||
self.assertFalse(self.selector._track.get_sensitive())
|
||||
self.replaygain._switch.set_active(True)
|
||||
self.assertTrue(self.replaygain.get_expanded())
|
||||
self.replaygain._switch.set_active(False)
|
||||
self.assertFalse(self.replaygain.get_expanded())
|
||||
|
||||
def test_automatic_mode(self):
|
||||
"""Test the Selector automatic mode button."""
|
||||
self.assertIsInstance(self.selector._auto, Gtk.CheckButton)
|
||||
self.assertEqual(self.selector.get_child_at(0, 1), self.selector._auto)
|
||||
"""Test the ReplayGainRow automatic mode option."""
|
||||
self.assertIsInstance(self.replaygain._automatic,
|
||||
emmental.header.replaygain.CheckRow)
|
||||
self.assertEqual(self.replaygain._automatic.get_title(),
|
||||
"Automatic Mode")
|
||||
self.assertEqual(self.replaygain._automatic.get_subtitle(),
|
||||
"Emmental decides automatically")
|
||||
|
||||
self.assertEqual(self.selector._auto.get_label(),
|
||||
"Decide automatically")
|
||||
self.assertFalse(self.selector._auto.get_sensitive())
|
||||
self.assertTrue(self.selector._auto.get_active())
|
||||
self.assertEqual(self.replaygain._automatic.mode, "auto")
|
||||
self.assertTrue(self.replaygain._automatic.active)
|
||||
|
||||
self.selector._track.set_active(True)
|
||||
self.selector._auto.set_active(True)
|
||||
self.assertEqual(self.selector.mode, "auto")
|
||||
self.replaygain._track.active = True
|
||||
self.replaygain._automatic.active = True
|
||||
self.assertEqual(self.replaygain.mode, "auto")
|
||||
self.assertFalse(self.replaygain._track.active)
|
||||
|
||||
def test_album_mode(self):
|
||||
"""Test the Selector album mode button."""
|
||||
self.assertIsInstance(self.selector._album, Gtk.CheckButton)
|
||||
self.assertEqual(self.selector.get_child_at(0, 2),
|
||||
self.selector._album)
|
||||
|
||||
self.assertEqual(self.selector._album.get_label(),
|
||||
"""Test the ReplayGainRow album mode option."""
|
||||
self.assertIsInstance(self.replaygain._album,
|
||||
emmental.header.replaygain.CheckRow)
|
||||
self.assertEqual(self.replaygain._album.get_title(), "Album Mode")
|
||||
self.assertEqual(self.replaygain._album.get_subtitle(),
|
||||
"Albums have the same volume")
|
||||
self.assertFalse(self.selector._album.get_sensitive())
|
||||
self.assertFalse(self.selector._album.get_active())
|
||||
|
||||
self.selector._album.set_active(True)
|
||||
self.assertEqual(self.selector.mode, "album")
|
||||
self.assertEqual(self.replaygain._album.mode, "album")
|
||||
self.assertEqual(self.replaygain._album.group,
|
||||
self.replaygain._automatic)
|
||||
|
||||
self.replaygain._album.active = True
|
||||
self.assertEqual(self.replaygain.mode, "album")
|
||||
|
||||
def test_track_mode(self):
|
||||
"""Test the Selector album mode button."""
|
||||
self.assertIsInstance(self.selector._track, Gtk.CheckButton)
|
||||
self.assertEqual(self.selector.get_child_at(0, 3),
|
||||
self.selector._track)
|
||||
|
||||
self.assertEqual(self.selector._track.get_label(),
|
||||
"""Test the ReplayGainRow track mode option."""
|
||||
self.assertIsInstance(self.replaygain._track,
|
||||
emmental.header.replaygain.CheckRow)
|
||||
self.assertEqual(self.replaygain._track.get_title(), "Track Mode")
|
||||
self.assertEqual(self.replaygain._track.get_subtitle(),
|
||||
"Tracks have the same volume")
|
||||
self.assertFalse(self.selector._track.get_sensitive())
|
||||
self.assertFalse(self.selector._track.get_active())
|
||||
|
||||
self.selector._track.set_active(True)
|
||||
self.assertEqual(self.selector.mode, "track")
|
||||
self.assertEqual(self.replaygain._track.mode, "track")
|
||||
self.assertEqual(self.replaygain._track.group,
|
||||
self.replaygain._automatic)
|
||||
|
||||
self.replaygain._track.active = True
|
||||
self.assertEqual(self.replaygain.mode, "track")
|
||||
|
||||
def test_mode_property(self):
|
||||
"""Test that the mode property is set correctly."""
|
||||
self.selector.mode = "album"
|
||||
self.assertTrue(self.selector._album.get_active())
|
||||
self.assertFalse(self.selector._auto.get_active())
|
||||
self.assertFalse(self.selector._track.get_active())
|
||||
self.replaygain.mode = "album"
|
||||
self.assertTrue(self.replaygain._album.active)
|
||||
self.assertFalse(self.replaygain._automatic.active)
|
||||
self.assertFalse(self.replaygain._track.active)
|
||||
|
||||
self.selector.mode = "track"
|
||||
self.assertTrue(self.selector._track.get_active())
|
||||
self.assertFalse(self.selector._auto.get_active())
|
||||
self.assertFalse(self.selector._album.get_active())
|
||||
self.replaygain.mode = "track"
|
||||
self.assertTrue(self.replaygain._track.active)
|
||||
self.assertFalse(self.replaygain._automatic.active)
|
||||
self.assertFalse(self.replaygain._album.active)
|
||||
|
||||
self.selector.mode = "anything else"
|
||||
self.assertTrue(self.selector._auto.get_active())
|
||||
self.assertFalse(self.selector._album.get_active())
|
||||
self.assertFalse(self.selector._track.get_active())
|
||||
self.assertEqual(self.selector.mode, "auto")
|
||||
self.replaygain.mode = "anything else"
|
||||
self.assertTrue(self.replaygain._automatic.active)
|
||||
self.assertFalse(self.replaygain._album.active)
|
||||
self.assertFalse(self.replaygain._track.active)
|
||||
self.assertEqual(self.replaygain.mode, "auto")
|
||||
|
|
Loading…
Reference in New Issue