211 lines
5.8 KiB
C++
211 lines
5.8 KiB
C++
![]() |
/******************************************************************************
|
||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "QskLayoutItem.h"
|
||
|
#include "QskControl.h"
|
||
|
#include "QskLayoutConstraint.h"
|
||
|
|
||
|
#include <QQuickItem>
|
||
|
|
||
|
QskLayoutItem::QskLayoutItem( QQuickItem* item,
|
||
|
int row, int column, int rowSpan, int columnSpan ):
|
||
|
Inherited( row, column, qMax( rowSpan, 1 ), qMax( columnSpan, 1 ), Qt::Alignment() ),
|
||
|
m_isGeometryDirty( false ),
|
||
|
m_isStretchable( false ),
|
||
|
m_retainSizeWhenHidden( false ),
|
||
|
m_unlimitedRowSpan( rowSpan <= 0 ),
|
||
|
m_unlimitedColumnSpan( columnSpan <= 0 ),
|
||
|
m_updateMode( UpdateWhenVisible ),
|
||
|
m_item( item )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
QskLayoutItem::QskLayoutItem( const QSizeF& size, int stretch, int row, int column ):
|
||
|
Inherited( row, column, 1, 1, Qt::Alignment() ),
|
||
|
m_isGeometryDirty( false ),
|
||
|
m_isStretchable( stretch > 0 ),
|
||
|
m_retainSizeWhenHidden( false ),
|
||
|
m_unlimitedRowSpan( false ),
|
||
|
m_unlimitedColumnSpan( false ),
|
||
|
m_updateMode( UpdateWhenVisible ),
|
||
|
m_spacingHint( size ),
|
||
|
m_item( nullptr )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
QskLayoutItem::~QskLayoutItem()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
QskLayoutItem::UpdateMode QskLayoutItem::updateMode() const
|
||
|
{
|
||
|
return m_updateMode;
|
||
|
}
|
||
|
|
||
|
void QskLayoutItem::setUpdateMode( UpdateMode mode )
|
||
|
{
|
||
|
m_updateMode = mode;
|
||
|
}
|
||
|
|
||
|
bool QskLayoutItem::retainSizeWhenHidden() const
|
||
|
{
|
||
|
return m_retainSizeWhenHidden;
|
||
|
}
|
||
|
|
||
|
void QskLayoutItem::setRetainSizeWhenHidden( bool on )
|
||
|
{
|
||
|
m_retainSizeWhenHidden = on;
|
||
|
}
|
||
|
|
||
|
QSizeF QskLayoutItem::spacingHint() const
|
||
|
{
|
||
|
return m_spacingHint;
|
||
|
}
|
||
|
|
||
|
void QskLayoutItem::setSpacingHint( const QSizeF& hint )
|
||
|
{
|
||
|
m_spacingHint = 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 ( m_isStretchable && whichHint == Qt::MaximumSize )
|
||
|
return QSizeF( QskLayoutConstraint::unlimited, QskLayoutConstraint::unlimited );
|
||
|
|
||
|
// a spacer item
|
||
|
return m_spacingHint;
|
||
|
}
|
||
|
|
||
|
QSizeF hint( 0, 0 );
|
||
|
|
||
|
if ( whichHint == Qt::PreferredSize && QskLayoutConstraint::hasDynamicConstraint( m_item ) )
|
||
|
{
|
||
|
const quint32 growFlags = QLayoutPolicy::GrowFlag | QLayoutPolicy::ExpandFlag;
|
||
|
hint = QskLayoutConstraint::effectiveConstraint( m_item, whichHint );
|
||
|
|
||
|
if ( constraint.width() > 0 )
|
||
|
{
|
||
|
qreal w = constraint.width();
|
||
|
if ( !( sizePolicy( Qt::Horizontal ) & growFlags ) )
|
||
|
w = qMin( w, hint.width() );
|
||
|
|
||
|
hint.setWidth( w );
|
||
|
hint.setHeight( QskLayoutConstraint::heightForWidth( m_item, w ) );
|
||
|
}
|
||
|
else if ( constraint.height() > 0 )
|
||
|
{
|
||
|
qreal h = constraint.height();
|
||
|
if ( !( sizePolicy( Qt::Vertical ) & growFlags ) )
|
||
|
h = qMin( h, hint.height() );
|
||
|
|
||
|
hint.setWidth( QskLayoutConstraint::widthForHeight( m_item, h ) );
|
||
|
hint.setHeight( h );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
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 hint;
|
||
|
}
|
||
|
|
||
|
QLayoutPolicy::Policy QskLayoutItem::sizePolicy( Qt::Orientation orientation ) const
|
||
|
{
|
||
|
auto policy = QskLayoutConstraint::sizePolicy( m_item ).policy( orientation );
|
||
|
#if 1
|
||
|
if ( ( policy == QskSizePolicy::Preferred ) && m_item )
|
||
|
{
|
||
|
// QskSizePolicy::Preferred without having a preferred size is the default
|
||
|
// setting of QskControl - taken from what QWidget does - but this combination
|
||
|
// doesn't make much sense. Usually every derived control is supposed
|
||
|
// to set specific values, but in case it has been forgotten we better
|
||
|
// ignore the preferred size then.
|
||
|
|
||
|
const QSizeF hint = QskLayoutConstraint::effectiveConstraint( m_item, Qt::PreferredSize );
|
||
|
|
||
|
const qreal h = ( orientation == Qt::Horizontal ) ? hint.width() : hint.height();
|
||
|
if ( h <= 0 )
|
||
|
policy = QskSizePolicy::Ignored;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return static_cast< QLayoutPolicy::Policy >( policy );
|
||
|
}
|
||
|
|
||
|
void QskLayoutItem::setGeometry( const QRectF& rect )
|
||
|
{
|
||
|
if ( m_item == nullptr )
|
||
|
return;
|
||
|
|
||
|
if( m_updateMode == UpdateNone )
|
||
|
{
|
||
|
if ( !m_isGeometryDirty )
|
||
|
m_isGeometryDirty = ( rect != m_item->boundingRect() );
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( m_updateMode == UpdateWhenVisible )
|
||
|
{
|
||
|
if ( !m_item->isVisible() )
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_isGeometryDirty = false;
|
||
|
m_item->setPosition( rect.topLeft() );
|
||
|
m_item->setSize( rect.size() );
|
||
|
}
|
||
|
|
||
|
bool QskLayoutItem::hasDynamicConstraint() const
|
||
|
{
|
||
|
if ( m_item )
|
||
|
return QskLayoutConstraint::hasDynamicConstraint( m_item );
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
Qt::Orientation QskLayoutItem::dynamicConstraintOrientation() const
|
||
|
{
|
||
|
Qt::Orientation orientation = Qt::Vertical;
|
||
|
|
||
|
if ( const QskControl* control = qobject_cast< const QskControl* >( m_item ) )
|
||
|
{
|
||
|
const QskSizePolicy& policy = control->sizePolicy();
|
||
|
if ( policy.horizontalPolicy() == QskSizePolicy::Constrained )
|
||
|
return Qt::Horizontal;
|
||
|
else
|
||
|
return Qt::Vertical;
|
||
|
}
|
||
|
|
||
|
return orientation;
|
||
|
}
|
||
|
|
||
|
bool QskLayoutItem::isIgnored() const
|
||
|
{
|
||
|
if ( m_item && !m_item->isVisible() )
|
||
|
return !m_retainSizeWhenHidden;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
QLayoutPolicy::ControlTypes QskLayoutItem::controlTypes( LayoutSide side ) const
|
||
|
{
|
||
|
return Inherited::controlTypes( side );
|
||
|
}
|