From bb18c5953020bc87b575dacdc9b15f8e31529f87 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 26 Feb 2022 11:23:21 +0000 Subject: [PATCH] Grid: Add row/column stretch implementation Also add a basic test case for stretch behaviour. --- simgear/canvas/layout/GridLayout.cxx | 45 ++++++++++++++++++++ simgear/canvas/layout/GridLayout.hxx | 18 ++++---- simgear/canvas/layout/canvas_layout_test.cxx | 39 +++++++++++++++++ 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/simgear/canvas/layout/GridLayout.cxx b/simgear/canvas/layout/GridLayout.cxx index 76f64606..28e141a0 100644 --- a/simgear/canvas/layout/GridLayout.cxx +++ b/simgear/canvas/layout/GridLayout.cxx @@ -301,17 +301,62 @@ void GridLayout::setDimensions(const SGVec2i& dim) invalidate(); } +//---------------------------------------------------------------------------- size_t GridLayout::numRows() const { return _dimensions.y(); } +//---------------------------------------------------------------------------- size_t GridLayout::numColumns() const { return _dimensions.x(); } +//---------------------------------------------------------------------------- +void GridLayout::setRowStretch(size_t index, int stretch) +{ + if (index >= _dimensions.y()) { + throw sg_range_exception("GridLayout::setRowStretch: invalid row"); + } + + if (stretch < 0) { + throw sg_range_exception("GridLayout: negative stretch values are forbidden"); + } + + // becuase we lazily update the rows data, we'd have nowhere to store the + // new stretch value, so actively resize it now. + if (index >= _rows.size()) { + _rows.resize(_dimensions.y()); + } + + _rows[index].stretch = stretch; + invalidate(); +} + +//---------------------------------------------------------------------------- + +void GridLayout::setColumnStretch(size_t index, int stretch) +{ + if (index >= _dimensions.x()) { + throw sg_range_exception("GridLayout::setColumnStretch: invalid column"); + } + + if (stretch < 0) { + throw sg_range_exception("GridLayout: negative stretch values are forbidden"); + } + + // becuase we lazily update the columns data, we'd have nowhere to store the + // new stretch value, so actively resize it now. + if (index >= _columns.size()) { + _columns.resize(_dimensions.x()); + } + + _columns[index].stretch = stretch; + invalidate(); +} + //---------------------------------------------------------------------------- void GridLayout::updateSizeHints() const { diff --git a/simgear/canvas/layout/GridLayout.hxx b/simgear/canvas/layout/GridLayout.hxx index 15a52cba..4447d077 100755 --- a/simgear/canvas/layout/GridLayout.hxx +++ b/simgear/canvas/layout/GridLayout.hxx @@ -26,21 +26,21 @@ public: void addItem(const LayoutItemRef& item, int column, int row, int colSpan = 1, int rowSpan = 1); - virtual void addItem(const LayoutItemRef& item); + void addItem(const LayoutItemRef& item) override; - virtual size_t count() const; - virtual LayoutItemRef itemAt(size_t index); - virtual LayoutItemRef takeAt(size_t index); - virtual void clear(); + size_t count() const override; + LayoutItemRef itemAt(size_t index) override; + LayoutItemRef takeAt(size_t index) override; + void clear() override; - virtual void setSpacing(int spacing); - virtual int spacing() const; + void setSpacing(int spacing) override; + int spacing() const override; void invalidate() override; - virtual bool hasHeightForWidth() const; + bool hasHeightForWidth() const override; - virtual void setCanvas(const CanvasWeakPtr& canvas); + void setCanvas(const CanvasWeakPtr& canvas) override; void setRowStretch(size_t index, int stretch); void setColumnStretch(size_t index, int stretch); diff --git a/simgear/canvas/layout/canvas_layout_test.cxx b/simgear/canvas/layout/canvas_layout_test.cxx index 578374f9..44db5698 100644 --- a/simgear/canvas/layout/canvas_layout_test.cxx +++ b/simgear/canvas/layout/canvas_layout_test.cxx @@ -807,3 +807,42 @@ BOOST_AUTO_TEST_CASE(gridlayout_min_size_layout) BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(89, 18, 109, 78)); BOOST_CHECK_EQUAL(w4->geometry(), SGRecti(0, 100, 198, 46)); } + +//------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(gridlayout_stretch) +{ + sc::GridLayoutRef grid(new sc::GridLayout); + grid->setSpacing(4); + grid->setDimensions({3, 3}); + + TestWidgetRef w1(new TestWidget(SGVec2i(16, 16), + SGVec2i(32, 32), + SGVec2i(9999, 9999))), + w2(new TestWidget(*w1)), + w3(new TestWidget(*w1)), + w4(new TestWidget(*w1)), + w5(new TestWidget(*w1)); + + + grid->setColumnStretch(1, 1); + grid->setColumnStretch(2, 2); + + grid->setRowStretch(0, 1); + grid->setRowStretch(1, 4); + grid->setRowStretch(2, 1); + + w1->setGridSpan({1, 2}); + + grid->addItem(w1); + grid->addItem(w2, 1, 1); + grid->addItem(w3, 2, 1); + grid->addItem(w4, 0, 2, 2 /* col span */, 1); + grid->addItem(w5, 2, 0); + + grid->setGeometry(SGRecti(0, 0, 248, 224)); + + BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(0, 0, 32, 168)); + BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(36, 56, 80, 112)); + BOOST_CHECK_EQUAL(w4->geometry(), SGRecti(0, 172, 116, 52)); + BOOST_CHECK_EQUAL(w5->geometry(), SGRecti(120, 0, 128, 52)); +}