canvas::Layout: keep user provided size hints.

Don't let size hints layouted or calculated by Nasal widgets
override user provided hints.
This commit is contained in:
Thomas Geymayer
2014-07-12 17:30:33 +02:00
parent f1677f5546
commit d9df10fe10
5 changed files with 125 additions and 14 deletions

View File

@@ -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)
{

View File

@@ -43,6 +43,7 @@ namespace canvas
{
public:
/** Maximum item size (indicating no limit) */
static const SGVec2i MAX_SIZE;
LayoutItem();

View File

@@ -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

View File

@@ -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;

View File

@@ -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<int>::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);
}