QskLayoutElement introduced
This commit is contained in:
parent
bc5510f7ef
commit
9daf934426
@ -6,6 +6,7 @@
|
|||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
#include "QskControl.h"
|
#include "QskControl.h"
|
||||||
#include "QskFunctions.h"
|
#include "QskFunctions.h"
|
||||||
|
#include "QskLayoutElement.h"
|
||||||
#include <qquickitem.h>
|
#include <qquickitem.h>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
@ -419,221 +420,23 @@ QSizeF qskEffectiveSizeHint( const QQuickItem* item,
|
|||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QSizeF qskBoundedConstraint( const QQuickItem* item,
|
|
||||||
const QSizeF& constraint, QskSizePolicy policy )
|
|
||||||
{
|
|
||||||
Qt::Orientation orientation;
|
|
||||||
|
|
||||||
if ( constraint.width() >= 0.0 )
|
|
||||||
{
|
|
||||||
orientation = Qt::Horizontal;
|
|
||||||
}
|
|
||||||
else if ( constraint.height() >= 0.0 )
|
|
||||||
{
|
|
||||||
orientation = Qt::Vertical;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return constraint;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto whichMin = policy.effectiveSizeHintType( Qt::MinimumSize, orientation );
|
|
||||||
const auto whichMax = policy.effectiveSizeHintType( Qt::MaximumSize, orientation );
|
|
||||||
|
|
||||||
const auto hintMin = qskEffectiveSizeHint( item, whichMin );
|
|
||||||
const auto hintMax = ( whichMax == whichMin )
|
|
||||||
? hintMin : qskEffectiveSizeHint( item, whichMax );
|
|
||||||
|
|
||||||
QSizeF size = constraint;
|
|
||||||
|
|
||||||
if ( orientation == Qt::Horizontal )
|
|
||||||
{
|
|
||||||
if ( hintMax.width() >= 0.0 )
|
|
||||||
size.rwidth() = qMin( size.width(), hintMax.width() );
|
|
||||||
|
|
||||||
size.rwidth() = qMax( size.width(), hintMin.width() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( hintMax.height() >= 0.0 )
|
|
||||||
size.rheight() = qMin( size.height(), hintMax.height() );
|
|
||||||
|
|
||||||
size.rheight() = qMax( size.height(), hintMin.height() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSizeF qskSizeConstraint( const QQuickItem* item,
|
QSizeF qskSizeConstraint( const QQuickItem* item,
|
||||||
Qt::SizeHint which, const QSizeF& constraint )
|
Qt::SizeHint which, const QSizeF& constraint )
|
||||||
{
|
{
|
||||||
if ( item == nullptr )
|
if ( item == nullptr )
|
||||||
return QSizeF( 0, 0 );
|
return QSizeF( 0, 0 );
|
||||||
|
|
||||||
if ( constraint.isValid() )
|
const QskItemLayoutElement layoutElement( item );
|
||||||
return constraint;
|
return layoutElement.sizeConstraint( which, constraint );
|
||||||
|
|
||||||
auto policy = qskSizePolicy( item );
|
|
||||||
|
|
||||||
bool ignoreWidth = false;
|
|
||||||
bool ignoreHeight = false;
|
|
||||||
|
|
||||||
if ( which == Qt::PreferredSize )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
First we are checking the IgnoreFlag, to avoid doing
|
|
||||||
pointless calculations.
|
|
||||||
*/
|
|
||||||
ignoreWidth = policy.policy( Qt::Horizontal ) & QskSizePolicy::IgnoreFlag;
|
|
||||||
ignoreHeight = policy.policy( Qt::Vertical ) & QskSizePolicy::IgnoreFlag;
|
|
||||||
|
|
||||||
if ( ( ignoreWidth && ignoreHeight )
|
|
||||||
|| ( ignoreWidth && constraint.height() >= 0.0 )
|
|
||||||
|| ( ignoreHeight && constraint.width() >= 0.0 ) )
|
|
||||||
{
|
|
||||||
return QSizeF();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto whichH = policy.effectiveSizeHintType( which, Qt::Horizontal );
|
|
||||||
const auto whichV = policy.effectiveSizeHintType( which, Qt::Vertical );
|
|
||||||
|
|
||||||
QSizeF size;
|
|
||||||
|
|
||||||
int constraintType = QskSizePolicy::Unconstrained;
|
|
||||||
|
|
||||||
/*
|
|
||||||
We apply a constraint - even, when the policy is unconstrained.
|
|
||||||
Do we really want to do this ???
|
|
||||||
*/
|
|
||||||
if ( constraint.height() >= 0.0 )
|
|
||||||
{
|
|
||||||
const auto c = qskBoundedConstraint( item, constraint, policy );
|
|
||||||
size = qskEffectiveSizeHint( item, whichV, c );
|
|
||||||
|
|
||||||
if ( ( whichH != whichV ) || ( size.height() != c.height() ) )
|
|
||||||
constraintType = QskSizePolicy::WidthForHeight;
|
|
||||||
}
|
|
||||||
else if ( constraint.width() >= 0.0 )
|
|
||||||
{
|
|
||||||
const auto c = qskBoundedConstraint( item, constraint, policy );
|
|
||||||
size = qskEffectiveSizeHint( item, whichH, c );
|
|
||||||
|
|
||||||
if ( ( whichV != whichH ) || ( size.width() != c.height() ) )
|
|
||||||
constraintType = QskSizePolicy::HeightForWidth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
constraintType = policy.constraintType();
|
|
||||||
|
|
||||||
switch( constraintType )
|
|
||||||
{
|
|
||||||
case QskSizePolicy::WidthForHeight:
|
|
||||||
{
|
|
||||||
size = qskEffectiveSizeHint( item, whichV );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QskSizePolicy::HeightForWidth:
|
|
||||||
{
|
|
||||||
size = qskEffectiveSizeHint( item, whichH );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if ( whichV != whichH )
|
|
||||||
{
|
|
||||||
if ( !ignoreWidth )
|
|
||||||
size.rwidth() = qskEffectiveSizeHint( item, whichH ).width();
|
|
||||||
|
|
||||||
if ( !ignoreHeight )
|
|
||||||
size.rheight() = qskEffectiveSizeHint( item, whichV ).height();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size = qskEffectiveSizeHint( item, whichH );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( constraintType )
|
|
||||||
{
|
|
||||||
case QskSizePolicy::HeightForWidth:
|
|
||||||
{
|
|
||||||
const QSizeF c( size.width(), -1.0 );
|
|
||||||
size.rheight() = qskEffectiveSizeHint( item, whichV, c ).height();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QskSizePolicy::WidthForHeight:
|
|
||||||
{
|
|
||||||
const QSizeF c( -1.0, size.height() );
|
|
||||||
size.rwidth() = qskEffectiveSizeHint( item, whichH, c ).width();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ignoreWidth || constraint.width() >= 0.0 )
|
|
||||||
size.rwidth() = -1.0;
|
|
||||||
|
|
||||||
if ( ignoreHeight || constraint.height() >= 0.0 )
|
|
||||||
size.rheight() = -1.0;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF qskConstrainedItemSize( const QQuickItem* item, const QSizeF& size )
|
QSizeF qskConstrainedItemSize( const QQuickItem* item, const QSizeF& size )
|
||||||
{
|
{
|
||||||
if ( item == nullptr || ( size.width() <= 0.0 && size.height() <= 0.0 ) )
|
if ( item == nullptr )
|
||||||
return QSizeF( 0.0, 0.0 );
|
return QSizeF( 0.0, 0.0 );
|
||||||
|
|
||||||
QSizeF min, max;
|
const QskItemLayoutElement layoutElement( item );
|
||||||
|
return layoutElement.constrainedSize( size );
|
||||||
const auto policy = qskSizePolicy( item );
|
|
||||||
|
|
||||||
switch( policy.constraintType() )
|
|
||||||
{
|
|
||||||
case QskSizePolicy::WidthForHeight:
|
|
||||||
{
|
|
||||||
const auto constraint = qskBoundedConstraint( item,
|
|
||||||
QSizeF( -1.0, size.height() ), policy );
|
|
||||||
|
|
||||||
min = qskSizeConstraint( item, Qt::MinimumSize, constraint );
|
|
||||||
max = qskSizeConstraint( item, Qt::MaximumSize, constraint );
|
|
||||||
|
|
||||||
min.rheight() = max.rheight() = constraint.height();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QskSizePolicy::HeightForWidth:
|
|
||||||
{
|
|
||||||
const auto constraint = qskBoundedConstraint( item,
|
|
||||||
QSizeF( size.width(), -1.0 ), policy );
|
|
||||||
|
|
||||||
min = qskSizeConstraint( item, Qt::MinimumSize, constraint );
|
|
||||||
max = qskSizeConstraint( item, Qt::MaximumSize, constraint );
|
|
||||||
|
|
||||||
min.rwidth() = max.rwidth() = constraint.width();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
min = qskSizeConstraint( item, Qt::MinimumSize, QSizeF() );
|
|
||||||
max = qskSizeConstraint( item, Qt::MaximumSize, QSizeF() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal width = size.width();
|
|
||||||
qreal height = size.height();
|
|
||||||
|
|
||||||
if ( max.width() >= 0.0 )
|
|
||||||
width = qMin( width, max.width() );
|
|
||||||
|
|
||||||
if ( max.height() >= 0.0 )
|
|
||||||
height = qMin( height, max.height() );
|
|
||||||
|
|
||||||
width = qMax( width, min.width() );
|
|
||||||
height = qMax( height, min.height() );
|
|
||||||
|
|
||||||
return QSizeF( width, height );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF qskConstrainedItemRect( const QQuickItem* item,
|
QRectF qskConstrainedItemRect( const QQuickItem* item,
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "QskGridLayoutEngine.h"
|
#include "QskGridLayoutEngine.h"
|
||||||
#include "QskLayoutMetrics.h"
|
#include "QskLayoutMetrics.h"
|
||||||
#include "QskLayoutChain.h"
|
#include "QskLayoutChain.h"
|
||||||
|
#include "QskLayoutElement.h"
|
||||||
#include "QskSizePolicy.h"
|
#include "QskSizePolicy.h"
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
|
|
||||||
@ -162,6 +163,13 @@ namespace
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
inline QskLayoutMetrics qskItemMetrics(
|
||||||
|
QQuickItem* item, Qt::Orientation orientation, qreal constraint )
|
||||||
|
{
|
||||||
|
const QskItemLayoutElement layoutItem( item );
|
||||||
|
return layoutItem.metrics( orientation, constraint );
|
||||||
|
}
|
||||||
|
|
||||||
class Element
|
class Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -543,6 +551,30 @@ QQuickItem* QskGridLayoutEngine::itemAt( int index ) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QskSizePolicy QskGridLayoutEngine::sizePolicyAt( int index ) const
|
||||||
|
{
|
||||||
|
return qskSizePolicy( itemAt( index ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QskGridLayoutEngine::indexOf( const QQuickItem* item ) const
|
||||||
|
{
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
indexOf is often called after inserting an item to
|
||||||
|
set additinal properties. So we search in reverse order
|
||||||
|
*/
|
||||||
|
|
||||||
|
for ( int i = count() - 1; i >= 0; --i )
|
||||||
|
{
|
||||||
|
if ( itemAt( i ) == item )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
QSizeF QskGridLayoutEngine::spacerAt( int index ) const
|
QSizeF QskGridLayoutEngine::spacerAt( int index ) const
|
||||||
{
|
{
|
||||||
if ( const auto element = m_data->elementAt( index ) )
|
if ( const auto element = m_data->elementAt( index ) )
|
||||||
@ -601,7 +633,12 @@ void QskGridLayoutEngine::layoutItems()
|
|||||||
if ( qskIsAdjustableByLayout( item ) )
|
if ( qskIsAdjustableByLayout( item ) )
|
||||||
{
|
{
|
||||||
const auto grid = m_data->effectiveGrid( element );
|
const auto grid = m_data->effectiveGrid( element );
|
||||||
layoutItem( item, grid );
|
|
||||||
|
const QskItemLayoutElement layoutElement( item );
|
||||||
|
|
||||||
|
const auto rect = geometryAt( &layoutElement, grid );
|
||||||
|
if ( rect.size().isValid() )
|
||||||
|
qskSetItemGeometry( item, rect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -650,8 +687,9 @@ void QskGridLayoutEngine::setupChain( Qt::Orientation orientation,
|
|||||||
constraint = qskSegmentLength( constraints, grid.left(), grid.right() );
|
constraint = qskSegmentLength( constraints, grid.left(), grid.right() );
|
||||||
|
|
||||||
auto cell = element.cell( orientation );
|
auto cell = element.cell( orientation );
|
||||||
|
|
||||||
if ( element.item() )
|
if ( element.item() )
|
||||||
cell.metrics = layoutMetrics( element.item(), orientation, constraint );
|
cell.metrics = qskItemMetrics( element.item(), orientation, constraint );
|
||||||
|
|
||||||
chain.expandCell( grid.top(), cell );
|
chain.expandCell( grid.top(), cell );
|
||||||
}
|
}
|
||||||
@ -677,7 +715,7 @@ void QskGridLayoutEngine::setupChain( Qt::Orientation orientation,
|
|||||||
constraint = qskSegmentLength( constraints, grid.left(), grid.right() );
|
constraint = qskSegmentLength( constraints, grid.left(), grid.right() );
|
||||||
|
|
||||||
auto cell = element->cell( orientation );
|
auto cell = element->cell( orientation );
|
||||||
cell.metrics = layoutMetrics( element->item(), orientation, constraint );
|
cell.metrics = qskItemMetrics( element->item(), orientation, constraint );
|
||||||
|
|
||||||
chain.expandCells( grid.top(), grid.height(), cell );
|
chain.expandCells( grid.top(), grid.height(), cell );
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,14 @@ class QskGridLayoutEngine : public QskLayoutEngine2D
|
|||||||
bool removeAt( int index );
|
bool removeAt( int index );
|
||||||
bool clear();
|
bool clear();
|
||||||
|
|
||||||
QQuickItem* itemAt( int index ) const override final;
|
QQuickItem* itemAt( int index ) const;
|
||||||
QSizeF spacerAt( int index ) const;
|
QSizeF spacerAt( int index ) const;
|
||||||
|
|
||||||
QQuickItem* itemAt( int row, int column ) const;
|
QQuickItem* itemAt( int row, int column ) const;
|
||||||
int indexAt( int row, int column ) const;
|
int indexAt( int row, int column ) const;
|
||||||
|
|
||||||
|
int indexOf( const QQuickItem* ) const;
|
||||||
|
|
||||||
bool setGridAt( int index, const QRect& );
|
bool setGridAt( int index, const QRect& );
|
||||||
QRect gridAt( int index ) const;
|
QRect gridAt( int index ) const;
|
||||||
|
|
||||||
@ -53,6 +55,7 @@ class QskGridLayoutEngine : public QskLayoutEngine2D
|
|||||||
void transpose();
|
void transpose();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QskSizePolicy sizePolicyAt( int index ) const override final;
|
||||||
void layoutItems() override;
|
void layoutItems() override;
|
||||||
int effectiveCount( Qt::Orientation ) const override;
|
int effectiveCount( Qt::Orientation ) const override;
|
||||||
|
|
||||||
|
385
src/layouts/QskLayoutElement.cpp
Normal file
385
src/layouts/QskLayoutElement.cpp
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskLayoutElement.h"
|
||||||
|
#include "QskLayoutMetrics.h"
|
||||||
|
#include "QskSizePolicy.h"
|
||||||
|
|
||||||
|
static inline bool qskCanGrow(
|
||||||
|
const QskLayoutElement* element, Qt::Orientation orientation )
|
||||||
|
{
|
||||||
|
const quint32 growFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
|
||||||
|
return element->sizePolicy().policy( orientation ) & growFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QskLayoutElement::QskLayoutElement()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QskLayoutElement::~QskLayoutElement()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskLayoutElement::sizeConstraint(
|
||||||
|
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||||
|
{
|
||||||
|
if ( constraint.isValid() )
|
||||||
|
return constraint;
|
||||||
|
|
||||||
|
auto policy = sizePolicy();
|
||||||
|
|
||||||
|
bool ignoreWidth = false;
|
||||||
|
bool ignoreHeight = false;
|
||||||
|
|
||||||
|
if ( which == Qt::PreferredSize )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
First we are checking the IgnoreFlag, to avoid doing
|
||||||
|
pointless calculations.
|
||||||
|
*/
|
||||||
|
ignoreWidth = policy.policy( Qt::Horizontal ) & QskSizePolicy::IgnoreFlag;
|
||||||
|
ignoreHeight = policy.policy( Qt::Vertical ) & QskSizePolicy::IgnoreFlag;
|
||||||
|
|
||||||
|
if ( ( ignoreWidth && ignoreHeight )
|
||||||
|
|| ( ignoreWidth && constraint.height() >= 0.0 )
|
||||||
|
|| ( ignoreHeight && constraint.width() >= 0.0 ) )
|
||||||
|
{
|
||||||
|
return QSizeF();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto whichH = policy.effectiveSizeHintType( which, Qt::Horizontal );
|
||||||
|
const auto whichV = policy.effectiveSizeHintType( which, Qt::Vertical );
|
||||||
|
|
||||||
|
QSizeF size;
|
||||||
|
|
||||||
|
int constraintType = QskSizePolicy::Unconstrained;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We apply a constraint - even, when the policy is unconstrained.
|
||||||
|
Do we really want to do this ???
|
||||||
|
*/
|
||||||
|
if ( constraint.height() >= 0.0 )
|
||||||
|
{
|
||||||
|
const auto h = boundedSize( Qt::Vertical, constraint.height() );
|
||||||
|
size = sizeHint( whichV, QSizeF( -1.0, h ) );
|
||||||
|
|
||||||
|
if ( ( whichH != whichV ) || ( size.height() != h ) )
|
||||||
|
constraintType = QskSizePolicy::WidthForHeight;
|
||||||
|
}
|
||||||
|
else if ( constraint.width() >= 0.0 )
|
||||||
|
{
|
||||||
|
const auto w = boundedSize( Qt::Horizontal, constraint.width() );
|
||||||
|
size = sizeHint( whichH, QSizeF( w, -1.0 ) );
|
||||||
|
|
||||||
|
if ( ( whichV != whichH ) || ( size.width() != w ) )
|
||||||
|
constraintType = QskSizePolicy::HeightForWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
constraintType = policy.constraintType();
|
||||||
|
|
||||||
|
switch( constraintType )
|
||||||
|
{
|
||||||
|
case QskSizePolicy::WidthForHeight:
|
||||||
|
{
|
||||||
|
size = sizeHint( whichV );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QskSizePolicy::HeightForWidth:
|
||||||
|
{
|
||||||
|
size = sizeHint( whichH );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if ( whichV != whichH )
|
||||||
|
{
|
||||||
|
if ( !ignoreWidth )
|
||||||
|
size.rwidth() = sizeHint( whichH ).width();
|
||||||
|
|
||||||
|
if ( !ignoreHeight )
|
||||||
|
size.rheight() = sizeHint( whichV ).height();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = sizeHint( whichH );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( constraintType )
|
||||||
|
{
|
||||||
|
case QskSizePolicy::HeightForWidth:
|
||||||
|
{
|
||||||
|
const QSizeF c( size.width(), -1.0 );
|
||||||
|
size.rheight() = sizeHint( whichV, c ).height();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QskSizePolicy::WidthForHeight:
|
||||||
|
{
|
||||||
|
const QSizeF c( -1.0, size.height() );
|
||||||
|
size.rwidth() = sizeHint( whichH, c ).width();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ignoreWidth || constraint.width() >= 0.0 )
|
||||||
|
size.rwidth() = -1.0;
|
||||||
|
|
||||||
|
if ( ignoreHeight || constraint.height() >= 0.0 )
|
||||||
|
size.rheight() = -1.0;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskLayoutElement::constrainedSize( const QSizeF& size ) const
|
||||||
|
{
|
||||||
|
if ( size.width() <= 0.0 && size.height() <= 0.0 )
|
||||||
|
return QSizeF( 0.0, 0.0 );
|
||||||
|
|
||||||
|
QSizeF min, max;
|
||||||
|
|
||||||
|
const auto policy = sizePolicy();
|
||||||
|
|
||||||
|
switch( policy.constraintType() )
|
||||||
|
{
|
||||||
|
case QskSizePolicy::WidthForHeight:
|
||||||
|
{
|
||||||
|
const qreal h = boundedSize( Qt::Vertical, size.height() );
|
||||||
|
|
||||||
|
min = sizeConstraint( Qt::MinimumSize, QSizeF( -1.0, h ) );
|
||||||
|
max = sizeConstraint( Qt::MaximumSize, QSizeF( -1.0, h ) );
|
||||||
|
|
||||||
|
min.rheight() = max.rheight() = h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QskSizePolicy::HeightForWidth:
|
||||||
|
{
|
||||||
|
const qreal w = boundedSize( Qt::Horizontal, size.width() );
|
||||||
|
|
||||||
|
min = sizeConstraint( Qt::MinimumSize, QSizeF( w, -1.0 ) );
|
||||||
|
max = sizeConstraint( Qt::MaximumSize, QSizeF( w, -1.0 ) );
|
||||||
|
|
||||||
|
min.rwidth() = max.rwidth() = w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
min = sizeConstraint( Qt::MinimumSize, QSizeF() );
|
||||||
|
max = sizeConstraint( Qt::MaximumSize, QSizeF() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal width = size.width();
|
||||||
|
qreal height = size.height();
|
||||||
|
|
||||||
|
if ( max.width() >= 0.0 )
|
||||||
|
width = qMin( width, max.width() );
|
||||||
|
|
||||||
|
if ( max.height() >= 0.0 )
|
||||||
|
height = qMin( height, max.height() );
|
||||||
|
|
||||||
|
width = qMax( width, min.width() );
|
||||||
|
height = qMax( height, min.height() );
|
||||||
|
|
||||||
|
return QSizeF( width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskLayoutMetrics QskLayoutElement::metrics(
|
||||||
|
Qt::Orientation orientation, qreal constraint ) const
|
||||||
|
{
|
||||||
|
const auto policy = sizePolicy().policy( orientation );
|
||||||
|
|
||||||
|
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 = metric( orientation, Qt::MinimumSize, -1.0 );
|
||||||
|
maximum = metric( orientation, Qt::MaximumSize, -1.0 );
|
||||||
|
preferred = minimum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( constraint >= 0.0 )
|
||||||
|
{
|
||||||
|
if ( !( policy & QskSizePolicy::ConstrainedFlag ) )
|
||||||
|
constraint = -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
preferred = metric( orientation, Qt::PreferredSize, constraint );
|
||||||
|
|
||||||
|
if ( policy & QskSizePolicy::ShrinkFlag )
|
||||||
|
minimum = metric( orientation, Qt::MinimumSize, -1.0 );
|
||||||
|
else
|
||||||
|
minimum = preferred;
|
||||||
|
|
||||||
|
if ( policy & expandFlags )
|
||||||
|
maximum = metric( orientation, Qt::MaximumSize, -1.0 );
|
||||||
|
else
|
||||||
|
maximum = preferred;
|
||||||
|
|
||||||
|
if ( policy & QskSizePolicy::IgnoreFlag )
|
||||||
|
preferred = minimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QskLayoutMetrics( minimum, preferred, maximum );
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QskLayoutElement::metric( Qt::Orientation orientation,
|
||||||
|
Qt::SizeHint which, qreal constraint ) const
|
||||||
|
{
|
||||||
|
qreal metric = 0.0;
|
||||||
|
|
||||||
|
if ( which == Qt::MinimumSize )
|
||||||
|
{
|
||||||
|
const auto hint = sizeHint( Qt::MinimumSize );
|
||||||
|
|
||||||
|
if ( orientation == Qt::Horizontal )
|
||||||
|
metric = hint.width();
|
||||||
|
else
|
||||||
|
metric = hint.height();
|
||||||
|
|
||||||
|
if ( metric < 0.0 )
|
||||||
|
metric = 0.0;
|
||||||
|
}
|
||||||
|
else if ( which == Qt::MaximumSize )
|
||||||
|
{
|
||||||
|
const auto hint = sizeHint( Qt::MaximumSize );
|
||||||
|
|
||||||
|
if ( orientation == Qt::Horizontal )
|
||||||
|
metric = hint.width();
|
||||||
|
else
|
||||||
|
metric = hint.height();
|
||||||
|
|
||||||
|
if ( metric < 0.0 )
|
||||||
|
metric = QskLayoutMetrics::unlimited;
|
||||||
|
}
|
||||||
|
else if ( which == Qt::PreferredSize )
|
||||||
|
{
|
||||||
|
const auto constraintType = sizePolicy().constraintType();
|
||||||
|
|
||||||
|
if ( constraintType == QskSizePolicy::Unconstrained )
|
||||||
|
{
|
||||||
|
const auto hint = sizeHint( Qt::PreferredSize );
|
||||||
|
|
||||||
|
if ( orientation == Qt::Horizontal )
|
||||||
|
metric = hint.width();
|
||||||
|
else
|
||||||
|
metric = hint.height();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( constraint < 0.0 )
|
||||||
|
{
|
||||||
|
auto hint = sizeHint( Qt::PreferredSize );
|
||||||
|
|
||||||
|
if ( orientation == Qt::Horizontal )
|
||||||
|
{
|
||||||
|
if ( constraintType == QskSizePolicy::WidthForHeight )
|
||||||
|
hint.setWidth( widthForHeight( hint.height() ) );
|
||||||
|
|
||||||
|
metric = hint.width();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( constraintType == QskSizePolicy::HeightForWidth )
|
||||||
|
hint.setHeight( heightForWidth( hint.width() ) );
|
||||||
|
|
||||||
|
metric = hint.height();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( orientation == Qt::Horizontal )
|
||||||
|
{
|
||||||
|
if ( !qskCanGrow( this, Qt::Vertical ) )
|
||||||
|
{
|
||||||
|
const auto maxH = sizeHint( Qt::PreferredSize ).height();
|
||||||
|
|
||||||
|
if ( maxH >= 0.0 )
|
||||||
|
constraint = qMin( constraint, maxH );
|
||||||
|
}
|
||||||
|
|
||||||
|
metric = widthForHeight( constraint );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !qskCanGrow( this, Qt::Horizontal ) )
|
||||||
|
{
|
||||||
|
const auto maxW = sizeHint( Qt::PreferredSize ).width();
|
||||||
|
|
||||||
|
if ( maxW >= 0.0 )
|
||||||
|
constraint = qMin( constraint, maxW );
|
||||||
|
}
|
||||||
|
|
||||||
|
metric = heightForWidth( constraint );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( metric < 0.0 )
|
||||||
|
metric = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return metric;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QskLayoutElement::boundedSize( Qt::Orientation orientation, qreal size ) const
|
||||||
|
{
|
||||||
|
const auto policy = sizePolicy();
|
||||||
|
|
||||||
|
const auto whichMin = policy.effectiveSizeHintType( Qt::MinimumSize, orientation );
|
||||||
|
const auto whichMax = policy.effectiveSizeHintType( Qt::MaximumSize, orientation );
|
||||||
|
|
||||||
|
const auto hintMin = sizeHint( whichMin );
|
||||||
|
const auto hintMax = ( whichMax == whichMin ) ? hintMin : sizeHint( whichMax );
|
||||||
|
|
||||||
|
if ( orientation == Qt::Horizontal )
|
||||||
|
{
|
||||||
|
if ( hintMax.width() >= 0.0 )
|
||||||
|
size = qMin( size, hintMax.width() );
|
||||||
|
|
||||||
|
size = qMax( size, hintMin.width() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( hintMax.height() >= 0.0 )
|
||||||
|
size = qMin( size, hintMax.height() );
|
||||||
|
|
||||||
|
size = qMax( size, hintMin.height() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "QskQuick.h"
|
||||||
|
|
||||||
|
QskItemLayoutElement::QskItemLayoutElement( const QQuickItem* item )
|
||||||
|
: m_item( item )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QskSizePolicy QskItemLayoutElement::sizePolicy() const
|
||||||
|
{
|
||||||
|
return qskSizePolicy( m_item );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskItemLayoutElement::sizeHint( Qt::SizeHint which,
|
||||||
|
const QSizeF& constraint ) const
|
||||||
|
{
|
||||||
|
return qskEffectiveSizeHint( m_item, which, constraint );
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::Alignment QskItemLayoutElement::alignment() const
|
||||||
|
{
|
||||||
|
return qskLayoutAlignmentHint( m_item );
|
||||||
|
}
|
71
src/layouts/QskLayoutElement.h
Normal file
71
src/layouts/QskLayoutElement.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_LAYOUT_ELEMENT_H
|
||||||
|
#define QSK_LAYOUT_ELEMENT_H
|
||||||
|
|
||||||
|
#include "QskGlobal.h"
|
||||||
|
#include <qnamespace.h>
|
||||||
|
#include <qrect.h>
|
||||||
|
|
||||||
|
class QskSizePolicy;
|
||||||
|
class QskLayoutMetrics;
|
||||||
|
|
||||||
|
class QskLayoutElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskLayoutElement();
|
||||||
|
virtual ~QskLayoutElement();
|
||||||
|
|
||||||
|
QskLayoutMetrics metrics( Qt::Orientation, qreal constraint ) const;
|
||||||
|
|
||||||
|
virtual QskSizePolicy sizePolicy() const = 0;
|
||||||
|
virtual Qt::Alignment alignment() const = 0;
|
||||||
|
|
||||||
|
QSizeF constrainedSize( const QSizeF& ) const;
|
||||||
|
|
||||||
|
QSizeF sizeConstraint( Qt::SizeHint, const QSizeF& constraint ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY( QskLayoutElement )
|
||||||
|
|
||||||
|
qreal metric( Qt::Orientation, Qt::SizeHint, qreal constraint ) const;
|
||||||
|
|
||||||
|
virtual QSizeF sizeHint( Qt::SizeHint,
|
||||||
|
const QSizeF& constraint = QSizeF() ) const = 0;
|
||||||
|
|
||||||
|
qreal heightForWidth( qreal ) const;
|
||||||
|
qreal widthForHeight( qreal ) const;
|
||||||
|
|
||||||
|
qreal boundedSize( Qt::Orientation, qreal ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline qreal QskLayoutElement::heightForWidth( qreal width ) const
|
||||||
|
{
|
||||||
|
return sizeHint( Qt::PreferredSize, QSizeF( width, -1.0 ) ).height();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline qreal QskLayoutElement::widthForHeight( qreal height ) const
|
||||||
|
{
|
||||||
|
return sizeHint( Qt::PreferredSize, QSizeF( -1.0, height ) ).width();
|
||||||
|
}
|
||||||
|
|
||||||
|
class QQuickItem;
|
||||||
|
|
||||||
|
class QskItemLayoutElement final : public QskLayoutElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskItemLayoutElement( const QQuickItem* );
|
||||||
|
|
||||||
|
QskSizePolicy sizePolicy() const override;
|
||||||
|
Qt::Alignment alignment() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSizeF sizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
|
const QQuickItem* m_item = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -5,100 +5,11 @@
|
|||||||
|
|
||||||
#include "QskLayoutEngine2D.h"
|
#include "QskLayoutEngine2D.h"
|
||||||
#include "QskLayoutChain.h"
|
#include "QskLayoutChain.h"
|
||||||
#include "QskLayoutMetrics.h"
|
#include "QskLayoutElement.h"
|
||||||
#include "QskControl.h"
|
#include "QskFunctions.h"
|
||||||
#include "QskQuick.h"
|
|
||||||
|
|
||||||
#include <qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
|
|
||||||
static QSizeF qskItemConstraint( const QQuickItem* item, const QSizeF& constraint )
|
|
||||||
{
|
|
||||||
QSizeF hint( 0, 0 );
|
|
||||||
|
|
||||||
const auto sizePolicy = qskSizePolicy( item );
|
|
||||||
|
|
||||||
const auto constraintType = sizePolicy.constraintType();
|
|
||||||
const auto which = Qt::PreferredSize;
|
|
||||||
|
|
||||||
if ( constraintType != QskSizePolicy::Unconstrained )
|
|
||||||
{
|
|
||||||
const quint32 growFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
|
|
||||||
|
|
||||||
if ( constraint.width() > 0 ) // && constrainedType == HeightForWidth ??
|
|
||||||
{
|
|
||||||
qreal w = constraint.width();
|
|
||||||
|
|
||||||
if ( !( sizePolicy.policy( Qt::Horizontal ) & growFlags ) )
|
|
||||||
{
|
|
||||||
const auto maxW = qskEffectiveSizeHint( item, which ).width();
|
|
||||||
|
|
||||||
if ( maxW >= 0.0 )
|
|
||||||
w = qMin( w, maxW );
|
|
||||||
}
|
|
||||||
|
|
||||||
hint.setWidth( w );
|
|
||||||
hint.setHeight( qskHeightForWidth( item, which, w ) );
|
|
||||||
}
|
|
||||||
else if ( constraint.height() > 0 ) // && constrainedType == WidthForHeight ??
|
|
||||||
{
|
|
||||||
qreal h = constraint.height();
|
|
||||||
|
|
||||||
if ( !( sizePolicy.policy( Qt::Vertical ) & growFlags ) )
|
|
||||||
{
|
|
||||||
const auto maxH = qskEffectiveSizeHint( item, which ).height();
|
|
||||||
|
|
||||||
if ( maxH >= 0.0 )
|
|
||||||
h = qMin( h, maxH );
|
|
||||||
}
|
|
||||||
|
|
||||||
hint.setWidth( qskWidthForHeight( item, which, h ) );
|
|
||||||
hint.setHeight( h );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hint = qskEffectiveSizeHint( item, which );
|
|
||||||
|
|
||||||
if ( constraintType == QskSizePolicy::WidthForHeight )
|
|
||||||
hint.setWidth( qskWidthForHeight( item, which, hint.height() ) );
|
|
||||||
else
|
|
||||||
hint.setHeight( qskHeightForWidth( item, which, hint.width() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hint = qskEffectiveSizeHint( item, which );
|
|
||||||
}
|
|
||||||
|
|
||||||
hint = hint.expandedTo( QSizeF( 0.0, 0.0 ) );
|
|
||||||
|
|
||||||
return hint;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline qreal qskLayoutConstraint( const QQuickItem* item,
|
|
||||||
Qt::Orientation orientation, qreal constraint )
|
|
||||||
{
|
|
||||||
if ( orientation == Qt::Horizontal )
|
|
||||||
return qskItemConstraint( item, QSizeF( -1.0, constraint ) ).width();
|
|
||||||
else
|
|
||||||
return qskItemConstraint( item, QSizeF( constraint, -1.0 ) ).height();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline qreal qskEffectiveConstraint( const QQuickItem* item,
|
|
||||||
Qt::SizeHint which, Qt::Orientation orientation )
|
|
||||||
{
|
|
||||||
qreal value;
|
|
||||||
|
|
||||||
if ( orientation == Qt::Horizontal )
|
|
||||||
value = qskEffectiveSizeHint( item, which ).width();
|
|
||||||
else
|
|
||||||
value = qskEffectiveSizeHint( item, which ).height();
|
|
||||||
|
|
||||||
if ( value < 0.0 )
|
|
||||||
value = ( which == Qt::MaximumSize ) ? QskLayoutMetrics::unlimited : 0.0;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class LayoutData
|
class LayoutData
|
||||||
@ -289,25 +200,6 @@ bool QskLayoutEngine2D::setExtraSpacingAt( Qt::Edges edges )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskLayoutEngine2D::indexOf( const QQuickItem* item ) const
|
|
||||||
{
|
|
||||||
if ( item )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
indexOf is often called after inserting an item to
|
|
||||||
set additinal properties. So we search in reverse order
|
|
||||||
*/
|
|
||||||
|
|
||||||
for ( int i = count() - 1; i >= 0; --i )
|
|
||||||
{
|
|
||||||
if ( itemAt( i ) == item )
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::Edges QskLayoutEngine2D::extraSpacingAt() const
|
Qt::Edges QskLayoutEngine2D::extraSpacingAt() const
|
||||||
{
|
{
|
||||||
return static_cast< Qt::Edges >( m_data->extraSpacingAt );
|
return static_cast< Qt::Edges >( m_data->extraSpacingAt );
|
||||||
@ -343,26 +235,30 @@ void QskLayoutEngine2D::setGeometries( const QRectF& rect )
|
|||||||
m_data->layoutData = nullptr;
|
m_data->layoutData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLayoutEngine2D::layoutItem( QQuickItem* item, const QRect& grid ) const
|
QRectF QskLayoutEngine2D::geometryAt(
|
||||||
|
const QskLayoutElement* element, const QRect& grid ) const
|
||||||
{
|
{
|
||||||
auto layoutData = m_data->layoutData;
|
const auto layoutData = m_data->layoutData;
|
||||||
|
|
||||||
if ( layoutData == nullptr || item == nullptr )
|
if ( layoutData && element )
|
||||||
return;
|
|
||||||
|
|
||||||
auto alignment = qskLayoutAlignmentHint( item );
|
|
||||||
alignment = m_data->effectiveAlignment( alignment );
|
|
||||||
|
|
||||||
auto rect = layoutData->geometryAt( grid );
|
|
||||||
rect = qskConstrainedItemRect( item, rect, alignment );
|
|
||||||
|
|
||||||
if ( layoutData->direction == Qt::RightToLeft )
|
|
||||||
{
|
{
|
||||||
const auto& r = layoutData->rect;
|
auto rect = layoutData->geometryAt( grid );
|
||||||
rect.moveRight( r.right() - ( rect.left() - r.left() ) );
|
|
||||||
|
const auto size = element->constrainedSize( rect.size() );
|
||||||
|
const auto alignment = m_data->effectiveAlignment( element->alignment() );
|
||||||
|
|
||||||
|
rect = qskAlignedRectF( rect, size, alignment );
|
||||||
|
|
||||||
|
if ( layoutData->direction == Qt::RightToLeft )
|
||||||
|
{
|
||||||
|
const auto& r = layoutData->rect;
|
||||||
|
rect.moveRight( r.right() - ( rect.left() - r.left() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
qskSetItemGeometry( item, rect );
|
return QRectF( 0, 0, -1, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal QskLayoutEngine2D::widthForHeight( qreal height ) const
|
qreal QskLayoutEngine2D::widthForHeight( qreal height ) const
|
||||||
@ -421,7 +317,7 @@ QSizeF QskLayoutEngine2D::sizeHint(
|
|||||||
if ( constraint.height() >= 0 || constraint.width() >= 0 )
|
if ( constraint.height() >= 0 || constraint.width() >= 0 )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
As none of the items have the Constrained flag the constraint
|
As none of the elements has the Constrained flag the constraint
|
||||||
will have no effect and we ignore it to make use of the cached
|
will have no effect and we ignore it to make use of the cached
|
||||||
results from unconstrained requests
|
results from unconstrained requests
|
||||||
*/
|
*/
|
||||||
@ -477,54 +373,6 @@ QSizeF QskLayoutEngine2D::sizeHint(
|
|||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
QskLayoutMetrics QskLayoutEngine2D::layoutMetrics( const QQuickItem* item,
|
|
||||||
Qt::Orientation orientation, qreal constraint ) const
|
|
||||||
{
|
|
||||||
if ( item == nullptr )
|
|
||||||
return QskLayoutMetrics();
|
|
||||||
|
|
||||||
const auto policy = qskSizePolicy( item ).policy( orientation );
|
|
||||||
|
|
||||||
if ( constraint >= 0.0 )
|
|
||||||
{
|
|
||||||
if ( !( policy & QskSizePolicy::ConstrainedFlag ) )
|
|
||||||
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 = qskEffectiveConstraint( item, Qt::MinimumSize, orientation );
|
|
||||||
maximum = qskEffectiveConstraint( item, Qt::MaximumSize, orientation );
|
|
||||||
preferred = minimum;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
preferred = qskLayoutConstraint( item, orientation, constraint );
|
|
||||||
|
|
||||||
if ( policy & QskSizePolicy::ShrinkFlag )
|
|
||||||
minimum = qskEffectiveConstraint( item, Qt::MinimumSize, orientation );
|
|
||||||
else
|
|
||||||
minimum = preferred;
|
|
||||||
|
|
||||||
if ( policy & expandFlags )
|
|
||||||
maximum = qskEffectiveConstraint( item, Qt::MaximumSize, orientation );
|
|
||||||
else
|
|
||||||
maximum = preferred;
|
|
||||||
|
|
||||||
if ( policy & QskSizePolicy::IgnoreFlag )
|
|
||||||
preferred = minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QskLayoutMetrics( minimum, preferred, maximum );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLayoutEngine2D::setupChain( Qt::Orientation orientation ) const
|
void QskLayoutEngine2D::setupChain( Qt::Orientation orientation ) const
|
||||||
{
|
{
|
||||||
setupChain( orientation, QskLayoutChain::Segments() );
|
setupChain( orientation, QskLayoutChain::Segments() );
|
||||||
@ -631,7 +479,7 @@ QskSizePolicy::ConstraintType QskLayoutEngine2D::constraintType() const
|
|||||||
|
|
||||||
for ( int i = 0; i < count(); i++ )
|
for ( int i = 0; i < count(); i++ )
|
||||||
{
|
{
|
||||||
const auto type = qskSizePolicy( itemAt( i ) ).constraintType();
|
const auto type = sizePolicyAt( i ).constraintType();
|
||||||
|
|
||||||
if ( type != QskSizePolicy::Unconstrained )
|
if ( type != QskSizePolicy::Unconstrained )
|
||||||
{
|
{
|
||||||
|
@ -13,8 +13,7 @@
|
|||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class QQuickItem;
|
class QskLayoutElement;
|
||||||
class QskLayoutMetrics;
|
|
||||||
|
|
||||||
class QskLayoutEngine2D
|
class QskLayoutEngine2D
|
||||||
{
|
{
|
||||||
@ -24,10 +23,6 @@ class QskLayoutEngine2D
|
|||||||
|
|
||||||
virtual int count() const = 0;
|
virtual int count() const = 0;
|
||||||
|
|
||||||
virtual QQuickItem* itemAt( int index ) const = 0;
|
|
||||||
|
|
||||||
int indexOf( const QQuickItem* ) const;
|
|
||||||
|
|
||||||
int rowCount() const;
|
int rowCount() const;
|
||||||
int columnCount() const;
|
int columnCount() const;
|
||||||
|
|
||||||
@ -55,10 +50,7 @@ class QskLayoutEngine2D
|
|||||||
void setGeometries( const QRectF& );
|
void setGeometries( const QRectF& );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
QRectF geometryAt( const QskLayoutElement*, const QRect& grid ) const;
|
||||||
void layoutItem( QQuickItem*, const QRect& grid ) const;
|
|
||||||
QskLayoutMetrics layoutMetrics( const QQuickItem*,
|
|
||||||
Qt::Orientation, qreal constraint ) const;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -79,6 +71,8 @@ class QskLayoutEngine2D
|
|||||||
virtual void invalidateElementCache() = 0;
|
virtual void invalidateElementCache() = 0;
|
||||||
QskSizePolicy::ConstraintType constraintType() const;
|
QskSizePolicy::ConstraintType constraintType() const;
|
||||||
|
|
||||||
|
virtual QskSizePolicy sizePolicyAt( int index ) const = 0;
|
||||||
|
|
||||||
void setupChain( Qt::Orientation ) const;
|
void setupChain( Qt::Orientation ) const;
|
||||||
void setupChain( Qt::Orientation, const QskLayoutChain::Segments& ) const;
|
void setupChain( Qt::Orientation, const QskLayoutChain::Segments& ) const;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "QskLinearLayoutEngine.h"
|
#include "QskLinearLayoutEngine.h"
|
||||||
#include "QskLayoutMetrics.h"
|
#include "QskLayoutMetrics.h"
|
||||||
#include "QskLayoutChain.h"
|
#include "QskLayoutChain.h"
|
||||||
|
#include "QskLayoutElement.h"
|
||||||
#include "QskSizePolicy.h"
|
#include "QskSizePolicy.h"
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
|
|
||||||
@ -13,6 +14,13 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
inline QskLayoutMetrics qskItemMetrics(
|
||||||
|
QQuickItem* item, Qt::Orientation orientation, qreal constraint )
|
||||||
|
{
|
||||||
|
const QskItemLayoutElement layoutItem( item );
|
||||||
|
return layoutItem.metrics( orientation, constraint );
|
||||||
|
}
|
||||||
|
|
||||||
class Element
|
class Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -331,6 +339,30 @@ bool QskLinearLayoutEngine::clear()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QskSizePolicy QskLinearLayoutEngine::sizePolicyAt( int index ) const
|
||||||
|
{
|
||||||
|
return qskSizePolicy( itemAt( index ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QskLinearLayoutEngine::indexOf( const QQuickItem* item ) const
|
||||||
|
{
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
indexOf is often called after inserting an item to
|
||||||
|
set additinal properties. So we search in reverse order
|
||||||
|
*/
|
||||||
|
|
||||||
|
for ( int i = count() - 1; i >= 0; --i )
|
||||||
|
{
|
||||||
|
if ( itemAt( i ) == item )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
QQuickItem* QskLinearLayoutEngine::itemAt( int index ) const
|
QQuickItem* QskLinearLayoutEngine::itemAt( int index ) const
|
||||||
{
|
{
|
||||||
if ( const auto element = m_data->elementAt( index ) )
|
if ( const auto element = m_data->elementAt( index ) )
|
||||||
@ -362,7 +394,12 @@ void QskLinearLayoutEngine::layoutItems()
|
|||||||
if ( qskIsAdjustableByLayout( item ) )
|
if ( qskIsAdjustableByLayout( item ) )
|
||||||
{
|
{
|
||||||
const QRect grid( col, row, 1, 1 );
|
const QRect grid( col, row, 1, 1 );
|
||||||
layoutItem( item, grid );
|
|
||||||
|
const QskItemLayoutElement layoutElement( item );
|
||||||
|
|
||||||
|
const auto rect = geometryAt( &layoutElement, grid );
|
||||||
|
if ( rect.size().isValid() )
|
||||||
|
qskSetItemGeometry( item, rect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +482,7 @@ void QskLinearLayoutEngine::setupChain( Qt::Orientation orientation,
|
|||||||
auto cell = element.cell( orientation, isLayoutOrientation );
|
auto cell = element.cell( orientation, isLayoutOrientation );
|
||||||
|
|
||||||
if ( element.item() )
|
if ( element.item() )
|
||||||
cell.metrics = layoutMetrics( element.item(), orientation, constraint );
|
cell.metrics = qskItemMetrics( element.item(), orientation, constraint );
|
||||||
|
|
||||||
chain.expandCell( index2, cell );
|
chain.expandCell( index2, cell );
|
||||||
|
|
||||||
|
@ -39,7 +39,9 @@ class QskLinearLayoutEngine : public QskLayoutEngine2D
|
|||||||
bool removeAt( int index );
|
bool removeAt( int index );
|
||||||
bool clear();
|
bool clear();
|
||||||
|
|
||||||
QQuickItem* itemAt( int index ) const override final;
|
int indexOf( const QQuickItem* ) const;
|
||||||
|
|
||||||
|
QQuickItem* itemAt( int index ) const;
|
||||||
qreal spacerAt( int index ) const;
|
qreal spacerAt( int index ) const;
|
||||||
|
|
||||||
bool setStretchFactorAt( int index, int stretchFactor );
|
bool setStretchFactorAt( int index, int stretchFactor );
|
||||||
@ -48,6 +50,7 @@ class QskLinearLayoutEngine : public QskLayoutEngine2D
|
|||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(QskLinearLayoutEngine)
|
Q_DISABLE_COPY(QskLinearLayoutEngine)
|
||||||
|
|
||||||
|
QskSizePolicy sizePolicyAt( int index ) const override final;
|
||||||
void layoutItems() override;
|
void layoutItems() override;
|
||||||
|
|
||||||
int effectiveCount() const;
|
int effectiveCount() const;
|
||||||
|
@ -317,6 +317,7 @@ HEADERS += \
|
|||||||
layouts/QskIndexedLayoutBox.h \
|
layouts/QskIndexedLayoutBox.h \
|
||||||
layouts/QskLayoutChain.h \
|
layouts/QskLayoutChain.h \
|
||||||
layouts/QskLayoutEngine2D.h \
|
layouts/QskLayoutEngine2D.h \
|
||||||
|
layouts/QskLayoutElement.h \
|
||||||
layouts/QskLayoutMetrics.h \
|
layouts/QskLayoutMetrics.h \
|
||||||
layouts/QskLinearBox.h \
|
layouts/QskLinearBox.h \
|
||||||
layouts/QskLinearLayoutEngine.h \
|
layouts/QskLinearLayoutEngine.h \
|
||||||
@ -329,6 +330,7 @@ SOURCES += \
|
|||||||
layouts/QskIndexedLayoutBox.cpp \
|
layouts/QskIndexedLayoutBox.cpp \
|
||||||
layouts/QskLayoutChain.cpp \
|
layouts/QskLayoutChain.cpp \
|
||||||
layouts/QskLayoutEngine2D.cpp \
|
layouts/QskLayoutEngine2D.cpp \
|
||||||
|
layouts/QskLayoutElement.cpp \
|
||||||
layouts/QskLayoutMetrics.cpp \
|
layouts/QskLayoutMetrics.cpp \
|
||||||
layouts/QskLinearBox.cpp \
|
layouts/QskLinearBox.cpp \
|
||||||
layouts/QskLinearLayoutEngine.cpp \
|
layouts/QskLinearLayoutEngine.cpp \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user