audio: Create a menu button with volume controls

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-07-17 14:54:48 -04:00
parent c844aba318
commit 1c6357a073
2 changed files with 112 additions and 0 deletions

47
audio/menu.py Normal file
View File

@ -0,0 +1,47 @@
# Copyright 2021 (c) Anna Schumaker.
from lib import settings
from gi.repository import Gtk
class Button(Gtk.MenuButton):
def __init__(self):
Gtk.MenuButton.__init__(self)
settings.initialize("audio.volume", 1.0)
self.vol_img = Gtk.Image()
self.volume = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL,
0.0, 1.0, 0.05)
self.volume.connect("value-changed", self.on_volume_changed)
self.volume.set_value(settings.get_float("audio.volume"))
self.volume.set_format_value_func(self.format_volume)
self.volume.set_draw_value(True)
self.on_volume_changed(self.volume)
self.grid = Gtk.Grid()
self.grid.attach(self.vol_img, 0, 1, 1, 1)
self.grid.attach(self.volume, 1, 1, 1, 1)
self.grid.add_css_class("large-icons")
self.grid.set_column_spacing(5)
self.popover = Gtk.Popover()
self.popover.set_child(self.grid)
self.set_popover(self.popover)
self.add_css_class("normal-icons")
def format_volume(self, scale, value):
return f"{int(value*100)}%"
def get_volume(self):
return self.volume.get_value()
def on_volume_changed(self, scale):
value = scale.get_value()
settings.set("audio.volume", value)
if value == 0:
self.vol_img.set_from_icon_name("audio-volume-muted-symbolic")
elif value < 1/3:
self.vol_img.set_from_icon_name("audio-volume-low-symbolic")
elif value < 2/3:
self.vol_img.set_from_icon_name("audio-volume-medium-symbolic")
else:
self.vol_img.set_from_icon_name("audio-volume-high-symbolic")

65
audio/test_menu.py Normal file
View File

@ -0,0 +1,65 @@
# Copyright 2021 (c) Anna Schumaker.
from . import menu
from lib import settings
from gi.repository import Gtk
import unittest
class TestAudioMenu(unittest.TestCase):
def setUp(self):
settings.reset()
def test_audio_menu_init(self):
button = menu.Button()
self.assertIsInstance(button, Gtk.MenuButton)
self.assertIsInstance(button.popover, Gtk.Popover)
self.assertIsInstance(button.grid, Gtk.Grid)
self.assertTrue(button.has_css_class("normal-icons"))
self.assertTrue(button.grid.has_css_class("large-icons"))
self.assertEqual(button.grid.get_column_spacing(), 5)
self.assertEqual(button.get_popover(), button.popover)
self.assertEqual(button.popover.get_child(), button.grid)
def test_audio_menu_volume_init(self):
button = menu.Button()
adjustment = button.volume.get_adjustment()
self.assertIsInstance(button.vol_img, Gtk.Image)
self.assertIsInstance(button.volume, Gtk.Scale)
self.assertTrue(button.volume.get_draw_value())
self.assertEqual(settings.get_float("audio.volume"), 1.0)
self.assertEqual(adjustment.get_lower(), 0.0)
self.assertEqual(adjustment.get_upper(), 1.0)
self.assertEqual(adjustment.get_step_increment(), 0.05)
self.assertEqual(adjustment.get_value(), 1.0)
self.assertEqual(button.vol_img.get_icon_name(), "audio-volume-high-symbolic")
self.assertIn(button.vol_img, button.grid)
self.assertIn(button.volume, button.grid)
def test_audio_menu_volume(self):
button = menu.Button()
button.volume.set_value(0)
self.assertEqual(button.vol_img.get_icon_name(), "audio-volume-muted-symbolic")
self.assertEqual(settings.get("audio.volume"), "0.0")
self.assertEqual(button.get_volume(), 0.0)
button.volume.set_value(0.3)
self.assertEqual(button.vol_img.get_icon_name(), "audio-volume-low-symbolic")
self.assertEqual(settings.get("audio.volume"), "0.3")
self.assertEqual(button.get_volume(), 0.3)
button.volume.set_value(0.6)
self.assertEqual(button.vol_img.get_icon_name(), "audio-volume-medium-symbolic")
self.assertEqual(settings.get("audio.volume"), "0.6")
self.assertEqual(button.get_volume(), 0.6)
button.volume.set_value(0.9)
self.assertEqual(button.vol_img.get_icon_name(), "audio-volume-high-symbolic")
self.assertEqual(settings.get("audio.volume"), "0.9")
self.assertEqual(button.get_volume(), 0.9)