From 18bea9a46f0058e0405a4c9d327ac137c8ae775d Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sun, 12 May 2019 12:27:25 +0200 Subject: [PATCH] code moved from QskLayoutItem to QskLayoutConstraint --- src/layouts/QskLayoutConstraint.cpp | 101 +++++++++++++++++++++++++--- src/layouts/QskLayoutConstraint.h | 8 ++- src/layouts/QskLayoutItem.cpp | 66 +++--------------- 3 files changed, 108 insertions(+), 67 deletions(-) diff --git a/src/layouts/QskLayoutConstraint.cpp b/src/layouts/QskLayoutConstraint.cpp index 310eb64c..dfe023b8 100644 --- a/src/layouts/QskLayoutConstraint.cpp +++ b/src/layouts/QskLayoutConstraint.cpp @@ -58,17 +58,35 @@ static inline qreal qskAdjustedValue( return value; } -bool QskLayoutConstraint::hasDynamicConstraint( const QQuickItem* item ) +QskLayoutConstraint::Type QskLayoutConstraint::constraintType( const QQuickItem* item ) { + Type constraintType = Unconstrained; + if ( auto control = qskControlCast( item ) ) - { - const auto& policy = control->sizePolicy(); - return ( policy.horizontalPolicy() == QskSizePolicy::Constrained ) || - ( policy.verticalPolicy() == QskSizePolicy::Constrained ); + { + const auto policy = control->sizePolicy(); + if ( policy.horizontalPolicy() == QskSizePolicy::Constrained ) + { + constraintType = WidthForHeight; + } + else if ( policy.verticalPolicy() == QskSizePolicy::Constrained ) + { + constraintType = HeightForWidth; + } } - - return qskHasHintFor( item, "hasHeightForWidth" ) || - qskHasHintFor( item, "hasWidthForHeight" ); + else + { + if ( qskHasHintFor( item, "hasWidthForHeight" ) ) + { + constraintType = WidthForHeight; + } + else if ( qskHasHintFor( item, "hasHeightForWidth" ) ) + { + constraintType = HeightForWidth; + } + } + + return constraintType; } qreal QskLayoutConstraint::heightForWidth( const QQuickItem* item, qreal width ) @@ -290,3 +308,70 @@ QSizeF QskLayoutConstraint::adjustedSize( const QQuickItem* item, const QSizeF& return QSizeF( w, h ); } + +QSizeF QskLayoutConstraint::sizeHint( const QQuickItem* item, + Qt::SizeHint whichHint, const QSizeF& constraint ) +{ + if ( item == nullptr || whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize ) + return QSizeF( 0, 0 ); + + QSizeF hint( 0, 0 ); + + Type constraintType = Unconstrained; + + if ( whichHint == Qt::PreferredSize ) + constraintType = QskLayoutConstraint::constraintType( item ); + + if ( constraintType != Unconstrained ) + { + const quint32 growFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag; + + if ( constraint.width() > 0 ) // && constrainedType == HeightForWidth ?? + { + qreal w = constraint.width(); + + if ( !( sizePolicy( item ).policy( Qt::Horizontal ) & growFlags ) ) + { + const auto maxW = effectiveConstraint( item, Qt::PreferredSize ).width(); + + if ( maxW >= 0.0 ) + w = qMin( w, maxW ); + } + + hint.setWidth( w ); + hint.setHeight( heightForWidth( item, w ) ); + } + else if ( constraint.height() > 0 ) // && constrainedType == WidthForHeight ?? + { + qreal h = constraint.height(); + + if ( !( sizePolicy( item ).policy( Qt::Vertical ) & growFlags ) ) + { + const auto maxH = effectiveConstraint( item, Qt::PreferredSize ).height(); + + if ( maxH >= 0.0 ) + h = qMin( h, maxH ); + } + + hint.setWidth( widthForHeight( item, h ) ); + hint.setHeight( h ); + } + else + { + hint = effectiveConstraint( item, Qt::PreferredSize ); + + if ( constraintType == WidthForHeight ) + hint.setWidth( widthForHeight( item, hint.height() ) ); + else + hint.setHeight( heightForWidth( item, hint.width() ) ); + } + } + else + { + hint = effectiveConstraint( item, whichHint ); + } + + hint = hint.expandedTo( QSizeF( 0.0, 0.0 ) ); + + return hint; +} diff --git a/src/layouts/QskLayoutConstraint.h b/src/layouts/QskLayoutConstraint.h index bb2fe0a0..7a567764 100644 --- a/src/layouts/QskLayoutConstraint.h +++ b/src/layouts/QskLayoutConstraint.h @@ -22,14 +22,17 @@ namespace QskLayoutConstraint { enum Type { + Unconstrained, + WidthForHeight, HeightForWidth }; - QSK_EXPORT bool hasDynamicConstraint( const QQuickItem* ); QSK_EXPORT qreal heightForWidth( const QQuickItem*, qreal width ); QSK_EXPORT qreal widthForHeight( const QQuickItem*, qreal height ); + QSK_EXPORT Type constraintType( const QQuickItem* ); + QSK_EXPORT qreal constrainedMetric( Type, const QskControl*, qreal value, std::function< qreal( Type, const QskControl*, qreal ) > ); @@ -44,6 +47,9 @@ namespace QskLayoutConstraint QSK_EXPORT QSizeF adjustedSize( const QQuickItem*, const QSizeF& ); + QSK_EXPORT QSizeF sizeHint( + const QQuickItem*, Qt::SizeHint, const QSizeF& constraint ); + // QGridLayoutEngine internally uses FLT_MAX const qreal unlimited = std::numeric_limits< float >::max(); } diff --git a/src/layouts/QskLayoutItem.cpp b/src/layouts/QskLayoutItem.cpp index 0f80d067..72acc6a2 100644 --- a/src/layouts/QskLayoutItem.cpp +++ b/src/layouts/QskLayoutItem.cpp @@ -70,11 +70,11 @@ void QskLayoutItem::setSpacingHint( const QSizeF& hint ) QSizeF QskLayoutItem::sizeHint( Qt::SizeHint whichHint, const QSizeF& constraint ) const { - if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize ) - return QSizeF( 0, 0 ); - if ( m_item == nullptr ) { + if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize ) + return QSizeF( 0, 0 ); + // a spacer item if ( whichHint == Qt::MaximumSize ) { @@ -94,63 +94,10 @@ QSizeF QskLayoutItem::sizeHint( return QSizeF( m_spacingHint.width(), 0 ); } } - - QSizeF hint( 0, 0 ); - - if ( whichHint == Qt::PreferredSize && QskLayoutConstraint::hasDynamicConstraint( m_item ) ) - { - const quint32 growFlags = QLayoutPolicy::GrowFlag | QLayoutPolicy::ExpandFlag; - - if ( constraint.width() > 0 ) - { - qreal w = constraint.width(); - - if ( !( sizePolicy( Qt::Horizontal ) & growFlags ) ) - { - const auto maxW = QskLayoutConstraint::effectiveConstraint( - m_item, Qt::PreferredSize ).width(); - - if ( maxW >= 0.0 ) - w = qMin( w, maxW ); - } - - hint.setWidth( w ); - hint.setHeight( QskLayoutConstraint::heightForWidth( m_item, w ) ); - } - else if ( constraint.height() > 0 ) - { - qreal h = constraint.height(); - - if ( !( sizePolicy( Qt::Vertical ) & growFlags ) ) - { - const auto maxH = QskLayoutConstraint::effectiveConstraint( - m_item, Qt::PreferredSize ).height(); - - if ( maxH >= 0.0 ) - h = qMin( h, maxH ); - } - - hint.setWidth( QskLayoutConstraint::widthForHeight( m_item, h ) ); - hint.setHeight( h ); - } - else - { - hint = QskLayoutConstraint::effectiveConstraint( m_item, Qt::PreferredSize ); - - if ( dynamicConstraintOrientation() == Qt::Horizontal ) - hint.setWidth( QskLayoutConstraint::widthForHeight( m_item, hint.height() ) ); - else - hint.setHeight( QskLayoutConstraint::heightForWidth( m_item, hint.width() ) ); - } - } else { - hint = QskLayoutConstraint::effectiveConstraint( m_item, whichHint ); + return QskLayoutConstraint::sizeHint( m_item, whichHint, constraint ); } - - hint = hint.expandedTo( QSizeF( 0.0, 0.0 ) ); - - return hint; } QLayoutPolicy::Policy QskLayoutItem::sizePolicy( Qt::Orientation orientation ) const @@ -203,7 +150,10 @@ void QskLayoutItem::setGeometry( const QRectF& rect ) bool QskLayoutItem::hasDynamicConstraint() const { if ( m_item ) - return QskLayoutConstraint::hasDynamicConstraint( m_item ); + { + using namespace QskLayoutConstraint; + return constraintType( m_item ) != Unconstrained; + } return false; }