layout: Create an adaptable Layout widget

I'm planning to build on this widget over the next several releases.
It'll eventually be fully adaptable to window size changes made by the
user.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-10-23 11:48:28 -04:00
parent 29693dcf84
commit d22a9b23a1
2 changed files with 110 additions and 0 deletions

45
emmental/layout.py Normal file
View File

@ -0,0 +1,45 @@
# Copyright 2023 (c) Anna Schumaker.
"""Our adaptable layout that can rearrange widgets as the window is resized."""
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Adw
class Layout(Adw.Bin):
"""A widget that can rearrange based on window dimensions."""
show_sidebar = GObject.Property(type=bool, default=False)
wide_view = GObject.Property(type=bool, default=False)
def __init__(self, *, content: Gtk.Widget = None,
sidebar: Gtk.Widget = None):
"""Initialize our Layout widget."""
super().__init__()
self._split_view = Adw.OverlaySplitView(content=content,
sidebar=sidebar,
collapsed=not self.wide_view)
self.props.child = self._split_view
self.bind_property("show-sidebar", self._split_view, "show-sidebar",
GObject.BindingFlags.BIDIRECTIONAL)
self.bind_property("wide-view", self._split_view, "collapsed",
GObject.BindingFlags.INVERT_BOOLEAN)
@GObject.Property(type=Gtk.Widget)
def content(self) -> Gtk.Widget:
"""Get the content widget for the Layout."""
return self._split_view.props.content
@content.setter
def content(self, widget: Gtk.Widget) -> None:
self._split_view.props.content = widget
@GObject.Property(type=Gtk.Widget)
def sidebar(self) -> Gtk.Widget:
"""Get the sidebar widget for the Layout."""
return self._split_view.props.sidebar
@sidebar.setter
def sidebar(self, widget: Gtk.Widget) -> None:
self._split_view.props.sidebar = widget

65
tests/test_layout.py Normal file
View File

@ -0,0 +1,65 @@
# Copyright 2023 (c) Anna Schumaker.
"""Tests our adaptable layout widget."""
import unittest
import emmental.layout
from gi.repository import Gtk
from gi.repository import Adw
class TestLayout(unittest.TestCase):
"""Test case for our adaptable layout."""
def setUp(self):
"""Set up common variables."""
self.layout = emmental.layout.Layout()
def test_init(self):
"""Check that the layout is set up properly."""
self.assertIsInstance(self.layout, Adw.Bin)
self.assertIsInstance(self.layout._split_view, Adw.OverlaySplitView)
self.assertTrue(self.layout._split_view.props.collapsed)
def test_wide_view(self):
"""Test the layout when we have a wide window."""
self.assertFalse(self.layout.wide_view)
self.assertEqual(self.layout.props.child, self.layout._split_view)
self.layout.wide_view = True
self.assertFalse(self.layout._split_view.props.collapsed)
def test_content(self):
"""Test the content widget property."""
self.assertIsNone(self.layout.content)
widget = Gtk.Label()
self.layout.content = widget
self.assertEqual(self.layout._split_view.props.content, widget)
self.assertEqual(self.layout.content, widget)
widget2 = Gtk.Label()
layout2 = emmental.layout.Layout(content=widget2)
self.assertEqual(layout2.content, widget2)
def test_sidebar(self):
"""Test the sidebar widget property."""
self.assertIsNone(self.layout.sidebar)
widget = Gtk.Label()
self.layout.sidebar = widget
self.assertEqual(self.layout._split_view.props.sidebar, widget)
self.assertEqual(self.layout.sidebar, widget)
widget2 = Gtk.Label()
layout2 = emmental.layout.Layout(sidebar=widget2)
self.assertEqual(layout2.sidebar, widget2)
def test_show_sidebar(self):
"""Test the show-sidebar property."""
self.assertFalse(self.layout.show_sidebar)
self.assertFalse(self.layout._split_view.props.show_sidebar)
self.layout.show_sidebar = True
self.assertTrue(self.layout._split_view.props.show_sidebar)
self.layout._split_view.props.show_sidebar = False
self.assertFalse(self.layout.show_sidebar)