diff --git a/tests/gtk/test_button.py b/tests/gtk/test_button.py new file mode 100644 index 0000000..4b67086 --- /dev/null +++ b/tests/gtk/test_button.py @@ -0,0 +1,51 @@ +# Copyright 2023 (c) Anna Schumaker. +"""Tests our custom button classes.""" +import unittest +import xfstestsdb.gtk.button +from gi.repository import Gtk + + +class TestStatusToggle(unittest.TestCase): + """Test our StatusToggle button.""" + + def setUp(self): + """Set up common variables.""" + self.button = xfstestsdb.gtk.button.StatusToggle("icon-name", + "css-class") + + def test_button(self): + """Test the StatusToggle button.""" + self.assertIsInstance(self.button, Gtk.Button) + self.assertEqual(self.button.icon_name, "icon-name") + self.assertTrue(self.button.has_css_class("css-class")) + + self.assertFalse(self.button.props.has_frame) + self.assertFalse(self.button.active) + + button2 = xfstestsdb.gtk.button.StatusToggle("icon-name", "css-class", + active=True) + self.assertTrue(button2.active) + self.assertAlmostEqual(button2.props.child.props.opacity, 1.0) + + def test_image(self): + """Test that the image is set up correctly, and opacity changes.""" + self.assertIsInstance(self.button.props.child, Gtk.Image) + self.assertEqual(self.button.props.child.props.icon_name, "icon-name") + + self.button.active = True + self.assertAlmostEqual(self.button.props.child.props.opacity, 1.0) + self.button.active = False + self.assertAlmostEqual(self.button.props.child.props.opacity, 0.4) + + def test_clicked(self): + """Test clicking the CSSToggle button.""" + self.assertFalse(self.button.active) + self.assertAlmostEqual(self.button.props.child.props.opacity, 0.4) + + self.button.emit("clicked") + self.assertTrue(self.button.active) + self.assertAlmostEqual(self.button.props.child.props.opacity, 1.0) + + self.button.emit("clicked") + self.assertFalse(self.button.active) + self.assertAlmostEqual(self.button.props.child.props.opacity, 0.4) diff --git a/xfstestsdb/gtk/button.py b/xfstestsdb/gtk/button.py new file mode 100644 index 0000000..6de08fc --- /dev/null +++ b/xfstestsdb/gtk/button.py @@ -0,0 +1,29 @@ +# Copyright 2023 (c) Anna Schumaker. +"""Custom, reusable Button classes.""" +import typing +from gi.repository import GObject +from gi.repository import Gtk + + +class StatusToggle(Gtk.Button): + """A toggle button that adds or removes a CSS class when pressed.""" + + active = GObject.Property(type=bool, default=False) + icon_name = GObject.Property(type=str) + + def __init__(self, icon_name: str, css_class: str, + *, active: bool = False): + """Initialize a StatusToggle button.""" + super().__init__(icon_name=icon_name, has_frame=False, + child=Gtk.Image(icon_name=icon_name, opacity=0.4)) + self.connect("notify::active", self.__notify_active) + self.add_css_class(css_class) + self.active = active + + def __notify_active(self, toggle: typing.Self, + param: GObject.ParamSpec) -> None: + self.props.child.set_opacity(1.0 if self.active else 0.4) + + def do_clicked(self) -> None: + """Adjust image opacity when the button is toggled.""" + self.active = not self.active