From d9df10fe109b476e51dbe5741f5012c36a59b489 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sat, 12 Jul 2014 17:30:33 +0200 Subject: [PATCH] canvas::Layout: keep user provided size hints. Don't let size hints layouted or calculated by Nasal widgets override user provided hints. --- simgear/canvas/layout/LayoutItem.cxx | 2 +- simgear/canvas/layout/LayoutItem.hxx | 1 + simgear/canvas/layout/NasalWidget.cxx | 72 +++++++++++++++++--- simgear/canvas/layout/NasalWidget.hxx | 28 ++++++++ simgear/canvas/layout/canvas_layout_test.cxx | 36 +++++++++- 5 files changed, 125 insertions(+), 14 deletions(-) diff --git a/simgear/canvas/layout/LayoutItem.cxx b/simgear/canvas/layout/LayoutItem.cxx index 5de51ce3..7c2e180b 100644 --- a/simgear/canvas/layout/LayoutItem.cxx +++ b/simgear/canvas/layout/LayoutItem.cxx @@ -29,7 +29,7 @@ namespace canvas //---------------------------------------------------------------------------- LayoutItem::LayoutItem(): _flags(0), - _size_hint(16, 16), + _size_hint(0, 0), _min_size(0, 0), _max_size(MAX_SIZE) { diff --git a/simgear/canvas/layout/LayoutItem.hxx b/simgear/canvas/layout/LayoutItem.hxx index f950605d..bd3fb70c 100644 --- a/simgear/canvas/layout/LayoutItem.hxx +++ b/simgear/canvas/layout/LayoutItem.hxx @@ -43,6 +43,7 @@ namespace canvas { public: + /** Maximum item size (indicating no limit) */ static const SGVec2i MAX_SIZE; LayoutItem(); diff --git a/simgear/canvas/layout/NasalWidget.cxx b/simgear/canvas/layout/NasalWidget.cxx index 6f5d5a1d..d3feb9b4 100644 --- a/simgear/canvas/layout/NasalWidget.cxx +++ b/simgear/canvas/layout/NasalWidget.cxx @@ -28,7 +28,13 @@ namespace canvas //---------------------------------------------------------------------------- NasalWidget::NasalWidget(naRef impl): - Object(impl) + Object(impl), + _layout_size_hint(32, 32), + _layout_min_size(16, 16), + _layout_max_size(MAX_SIZE), + _user_size_hint(0, 0), + _user_min_size(0, 0), + _user_max_size(MAX_SIZE) { } @@ -121,10 +127,10 @@ namespace canvas //---------------------------------------------------------------------------- void NasalWidget::setSizeHint(const SGVec2i& s) { - if( _size_hint == s ) + if( _user_size_hint == s ) return; - _size_hint = s; + _user_size_hint = s; // TODO just invalidate size_hint? Probably not a performance issue... invalidate(); @@ -133,20 +139,50 @@ namespace canvas //---------------------------------------------------------------------------- void NasalWidget::setMinimumSize(const SGVec2i& s) { - if( _min_size == s ) + if( _user_min_size == s ) return; - _min_size = s; + _user_min_size = s; invalidate(); } //---------------------------------------------------------------------------- void NasalWidget::setMaximumSize(const SGVec2i& s) { - if( _max_size == s ) + if( _user_max_size == s ) return; - _max_size = s; + _user_max_size = s; + invalidate(); + } + + //---------------------------------------------------------------------------- + void NasalWidget::setLayoutSizeHint(const SGVec2i& s) + { + if( _layout_size_hint == s ) + return; + + _layout_size_hint = s; + invalidate(); + } + + //---------------------------------------------------------------------------- + void NasalWidget::setLayoutMinimumSize(const SGVec2i& s) + { + if( _layout_min_size == s ) + return; + + _layout_min_size = s; + invalidate(); + } + + //---------------------------------------------------------------------------- + void NasalWidget::setLayoutMaximumSize(const SGVec2i& s) + { + if( _layout_max_size == s ) + return; + + _layout_max_size = s; invalidate(); } @@ -192,7 +228,10 @@ namespace canvas .method("setHeightForWidthFunc", &NasalWidget::setHeightForWidthFunc) .method("setSizeHint", &NasalWidget::setSizeHint) .method("setMinimumSize", &NasalWidget::setMinimumSize) - .method("setMaximumSize", &NasalWidget::setMaximumSize); + .method("setMaximumSize", &NasalWidget::setMaximumSize) + .method("setLayoutSizeHint", &NasalWidget::setLayoutSizeHint) + .method("setLayoutMinimumSize", &NasalWidget::setLayoutMinimumSize) + .method("setLayoutMaximumSize", &NasalWidget::setLayoutMaximumSize); nasal::Hash widget_hash = ns.createHash("Widget"); widget_hash.set("new", &f_makeNasalWidget); @@ -226,19 +265,30 @@ namespace canvas //---------------------------------------------------------------------------- SGVec2i NasalWidget::sizeHintImpl() const { - return _size_hint; + return SGVec2i( + _user_size_hint.x() > 0 ? _user_size_hint.x() : _layout_size_hint.x(), + _user_size_hint.y() > 0 ? _user_size_hint.y() : _layout_size_hint.y() + ); } //---------------------------------------------------------------------------- SGVec2i NasalWidget::minimumSizeImpl() const { - return _min_size; + return SGVec2i( + _user_min_size.x() > 0 ? _user_min_size.x() : _layout_min_size.x(), + _user_min_size.y() > 0 ? _user_min_size.y() : _layout_min_size.y() + ); } //---------------------------------------------------------------------------- SGVec2i NasalWidget::maximumSizeImpl() const { - return _max_size; + return SGVec2i( + _user_max_size.x() < MAX_SIZE.x() ? _user_max_size.x() + : _layout_max_size.x(), + _user_max_size.y() < MAX_SIZE.y() ? _user_max_size.y() + : _layout_max_size.y() + ); } } // namespace canvas diff --git a/simgear/canvas/layout/NasalWidget.hxx b/simgear/canvas/layout/NasalWidget.hxx index c763953e..a55fa228 100644 --- a/simgear/canvas/layout/NasalWidget.hxx +++ b/simgear/canvas/layout/NasalWidget.hxx @@ -59,10 +59,31 @@ namespace canvas void setHeightForWidthFunc(const HeightForWidthFunc& func); void setMinimumHeightForWidthFunc(const HeightForWidthFunc& func); + /** Set size hint. + * + * Overrides default size hint. Set to (0, 0) to fall back to default size + * hint. + */ void setSizeHint(const SGVec2i& s); + + /** Set minimum size. + * + * Overrides default minimum size. Set to (0, 0) to fall back to default + * minimum size. + */ void setMinimumSize(const SGVec2i& s); + + /** Set maximum size. + * + * Overrides default maximum size hint. Set to LayoutItem::MAX_SIZE to + * fall back to default maximum size. + */ void setMaximumSize(const SGVec2i& s); + void setLayoutSizeHint(const SGVec2i& s); + void setLayoutMinimumSize(const SGVec2i& s); + void setLayoutMaximumSize(const SGVec2i& s); + virtual bool hasHeightForWidth() const; virtual int heightForWidth(int w) const; virtual int minimumHeightForWidth(int w) const; @@ -83,6 +104,13 @@ namespace canvas HeightForWidthFunc _height_for_width, _min_height_for_width; + SGVec2i _layout_size_hint, + _layout_min_size, + _layout_max_size, + _user_size_hint, + _user_min_size, + _user_max_size; + int callHeightForWidthFunc( const HeightForWidthFunc& hfw, int w ) const; diff --git a/simgear/canvas/layout/canvas_layout_test.cxx b/simgear/canvas/layout/canvas_layout_test.cxx index 1077d30d..0b59daca 100644 --- a/simgear/canvas/layout/canvas_layout_test.cxx +++ b/simgear/canvas/layout/canvas_layout_test.cxx @@ -409,12 +409,44 @@ BOOST_AUTO_TEST_CASE( boxlayout_hfw ) } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE( nasal_layout ) +BOOST_AUTO_TEST_CASE( nasal_widget ) { naContext c = naNewContext(); naRef me = naNewHash(c); - sc::LayoutItemRef nasal_item( new sc::NasalWidget(me) ); + sc::NasalWidgetRef w( new sc::NasalWidget(me) ); + + // Default layout sizes (no user set values) + BOOST_CHECK_EQUAL(w->minimumSize(), SGVec2i(16, 16)); + BOOST_CHECK_EQUAL(w->sizeHint(), SGVec2i(32, 32)); + BOOST_CHECK_EQUAL(w->maximumSize(), sc::LayoutItem::MAX_SIZE); + + // Changed layout sizes + w->setLayoutMinimumSize( SGVec2i(2, 12) ); + w->setLayoutSizeHint( SGVec2i(3, 13) ); + w->setLayoutMaximumSize( SGVec2i(4, 14) ); + + BOOST_CHECK_EQUAL(w->minimumSize(), SGVec2i(2, 12)); + BOOST_CHECK_EQUAL(w->sizeHint(), SGVec2i(3, 13)); + BOOST_CHECK_EQUAL(w->maximumSize(), SGVec2i(4, 14)); + + // User set values (overwrite layout sizes) + w->setMinimumSize( SGVec2i(15, 16) ); + w->setSizeHint( SGVec2i(17, 18) ); + w->setMaximumSize( SGVec2i(19, 20) ); + + BOOST_CHECK_EQUAL(w->minimumSize(), SGVec2i(15, 16)); + BOOST_CHECK_EQUAL(w->sizeHint(), SGVec2i(17, 18)); + BOOST_CHECK_EQUAL(w->maximumSize(), SGVec2i(19, 20)); + + // Only vertical user set values (layout/default for horizontal hints) + w->setMinimumSize( SGVec2i(0, 21) ); + w->setSizeHint( SGVec2i(0, 22) ); + w->setMaximumSize( SGVec2i(SGLimits::max(), 23) ); + + BOOST_CHECK_EQUAL(w->minimumSize(), SGVec2i(2, 21)); + BOOST_CHECK_EQUAL(w->sizeHint(), SGVec2i(3, 22)); + BOOST_CHECK_EQUAL(w->maximumSize(), SGVec2i(4, 23)); naFreeContext(c); } -- 2.39.5