QskViewportChange events added ( using the QQuickItem::ItemObservesViewport
concept )
This commit is contained in:
parent
70cc744ba2
commit
4f91034745
@ -26,8 +26,6 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#define HIDE_NODES 1
|
||||
|
||||
const int gridSize = 20;
|
||||
const int thumbnailSize = 150;
|
||||
|
||||
@ -81,18 +79,6 @@ class Thumbnail : public QskPushButton
|
||||
setStrutSizeHint( QskPushButton::Icon, -1, -1 );
|
||||
}
|
||||
|
||||
#if 0
|
||||
void mousePressEvent( QMouseEvent* event ) override
|
||||
{
|
||||
/*
|
||||
ignore events: to check if the pan gesture recoognizer of the scroll
|
||||
area works, when the event arrives as regular event
|
||||
( not via childMouseEventFilter )
|
||||
*/
|
||||
event->setAccepted( false );
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
QskGraphic thumbnailGraphic( const QColor& color,
|
||||
int shape, const QSizeF& size ) const
|
||||
@ -124,41 +110,55 @@ class IconGrid : public QskLinearBox
|
||||
IconGrid( QQuickItem* parentItem = nullptr )
|
||||
: QskLinearBox( Qt::Horizontal, gridSize, parentItem )
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 3, 0 )
|
||||
setFlag( QQuickItem::ItemObservesViewport, true );
|
||||
#endif
|
||||
|
||||
setMargins( 20 );
|
||||
setSpacing( 20 );
|
||||
|
||||
for ( int col = 0; col < gridSize; col++ )
|
||||
{
|
||||
for ( int row = 0; row < gridSize; row++ )
|
||||
( void ) new Thumbnail( randomColor(), randomShape(), this );
|
||||
{
|
||||
auto thumbnail = new Thumbnail( randomColor(), randomShape(), this );
|
||||
thumbnail->setPlacementPolicy( Qsk::Hidden, QskPlacementPolicy::Reserve );
|
||||
thumbnail->setVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
#if HIDE_NODES
|
||||
setSize( sizeConstraint() );
|
||||
}
|
||||
|
||||
protected:
|
||||
void viewportChangeEvent( QskViewportChangeEvent* ) override
|
||||
{
|
||||
if ( isEmpty() )
|
||||
return;
|
||||
|
||||
/*
|
||||
When having too many nodes, the scene graph becomes horribly slow.
|
||||
So we explicitely hide all items outside the visible area
|
||||
( see updateVisibilities below ) and make use of the DeferredUpdate and
|
||||
CleanupOnVisibility features of QskItem.
|
||||
*/
|
||||
setSize( sizeConstraint() );
|
||||
updateLayout(); // so that every item has its initial geometry
|
||||
|
||||
for ( int i = 0; i < elementCount(); i++ )
|
||||
{
|
||||
if ( auto control = qskControlCast( itemAtIndex( i ) ) )
|
||||
{
|
||||
// to support the optimizations in ScrollArea::updateVisibilities
|
||||
control->setPlacementPolicy( Qsk::Hidden, QskPlacementPolicy::Reserve );
|
||||
control->setVisible( false );
|
||||
}
|
||||
}
|
||||
QQuickItem* item;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 3, 0 )
|
||||
item = viewportItem();
|
||||
#else
|
||||
for ( item = parentItem(); item && !item->clip(); item = item->parentItem() );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HIDE_NODES
|
||||
void updateVisibilities( const QRectF& viewPort )
|
||||
if ( item )
|
||||
{
|
||||
if ( !isEmpty() && viewPort != m_viewPort )
|
||||
auto r = item->clipRect();
|
||||
r.moveTo( mapFromItem( item, r.topLeft() ) );
|
||||
|
||||
const auto viewPort = this->viewPort( r );
|
||||
|
||||
if ( m_viewPort != viewPort )
|
||||
{
|
||||
setItemsVisible( m_viewPort, false );
|
||||
setItemsVisible( viewPort, true );
|
||||
@ -166,12 +166,11 @@ class IconGrid : public QskLinearBox
|
||||
m_viewPort = viewPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void setItemsVisible( const QRectF& rect, bool on )
|
||||
QRect viewPort( const QRectF& rect ) const
|
||||
{
|
||||
const auto dim = dimension();
|
||||
|
||||
// we know, that all items have the same size
|
||||
const auto itemSize = itemAtIndex( 0 )->size();
|
||||
|
||||
@ -181,9 +180,16 @@ class IconGrid : public QskLinearBox
|
||||
const int colMin = rect.left() / ( itemSize.width() + spacing() );
|
||||
const int colMax = rect.right() / ( itemSize.height() + spacing() );
|
||||
|
||||
for ( int row = rowMin; row <= rowMax; row++ )
|
||||
return QRect( colMin, rowMin, colMax - colMin + 1, rowMax - rowMin + 1 );
|
||||
}
|
||||
|
||||
void setItemsVisible( const QRect& viewPort, bool on )
|
||||
{
|
||||
for ( int col = colMin; col <= colMax; col++ )
|
||||
const auto dim = dimension();
|
||||
|
||||
for ( int row = viewPort.top(); row <= viewPort.bottom(); row++ )
|
||||
{
|
||||
for ( int col = viewPort.left(); col <= viewPort.right(); col++ )
|
||||
{
|
||||
if ( auto item = itemAtIndex( row * dim + col ) )
|
||||
item->setVisible( on );
|
||||
@ -191,8 +197,7 @@ class IconGrid : public QskLinearBox
|
||||
}
|
||||
}
|
||||
|
||||
QRectF m_viewPort;
|
||||
#endif
|
||||
QRect m_viewPort;
|
||||
};
|
||||
|
||||
class ScrollArea : public QskScrollArea
|
||||
@ -218,29 +223,6 @@ class ScrollArea : public QskScrollArea
|
||||
setBoxShapeHint( HorizontalScrollHandle, 8 );
|
||||
|
||||
setFlickRecognizerTimeout( 300 );
|
||||
|
||||
connect( this, &QskScrollView::scrollPosChanged,
|
||||
this, &ScrollArea::updateVisibilities );
|
||||
}
|
||||
|
||||
protected:
|
||||
void geometryChangeEvent( QskGeometryChangeEvent* event ) override
|
||||
{
|
||||
QskScrollArea::geometryChangeEvent( event );
|
||||
updateVisibilities();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateVisibilities()
|
||||
{
|
||||
#if HIDE_NODES
|
||||
const auto box = static_cast< IconGrid* >( scrolledItem() );
|
||||
if ( box )
|
||||
{
|
||||
const QRectF viewPort( scrollPos(), viewContentsRect().size() );
|
||||
box->updateVisibilities( viewPort );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -189,6 +189,7 @@ QskEvent* QskEvent::clone() const
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -- QskGeometryChangeEvent
|
||||
|
||||
QskGeometryChangeEvent::QskGeometryChangeEvent(
|
||||
@ -216,6 +217,19 @@ bool QskGeometryChangeEvent::isMoved() const
|
||||
( m_rect.y() != m_oldRect.y() );
|
||||
}
|
||||
|
||||
// -- QskViewportChangeEvent
|
||||
|
||||
QskViewportChangeEvent::QskViewportChangeEvent( QQuickItem* modifiedParent )
|
||||
: QskEvent( QskEvent::ViewportChange )
|
||||
, m_modifiedParent( modifiedParent )
|
||||
{
|
||||
}
|
||||
|
||||
QskViewportChangeEvent* QskViewportChangeEvent::clone() const
|
||||
{
|
||||
return new QskViewportChangeEvent( *this );
|
||||
}
|
||||
|
||||
// -- QskWindowChangeEvent
|
||||
|
||||
QskWindowChangeEvent::QskWindowChangeEvent(
|
||||
|
@ -37,6 +37,7 @@ class QSK_EXPORT QskEvent : public QEvent
|
||||
NoEvent = 53800,
|
||||
|
||||
GeometryChange,
|
||||
ViewportChange,
|
||||
WindowChange,
|
||||
|
||||
/*
|
||||
@ -85,6 +86,22 @@ class QSK_EXPORT QskGeometryChangeEvent : public QskEvent
|
||||
QRectF m_oldRect;
|
||||
};
|
||||
|
||||
class QSK_EXPORT QskViewportChangeEvent : public QskEvent
|
||||
{
|
||||
public:
|
||||
QskViewportChangeEvent( QQuickItem* );
|
||||
|
||||
inline QQuickItem* modifiedParent() const { return m_modifiedParent; }
|
||||
|
||||
QskViewportChangeEvent* clone() const override;
|
||||
|
||||
protected:
|
||||
QSK_EVENT_DISABLE_COPY( QskViewportChangeEvent )
|
||||
|
||||
private:
|
||||
QQuickItem* m_modifiedParent;
|
||||
};
|
||||
|
||||
class QSK_EXPORT QskWindowChangeEvent : public QskEvent
|
||||
{
|
||||
public:
|
||||
|
@ -781,6 +781,11 @@ bool QskItem::event( QEvent* event )
|
||||
changeEvent( event );
|
||||
return true;
|
||||
}
|
||||
case QskEvent::ViewportChange:
|
||||
{
|
||||
viewportChangeEvent( static_cast< QskViewportChangeEvent* >( event ) );
|
||||
return true;
|
||||
}
|
||||
case QskEvent::GeometryChange:
|
||||
{
|
||||
geometryChangeEvent( static_cast< QskGeometryChangeEvent* >( event ) );
|
||||
@ -858,6 +863,11 @@ void QskItem::windowChangeEvent( QskWindowChangeEvent* )
|
||||
{
|
||||
}
|
||||
|
||||
void QskItem::viewportChangeEvent( QskViewportChangeEvent* event )
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void QskItem::geometryChangeEvent( QskGeometryChangeEvent* )
|
||||
{
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
class QskItemPrivate;
|
||||
class QskGeometryChangeEvent;
|
||||
class QskViewportChangeEvent;
|
||||
class QskWindowChangeEvent;
|
||||
|
||||
class QSK_EXPORT QskItem : public QQuickItem
|
||||
@ -154,6 +155,7 @@ class QSK_EXPORT QskItem : public QQuickItem
|
||||
|
||||
virtual void changeEvent( QEvent* );
|
||||
virtual void geometryChangeEvent( QskGeometryChangeEvent* );
|
||||
virtual void viewportChangeEvent( QskViewportChangeEvent* );
|
||||
virtual void windowChangeEvent( QskWindowChangeEvent* );
|
||||
|
||||
void mouseUngrabEvent() override;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "QskItemPrivate.h"
|
||||
#include "QskTreeNode.h"
|
||||
#include "QskSetup.h"
|
||||
#include "QskEvent.h"
|
||||
|
||||
static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
||||
{
|
||||
@ -251,8 +252,24 @@ QSGTransformNode* QskItemPrivate::createTransformNode()
|
||||
return new QskItemNode();
|
||||
}
|
||||
|
||||
/*
|
||||
Can we do something useful with overloading:
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 3, 0 )
|
||||
|
||||
- QQuickItemPrivate::transformChanged
|
||||
*/
|
||||
bool QskItemPrivate::transformChanged( QQuickItem* transformedItem )
|
||||
{
|
||||
bool accepted = false;
|
||||
|
||||
if ( q_func()->flags() & QQuickItem::ItemObservesViewport )
|
||||
{
|
||||
QskViewportChangeEvent event( transformedItem );
|
||||
QCoreApplication::sendEvent( q_func(), &event );
|
||||
|
||||
accepted = event.isAccepted();
|
||||
}
|
||||
|
||||
accepted |= Inherited::transformChanged( transformedItem );
|
||||
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -45,6 +45,10 @@ class QskItemPrivate : public QQuickItemPrivate
|
||||
void setImplicitSize( qreal width, qreal height, bool doNotify );
|
||||
virtual QSizeF implicitSizeHint() const = 0;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 3, 0 )
|
||||
bool transformChanged( QQuickItem* ) override final;
|
||||
#endif
|
||||
|
||||
private:
|
||||
Q_DECLARE_PUBLIC( QskItem )
|
||||
|
||||
|
@ -245,6 +245,8 @@ namespace
|
||||
{
|
||||
if ( change.sizeChange() )
|
||||
scrolledItemGeometryChange();
|
||||
|
||||
viewportChanged();
|
||||
}
|
||||
|
||||
void updateNode( QSGNode* ) override;
|
||||
@ -287,6 +289,17 @@ namespace
|
||||
|
||||
const QSGClipNode* viewPortClipNode() const;
|
||||
|
||||
void viewportChanged()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 3, 0 )
|
||||
if ( auto item = scrollArea()->scrolledItem() )
|
||||
{
|
||||
QskViewportChangeEvent ev( this );
|
||||
QCoreApplication::sendEvent( item, &ev );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool m_isSizeChangedEnabled = true;
|
||||
};
|
||||
|
||||
@ -422,6 +435,7 @@ namespace
|
||||
{
|
||||
// we need to restore the clip node
|
||||
update();
|
||||
viewportChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user