moving ClipItem to namespace
This commit is contained in:
parent
1228518e6a
commit
571f532307
|
@ -175,212 +175,215 @@ namespace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeListener
|
namespace
|
||||||
{
|
{
|
||||||
// when inheriting from QskControl we participate in node cleanups
|
class ClipItem final : public QskControl, public QQuickItemChangeListener
|
||||||
using Inherited = QskControl;
|
|
||||||
|
|
||||||
public:
|
|
||||||
QskScrollAreaClipItem( QskScrollArea* );
|
|
||||||
virtual ~QskScrollAreaClipItem();
|
|
||||||
|
|
||||||
void enableGeometryListener( bool on );
|
|
||||||
|
|
||||||
QQuickItem* scrolledItem() const
|
|
||||||
{
|
{
|
||||||
auto children = childItems();
|
// when inheriting from QskControl we participate in node cleanups
|
||||||
return children.isEmpty() ? nullptr : children.first();
|
using Inherited = QskControl;
|
||||||
}
|
|
||||||
|
|
||||||
bool contains( const QPointF& pos ) const override
|
public:
|
||||||
{
|
ClipItem( QskScrollArea* );
|
||||||
return clipRect().contains( pos );
|
virtual ~ClipItem();
|
||||||
}
|
|
||||||
|
|
||||||
QRectF clipRect() const override
|
void enableGeometryListener( bool on );
|
||||||
{
|
|
||||||
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setItemSizeChangedEnabled( bool on )
|
QQuickItem* scrolledItem() const
|
||||||
{
|
|
||||||
m_isSizeChangedEnabled = on;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool event( QEvent* event ) override;
|
|
||||||
|
|
||||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
|
||||||
void geometryChanged( const QRectF&, const QRectF& ) override;
|
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK( 5, 8, 0 )
|
|
||||||
void itemGeometryChanged( QQuickItem*,
|
|
||||||
QQuickGeometryChange change, const QRectF& ) override
|
|
||||||
{
|
|
||||||
if ( m_isSizeChangedEnabled && change.sizeChange() )
|
|
||||||
scrollArea()->polish();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void itemGeometryChanged( QQuickItem*,
|
|
||||||
const QRectF& newRect, const QRectF& oldRect ) override
|
|
||||||
{
|
|
||||||
if ( m_isSizeChangedEnabled && ( oldRect.size() != newRect.size() ) )
|
|
||||||
scrollArea()->polish();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void updateNode( QSGNode* ) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline QskScrollArea* scrollArea()
|
|
||||||
{
|
|
||||||
return static_cast< QskScrollArea* >( parentItem() );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const QskScrollArea* scrollArea() const
|
|
||||||
{
|
|
||||||
return static_cast< const QskScrollArea* >( parentItem() );
|
|
||||||
}
|
|
||||||
|
|
||||||
const QSGClipNode* viewPortClipNode() const;
|
|
||||||
|
|
||||||
bool m_isSizeChangedEnabled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
QskScrollAreaClipItem::QskScrollAreaClipItem( QskScrollArea* scrollArea )
|
|
||||||
: Inherited( scrollArea )
|
|
||||||
{
|
|
||||||
setObjectName( QStringLiteral( "QskScrollAreaClipItem" ) );
|
|
||||||
setClip( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
QskScrollAreaClipItem::~QskScrollAreaClipItem()
|
|
||||||
{
|
|
||||||
enableGeometryListener( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskScrollAreaClipItem::updateNode( QSGNode* )
|
|
||||||
{
|
|
||||||
auto* d = QQuickItemPrivate::get( this );
|
|
||||||
|
|
||||||
if ( QQuickItemPrivate::get( scrollArea() )->dirtyAttributes &
|
|
||||||
QQuickItemPrivate::ContentUpdateMask )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
The update order depends on who calls update first and we
|
|
||||||
have to handle being called before a new clip node has
|
|
||||||
been created by the scrollview.
|
|
||||||
But better invalidate the unguarded clip geometry until then ...
|
|
||||||
*/
|
|
||||||
auto clipNode = d->clipNode();
|
|
||||||
if ( clipNode && !clipNode->isRectangular() )
|
|
||||||
{
|
{
|
||||||
clipNode->setIsRectangular( true );
|
auto children = childItems();
|
||||||
clipNode->setGeometry( nullptr );
|
return children.isEmpty() ? nullptr : children.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
// in the next cycle we will find a valid clip
|
bool contains( const QPointF& pos ) const override
|
||||||
update();
|
{
|
||||||
return;
|
return clipRect().contains( pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto clipNode = d->clipNode();
|
QRectF clipRect() const override
|
||||||
|
{
|
||||||
|
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
||||||
|
}
|
||||||
|
|
||||||
if ( clipNode && !( clipNode->flags() & QSGNode::OwnsMaterial ) )
|
inline void setItemSizeChangedEnabled( bool on )
|
||||||
|
{
|
||||||
|
m_isSizeChangedEnabled = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool event( QEvent* event ) override;
|
||||||
|
|
||||||
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
|
void geometryChanged( const QRectF&, const QRectF& ) override;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK( 5, 8, 0 )
|
||||||
|
void itemGeometryChanged( QQuickItem*,
|
||||||
|
QQuickGeometryChange change, const QRectF& ) override
|
||||||
|
{
|
||||||
|
if ( m_isSizeChangedEnabled && change.sizeChange() )
|
||||||
|
scrollArea()->polish();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void itemGeometryChanged( QQuickItem*,
|
||||||
|
const QRectF& newRect, const QRectF& oldRect ) override
|
||||||
|
{
|
||||||
|
if ( m_isSizeChangedEnabled && ( oldRect.size() != newRect.size() ) )
|
||||||
|
scrollArea()->polish();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void updateNode( QSGNode* ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline QskScrollArea* scrollArea()
|
||||||
|
{
|
||||||
|
return static_cast< QskScrollArea* >( parentItem() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const QskScrollArea* scrollArea() const
|
||||||
|
{
|
||||||
|
return static_cast< const QskScrollArea* >( parentItem() );
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSGClipNode* viewPortClipNode() const;
|
||||||
|
|
||||||
|
bool m_isSizeChangedEnabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ClipItem::ClipItem( QskScrollArea* scrollArea )
|
||||||
|
: Inherited( scrollArea )
|
||||||
{
|
{
|
||||||
// Replace the clip node being inserted from QQuickWindow
|
setObjectName( QStringLiteral( "QskScrollAreaClipItem" ) );
|
||||||
|
setClip( true );
|
||||||
auto parentNode = clipNode->parent();
|
|
||||||
|
|
||||||
auto node = new ViewportClipNode();
|
|
||||||
parentNode->appendChildNode( node );
|
|
||||||
clipNode->reparentChildNodesTo( node );
|
|
||||||
|
|
||||||
parentNode->removeChildNode( clipNode );
|
|
||||||
|
|
||||||
if ( clipNode->flags() & QSGNode::OwnedByParent )
|
|
||||||
delete clipNode;
|
|
||||||
|
|
||||||
d->extra->clipNode = clipNode = node;
|
|
||||||
Q_ASSERT( clipNode == QQuickItemPrivate::get( this )->clipNode() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( clipNode )
|
ClipItem::~ClipItem()
|
||||||
{
|
|
||||||
/*
|
|
||||||
Update the clip node with the geometry of the clip node
|
|
||||||
of the viewport of the scrollview.
|
|
||||||
*/
|
|
||||||
auto viewClipNode = static_cast< ViewportClipNode* >( clipNode );
|
|
||||||
viewClipNode->copyFrom( viewPortClipNode() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QSGClipNode* QskScrollAreaClipItem::viewPortClipNode() const
|
|
||||||
{
|
|
||||||
auto node = const_cast< QSGNode* >( qskPaintNode( scrollArea() ) );
|
|
||||||
if ( node )
|
|
||||||
node = QskSkinlet::findNodeByRole( node, QskScrollViewSkinlet::ContentsRootRole );
|
|
||||||
|
|
||||||
if ( node && node->type() == QSGNode::ClipNodeType )
|
|
||||||
return static_cast< QSGClipNode* >( node );
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskScrollAreaClipItem::geometryChanged(
|
|
||||||
const QRectF& newRect, const QRectF& oldRect )
|
|
||||||
{
|
|
||||||
Inherited::geometryChanged( newRect, oldRect );
|
|
||||||
|
|
||||||
if ( newRect.size() != oldRect.size() )
|
|
||||||
{
|
|
||||||
// we need to restore the clip node
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskScrollAreaClipItem::itemChange(
|
|
||||||
QQuickItem::ItemChange change, const QQuickItem::ItemChangeData& value )
|
|
||||||
{
|
|
||||||
if ( change == QQuickItem::ItemChildAddedChange )
|
|
||||||
{
|
|
||||||
enableGeometryListener( true );
|
|
||||||
}
|
|
||||||
else if ( change == QQuickItem::ItemChildRemovedChange )
|
|
||||||
{
|
{
|
||||||
enableGeometryListener( false );
|
enableGeometryListener( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
Inherited::itemChange( change, value );
|
void ClipItem::updateNode( QSGNode* )
|
||||||
}
|
|
||||||
|
|
||||||
void QskScrollAreaClipItem::enableGeometryListener( bool on )
|
|
||||||
{
|
|
||||||
auto item = scrolledItem();
|
|
||||||
if ( item )
|
|
||||||
{
|
{
|
||||||
// we might also be interested in ImplicitWidth/ImplicitHeight
|
auto* d = QQuickItemPrivate::get( this );
|
||||||
const QQuickItemPrivate::ChangeTypes types = QQuickItemPrivate::Geometry;
|
|
||||||
|
|
||||||
QQuickItemPrivate* p = QQuickItemPrivate::get( item );
|
if ( QQuickItemPrivate::get( scrollArea() )->dirtyAttributes &
|
||||||
if ( on )
|
QQuickItemPrivate::ContentUpdateMask )
|
||||||
p->addItemChangeListener( this, types );
|
{
|
||||||
else
|
/*
|
||||||
p->removeItemChangeListener( this, types );
|
The update order depends on who calls update first and we
|
||||||
}
|
have to handle being called before a new clip node has
|
||||||
}
|
been created by the scrollview.
|
||||||
|
But better invalidate the unguarded clip geometry until then ...
|
||||||
|
*/
|
||||||
|
auto clipNode = d->clipNode();
|
||||||
|
if ( clipNode && !clipNode->isRectangular() )
|
||||||
|
{
|
||||||
|
clipNode->setIsRectangular( true );
|
||||||
|
clipNode->setGeometry( nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
bool QskScrollAreaClipItem::event( QEvent* event )
|
// in the next cycle we will find a valid clip
|
||||||
{
|
update();
|
||||||
if ( event->type() == QEvent::LayoutRequest )
|
return;
|
||||||
{
|
}
|
||||||
if ( scrollArea()->isItemResizable() )
|
|
||||||
scrollArea()->polish();
|
auto clipNode = d->clipNode();
|
||||||
|
|
||||||
|
if ( clipNode && !( clipNode->flags() & QSGNode::OwnsMaterial ) )
|
||||||
|
{
|
||||||
|
// Replace the clip node being inserted from QQuickWindow
|
||||||
|
|
||||||
|
auto parentNode = clipNode->parent();
|
||||||
|
|
||||||
|
auto node = new ViewportClipNode();
|
||||||
|
parentNode->appendChildNode( node );
|
||||||
|
clipNode->reparentChildNodesTo( node );
|
||||||
|
|
||||||
|
parentNode->removeChildNode( clipNode );
|
||||||
|
|
||||||
|
if ( clipNode->flags() & QSGNode::OwnedByParent )
|
||||||
|
delete clipNode;
|
||||||
|
|
||||||
|
d->extra->clipNode = clipNode = node;
|
||||||
|
Q_ASSERT( clipNode == QQuickItemPrivate::get( this )->clipNode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( clipNode )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Update the clip node with the geometry of the clip node
|
||||||
|
of the viewport of the scrollview.
|
||||||
|
*/
|
||||||
|
auto viewClipNode = static_cast< ViewportClipNode* >( clipNode );
|
||||||
|
viewClipNode->copyFrom( viewPortClipNode() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::event( event );
|
const QSGClipNode* ClipItem::viewPortClipNode() const
|
||||||
|
{
|
||||||
|
auto node = const_cast< QSGNode* >( qskPaintNode( scrollArea() ) );
|
||||||
|
if ( node )
|
||||||
|
node = QskSkinlet::findNodeByRole( node, QskScrollViewSkinlet::ContentsRootRole );
|
||||||
|
|
||||||
|
if ( node && node->type() == QSGNode::ClipNodeType )
|
||||||
|
return static_cast< QSGClipNode* >( node );
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipItem::geometryChanged(
|
||||||
|
const QRectF& newRect, const QRectF& oldRect )
|
||||||
|
{
|
||||||
|
Inherited::geometryChanged( newRect, oldRect );
|
||||||
|
|
||||||
|
if ( newRect.size() != oldRect.size() )
|
||||||
|
{
|
||||||
|
// we need to restore the clip node
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipItem::itemChange(
|
||||||
|
QQuickItem::ItemChange change, const QQuickItem::ItemChangeData& value )
|
||||||
|
{
|
||||||
|
if ( change == QQuickItem::ItemChildAddedChange )
|
||||||
|
{
|
||||||
|
enableGeometryListener( true );
|
||||||
|
}
|
||||||
|
else if ( change == QQuickItem::ItemChildRemovedChange )
|
||||||
|
{
|
||||||
|
enableGeometryListener( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
Inherited::itemChange( change, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipItem::enableGeometryListener( bool on )
|
||||||
|
{
|
||||||
|
auto item = scrolledItem();
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
// we might also be interested in ImplicitWidth/ImplicitHeight
|
||||||
|
const QQuickItemPrivate::ChangeTypes types = QQuickItemPrivate::Geometry;
|
||||||
|
|
||||||
|
QQuickItemPrivate* p = QQuickItemPrivate::get( item );
|
||||||
|
if ( on )
|
||||||
|
p->addItemChangeListener( this, types );
|
||||||
|
else
|
||||||
|
p->removeItemChangeListener( this, types );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClipItem::event( QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::LayoutRequest )
|
||||||
|
{
|
||||||
|
if ( scrollArea()->isItemResizable() )
|
||||||
|
scrollArea()->polish();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::event( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class QskScrollArea::PrivateData
|
class QskScrollArea::PrivateData
|
||||||
|
@ -405,7 +408,7 @@ class QskScrollArea::PrivateData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QskScrollAreaClipItem* clipItem = nullptr;
|
ClipItem* clipItem = nullptr;
|
||||||
|
|
||||||
bool isItemResizable : 1;
|
bool isItemResizable : 1;
|
||||||
};
|
};
|
||||||
|
@ -430,7 +433,7 @@ QskScrollArea::QskScrollArea( QQuickItem* parentItem )
|
||||||
{
|
{
|
||||||
setPolishOnResize( true );
|
setPolishOnResize( true );
|
||||||
|
|
||||||
m_data->clipItem = new QskScrollAreaClipItem( this );
|
m_data->clipItem = new ClipItem( this );
|
||||||
m_data->enableAutoTranslation( this, true );
|
m_data->enableAutoTranslation( this, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue