From 585f7635422125281e1f76c9a23c589657107f93 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 2 May 2023 09:44:57 +0200 Subject: [PATCH] QskSkinnable can be used in combination with a simple QQuickItem now --- src/controls/QskControl.cpp | 2 +- src/controls/QskControl.h | 2 +- src/controls/QskSkinlet.cpp | 18 ++++++---- src/controls/QskSkinnable.cpp | 62 ++++++++++++++++++++--------------- src/controls/QskSkinnable.h | 3 +- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index 42c1fdba..86c863e3 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -916,7 +916,7 @@ QSGNode* QskControl::updateItemPaintNode( QSGNode* node ) return node; } -QskControl* QskControl::owningControl() const +QskControl* QskControl::owningItem() const { return const_cast< QskControl* >( this ); } diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index 9a81536e..e9a4bb7a 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -217,7 +217,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable QSGNode* updateItemPaintNode( QSGNode* ) override final; void updateItemPolish() override final; - QskControl* owningControl() const override final; + QskControl* owningItem() const override final; private: Q_DECLARE_PRIVATE( QskControl ) diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 02c7e339..a8a194f5 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -28,6 +28,7 @@ #include "QskTextOptions.h" #include "QskSkinStateChanger.h" #include "QskTextureRenderer.h" +#include "QskSetup.h" #include #include @@ -101,7 +102,7 @@ static inline QSGNode* qskUpdateTextNode( const QskSkinnable* skinnable, break; } - textNode->setTextData( skinnable->owningControl(), + textNode->setTextData( skinnable->owningItem(), text, rect, effectiveFont, textOptions, textColors, alignment, textStyle ); return textNode; @@ -115,21 +116,26 @@ static inline QSGNode* qskUpdateGraphicNode( if ( rect.isEmpty() ) return nullptr; - const auto control = skinnable->owningControl(); - if ( control == nullptr ) + const auto item = skinnable->owningItem(); + if ( item == nullptr ) return nullptr; auto graphicNode = static_cast< QskGraphicNode* >( node ); if ( graphicNode == nullptr ) graphicNode = new QskGraphicNode(); - const bool useRaster = control->testUpdateFlag( QskControl::PreferRasterForTextures ); + const auto flag = QskQuickItem::PreferRasterForTextures; + + bool useRaster = qskSetup->testItemUpdateFlag( flag ); + if ( auto qItem = qobject_cast< const QskQuickItem* >( item ) ) + useRaster = qItem->testUpdateFlag( flag ); + graphicNode->setRenderHint( useRaster ? QskPaintedNode::Raster : QskPaintedNode::OpenGL ); graphicNode->setMirrored( mirrored ); - const auto r = qskSceneAlignedRect( control, rect ); - graphicNode->setGraphic( control->window(), graphic, colorFilter, r ); + const auto r = qskSceneAlignedRect( item, rect ); + graphicNode->setGraphic( item->window(), graphic, colorFilter, r ); return graphicNode; } diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index ecc800c7..f3d273cb 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -121,7 +121,7 @@ static inline T qskColor( const QskSkinnable* skinnable, aspect | QskAspect::Color, status ).value< T >(); } -static inline void qskTriggerUpdates( QskAspect aspect, QskControl* control ) +static inline void qskTriggerUpdates( QskAspect aspect, QQuickItem* item ) { /* To put the hint into effect we have to call the usual suspects: @@ -137,7 +137,13 @@ static inline void qskTriggerUpdates( QskAspect aspect, QskControl* control ) controls. */ - if ( control == nullptr || aspect.isAnimator() ) + if ( item == nullptr || aspect.isAnimator() ) + return; + + item->update(); // always + + auto control = qskControlCast( item ); + if ( control == nullptr ) return; bool maybeLayout = false; @@ -185,8 +191,6 @@ static inline void qskTriggerUpdates( QskAspect aspect, QskControl* control ) } } - control->update(); // always - if ( maybeLayout && control->hasChildItems() ) { if ( control->polishOnResize() || control->autoLayoutChildren() ) @@ -269,13 +273,15 @@ void QskSkinnable::setSkinlet( const QskSkinlet* skinlet ) m_data->skinlet = skinlet; m_data->hasLocalSkinlet = ( skinlet != nullptr ); - if ( auto control = owningControl() ) + if ( auto item = owningItem() ) { - control->resetImplicitSize(); - control->polish(); + if ( auto control = qskControlCast( item ) ) + control->resetImplicitSize(); - if ( control->flags() & QQuickItem::ItemHasContents ) - control->update(); + item->polish(); + + if ( item->flags() & QQuickItem::ItemHasContents ) + item->update(); } } @@ -760,12 +766,12 @@ QskColorFilter QskSkinnable::effectiveGraphicFilter( return v.value< QskColorFilter >(); } - if ( auto control = owningControl() ) + if ( auto item = owningItem() ) { const auto graphicRole = hint.toInt(); const auto v = QskSkinTransition::animatedGraphicFilter( - control->window(), graphicRole ); + item->window(), graphicRole ); if ( v.canConvert< QskColorFilter >() ) { @@ -776,7 +782,7 @@ QskColorFilter QskSkinnable::effectiveGraphicFilter( filter. As a workaround we schedule the update in the getter: TODO ... */ - control->update(); + item->update(); #endif return v.value< QskColorFilter >(); } @@ -862,7 +868,7 @@ bool QskSkinnable::setSkinHint( QskAspect aspect, const QVariant& hint ) if ( m_data->hintTable.setHint( aspect, hint ) ) { - qskTriggerUpdates( aspect, owningControl() ); + qskTriggerUpdates( aspect, owningItem() ); return true; } @@ -875,7 +881,7 @@ bool QskSkinnable::resetSkinHint( QskAspect aspect ) if ( m_data->hintTable.removeHint( aspect ) ) { - qskTriggerUpdates( aspect, owningControl() ); + qskTriggerUpdates( aspect, owningItem() ); return true; } @@ -980,8 +986,8 @@ QVariant QskSkinnable::interpolatedHint( if ( !QskSkinTransition::isRunning() || m_data->hintTable.hasHint( aspect ) ) return QVariant(); - const auto control = owningControl(); - if ( control == nullptr ) + const auto item = owningItem(); + if ( item == nullptr ) return QVariant(); QVariant v; @@ -990,7 +996,7 @@ QVariant QskSkinnable::interpolatedHint( Q_FOREVER { - v = QskSkinTransition::animatedHint( control->window(), aspect ); + v = QskSkinTransition::animatedHint( item->window(), aspect ); if ( !v.isValid() ) { @@ -1227,7 +1233,7 @@ bool QskSkinnable::isTransitionAccepted( QskAspect aspect ) const happen while the skinnable is visible. There are few exceptions like QskPopup::Closed, that is used to slide/fade in. */ - if ( auto control = owningControl() ) + if ( auto control = qskControlCast( owningItem() ) ) return control->isInitiallyPainted(); return false; @@ -1252,7 +1258,7 @@ void QskSkinnable::startHintTransition( QskAspect aspect, int index, if ( animationHint.duration <= 0 || ( from == to ) ) return; - auto control = this->owningControl(); + auto control = qskControlCast( owningItem() ); if ( control->window() == nullptr || !isTransitionAccepted( aspect ) ) return; @@ -1321,17 +1327,17 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates ) if ( m_data->skinStates == newStates ) return; - auto control = owningControl(); + auto item = owningItem(); #if DEBUG_STATE - const auto className = control ? control->className() : "QskSkinnable"; + const auto className = item ? item->className() : "QskSkinnable"; qDebug() << className << ":" << skinStateAsPrintable( m_data->skinState ) << "->" << skinStateAsPrintable( newState ); #endif - if ( control && control->window() ) + if ( item && item->window() ) { if ( const auto skin = effectiveSkin() ) { @@ -1347,8 +1353,8 @@ void QskSkinnable::setSkinStates( QskAspect::States newStates ) } } - if ( control->flags() & QQuickItem::ItemHasContents ) - control->update(); + if ( item->flags() & QQuickItem::ItemHasContents ) + item->update(); } m_data->skinStates = newStates; @@ -1370,7 +1376,9 @@ bool QskSkinnable::startHintTransitions( aspect.setSection( section() ); const auto skin = effectiveSkin(); - const auto control = owningControl(); + const auto control = qskControlCast( owningItem() ); + if ( control == nullptr ) + return false; const auto primitiveCount = QskAspect::primitiveCount(); @@ -1440,8 +1448,8 @@ QskSkin* QskSkinnable::effectiveSkin() const if ( skin == nullptr ) { - if ( const auto control = owningControl() ) - skin = qskEffectiveSkin( control->window() ); + if ( const auto item = owningItem() ) + skin = qskEffectiveSkin( item->window() ); } return skin ? skin : qskSetup->skin(); diff --git a/src/controls/QskSkinnable.h b/src/controls/QskSkinnable.h index 54788ca9..3a736a83 100644 --- a/src/controls/QskSkinnable.h +++ b/src/controls/QskSkinnable.h @@ -20,6 +20,7 @@ class QVariant; class QDebug; class QSGNode; +class QQuickItem; class QskArcMetrics; class QskControl; @@ -133,7 +134,7 @@ class QSK_EXPORT QskSkinnable QskControl* controlCast(); const QskControl* controlCast() const; - virtual QskControl* owningControl() const = 0; + virtual QQuickItem* owningItem() const = 0; virtual const QMetaObject* metaObject() const = 0; void debug( QskAspect ) const;