QskScrollArea respecting dynamic constraints
This commit is contained in:
parent
4c5e656283
commit
f3d6cdd669
@ -164,9 +164,15 @@ int main( int argc, char* argv[] )
|
|||||||
new QskPushButton( "Push Me", buttonBox );
|
new QskPushButton( "Push Me", buttonBox );
|
||||||
new QskPushButton( "Push Me", buttonBox );
|
new QskPushButton( "Push Me", buttonBox );
|
||||||
|
|
||||||
|
auto iconGrid = new IconGrid();
|
||||||
|
|
||||||
|
// don't allow to shrink the iconGrid
|
||||||
|
iconGrid->setSizePolicy( QskSizePolicy::MinimumExpanding,
|
||||||
|
QskSizePolicy::MinimumExpanding );
|
||||||
|
|
||||||
auto scrollArea = new ScrollArea( box );
|
auto scrollArea = new ScrollArea( box );
|
||||||
scrollArea->setMargins( QMarginsF( 25, 25, 5, 5 ) );
|
scrollArea->setMargins( QMarginsF( 25, 25, 5, 5 ) );
|
||||||
scrollArea->setScrolledItem( new IconGrid() );
|
scrollArea->setScrolledItem( iconGrid );
|
||||||
|
|
||||||
auto focusIndicator = new QskFocusIndicator();
|
auto focusIndicator = new QskFocusIndicator();
|
||||||
focusIndicator->setBoxBorderColorsHint( QskFocusIndicator::Panel, Qt::darkRed );
|
focusIndicator->setBoxBorderColorsHint( QskFocusIndicator::Panel, Qt::darkRed );
|
||||||
|
@ -24,10 +24,12 @@ class QSK_EXPORT QskSizePolicy
|
|||||||
public:
|
public:
|
||||||
enum Flag
|
enum Flag
|
||||||
{
|
{
|
||||||
GrowFlag = 1,
|
GrowFlag = 1 << 0,
|
||||||
ExpandFlag = 2,
|
ExpandFlag = 1 << 1,
|
||||||
ShrinkFlag = 4,
|
ShrinkFlag = 1 << 2,
|
||||||
IgnoreFlag = 8
|
IgnoreFlag = 1 << 3,
|
||||||
|
|
||||||
|
ConstrainedFlag = IgnoreFlag
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Policy
|
enum Policy
|
||||||
@ -39,7 +41,7 @@ class QSK_EXPORT QskSizePolicy
|
|||||||
MinimumExpanding = GrowFlag | ExpandFlag,
|
MinimumExpanding = GrowFlag | ExpandFlag,
|
||||||
Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
|
Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
|
||||||
Ignored = ShrinkFlag | GrowFlag | IgnoreFlag,
|
Ignored = ShrinkFlag | GrowFlag | IgnoreFlag,
|
||||||
Constrained = IgnoreFlag
|
Constrained = ConstrainedFlag
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_ENUM( Flag )
|
Q_ENUM( Flag )
|
||||||
|
@ -16,48 +16,6 @@ QSK_QT_PRIVATE_BEGIN
|
|||||||
#include <private/qquickwindow_p.h>
|
#include <private/qquickwindow_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
static QSizeF qskAdjustedSize( const QQuickItem* item, const QSizeF& targetSize )
|
|
||||||
{
|
|
||||||
using namespace QskLayoutConstraint;
|
|
||||||
|
|
||||||
QSizeF sz = effectiveConstraint( item, Qt::PreferredSize );
|
|
||||||
|
|
||||||
qreal w = sz.width();
|
|
||||||
qreal h = sz.height();
|
|
||||||
|
|
||||||
if ( targetSize != sz )
|
|
||||||
{
|
|
||||||
const QSizeF minSize = effectiveConstraint( item, Qt::MinimumSize );
|
|
||||||
const QSizeF maxSize = effectiveConstraint( item, Qt::MaximumSize );
|
|
||||||
|
|
||||||
const auto policy = sizePolicy( item );
|
|
||||||
|
|
||||||
if ( targetSize.width() > w )
|
|
||||||
{
|
|
||||||
if ( policy.horizontalPolicy() & QskSizePolicy::GrowFlag )
|
|
||||||
w = qMin( maxSize.width(), targetSize.width() );
|
|
||||||
}
|
|
||||||
else if ( targetSize.width() < w )
|
|
||||||
{
|
|
||||||
if ( policy.horizontalPolicy() & QskSizePolicy::ShrinkFlag )
|
|
||||||
w = qMax( minSize.width(), w );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( targetSize.height() > h )
|
|
||||||
{
|
|
||||||
if ( policy.verticalPolicy() & QskSizePolicy::GrowFlag )
|
|
||||||
h = qMin( maxSize.height(), targetSize.height() );
|
|
||||||
}
|
|
||||||
else if ( targetSize.height() < h )
|
|
||||||
{
|
|
||||||
if ( policy.verticalPolicy() & QskSizePolicy::ShrinkFlag )
|
|
||||||
h = qMax( minSize.height(), h );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QSizeF( w, h );
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class ViewportClipNode final : public QQuickDefaultClipNode
|
class ViewportClipNode final : public QQuickDefaultClipNode
|
||||||
@ -485,7 +443,7 @@ void QskScrollArea::adjustItem()
|
|||||||
moment we ignore this and start with a simplified code.
|
moment we ignore this and start with a simplified code.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
auto newSize = qskAdjustedSize( item, rect.size() );
|
const auto newSize = QskLayoutConstraint::adjustedSize( item, rect.size() );
|
||||||
item->setSize( newSize );
|
item->setSize( newSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,50 +628,54 @@ QPointF QskScrollView::boundedScrollPos( const QPointF& pos ) const
|
|||||||
|
|
||||||
Qt::Orientations QskScrollView::scrollableOrientations() const
|
Qt::Orientations QskScrollView::scrollableOrientations() const
|
||||||
{
|
{
|
||||||
|
// layoutRect ???
|
||||||
const QRectF vr = contentsRect();
|
const QRectF vr = contentsRect();
|
||||||
|
|
||||||
Qt::ScrollBarPolicy policyV = m_data->verticalScrollBarPolicy;
|
auto policyVertical = m_data->verticalScrollBarPolicy;
|
||||||
Qt::ScrollBarPolicy policyH = m_data->horizontalScrollBarPolicy;
|
auto policyHorizontal = m_data->horizontalScrollBarPolicy;
|
||||||
|
|
||||||
if ( policyV == Qt::ScrollBarAsNeeded )
|
if ( policyVertical == Qt::ScrollBarAsNeeded )
|
||||||
{
|
{
|
||||||
qreal h = vr.height();
|
qreal height = vr.height();
|
||||||
if ( policyH == Qt::ScrollBarAlwaysOn )
|
|
||||||
h -= metric( HorizontalScrollBar | QskAspect::Size );
|
|
||||||
|
|
||||||
if ( m_data->scrollableSize.height() > h )
|
if ( policyHorizontal == Qt::ScrollBarAlwaysOn )
|
||||||
policyV = Qt::ScrollBarAlwaysOn;
|
height -= metric( HorizontalScrollBar | QskAspect::Size );
|
||||||
|
|
||||||
|
if ( m_data->scrollableSize.height() > height )
|
||||||
|
policyVertical = Qt::ScrollBarAlwaysOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( policyH == Qt::ScrollBarAsNeeded )
|
if ( policyHorizontal == Qt::ScrollBarAsNeeded )
|
||||||
{
|
{
|
||||||
qreal w = vr.width();
|
qreal width = vr.width();
|
||||||
if ( policyV == Qt::ScrollBarAlwaysOn )
|
|
||||||
w -= metric( VerticalScrollBar | QskAspect::Size );
|
|
||||||
|
|
||||||
if ( m_data->scrollableSize.width() > w )
|
if ( policyVertical == Qt::ScrollBarAlwaysOn )
|
||||||
|
width -= metric( VerticalScrollBar | QskAspect::Size );
|
||||||
|
|
||||||
|
if ( m_data->scrollableSize.width() > width )
|
||||||
{
|
{
|
||||||
policyH = Qt::ScrollBarAlwaysOn;
|
policyHorizontal = Qt::ScrollBarAlwaysOn;
|
||||||
|
|
||||||
// we have to check the vertical once more
|
// we have to check the vertical once more
|
||||||
|
|
||||||
if ( ( policyV == Qt::ScrollBarAsNeeded ) &&
|
if ( ( policyVertical == Qt::ScrollBarAsNeeded ) &&
|
||||||
( m_data->scrollableSize.height() >
|
( m_data->scrollableSize.height() >
|
||||||
vr.height() - metric( HorizontalScrollBar | QskAspect::Size ) ) )
|
vr.height() - metric( HorizontalScrollBar | QskAspect::Size ) ) )
|
||||||
{
|
{
|
||||||
policyV = Qt::ScrollBarAlwaysOn;
|
policyVertical = Qt::ScrollBarAlwaysOn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::Orientations o;
|
Qt::Orientations orientations;
|
||||||
if ( policyH == Qt::ScrollBarAlwaysOn )
|
|
||||||
o |= Qt::Horizontal;
|
|
||||||
|
|
||||||
if ( policyV == Qt::ScrollBarAlwaysOn )
|
if ( policyHorizontal == Qt::ScrollBarAlwaysOn )
|
||||||
o |= Qt::Vertical;
|
orientations |= Qt::Horizontal;
|
||||||
|
|
||||||
return o;
|
if ( policyVertical == Qt::ScrollBarAlwaysOn )
|
||||||
|
orientations |= Qt::Vertical;
|
||||||
|
|
||||||
|
return orientations;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskScrollView.cpp"
|
#include "moc_QskScrollView.cpp"
|
||||||
|
@ -54,6 +54,7 @@ QRectF QskScrollViewSkinlet::subControlRect(
|
|||||||
|
|
||||||
if ( subControl == QskScrollView::Panel )
|
if ( subControl == QskScrollView::Panel )
|
||||||
{
|
{
|
||||||
|
// layoutRect ???
|
||||||
return scrollView->contentsRect();
|
return scrollView->contentsRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,23 @@ static inline bool qskHasHintFor( const QQuickItem* item, const char* method )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline qreal qskAdjustedValue( QskSizePolicy::Policy policy, qreal value, qreal targetValue )
|
||||||
|
{
|
||||||
|
if ( targetValue > value )
|
||||||
|
{
|
||||||
|
if ( policy & QskSizePolicy::GrowFlag )
|
||||||
|
return targetValue;
|
||||||
|
}
|
||||||
|
else if ( targetValue < value )
|
||||||
|
{
|
||||||
|
if ( policy & QskSizePolicy::ShrinkFlag )
|
||||||
|
return targetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool QskLayoutConstraint::hasDynamicConstraint( const QQuickItem* item )
|
bool QskLayoutConstraint::hasDynamicConstraint( const QQuickItem* item )
|
||||||
{
|
{
|
||||||
if ( const QskControl* control = qobject_cast< const QskControl* >( item ) )
|
if ( const QskControl* control = qobject_cast< const QskControl* >( item ) )
|
||||||
@ -141,3 +158,68 @@ QskSizePolicy QskLayoutConstraint::sizePolicy( const QQuickItem* item )
|
|||||||
|
|
||||||
return QskSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred );
|
return QskSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSizeF QskLayoutConstraint::boundedSize( const QQuickItem* item, const QSizeF& size )
|
||||||
|
{
|
||||||
|
const auto minSize = effectiveConstraint( item, Qt::MinimumSize );
|
||||||
|
const auto maxSize = effectiveConstraint( item, Qt::MaximumSize );
|
||||||
|
|
||||||
|
qreal width = size.width();
|
||||||
|
qreal height = size.height();
|
||||||
|
|
||||||
|
if ( ( minSize.width() >= 0 ) && ( minSize.width() > width ) )
|
||||||
|
width = minSize.width();
|
||||||
|
|
||||||
|
if ( ( minSize.height() >= 0 ) && ( minSize.height() > height ) )
|
||||||
|
height = minSize.height();
|
||||||
|
|
||||||
|
if ( ( maxSize.width() >= 0 ) && ( maxSize.width() < width ) )
|
||||||
|
width = maxSize.width();
|
||||||
|
|
||||||
|
if ( ( maxSize.height() >= 0 ) && ( maxSize.height() < height ) )
|
||||||
|
height = maxSize.height();
|
||||||
|
|
||||||
|
return QSizeF( width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskLayoutConstraint::adjustedSize( const QQuickItem* item, const QSizeF& targetSize )
|
||||||
|
{
|
||||||
|
const auto policy = sizePolicy( item );
|
||||||
|
|
||||||
|
const auto boundedSize = QskLayoutConstraint::boundedSize( item, targetSize );
|
||||||
|
const auto preferredSize = effectiveConstraint( item, Qt::PreferredSize );
|
||||||
|
|
||||||
|
qreal w;
|
||||||
|
qreal h;
|
||||||
|
|
||||||
|
if ( policy.horizontalPolicy() == QskSizePolicy::Constrained )
|
||||||
|
{
|
||||||
|
h = qskAdjustedValue( policy.verticalPolicy(),
|
||||||
|
preferredSize.height(), boundedSize.height() );
|
||||||
|
|
||||||
|
w = widthForHeight( item, h );
|
||||||
|
|
||||||
|
if ( w < boundedSize.height() )
|
||||||
|
w = boundedSize.height();
|
||||||
|
}
|
||||||
|
else if ( policy.verticalPolicy() == QskSizePolicy::Constrained )
|
||||||
|
{
|
||||||
|
w = qskAdjustedValue( policy.horizontalPolicy(),
|
||||||
|
preferredSize.width(), boundedSize.width() );
|
||||||
|
|
||||||
|
h = heightForWidth( item, w );
|
||||||
|
|
||||||
|
if ( h < boundedSize.height() )
|
||||||
|
h = boundedSize.height();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w = qskAdjustedValue( policy.horizontalPolicy(),
|
||||||
|
preferredSize.width(), boundedSize.width() );
|
||||||
|
|
||||||
|
h = qskAdjustedValue( policy.verticalPolicy(),
|
||||||
|
preferredSize.height(), boundedSize.height() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSizeF( w, h );
|
||||||
|
}
|
||||||
|
@ -24,6 +24,11 @@ namespace QskLayoutConstraint
|
|||||||
QSK_EXPORT QSizeF effectiveConstraint( const QQuickItem*, Qt::SizeHint );
|
QSK_EXPORT QSizeF effectiveConstraint( const QQuickItem*, Qt::SizeHint );
|
||||||
QSK_EXPORT QskSizePolicy sizePolicy( const QQuickItem* );
|
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& );
|
||||||
|
|
||||||
// QGridLayoutEngine internally uses FLT_MAX
|
// QGridLayoutEngine internally uses FLT_MAX
|
||||||
const qreal unlimited = std::numeric_limits< float >::max();
|
const qreal unlimited = std::numeric_limits< float >::max();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user