buttons: Create an ImageToggle button
This button is inspired by the Gtk.ToggleButton button, except it changes the displayed icon when active. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
f85cdb5b49
commit
011dbd114b
|
@ -78,3 +78,37 @@ class SplitButton(Gtk.Box):
|
||||||
@GObject.Signal
|
@GObject.Signal
|
||||||
def clicked(self) -> None:
|
def clicked(self) -> None:
|
||||||
"""Signal that the primary button has been clicked."""
|
"""Signal that the primary button has been clicked."""
|
||||||
|
|
||||||
|
|
||||||
|
class ImageToggle(Button):
|
||||||
|
"""Inspired by a ToggleButton, but changes image based on state."""
|
||||||
|
|
||||||
|
active_icon_name = GObject.Property(type=str)
|
||||||
|
inactive_icon_name = GObject.Property(type=str)
|
||||||
|
|
||||||
|
def __init__(self, active_icon_name: str, inactive_icon_name: str,
|
||||||
|
active: bool = False, **kwargs) -> None:
|
||||||
|
"""Initialize an ImageToggle button."""
|
||||||
|
super().__init__(active_icon_name=active_icon_name,
|
||||||
|
inactive_icon_name=inactive_icon_name,
|
||||||
|
icon_name=inactive_icon_name, active=active, **kwargs)
|
||||||
|
|
||||||
|
def do_clicked(self) -> None:
|
||||||
|
"""Handle a click event."""
|
||||||
|
self.active = not self.active
|
||||||
|
|
||||||
|
@GObject.Property(type=bool, default=False)
|
||||||
|
def active(self) -> bool:
|
||||||
|
"""Get the active state."""
|
||||||
|
return self.icon_name == self.active_icon_name
|
||||||
|
|
||||||
|
@active.setter
|
||||||
|
def active(self, newval: bool) -> None:
|
||||||
|
if newval != self.active:
|
||||||
|
icon = self.active_icon_name if newval else self.inactive_icon_name
|
||||||
|
self.icon_name = icon
|
||||||
|
self.emit("toggled")
|
||||||
|
|
||||||
|
@GObject.Signal
|
||||||
|
def toggled(self) -> None:
|
||||||
|
"""Active state has been toggled."""
|
||||||
|
|
|
@ -147,3 +147,49 @@ class TestSplitButton(unittest.TestCase):
|
||||||
self.button.connect("clicked", on_click)
|
self.button.connect("clicked", on_click)
|
||||||
self.button._primary.emit("clicked")
|
self.button._primary.emit("clicked")
|
||||||
on_click.assert_called_with(self.button)
|
on_click.assert_called_with(self.button)
|
||||||
|
|
||||||
|
|
||||||
|
class TestImageToggle(unittest.TestCase):
|
||||||
|
"""Test an ImageToggle button."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Set up common variables."""
|
||||||
|
self.button = emmental.buttons.ImageToggle("active", "inactive")
|
||||||
|
|
||||||
|
def test_init(self):
|
||||||
|
"""Test that the ImageToggle button is configured correctly."""
|
||||||
|
self.assertIsInstance(self.button, emmental.buttons.Button)
|
||||||
|
self.assertEqual(self.button.active_icon_name, "active")
|
||||||
|
self.assertEqual(self.button.inactive_icon_name, "inactive")
|
||||||
|
self.assertEqual(self.button.icon_name, "inactive")
|
||||||
|
self.assertFalse(self.button.active)
|
||||||
|
|
||||||
|
def test_active(self):
|
||||||
|
"""Test the active property."""
|
||||||
|
self.button.active = True
|
||||||
|
self.assertTrue(self.button.active)
|
||||||
|
self.assertEqual(self.button.icon_name, "active")
|
||||||
|
|
||||||
|
self.button.active = False
|
||||||
|
self.assertFalse(self.button.active)
|
||||||
|
self.assertEqual(self.button.icon_name, "inactive")
|
||||||
|
|
||||||
|
button2 = emmental.buttons.ImageToggle("active", "inactive",
|
||||||
|
active=True)
|
||||||
|
self.assertTrue(button2.active)
|
||||||
|
|
||||||
|
def test_toggle(self):
|
||||||
|
"""Test the toggle signal."""
|
||||||
|
toggled = unittest.mock.Mock()
|
||||||
|
self.button.connect("toggled", toggled)
|
||||||
|
|
||||||
|
self.button.active = False
|
||||||
|
toggled.assert_not_called()
|
||||||
|
|
||||||
|
self.button.active = True
|
||||||
|
toggled.assert_called()
|
||||||
|
|
||||||
|
toggled.reset_mock()
|
||||||
|
self.button.emit("clicked")
|
||||||
|
self.assertFalse(self.button.active)
|
||||||
|
toggled.assert_called()
|
||||||
|
|
Loading…
Reference in New Issue