From e73b6c09e784af800c20e6c8b55a836db94b18f2 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Mon, 23 Oct 2023 15:23:25 -0400 Subject: [PATCH] layout: Add a "wide-view" breakpoint We un-collapse the sidebar when we detect that we have a wide enough window. Signed-off-by: Anna Schumaker --- emmental/layout.py | 16 ++++++++++++++++ emmental/window.py | 3 +++ tests/test_layout.py | 22 ++++++++++++++++++++++ tests/test_window.py | 7 +++++++ 4 files changed, 48 insertions(+) diff --git a/emmental/layout.py b/emmental/layout.py index 8e10f8b..501f80c 100644 --- a/emmental/layout.py +++ b/emmental/layout.py @@ -5,6 +5,9 @@ from gi.repository import Gtk from gi.repository import Adw +MIN_WIDTH = Adw.BreakpointConditionLengthType.MIN_WIDTH + + class Layout(Adw.Bin): """A widget that can rearrange based on window dimensions.""" @@ -26,6 +29,14 @@ class Layout(Adw.Bin): self.bind_property("wide-view", self._split_view, "collapsed", GObject.BindingFlags.INVERT_BOOLEAN) + def __define_breakpoint(self, property: str, value: bool, + length: int) -> Adw.Breakpoint: + condition = Adw.BreakpointCondition.new_length(MIN_WIDTH, length, + Adw.LengthUnit.SP) + breakpoint = Adw.Breakpoint.new(condition) + breakpoint.add_setter(self, property, GObject.Value(bool, value)) + return breakpoint + @GObject.Property(type=Gtk.Widget) def content(self) -> Gtk.Widget: """Get the content widget for the Layout.""" @@ -43,3 +54,8 @@ class Layout(Adw.Bin): @sidebar.setter def sidebar(self, widget: Gtk.Widget) -> None: self._split_view.props.sidebar = widget + + @property + def breakpoints(self) -> list[Adw.Breakpoint]: + """Get a list of breakpoints supported by the layout.""" + return [self.__define_breakpoint("wide-view", True, 1000)] diff --git a/emmental/window.py b/emmental/window.py index 741f301..5b14c28 100644 --- a/emmental/window.py +++ b/emmental/window.py @@ -66,6 +66,9 @@ class Window(Adw.Window): self.connect("notify::focus-widget", self.__notify_focus_widget) + for breakpoint in self._layout.breakpoints: + self.add_breakpoint(breakpoint) + self._box.append(self._header) self._box.append(self._toast) self.set_content(self._box) diff --git a/tests/test_layout.py b/tests/test_layout.py index f4789ef..6d44a5e 100644 --- a/tests/test_layout.py +++ b/tests/test_layout.py @@ -13,6 +13,11 @@ class TestLayout(unittest.TestCase): """Set up common variables.""" self.layout = emmental.layout.Layout() + def test_constants(self): + """Check constant variables.""" + self.assertEqual(emmental.layout.MIN_WIDTH, + Adw.BreakpointConditionLengthType.MIN_WIDTH) + def test_init(self): """Check that the layout is set up properly.""" self.assertIsInstance(self.layout, Adw.Bin) @@ -63,3 +68,20 @@ class TestLayout(unittest.TestCase): self.layout._split_view.props.show_sidebar = False self.assertFalse(self.layout.show_sidebar) + + @unittest.mock.patch("gi.repository.Adw.Breakpoint.add_setter") + def test_breakpoints(self, mock_add_setter: unittest.mock.Mock): + """Test the layout breakpoints property.""" + points = self.layout.breakpoints + self.assertEqual(len(points), 1) + + self.assertIsInstance(points[0], Adw.Breakpoint) + condition = points[0].props.condition + self.assertIsInstance(condition, Adw.BreakpointCondition) + self.assertEqual(condition.to_string(), "min-width: 1000sp") + + mock_add_setter.assert_called_once() + args = mock_add_setter.mock_calls[0].args + self.assertEqual(args[0], self.layout) + self.assertEqual(args[1], "wide-view") + self.assertTrue(args[2].get_boolean()) diff --git a/tests/test_window.py b/tests/test_window.py index eb5f70b..ad19693 100644 --- a/tests/test_window.py +++ b/tests/test_window.py @@ -166,3 +166,10 @@ class TestWindow(unittest.TestCase): self.assertEqual(accels[0].name, "reset-focus") self.assertEqual(accels[0].func, self.window.set_focus) self.assertListEqual(accels[0].accels, ["Escape"]) + + @unittest.mock.patch("emmental.window.Window.add_breakpoint") + def test_breakpoints(self, mock_add_breakpoint: unittest.mock.Mock): + """Test that the Window breakpoints are set up properly.""" + window2 = emmental.window.Window(version="1.2.3") + self.assertEqual(len(mock_add_breakpoint.mock_calls), + len(window2._layout.breakpoints))