gtk: Create a Sidebar for selecting xfstests runs

I plan to have a few different ways to view and select xfstests runs, so
I use an Gtk.Stack() and Gtk.StackSwitcher() to animate switching
between the different sidebar pages.

Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
This commit is contained in:
Anna Schumaker 2023-11-03 15:39:23 -04:00
parent 704eb08091
commit 521c96b432
5 changed files with 98 additions and 0 deletions

View File

@ -166,3 +166,67 @@ class TestCalendarView(unittest.TestCase):
self.assertEqual(self.sidebar.runid, 0)
self.sidebar._view.runid = 42
self.assertEqual(self.sidebar.runid, 42)
class TestSidebar(unittest.TestCase):
"""Test the Sidebar class."""
def setUp(self):
"""Set up common variables."""
self.xfstestsdb = xfstestsdb.Command()
self.sidebar = xfstestsdb.gtk.sidebar.Sidebar(self.xfstestsdb.sql)
def test_init(self):
"""Test taht the sidebar was set up properly."""
self.assertIsInstance(self.sidebar, Gtk.Box)
self.assertEqual(self.sidebar.props.orientation,
Gtk.Orientation.VERTICAL)
self.assertEqual(self.sidebar.sql, self.xfstestsdb.sql)
def test_stack_switcher(self):
"""Test the Gtk.StackSwitcher."""
self.assertIsInstance(self.sidebar._switcher, Gtk.StackSwitcher)
self.assertEqual(self.sidebar._switcher.props.stack,
self.sidebar._stack)
self.assertTrue(self.sidebar._switcher.has_css_class("large-icons"))
self.assertEqual(self.sidebar._switcher.props.margin_top, 6)
self.assertEqual(self.sidebar._switcher.props.margin_bottom, 6)
self.assertEqual(self.sidebar._switcher.props.margin_start, 80)
self.assertEqual(self.sidebar._switcher.props.margin_end, 80)
self.assertEqual(self.sidebar.get_first_child(),
self.sidebar._switcher)
def test_separator(self):
"""Test the Gtk.Separator between sidebar widgets."""
sep = self.sidebar._switcher.get_next_sibling()
self.assertIsInstance(sep, Gtk.Separator)
self.assertEqual(sep.props.orientation, Gtk.Orientation.HORIZONTAL)
self.assertEqual(sep.get_next_sibling(), self.sidebar._stack)
def test_stack(self):
"""Test the Gtk.Stack."""
self.assertIsInstance(self.sidebar._stack, Gtk.Stack)
self.assertEqual(self.sidebar._stack.props.transition_type,
Gtk.StackTransitionType.OVER_LEFT_RIGHT)
self.assertEqual(self.sidebar.get_last_child(), self.sidebar._stack)
def test_calendar_page(self):
"""Test the Sidebar calendar view page."""
self.assertIsInstance(self.sidebar._calendar,
xfstestsdb.gtk.sidebar.CalendarView)
self.assertEqual(self.sidebar._calendar.sql, self.xfstestsdb.sql)
self.assertEqual(self.sidebar._stack.get_child_by_name("calendar"),
self.sidebar._calendar)
page = self.sidebar._stack.get_page(self.sidebar._calendar)
self.assertEqual(page.props.title, "Calendar")
self.assertEqual(page.props.icon_name, "month-symbolic")
def test_runid(self):
"""Test the runid property."""
self.assertEqual(self.sidebar.runid, 0)
self.sidebar._calendar.runid = 1
self.assertEqual(self.sidebar.runid, 1)

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 3.042969 1 c -1.128907 0 -2.042969 0.914062 -2.042969 2.042969 v 9.875 c 0 1.132812 0.914062 2.042969 2.042969 2.042969 h 9.914062 c 1.128907 0 2.042969 -0.910157 2.042969 -2.042969 v -9.875 c 0 -1.128907 -0.914062 -2.042969 -2.042969 -2.042969 z m -0.042969 4.960938 h 10 v 7 h -10 z m 1 1.039062 v 2 h 2 v -2 z m 3 0 v 2 h 2 v -2 z m 3 0 v 2 h 2 v -2 z m -6 3 v 2 h 2 v -2 z m 3 0 v 2 h 2 v -2 z m 0 0"/></svg>

After

Width:  |  Height:  |  Size: 550 B

View File

@ -5,5 +5,6 @@
<file preprocess="xml-stripblanks">test-skip-symbolic.svg</file>
<file preprocess="xml-stripblanks">test-fail-symbolic.svg</file>
<file preprocess="xml-stripblanks">down-large-symbolic.svg</file>
<file preprocess="xml-stripblanks">month-symbolic.svg</file>
</gresource>
</gresources>

View File

@ -95,3 +95,34 @@ class CalendarView(Gtk.Box):
min, max).fetchall():
ts = datetime.datetime.fromisoformat(stamp['timestamp'])
self._calendar.mark_day(ts.day)
class Sidebar(Gtk.Box):
"""Our sidebar for seleting an xfstests run."""
runid = GObject.Property(type=int)
sql = GObject.Property(type=GObject.TYPE_PYOBJECT)
def __init__(self, sql: sqlite.Connection) -> None:
"""Initialize a CalendarView instance."""
animation = Gtk.StackTransitionType.OVER_LEFT_RIGHT
super().__init__(sql=sql, orientation=Gtk.Orientation.VERTICAL)
self._stack = Gtk.Stack(transition_type=animation)
self._switcher = Gtk.StackSwitcher(stack=self._stack,
margin_top=6, margin_bottom=6,
margin_start=80, margin_end=80)
self._calendar = CalendarView(sql)
self._calendar.bind_property("runid", self, "runid")
self.__add_page(self._calendar, "Calendar", "month-symbolic")
self._switcher.add_css_class("large-icons")
self.append(self._switcher)
self.append(Gtk.Separator())
self.append(self._stack)
def __add_page(self, page: Gtk.Widget, title: str, icon: str) -> None:
pg = self._stack.add_titled(page, title.lower(), title)
pg.set_icon_name(icon)