From aca538a89d4e7284ea8cd52d4a043a97c1647414 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 28 Dec 2021 16:14:30 +0100 Subject: [PATCH] introducing series/sample for subcontrols being related to multiple instances --- src/controls/QskMenu.cpp | 4 +- src/controls/QskMenuSkinlet.cpp | 65 +++++++++++++++++++-------------- src/controls/QskMenuSkinlet.h | 14 +++---- src/controls/QskSkinlet.cpp | 27 ++++++-------- src/controls/QskSkinlet.h | 24 +++++++----- 5 files changed, 74 insertions(+), 60 deletions(-) diff --git a/src/controls/QskMenu.cpp b/src/controls/QskMenu.cpp index 7c914024..c4ee84dc 100644 --- a/src/controls/QskMenu.cpp +++ b/src/controls/QskMenu.cpp @@ -308,13 +308,13 @@ void QskMenu::setSelectedIndex( int index ) QRectF QskMenu::cellRect( int index ) const { - return effectiveSkinlet()->subControlCell( + return effectiveSkinlet()->sampleRect( this, contentsRect(), QskMenu::Cell, index ); } int QskMenu::indexAtPosition( const QPointF& pos ) const { - return effectiveSkinlet()->subControlCellIndexAt( + return effectiveSkinlet()->sampleIndexAt( this, contentsRect(), QskMenu::Cell, pos ); } diff --git a/src/controls/QskMenuSkinlet.cpp b/src/controls/QskMenuSkinlet.cpp index 7fb30566..c66a8dfb 100644 --- a/src/controls/QskMenuSkinlet.cpp +++ b/src/controls/QskMenuSkinlet.cpp @@ -15,7 +15,7 @@ #include template< class T > -static inline QVariant qskValueAt( const QskMenu* menu, int index ) +static inline QVariant qskSampleAt( const QskMenu* menu, int index ) { const auto item = menu->itemAt( index ); @@ -35,6 +35,13 @@ static inline QVariant qskValueAt( const QskMenu* menu, int index ) return QVariant(); } +template< class T > +static inline T qskValueAt( const QskMenu* menu, int index ) +{ + const auto sample = qskSampleAt< T >( menu, index ); + return sample.template value< T >(); +} + class QskMenuSkinlet::PrivateData { public: @@ -126,10 +133,10 @@ class QskMenuSkinlet::PrivateData qreal maxW = 0.0; for ( int i = 0; i < menu->count(); i++ ) { - const auto value = skinlet->valueAt( menu, QskMenu::Graphic, i ); - if ( value.canConvert< QskGraphic >() ) + const auto sample = skinlet->sampleAt( menu, QskMenu::Graphic, i ); + if ( sample.canConvert< QskGraphic >() ) { - const auto graphic = value.value< QskGraphic >(); + const auto graphic = sample.value< QskGraphic >(); if ( !graphic.isNull() ) { const auto w = graphic.widthForHeight( h ); @@ -152,10 +159,10 @@ class QskMenuSkinlet::PrivateData for ( int i = 0; i < menu->count(); i++ ) { - const auto value = skinlet->valueAt( menu, QskMenu::Text, i ); - if ( value.canConvert< QString >() ) + const auto sample = skinlet->sampleAt( menu, QskMenu::Text, i ); + if ( sample.canConvert< QString >() ) { - const auto text = value.value< QString >(); + const auto text = sample.value< QString >(); if( !text.isEmpty() ) { const auto w = qskHorizontalAdvance( fm, text ); @@ -234,7 +241,7 @@ QRectF QskMenuSkinlet::subControlRect( return Inherited::subControlRect( skinnable, contentsRect, subControl ); } -QRectF QskMenuSkinlet::subControlCell( +QRectF QskMenuSkinlet::sampleRect( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl, int index ) const { @@ -252,7 +259,7 @@ QRectF QskMenuSkinlet::subControlCell( if ( subControl == QskMenu::Graphic || subControl == QskMenu::Text ) { - const auto r = subControlCell( menu, contentsRect, Q::Cell, index ); + const auto r = sampleRect( menu, contentsRect, Q::Cell, index ); const auto graphicWidth = m_data->graphicWidth( menu ); if ( subControl == QskMenu::Graphic ) @@ -276,19 +283,19 @@ QRectF QskMenuSkinlet::subControlCell( } } - return Inherited::subControlCell( + return Inherited::sampleRect( skinnable, contentsRect, subControl, index ); } -int QskMenuSkinlet::subControlCellIndexAt( +int QskMenuSkinlet::sampleIndexAt( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl, const QPointF& pos ) const { const PrivateData::CacheGuard guard( m_data.get() ); - return Inherited::subControlCellIndexAt( skinnable, contentsRect, subControl, pos ); + return Inherited::sampleIndexAt( skinnable, contentsRect, subControl, pos ); } -int QskMenuSkinlet::subControlCellCount( +int QskMenuSkinlet::sampleCount( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const { using Q = QskMenu; @@ -299,15 +306,15 @@ int QskMenuSkinlet::subControlCellCount( return menu->count(); } - return Inherited::subControlCellCount( skinnable, subControl ); + return Inherited::sampleCount( skinnable, subControl ); } -QskAspect::States QskMenuSkinlet::subControlCellStates( +QskAspect::States QskMenuSkinlet::sampleStates( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const { using Q = QskMenu; - auto states = Inherited::subControlCellStates( skinnable, subControl, index ); + auto states = Inherited::sampleStates( skinnable, subControl, index ); if ( subControl == Q::Cell || subControl == Q::Graphic || subControl == Q::Text ) { @@ -319,7 +326,7 @@ QskAspect::States QskMenuSkinlet::subControlCellStates( return states; } -QVariant QskMenuSkinlet::valueAt( const QskSkinnable* skinnable, +QVariant QskMenuSkinlet::sampleAt( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const { using Q = QskMenu; @@ -327,12 +334,12 @@ QVariant QskMenuSkinlet::valueAt( const QskSkinnable* skinnable, const auto menu = static_cast< const QskMenu* >( skinnable ); if ( subControl == Q::Graphic ) - return qskValueAt< QskGraphic >( menu, index ); + return qskSampleAt< QskGraphic >( menu, index ); if ( subControl == Q::Text ) - return qskValueAt< QString >( menu, index ); + return qskSampleAt< QString >( menu, index ); - return Inherited::valueAt( skinnable, subControl, index ); + return Inherited::sampleAt( skinnable, subControl, index ); } QSGNode* QskMenuSkinlet::updateContentsNode( @@ -392,14 +399,14 @@ QSGNode* QskMenuSkinlet::updateMenuNode( return contentsNode; } -QSGNode* QskMenuSkinlet::updateSeriesSubNode( const QskSkinnable* skinnable, +QSGNode* QskMenuSkinlet::updateSampleNode( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index, QSGNode* node ) const { using Q = QskMenu; auto menu = static_cast< const QskMenu* >( skinnable ); - const auto rect = subControlCell( menu, menu->contentsRect(), subControl, index ); + const auto rect = sampleRect( menu, menu->contentsRect(), subControl, index ); if ( subControl == Q::Cell ) { @@ -408,24 +415,28 @@ QSGNode* QskMenuSkinlet::updateSeriesSubNode( const QskSkinnable* skinnable, if ( subControl == Q::Graphic ) { - const auto v = qskValueAt< QskGraphic >( menu, index ); + const auto graphic = qskValueAt< QskGraphic >( menu, index ); + if ( graphic.isNull() ) + return nullptr; const auto alignment = menu->alignmentHint( subControl, Qt::AlignCenter ); const auto filter = menu->effectiveGraphicFilter( subControl ); return QskSkinlet::updateGraphicNode( - menu, node, v.value< QskGraphic >(), filter, rect, alignment ); + menu, node, graphic, filter, rect, alignment ); } if ( subControl == Q::Text ) { - const auto v = qskValueAt< QString >( menu, index ); + const auto text = qskValueAt< QString >( menu, index ); + if ( text.isEmpty() ) + return nullptr; const auto alignment = menu->alignmentHint( subControl, Qt::AlignVCenter | Qt::AlignLeft ); return QskSkinlet::updateTextNode( menu, node, rect, alignment, - v.value< QString>(), menu->textOptions(), QskMenu::Text ); + text, menu->textOptions(), QskMenu::Text ); } return nullptr; @@ -440,7 +451,7 @@ QSizeF QskMenuSkinlet::sizeHint( const QskSkinnable* skinnable, const PrivateData::CacheGuard guard( m_data.get() ); - const auto count = subControlCellCount( skinnable, QskMenu::Cell ); + const auto count = sampleCount( skinnable, QskMenu::Cell ); qreal w = 0.0; qreal h = 0.0; diff --git a/src/controls/QskMenuSkinlet.h b/src/controls/QskMenuSkinlet.h index eb4c1c5a..500f93a1 100644 --- a/src/controls/QskMenuSkinlet.h +++ b/src/controls/QskMenuSkinlet.h @@ -24,18 +24,18 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; - QRectF subControlCell( const QskSkinnable*, + int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const override; + + QRectF sampleRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol, int index ) const override; - int subControlCellIndexAt( const QskSkinnable*, + int sampleIndexAt( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override; - int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const override; - - QskAspect::States subControlCellStates( const QskSkinnable*, + QskAspect::States sampleStates( const QskSkinnable*, QskAspect::Subcontrol, int index ) const override; - QVariant valueAt( const QskSkinnable*, + QVariant sampleAt( const QskSkinnable*, QskAspect::Subcontrol, int index ) const override; QSizeF sizeHint( const QskSkinnable*, @@ -45,7 +45,7 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const override; QSGNode* updateMenuNode( const QskSkinnable*, QSGNode* ) const; - QSGNode* updateSeriesSubNode( const QskSkinnable*, + QSGNode* updateSampleNode( const QskSkinnable*, QskAspect::Subcontrol, int index, QSGNode* ) const override; private: diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 7335d7be..50e37d0e 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -564,20 +564,17 @@ QSGNode* QskSkinlet::updateGraphicNode( return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, rect, mirrored ); } -int QskSkinlet::subControlCellIndexAt( const QskSkinnable* skinnable, +int QskSkinlet::sampleIndexAt( const QskSkinnable* skinnable, const QRectF& rect, QskAspect::Subcontrol subControl, const QPointF& pos ) const { - /* - slow default implementation to be overloaded when - having many cells - */ + // slow default implementation to be overloaded when having many cells - const auto cellCount = subControlCellCount( skinnable, subControl ); + const auto count = sampleCount( skinnable, subControl ); - for ( int i = 0; i < cellCount; i++ ) + for ( int i = 0; i < count; i++ ) { - const auto cellRect = subControlCell( skinnable, rect, subControl, i ); - if ( cellRect.contains( pos ) ) + const auto r = sampleRect( skinnable, rect, subControl, i ); + if ( r.contains( pos ) ) return i; } @@ -590,19 +587,19 @@ QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable, auto node = rootNode ? rootNode->firstChild() : nullptr; QSGNode* lastNode = nullptr; - const auto count = subControlCellCount( skinnable, subControl ); + const auto count = sampleCount( skinnable, subControl ); for( int i = 0; i < count; i++ ) { QSGNode* newNode = nullptr; { - const auto newStates = subControlCellStates( skinnable, subControl, i ); + const auto newStates = sampleStates( skinnable, subControl, i ); QskSkinStateChanger stateChanger( skinnable ); stateChanger.setStates( newStates ); - newNode = updateSeriesSubNode( skinnable, subControl, i, node ); + newNode = updateSampleNode( skinnable, subControl, i, node ); } if ( newNode ) @@ -631,21 +628,21 @@ QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable, return rootNode; } -QSGNode* QskSkinlet::updateSeriesSubNode( const QskSkinnable*, +QSGNode* QskSkinlet::updateSampleNode( const QskSkinnable*, QskAspect::Subcontrol, int index, QSGNode* ) const { Q_UNUSED( index ) return nullptr; } -QskAspect::States QskSkinlet::subControlCellStates( +QskAspect::States QskSkinlet::sampleStates( const QskSkinnable* skinnable, QskAspect::Subcontrol, int index ) const { Q_UNUSED( index ) return skinnable->skinStates(); } -QVariant QskSkinlet::valueAt( const QskSkinnable*, +QVariant QskSkinlet::sampleAt( const QskSkinnable*, QskAspect::Subcontrol, int index ) const { Q_UNUSED( index ) diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index 976ea540..4ec4f429 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -42,18 +42,22 @@ class QSK_EXPORT QskSkinlet virtual QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const; - virtual QRectF subControlCell( const QskSkinnable*, + /* + When having more than one instance for the + same QskAspect::Subcontrol it is called a sample + */ + virtual QRectF sampleRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol, int index ) const; - virtual int subControlCellIndexAt( const QskSkinnable*, + virtual int sampleIndexAt( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol, const QPointF& ) const; - virtual int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const; + virtual int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const; - virtual QskAspect::States subControlCellStates( const QskSkinnable*, + virtual QskAspect::States sampleStates( const QskSkinnable*, QskAspect::Subcontrol, int index ) const; - virtual QVariant valueAt( const QskSkinnable*, + virtual QVariant sampleAt( const QskSkinnable*, QskAspect::Subcontrol, int index ) const; const QVector< quint8 >& nodeRoles() const; @@ -61,6 +65,8 @@ class QSK_EXPORT QskSkinlet void setOwnedBySkinnable( bool on ); bool isOwnedBySkinnable() const; + // Helper functions for creating nodes + static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*, const QRectF&, QskAspect::Subcontrol ); @@ -136,7 +142,7 @@ class QSK_EXPORT QskSkinlet QSGNode* updateSeriesNode( const QskSkinnable*, QskAspect::Subcontrol, QSGNode* ) const; - virtual QSGNode* updateSeriesSubNode( const QskSkinnable*, + virtual QSGNode* updateSampleNode( const QskSkinnable*, QskAspect::Subcontrol, int index, QSGNode* ) const; void replaceChildNode( quint8 nodeRole, QSGNode* parentNode, @@ -168,17 +174,17 @@ inline QSizeF QskSkinlet::sizeHint( return QSizeF(); } -inline QRectF QskSkinlet::subControlCell( const QskSkinnable*, +inline QRectF QskSkinlet::sampleRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol, int index ) const { Q_UNUSED( index ) return QRectF(); } -inline int QskSkinlet::subControlCellCount( +inline int QskSkinlet::sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const { - return 1; + return 0; } #endif