code moved to QskLayoutConstraint

This commit is contained in:
Uwe Rathmann 2019-07-12 15:24:06 +02:00
parent f53b28727f
commit a762d51099
3 changed files with 85 additions and 92 deletions

View File

@ -6,6 +6,7 @@
#include "QskLayoutConstraint.h"
#include "QskControl.h"
#include "QskSizePolicy.h"
#include "QskLayoutHint.h"
#include "QskFunctions.h"
#include <functional>
@ -129,6 +130,22 @@ QskLayoutConstraint::Type QskLayoutConstraint::constraintType( const QQuickItem*
return constraintType;
}
bool QskLayoutConstraint::isConstrained(
const QQuickItem* item, Qt::Orientation orientation )
{
switch( constraintType( item ) )
{
case QskLayoutConstraint::WidthForHeight:
return orientation == Qt::Horizontal;
case QskLayoutConstraint::HeightForWidth:
return orientation == Qt::Vertical;
default:
return false;
}
}
qreal QskLayoutConstraint::heightForWidth( const QQuickItem* item, qreal width )
{
if ( auto control = qskControlCast( item ) )
@ -186,7 +203,7 @@ qreal QskLayoutConstraint::constrainedMetric(
}
qreal QskLayoutConstraint::constrainedChildrenMetric(
Type type, const QskControl* control, qreal widthOrHeight )
Type type, const QskControl* control, qreal constraint )
{
auto constrainFunction =
( type == WidthForHeight ) ? widthForHeight : heightForWidth;
@ -200,7 +217,7 @@ qreal QskLayoutConstraint::constrainedChildrenMetric(
{
if ( !control->isTransparentForPositioner() )
{
const auto v = constrainFunction( control, widthOrHeight );
const auto v = constrainFunction( control, constraint );
if ( v > constrainedValue )
constrainedValue = v;
}
@ -460,3 +477,50 @@ QRectF QskLayoutConstraint::itemRect( const QQuickItem* item,
return qskAlignedRectF( rect, size.width(), size.height(), alignment );
}
QskLayoutHint QskLayoutConstraint::layoutHint(
const QQuickItem* item, Qt::Orientation orientation, qreal constraint )
{
if ( item == nullptr )
return QskLayoutHint();
const auto policy = sizePolicy( item ).policy( orientation );
if ( constraint >= 0.0 )
{
if ( !isConstrained( item, orientation ) )
constraint = -1.0;
}
qreal minimum, preferred, maximum;
const auto expandFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
if ( ( policy & QskSizePolicy::ShrinkFlag ) &&
( policy & expandFlags ) && ( policy & QskSizePolicy::IgnoreFlag ) )
{
// we don't need to calculate the preferred size
minimum = sizeHint( item, Qt::MinimumSize, orientation, constraint );
maximum = sizeHint( item, Qt::MaximumSize, orientation, constraint );
preferred = minimum;
}
else
{
preferred = sizeHint( item, Qt::PreferredSize, orientation, constraint );
if ( policy & QskSizePolicy::ShrinkFlag )
minimum = sizeHint( item, Qt::MinimumSize, orientation, constraint );
else
minimum = preferred;
if ( policy & expandFlags )
maximum = sizeHint( item, Qt::MaximumSize, orientation, constraint );
else
maximum = preferred;
if ( policy & QskSizePolicy::IgnoreFlag )
preferred = minimum;
}
return QskLayoutHint( minimum, preferred, maximum );
}

View File

@ -13,6 +13,7 @@
class QskSizePolicy;
class QskControl;
class QskLayoutHint;
class QQuickItem;
class QSizeF;
class QRectF;
@ -33,17 +34,18 @@ namespace QskLayoutConstraint
QSK_EXPORT qreal widthForHeight( const QQuickItem*, qreal height );
QSK_EXPORT Type constraintType( const QQuickItem* );
QSK_EXPORT bool isConstrained( const QQuickItem*, Qt::Orientation );
QSK_EXPORT qreal constrainedMetric(
Type, const QskControl*, qreal value,
std::function< qreal( Type, const QskControl*, qreal ) > );
QSK_EXPORT qreal constrainedChildrenMetric( Type, const QskControl*, qreal width );
QSK_EXPORT qreal constrainedChildrenMetric(
Type, const QskControl*, qreal constraint );
QSK_EXPORT QSizeF effectiveConstraint( const QQuickItem*, Qt::SizeHint );
QSK_EXPORT QskSizePolicy sizePolicy( const QQuickItem* );
// bounded by Qt::MinimumSize/Qt::MaximumSize
QSK_EXPORT QSizeF boundedSize( const QQuickItem*, const QSizeF& );
QSK_EXPORT QSizeF adjustedSize( const QQuickItem*, const QSizeF& );
@ -56,7 +58,9 @@ namespace QskLayoutConstraint
QSK_EXPORT QRectF itemRect(
const QQuickItem*, const QRectF&, Qt::Alignment );
// QGridLayoutEngine internally uses FLT_MAX
QSK_EXPORT QskLayoutHint layoutHint(
const QQuickItem*, Qt::Orientation, qreal constraint );
const qreal unlimited = std::numeric_limits< float >::max();
}

View File

@ -53,7 +53,6 @@ namespace
EntryData& operator=( const EntryData& );
bool isIgnored() const;
bool isConstrained( Qt::Orientation ) const;
qreal spacer() const { return m_isSpacer ? m_spacer : -1.0; }
QQuickItem* item() const { return m_isSpacer ? nullptr : m_item; }
@ -200,24 +199,6 @@ bool EntryData::isIgnored() const
return false;
}
bool EntryData::isConstrained( Qt::Orientation orientation ) const
{
if ( m_isSpacer )
return false;
switch( QskLayoutConstraint::constraintType( m_item ) )
{
case QskLayoutConstraint::WidthForHeight:
return orientation == Qt::Horizontal;
case QskLayoutConstraint::HeightForWidth:
return orientation == Qt::Vertical;
default:
return false;
}
}
EntryTable::EntryTable( Qt::Orientation orientation, uint dimension )
: m_dimension( dimension )
, m_sumIgnored( -1 )
@ -496,95 +477,39 @@ QskLayoutConstraint::Type EntryTable::constraintType() const
QskLayoutChain::Cell EntryTable::cell( const EntryData& entry,
Qt::Orientation orientation, qreal constraint ) const
{
int stretch = 0;
bool canGrow = true;
qreal minimum, preferred, maximum;
QskLayoutChain::Cell cell;
cell.canGrow = true;
if ( const auto item = entry.item() )
{
cell.hint = QskLayoutConstraint::layoutHint( item, orientation, constraint );
const auto policy = QskLayoutConstraint::sizePolicy( item ).policy( orientation );
if ( constraint >= 0.0 )
{
if ( !entry.isConstrained( orientation ) )
constraint = -1.0;
}
const auto expandFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
if ( ( policy & QskSizePolicy::ShrinkFlag ) &&
( policy & expandFlags ) && ( policy & QskSizePolicy::IgnoreFlag ) )
{
// we don't need to calculate the preferred size
minimum = QskLayoutConstraint::sizeHint(
item, Qt::MinimumSize, orientation, constraint );
maximum = QskLayoutConstraint::sizeHint(
item, Qt::MaximumSize, orientation, constraint );
preferred = minimum;
}
else
{
preferred = QskLayoutConstraint::sizeHint(
item, Qt::PreferredSize, orientation, constraint );
minimum = maximum = preferred;
if ( policy & QskSizePolicy::ShrinkFlag )
{
minimum = QskLayoutConstraint::sizeHint(
item, Qt::MinimumSize, orientation, constraint );
}
if ( policy & expandFlags )
{
maximum = QskLayoutConstraint::sizeHint(
item, Qt::MaximumSize, orientation, constraint );
}
if ( policy & QskSizePolicy::IgnoreFlag )
preferred = minimum;
}
if ( orientation == m_orientation )
{
if ( entry.stretch() < 0 )
stretch = ( policy & QskSizePolicy::ExpandFlag ) ? 1 : 0;
cell.stretch = ( policy & QskSizePolicy::ExpandFlag ) ? 1 : 0;
else
stretch = entry.stretch();
cell.stretch = entry.stretch();
}
canGrow = policy & QskSizePolicy::GrowFlag;
cell.canGrow = policy & QskSizePolicy::GrowFlag;
}
else
{
// a spacer
if ( orientation == m_orientation )
{
minimum = preferred = maximum = entry.spacer();
cell.hint.setMinimum( entry.spacer() );
cell.hint.setPreferred( entry.spacer() );
// >= 0 ???
if ( entry.stretch() > 0 )
maximum = QskLayoutConstraint::unlimited;
if ( entry.stretch() <= 0 )
cell.hint.setMaximum( entry.spacer() );
stretch = qMax( entry.stretch(), 0 );
}
else
{
minimum = 0.0;
preferred = 0.0;
maximum = QskLayoutConstraint::unlimited;
cell.stretch = qMax( entry.stretch(), 0 );
}
}
QskLayoutChain::Cell cell;
cell.hint = QskLayoutHint( minimum, preferred, maximum );
cell.stretch = stretch;
cell.canGrow = canGrow;
return cell;
}