antizipate scrollbars before resizing the content item
This commit is contained in:
parent
94b2aec272
commit
90bfc14a00
@ -7,6 +7,7 @@
|
|||||||
#include "QskEvent.h"
|
#include "QskEvent.h"
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
#include "QskScrollViewSkinlet.h"
|
#include "QskScrollViewSkinlet.h"
|
||||||
|
#include "QskBoxBorderMetrics.h"
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickclipnode_p.h>
|
#include <private/qquickclipnode_p.h>
|
||||||
@ -15,6 +16,83 @@ QSK_QT_PRIVATE_BEGIN
|
|||||||
#include <private/qquickwindow_p.h>
|
#include <private/qquickwindow_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
static inline bool qskNeedsScrollBars(
|
||||||
|
qreal available, qreal required, Qt::ScrollBarPolicy policy )
|
||||||
|
{
|
||||||
|
if ( policy == Qt::ScrollBarAsNeeded )
|
||||||
|
return required > available;
|
||||||
|
else
|
||||||
|
return policy == Qt::ScrollBarAlwaysOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QSizeF qskPanelInnerSize( const QskScrollView* scrollView )
|
||||||
|
{
|
||||||
|
auto size = scrollView->subControlRect( QskScrollView::Panel ).size();
|
||||||
|
|
||||||
|
const auto borderMetrics = scrollView->boxBorderMetricsHint( QskScrollView::Viewport );
|
||||||
|
const qreal bw = 2 * borderMetrics.widthAt( Qt::TopEdge );
|
||||||
|
|
||||||
|
size.setWidth( qMax( size.width() - bw, 0.0 ) );
|
||||||
|
size.setHeight( qMax( size.height() - bw, 0.0 ) );
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QSizeF qskScrolledItemSize( const QskScrollView* scrollView,
|
||||||
|
const QQuickItem* item, const QSizeF& boundingSize )
|
||||||
|
{
|
||||||
|
QSizeF outerSize = boundingSize;
|
||||||
|
|
||||||
|
const qreal spacing = scrollView->metric( QskScrollView::Panel | QskAspect::Spacing );
|
||||||
|
|
||||||
|
const auto sbV = scrollView->metric( QskScrollView::VerticalScrollBar | QskAspect::Size );
|
||||||
|
const auto sbH = scrollView->metric( QskScrollView::HorizontalScrollBar | QskAspect::Size );
|
||||||
|
|
||||||
|
const auto policyH = scrollView->horizontalScrollBarPolicy();
|
||||||
|
const auto policyV = scrollView->verticalScrollBarPolicy();
|
||||||
|
|
||||||
|
auto itemSize = qskConstrainedItemSize( item, outerSize );
|
||||||
|
|
||||||
|
bool needScrollBarV = qskNeedsScrollBars( outerSize.height(), itemSize.height(), policyV );
|
||||||
|
bool needScrollBarH = qskNeedsScrollBars( outerSize.width(), itemSize.width(), policyH );
|
||||||
|
|
||||||
|
bool hasScrollBarV = needScrollBarV;
|
||||||
|
|
||||||
|
// Vertical/Horizonal scroll bars might depend on each other
|
||||||
|
|
||||||
|
if ( needScrollBarV )
|
||||||
|
{
|
||||||
|
outerSize.rwidth() -= sbV + spacing;
|
||||||
|
itemSize = qskConstrainedItemSize( item, outerSize );
|
||||||
|
|
||||||
|
if ( !needScrollBarH )
|
||||||
|
{
|
||||||
|
needScrollBarH = qskNeedsScrollBars(
|
||||||
|
outerSize.width(), itemSize.width(), policyH );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( needScrollBarH )
|
||||||
|
{
|
||||||
|
outerSize.rheight() -= sbH + spacing;
|
||||||
|
itemSize = qskConstrainedItemSize( item, outerSize );
|
||||||
|
|
||||||
|
if ( !hasScrollBarV )
|
||||||
|
{
|
||||||
|
needScrollBarV = qskNeedsScrollBars(
|
||||||
|
outerSize.height(), itemSize.height(), policyV );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( needScrollBarV )
|
||||||
|
{
|
||||||
|
outerSize.rwidth() -= sbV + spacing;
|
||||||
|
itemSize = qskConstrainedItemSize( item, outerSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemSize;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class ViewportClipNode final : public QQuickDefaultClipNode
|
class ViewportClipNode final : public QQuickDefaultClipNode
|
||||||
@ -124,6 +202,11 @@ class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeLi
|
|||||||
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setItemSizeChangedEnabled( bool on )
|
||||||
|
{
|
||||||
|
m_isSizeChangedEnabled = on;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event( QEvent* event ) override;
|
bool event( QEvent* event ) override;
|
||||||
|
|
||||||
@ -134,7 +217,7 @@ class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeLi
|
|||||||
void itemGeometryChanged( QQuickItem*,
|
void itemGeometryChanged( QQuickItem*,
|
||||||
QQuickGeometryChange change, const QRectF& ) override
|
QQuickGeometryChange change, const QRectF& ) override
|
||||||
{
|
{
|
||||||
if ( change.sizeChange() )
|
if ( m_isSizeChangedEnabled && change.sizeChange() )
|
||||||
scrollArea()->polish();
|
scrollArea()->polish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +225,7 @@ class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeLi
|
|||||||
void itemGeometryChanged( QQuickItem*,
|
void itemGeometryChanged( QQuickItem*,
|
||||||
const QRectF& newRect, const QRectF& oldRect ) override
|
const QRectF& newRect, const QRectF& oldRect ) override
|
||||||
{
|
{
|
||||||
if ( oldRect.size() != newRect.size() )
|
if ( m_isSizeChangedEnabled && ( oldRect.size() != newRect.size() ) )
|
||||||
scrollArea()->polish();
|
scrollArea()->polish();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -161,6 +244,8 @@ class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QSGClipNode* viewPortClipNode() const;
|
const QSGClipNode* viewPortClipNode() const;
|
||||||
|
|
||||||
|
bool m_isSizeChangedEnabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
QskScrollAreaClipItem::QskScrollAreaClipItem( QskScrollArea* scrollArea )
|
QskScrollAreaClipItem::QskScrollAreaClipItem( QskScrollArea* scrollArea )
|
||||||
@ -371,39 +456,38 @@ void QskScrollArea::adjustItem()
|
|||||||
{
|
{
|
||||||
setScrollableSize( QSizeF() );
|
setScrollableSize( QSizeF() );
|
||||||
setScrollPos( QPointF() );
|
setScrollPos( QPointF() );
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if ( m_data->isItemResizable )
|
||||||
{
|
{
|
||||||
if ( m_data->isItemResizable )
|
QSizeF itemSize;
|
||||||
|
|
||||||
|
const auto viewSize = qskPanelInnerSize( this );
|
||||||
|
if ( !viewSize.isEmpty() )
|
||||||
{
|
{
|
||||||
auto size = viewContentsRect().size();
|
// we have to anticipate the scrollbars
|
||||||
if ( size.isEmpty() )
|
itemSize = qskScrolledItemSize( this, item, viewSize );
|
||||||
{
|
|
||||||
size = QSizeF( 0.0, 0.0 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
For optional scrollbars the available space also depends
|
|
||||||
on wether the adjustedSize results in scroll bars. For the
|
|
||||||
moment we ignore this and start with a simplified code. TODO ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
size = qskConstrainedItemSize( item, size );
|
|
||||||
}
|
|
||||||
|
|
||||||
item->setSize( size );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data->enableAutoTranslation( this, false );
|
if ( itemSize.isEmpty() )
|
||||||
|
itemSize = QSizeF( 0.0, 0.0 );
|
||||||
|
|
||||||
setScrollableSize( QSizeF( item->width(), item->height() ) );
|
|
||||||
setScrollPos( scrollPos() );
|
|
||||||
|
|
||||||
m_data->enableAutoTranslation( this, true );
|
m_data->clipItem->setItemSizeChangedEnabled( false );
|
||||||
|
item->setSize( itemSize );
|
||||||
translateItem();
|
m_data->clipItem->setItemSizeChangedEnabled( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_data->enableAutoTranslation( this, false );
|
||||||
|
|
||||||
|
setScrollableSize( QSizeF( item->width(), item->height() ) );
|
||||||
|
setScrollPos( scrollPos() );
|
||||||
|
|
||||||
|
m_data->enableAutoTranslation( this, true );
|
||||||
|
|
||||||
|
translateItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskScrollArea::setItemResizable( bool on )
|
void QskScrollArea::setItemResizable( bool on )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user