slightly faster constructor by avoiding some connections

This commit is contained in:
Uwe Rathmann 2017-12-12 20:02:48 +01:00
parent 4c74d9c19a
commit 51d1e9fe59
2 changed files with 71 additions and 84 deletions

View File

@ -33,19 +33,19 @@ typedef quint16 controlFlags_t;
void qskResolveLocale( QskControl* ); void qskResolveLocale( QskControl* );
static void qskSendEventTo( QObject* object, QEvent::Type type ) static inline void qskSendEventTo( QObject* object, QEvent::Type type )
{ {
QEvent event( type ); QEvent event( type );
QCoreApplication::sendEvent( object, &event ); QCoreApplication::sendEvent( object, &event );
} }
static controlFlags_t qskControlFlags() static inline controlFlags_t qskControlFlags()
{ {
// we are only interested in the first 8 bits // we are only interested in the first 8 bits
return static_cast< controlFlags_t >( qskSetup->controlFlags() ); return static_cast< controlFlags_t >( qskSetup->controlFlags() );
} }
static void qskFilterWindow( QQuickWindow* window ) static inline void qskFilterWindow( QQuickWindow* window )
{ {
if ( window == nullptr ) if ( window == nullptr )
return; return;
@ -117,34 +117,29 @@ public:
blockedPolish( false ), blockedPolish( false ),
blockedImplicitSize( true ), blockedImplicitSize( true ),
clearPreviousNodes( false ), clearPreviousNodes( false ),
blockImplicitSizeNotification( false ),
isInitiallyPainted( false ), isInitiallyPainted( false ),
focusPolicy( Qt::NoFocus ), focusPolicy( Qt::NoFocus ),
isWheelEnabled( false ) isWheelEnabled( false )
{ {
} if ( controlFlags & QskControl::DeferredLayout )
inline void setupImplicitSizeConnections( bool on )
{
// in case of someone manipulating the implicit size from
// outside, we might need to adjust some layouts
Q_Q( QskControl );
if ( on )
{ {
QObject::connect( q, &QskControl::implicitWidthChanged, /*
q, &QskControl::onImplicitSizeChanged ); In general the geometry of an item should be the job of
the parent - unfortunatly not done by Qt Quick
probably in the spirit of "making things easier".
QObject::connect( q, &QskControl::implicitHeightChanged, To avoid potentially expensive calculations happening
q, &QskControl::onImplicitSizeChanged ); too often and early QskControl blocks updates of
} the implicitSize and any auto resizing of the control
else according to it.
{
QObject::disconnect( q, &QskControl::implicitWidthChanged,
q, &QskControl::onImplicitSizeChanged );
QObject::disconnect( q, &QskControl::implicitHeightChanged, There should be no strong reason for using concepts
q, &QskControl::onImplicitSizeChanged ); like Positioners, that rely on implicit resizing,
but to make it working: the DeferredLayout flag needs to be disabled.
*/
widthValid = heightValid = true;
} }
} }
@ -154,17 +149,43 @@ public:
qskSendEventTo( q, QEvent::LayoutDirectionChange ); qskSendEventTo( q, QEvent::LayoutDirectionChange );
} }
inline void implicitSizeChanged()
{
Q_Q( QskControl );
if ( !q->QskResizable::sizeHint( Qt::PreferredSize ).isValid() )
{
// when we have no PreferredSize we fall back
// to the implicit size
q->layoutConstraintChanged();
}
}
#if 0 #if 0
// can we do something useful with overloading those ??? // can we do something useful with overloading those ???
virtual qreal getImplicitWidth() const override final; virtual qreal getImplicitWidth() const override final;
virtual qreal getImplicitHeight() const override final; virtual qreal getImplicitHeight() const override final;
virtual void implicitWidthChanged();
virtual void implicitHeightChanged();
virtual QSGTransformNode* createTransformNode(); virtual QSGTransformNode* createTransformNode();
#endif #endif
virtual void implicitWidthChanged() override final
{
QQuickItemPrivate::implicitWidthChanged();
if ( !blockImplicitSizeNotification )
implicitSizeChanged();
}
virtual void implicitHeightChanged() override final
{
QQuickItemPrivate::implicitWidthChanged();
if ( !blockImplicitSizeNotification )
implicitSizeChanged();
}
bool maybeGesture( QQuickItem* child, QEvent* event ) bool maybeGesture( QQuickItem* child, QEvent* event )
{ {
Q_Q( QskControl ); Q_Q( QskControl );
@ -213,6 +234,8 @@ public:
bool blockedImplicitSize : 1; bool blockedImplicitSize : 1;
bool clearPreviousNodes : 1; bool clearPreviousNodes : 1;
bool blockImplicitSizeNotification : 1;
bool isInitiallyPainted : 1; bool isInitiallyPainted : 1;
uint focusPolicy : 4; uint focusPolicy : 4;
@ -220,33 +243,8 @@ public:
}; };
QskControl::QskControl( QQuickItem* parent ): QskControl::QskControl( QQuickItem* parent ):
QskControl( *( new QskControlPrivate() ), parent ) Inherited( *( new QskControlPrivate() ), parent )
{ {
}
QskControl::QskControl( QQuickItemPrivate& dd, QQuickItem* parent ):
Inherited( dd, parent )
{
Q_D( QskControl );
if ( d->controlFlags & QskControl::DeferredLayout )
{
// In general the geometry of an item should be the job of
// the parent - unfortunatly not done by Qt Quick
// probably in the spirit of "making things easier".
// To avoid potentially expensive calculations happening
// too often and early QskControl blocks updates of
// the implicitSize and any auto resizing of the control
// according to it.
// There should be no strong reason for using concepts
// like Positioners, that rely on implicit resizing,
// but to make it working: the DeferredLayout flag needs to be disabled.
d->widthValid = d->heightValid = true;
}
setFlag( QQuickItem::ItemHasContents, true ); setFlag( QQuickItem::ItemHasContents, true );
QQuickItem::setActiveFocusOnTab( false ); QQuickItem::setActiveFocusOnTab( false );
@ -256,17 +254,21 @@ QskControl::QskControl( QQuickItemPrivate& dd, QQuickItem* parent ):
qskResolveLocale( this ); qskResolveLocale( this );
} }
d->setupImplicitSizeConnections( true ); #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
connect( this, &QQuickItem::enabledChanged, connect( this, &QQuickItem::enabledChanged,
[this] { setSkinStateFlag( Disabled, !isEnabled() ); } ); [this] { setSkinStateFlag( Disabled, !isEnabled() ); } );
#endif
// using a conventional connection as being automatically #if 1
// removed by the destructor /*
Would be good to get rid of this connection as it slows down
connect( qskSetup, SIGNAL( controlFlagsChanged() ), the constructor by ~25% ( when ignoring the locale )
this, SLOT( updateControlFlags() ) ); */
connect( qskSetup, &QskSetup::controlFlagsChanged,
this, [this] { updateControlFlags( static_cast< Flags >( qskControlFlags() ) ); } );
#endif
Q_D( QskControl );
if ( d->controlFlags & QskControl::DeferredUpdate ) if ( d->controlFlags & QskControl::DeferredUpdate )
qskFilterWindow( window() ); qskFilterWindow( window() );
} }
@ -549,11 +551,6 @@ bool QskControl::testControlFlag( Flag flag ) const
return d_func()->controlFlags & flag; return d_func()->controlFlags & flag;
} }
void QskControl::updateControlFlags()
{
updateControlFlags( static_cast< Flags >( qskControlFlags() ) );
}
void QskControl::updateControlFlags( Flags flags ) void QskControl::updateControlFlags( Flags flags )
{ {
const auto oldFlags = d_func()->controlFlags; const auto oldFlags = d_func()->controlFlags;
@ -918,7 +915,7 @@ void QskControl::resetImplicitSize()
updateImplicitSize(); updateImplicitSize();
if ( sz != implicitSize() ) if ( sz != implicitSize() )
onImplicitSizeChanged(); d->implicitSizeChanged();
} }
} }
@ -1177,6 +1174,13 @@ void QskControl::itemChange( QQuickItem::ItemChange change,
setSkinStateFlag( Focused, hasActiveFocus() ); setSkinStateFlag( Focused, hasActiveFocus() );
break; break;
} }
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
case QQuickItem::QQuickItem::ItemEnabledHasChanged:
{
setSkinStateFlag( Disabled, !value.boolValue );
break;
}
#endif
default: default:
{ {
break; break;
@ -1308,17 +1312,6 @@ void QskControl::cleanupNodes()
} }
} }
void QskControl::onImplicitSizeChanged()
{
if ( !QskResizable::sizeHint( Qt::PreferredSize ).isValid() )
{
// when we have no PreferredSize we fall back
// the constraint depends on the implicit size
layoutConstraintChanged();
}
}
QskControl* QskControl::owningControl() const QskControl* QskControl::owningControl() const
{ {
return const_cast< QskControl* >( this ); return const_cast< QskControl* >( this );
@ -1352,9 +1345,9 @@ void QskControl::updateImplicitSize()
const qreal w = ( hint.width() >= 0 ) ? dw + hint.width() : 0.0; const qreal w = ( hint.width() >= 0 ) ? dw + hint.width() : 0.0;
const qreal h = ( hint.height() >= 0 ) ? dh + hint.height() : 0.0; const qreal h = ( hint.height() >= 0 ) ? dh + hint.height() : 0.0;
d->setupImplicitSizeConnections( false ); d->blockImplicitSizeNotification = false;
setImplicitSize( w, h ); setImplicitSize( w, h );
d->setupImplicitSizeConnections( true ); d->blockImplicitSizeNotification = true;
} }
QSizeF QskControl::contentsSizeHint() const QSizeF QskControl::contentsSizeHint() const

View File

@ -187,8 +187,6 @@ public Q_SLOTS:
void resetImplicitSize(); void resetImplicitSize();
protected: protected:
QskControl( QQuickItemPrivate&, QQuickItem* parent = nullptr );
virtual bool event( QEvent* ) override; virtual bool event( QEvent* ) override;
virtual void changeEvent( QEvent* ); virtual void changeEvent( QEvent* );
virtual void geometryChangeEvent( QskGeometryChangeEvent* ); virtual void geometryChangeEvent( QskGeometryChangeEvent* );
@ -212,10 +210,6 @@ protected:
virtual void updateLayout(); // called in updatePolish virtual void updateLayout(); // called in updatePolish
private Q_SLOTS:
void onImplicitSizeChanged();
void updateControlFlags();
private: private:
void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy instead void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy instead