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