diff --git a/src/controls/QskMenuSkinlet.cpp b/src/controls/QskMenuSkinlet.cpp index 3e9a4c96..7fb30566 100644 --- a/src/controls/QskMenuSkinlet.cpp +++ b/src/controls/QskMenuSkinlet.cpp @@ -15,12 +15,12 @@ #include template< class T > -static T qskValueAt( const QskMenu* menu, int index ) +static inline QVariant qskValueAt( const QskMenu* menu, int index ) { const auto item = menu->itemAt( index ); if ( item.canConvert< T >() ) - return item.value< T >(); + return item; if ( item.canConvert< QVariantList >() ) { @@ -28,234 +28,189 @@ static T qskValueAt( const QskMenu* menu, int index ) for ( const auto& value : list ) { if ( value.canConvert< T >() ) - return value.value< T >(); + return value; } } - return T(); + return QVariant(); } -static qreal qskMaxTextWidth( const QskMenu* menu ) +class QskMenuSkinlet::PrivateData { - const QFontMetricsF fm( menu->effectiveFont( QskMenu::Text ) ); - - auto maxWidth = 0.0; - - for ( int i = 0; i < menu->count(); i++ ) + public: + class CacheGuard { - const auto value = menu->itemAt( i ); - - const auto text = qskValueAt< QString >( menu, i ); - if( !text.isEmpty() ) + public: + CacheGuard( QskMenuSkinlet::PrivateData* data ) + : m_data( data ) { - const auto w = qskHorizontalAdvance( fm, text ); - if( w > maxWidth ) - maxWidth = w; - } - } - - return maxWidth; -} - -static qreal qskGraphicWidth( const QskMenu* menu ) -{ - const auto hint = menu->strutSizeHint( QskMenu::Graphic ); - const qreal textHeight = menu->effectiveFontHeight( QskMenu::Text ); - - const auto h = qMax( hint.height(), textHeight ); - - qreal maxW = 0.0; - for ( int i = 0; i < menu->count(); i++ ) - { - const auto graphic = qskValueAt< QskGraphic >( menu, i ); - const auto w = graphic.widthForHeight( h ); - if( w > maxW ) - maxW = w; - } - - return qMax( hint.width(), maxW ); -} - -static qreal qskCellWidth( const QskMenu* menu ) -{ - using Q = QskMenu; - - const auto spacing = menu->spacingHint( Q::Cell ); - const auto padding = menu->paddingHint( Q::Cell ); - - auto w = qskGraphicWidth( menu ) - + spacing + qskMaxTextWidth( menu ); - - w += padding.left() + padding.right(); - - const auto minWidth = menu->strutSizeHint( Q::Cell ).width(); - return qMax( w, minWidth ); -} - -static qreal qskCellHeight( const QskMenu* menu ) -{ - using Q = QskMenu; - - const auto graphicHeight = menu->strutSizeHint( Q::Graphic ).height(); - const auto textHeight = menu->effectiveFontHeight( Q::Text ); - const auto padding = menu->paddingHint( Q::Cell ); - - qreal h = qMax( graphicHeight, textHeight ); - h += padding.top() + padding.bottom(); - - const auto minHeight = menu->strutSizeHint( Q::Cell ).height(); - h = qMax( h, minHeight ); - - return h; -} - -static QSGNode* qskUpdateGraphicNode( const QskMenu* menu, - const QRectF& rect, const QskGraphic& graphic, QSGNode* node ) -{ - const auto alignment = menu->alignmentHint( QskMenu::Graphic, Qt::AlignCenter ); - const auto colorFilter = menu->effectiveGraphicFilter( QskMenu::Graphic ); - - return QskSkinlet::updateGraphicNode( - menu, node, graphic, colorFilter, rect, alignment ); -} - -static QSGNode* qskUpdateTextNode( const QskMenu* menu, - const QRectF& rect, const QString& text, QSGNode* node ) -{ - const auto alignment = menu->alignmentHint( - QskMenu::Text, Qt::AlignVCenter | Qt::AlignLeft ); - - return QskSkinlet::updateTextNode( menu, node, rect, alignment, - text, menu->textOptions(), QskMenu::Text ); -} - -static QSGNode* qskUpdateBackgroundNode( const QskMenu* menu, QSGNode* rootNode ) -{ - using Q = QskMenu; - - const auto skinlet = menu->effectiveSkinlet(); - - auto node = rootNode ? rootNode->firstChild() : nullptr; - QSGNode* lastNode = nullptr; - - for( int i = 0; i < menu->count(); i++ ) - { - QSGNode* newNode = nullptr; - - { - QskSkinStateChanger stateChanger( menu ); - stateChanger.setStates( - skinlet->subControlCellStates( menu, Q::Cell, i ) ); - - newNode = QskSkinlet::updateBoxNode( - menu, node, menu->cellRect( i ), Q::Cell ); + m_data->enableCache( true ); } - if ( newNode ) + ~CacheGuard() { - if ( newNode == node ) + m_data->enableCache( false ); + } + private: + QskMenuSkinlet::PrivateData* m_data; + }; + + void enableCache( bool on ) + { + m_isCaching = on; + m_cellHeight = m_cellWidth = m_graphicWidth = m_textWidth = -1.0; + } + + inline qreal graphicWidth( const QskMenu* menu ) const + { + if ( m_isCaching ) + { + if ( m_graphicWidth < 0.0 ) + m_graphicWidth = graphicWidthInternal( menu ); + + return m_graphicWidth; + } + + return graphicWidthInternal( menu ); + } + + inline qreal textWidth( const QskMenu* menu ) const + { + if ( m_isCaching ) + { + if ( m_textWidth < 0.0 ) + m_textWidth = textWidthInternal( menu ); + + return m_textWidth; + } + + return textWidthInternal( menu ); + } + + inline qreal cellWidth( const QskMenu* menu ) const + { + if ( m_isCaching ) + { + if ( m_cellWidth < 0.0 ) + m_cellWidth = cellWidthInternal( menu ); + + return m_cellWidth; + } + + return cellWidthInternal( menu ); + } + + inline qreal cellHeight( const QskMenu* menu ) const + { + if ( m_isCaching ) + { + if ( m_cellHeight < 0.0 ) + m_cellHeight = cellHeightInternal( menu ); + + return m_cellHeight; + } + + return cellHeightInternal( menu ); + } + + private: + qreal graphicWidthInternal( const QskMenu* menu ) const + { + const auto skinlet = menu->effectiveSkinlet(); + + const auto hint = menu->strutSizeHint( QskMenu::Graphic ); + const qreal textHeight = menu->effectiveFontHeight( QskMenu::Text ); + + const auto h = qMax( hint.height(), textHeight ); + + 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 >() ) { - node = node->nextSibling(); + const auto graphic = value.value< QskGraphic >(); + if ( !graphic.isNull() ) + { + const auto w = graphic.widthForHeight( h ); + if( w > maxW ) + maxW = w; + } } - else + } + + return qMax( hint.width(), maxW ); + } + + qreal textWidthInternal( const QskMenu* menu ) const + { + const auto skinlet = menu->effectiveSkinlet(); + + const QFontMetricsF fm( menu->effectiveFont( QskMenu::Text ) ); + + auto maxWidth = 0.0; + + for ( int i = 0; i < menu->count(); i++ ) + { + const auto value = skinlet->valueAt( menu, QskMenu::Text, i ); + if ( value.canConvert< QString >() ) { - if ( rootNode == nullptr ) - rootNode = new QSGNode(); - - if ( node ) - rootNode->insertChildNodeBefore( newNode, node ); - else - rootNode->appendChildNode( newNode ); + const auto text = value.value< QString >(); + if( !text.isEmpty() ) + { + const auto w = qskHorizontalAdvance( fm, text ); + if( w > maxWidth ) + maxWidth = w; + } } - - lastNode = newNode; } + + return maxWidth; } - QskSGNode::removeAllChildNodesAfter( rootNode, lastNode ); - - return rootNode; -} - -static void qskUpdateItemNode( - const QskMenu* menu, const QRectF& graphicRect, const QskGraphic& graphic, - const QRectF& textRect, const QString& text, QSGNode* itemNode ) -{ - enum { GraphicRole, TextRole }; - static QVector< quint8 > roles = { GraphicRole, TextRole }; - - for ( const auto role : roles ) + qreal cellWidthInternal( const QskMenu* menu ) const { - auto oldNode = QskSGNode::findChildNode( itemNode, role ); - QSGNode* newNode = nullptr; + using Q = QskMenu; - if( role == GraphicRole ) - newNode = qskUpdateGraphicNode( menu, graphicRect, graphic, oldNode ); - else - newNode = qskUpdateTextNode( menu, textRect, text, oldNode ); + const auto spacing = menu->spacingHint( Q::Cell ); + const auto padding = menu->paddingHint( Q::Cell ); - QskSGNode::replaceChildNode( roles, role, itemNode, oldNode, newNode ); + auto w = graphicWidth( menu ) + spacing + textWidth( menu ); + + w += padding.left() + padding.right(); + + const auto minWidth = menu->strutSizeHint( Q::Cell ).width(); + return qMax( w, minWidth ); } -} -static QSGNode* qskUpdateItemsNode( const QskMenu* menu, QSGNode* rootNode ) -{ - using Q = QskMenu; - - const auto skinlet = menu->effectiveSkinlet(); - - const auto spacing = menu->spacingHint( Q::Cell ); - const auto graphicWidth = qskGraphicWidth( menu ); - const auto contentsRect = menu->contentsRect(); - - if ( rootNode == nullptr ) - rootNode = new QSGNode(); - - QSGNode* node = nullptr; - - const auto count = skinlet->subControlCellCount( menu, Q::Cell ); - for( int i = 0; i < count; i++ ) + qreal cellHeightInternal( const QskMenu* menu ) const { - if ( node == nullptr ) - node = rootNode->firstChild(); - else - node = node->nextSibling(); + using Q = QskMenu; - if ( node == nullptr ) - { - node = new QSGNode(); - rootNode->appendChildNode( node ); - } + const auto graphicHeight = menu->strutSizeHint( Q::Graphic ).height(); + const auto textHeight = menu->effectiveFontHeight( Q::Text ); + const auto padding = menu->paddingHint( Q::Cell ); - { - QskSkinStateChanger stateChanger( menu ); - stateChanger.setStates( - skinlet->subControlCellStates( menu, Q::Cell, i ) ); + qreal h = qMax( graphicHeight, textHeight ); + h += padding.top() + padding.bottom(); - const auto cellRect = skinlet->subControlCell( - menu, contentsRect, Q::Cell, i ); + const auto minHeight = menu->strutSizeHint( Q::Cell ).height(); + h = qMax( h, minHeight ); - auto graphicRect = cellRect; - graphicRect.setWidth( graphicWidth ); - - auto textRect = cellRect; - textRect.setX( graphicRect.right() + spacing ); - - const auto graphic = qskValueAt< QskGraphic >( menu, i ); - const auto text = qskValueAt< QString >( menu, i ); - - qskUpdateItemNode( menu, graphicRect, graphic, - textRect, text, node ); - } + return h; } - QskSGNode::removeAllChildNodesAfter( rootNode, node ); + bool m_isCaching; - return rootNode; -} + mutable qreal m_graphicWidth = -1.0; + mutable qreal m_textWidth = -1.0; + mutable qreal m_cellHeight = -1.0; + mutable qreal m_cellWidth = -1.0; +}; QskMenuSkinlet::QskMenuSkinlet( QskSkin* skin ) : Inherited( skin ) + , m_data( new PrivateData() ) { appendNodeRoles( { PanelRole } ); } @@ -283,29 +238,62 @@ QRectF QskMenuSkinlet::subControlCell( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl, int index ) const { - // QskMenu::Text, QskMenu::Graphic ??? - if ( subControl == QskMenu::Cell ) + using Q = QskMenu; + + const auto menu = static_cast< const QskMenu* >( skinnable ); + + if ( subControl == Q::Cell ) { - const auto menu = static_cast< const QskMenu* >( skinnable ); - - if ( index < 0 || index >= menu->count() ) - return QRectF(); - - const auto r = menu->subControlContentsRect( QskMenu::Panel ); - const auto h = qskCellHeight( menu ); + const auto r = menu->subControlContentsRect( Q::Panel ); + const auto h = m_data->cellHeight( menu ); return QRectF( r.x(), r.y() + index * h, r.width(), h ); } + if ( subControl == QskMenu::Graphic || subControl == QskMenu::Text ) + { + const auto r = subControlCell( menu, contentsRect, Q::Cell, index ); + const auto graphicWidth = m_data->graphicWidth( menu ); + + if ( subControl == QskMenu::Graphic ) + { + auto graphicRect = r; + graphicRect.setWidth( graphicWidth ); + + return QRectF( r.x(), r.y(), graphicWidth, r.height() ); + } + else + { + auto textRect = r; + + if ( graphicWidth > 0.0 ) + { + const auto spacing = skinnable->spacingHint( Q::Cell ); + textRect.setX( r.x() + graphicWidth + spacing ); + } + + return textRect; + } + } + return Inherited::subControlCell( skinnable, contentsRect, subControl, index ); } +int QskMenuSkinlet::subControlCellIndexAt( + 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 ); +} + int QskMenuSkinlet::subControlCellCount( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const { - // QskMenu::Text, QskMenu::Graphic ??? - if ( subControl == QskMenu::Cell ) + using Q = QskMenu; + + if ( subControl == Q::Cell || subControl == Q::Graphic || subControl == Q::Text ) { const auto menu = static_cast< const QskMenu* >( skinnable ); return menu->count(); @@ -317,10 +305,11 @@ int QskMenuSkinlet::subControlCellCount( QskAspect::States QskMenuSkinlet::subControlCellStates( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const { + using Q = QskMenu; + auto states = Inherited::subControlCellStates( skinnable, subControl, index ); - // QskMenu::Text, QskMenu::Graphic ??? - if ( subControl == QskMenu::Cell ) + if ( subControl == Q::Cell || subControl == Q::Graphic || subControl == Q::Text ) { const auto menu = static_cast< const QskMenu* >( skinnable ); if ( menu->currentIndex() == index ) @@ -330,17 +319,38 @@ QskAspect::States QskMenuSkinlet::subControlCellStates( return states; } +QVariant QskMenuSkinlet::valueAt( const QskSkinnable* skinnable, + QskAspect::Subcontrol subControl, int index ) const +{ + using Q = QskMenu; + + const auto menu = static_cast< const QskMenu* >( skinnable ); + + if ( subControl == Q::Graphic ) + return qskValueAt< QskGraphic >( menu, index ); + + if ( subControl == Q::Text ) + return qskValueAt< QString >( menu, index ); + + return Inherited::valueAt( skinnable, subControl, index ); +} + QSGNode* QskMenuSkinlet::updateContentsNode( const QskPopup* popup, QSGNode* contentsNode ) const { - enum { Panel, Backgrounds, Cursor, Items }; - static QVector< quint8 > roles = { Panel, Backgrounds, Cursor, Items }; + const PrivateData::CacheGuard guard( m_data.get() ); + return updateMenuNode( popup, contentsNode ); +} + +QSGNode* QskMenuSkinlet::updateMenuNode( + const QskSkinnable* skinnable, QSGNode* contentsNode ) const +{ + enum { Panel, Background, Cursor, Graphic, Text }; + static QVector< quint8 > roles = { Panel, Background, Cursor, Graphic, Text }; if ( contentsNode == nullptr ) contentsNode = new QSGNode(); - const auto menu = static_cast< const QskMenu* >( popup ); - for ( const auto role : roles ) { auto oldNode = QskSGNode::findChildNode( contentsNode, role ); @@ -351,22 +361,27 @@ QSGNode* QskMenuSkinlet::updateContentsNode( { case Panel: { - newNode = updateBoxNode( menu, oldNode, QskMenu::Panel ); + newNode = updateBoxNode( skinnable, oldNode, QskMenu::Panel ); break; } - case Backgrounds: + case Background: { - newNode = qskUpdateBackgroundNode( menu, oldNode ); + newNode = updateSeriesNode( skinnable, QskMenu::Cell, oldNode ); break; } case Cursor: { - newNode = updateBoxNode( menu, oldNode, QskMenu::Cursor ); + newNode = updateBoxNode( skinnable, oldNode, QskMenu::Cursor ); break; } - case Items: + case Graphic: { - newNode = qskUpdateItemsNode( menu, oldNode ); + newNode = updateSeriesNode( skinnable, QskMenu::Graphic, oldNode ); + break; + } + case Text: + { + newNode = updateSeriesNode( skinnable, QskMenu::Text, oldNode ); break; } } @@ -377,18 +392,71 @@ QSGNode* QskMenuSkinlet::updateContentsNode( return contentsNode; } +QSGNode* QskMenuSkinlet::updateSeriesSubNode( 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 ); + + if ( subControl == Q::Cell ) + { + return updateBoxNode( menu, node, rect, subControl ); + } + + if ( subControl == Q::Graphic ) + { + const auto v = qskValueAt< QskGraphic >( menu, index ); + + 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 ); + } + + if ( subControl == Q::Text ) + { + const auto v = qskValueAt< QString >( menu, index ); + + const auto alignment = menu->alignmentHint( + subControl, Qt::AlignVCenter | Qt::AlignLeft ); + + return QskSkinlet::updateTextNode( menu, node, rect, alignment, + v.value< QString>(), menu->textOptions(), QskMenu::Text ); + } + + return nullptr; +} + + QSizeF QskMenuSkinlet::sizeHint( const QskSkinnable* skinnable, Qt::SizeHint which, const QSizeF& ) const { if ( which != Qt::PreferredSize ) return QSizeF(); - const auto menu = static_cast< const QskMenu* >( skinnable ); + const PrivateData::CacheGuard guard( m_data.get() ); - const qreal w = qskCellWidth( menu ); - const auto h = menu->count() * qskCellHeight( menu ); + const auto count = subControlCellCount( skinnable, QskMenu::Cell ); - return menu->outerBoxSize( QskMenu::Panel, QSizeF( w, h ) ); + qreal w = 0.0; + qreal h = 0.0; + + if ( count > 0 ) + { + const auto menu = static_cast< const QskMenu* >( skinnable ); + + w = m_data->cellWidth( menu ); + h = count * m_data->cellHeight( menu ); + } + + auto hint = skinnable->outerBoxSize( QskMenu::Panel, QSizeF( w, h ) ); + hint = hint.expandedTo( skinnable->strutSizeHint( QskMenu::Panel ) ); + + return hint; } #include "moc_QskMenuSkinlet.cpp" diff --git a/src/controls/QskMenuSkinlet.h b/src/controls/QskMenuSkinlet.h index fd0df36a..eb4c1c5a 100644 --- a/src/controls/QskMenuSkinlet.h +++ b/src/controls/QskMenuSkinlet.h @@ -1,6 +1,7 @@ #pragma once #include +#include class QskMenu; @@ -26,14 +27,28 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet QRectF subControlCell( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol, int index ) const override; + int subControlCellIndexAt( const QskSkinnable*, + const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override; + int subControlCellCount( const QskSkinnable*, QskAspect::Subcontrol ) const override; QskAspect::States subControlCellStates( const QskSkinnable*, QskAspect::Subcontrol, int index ) const override; + QVariant valueAt( const QskSkinnable*, + QskAspect::Subcontrol, int index ) const override; + QSizeF sizeHint( const QskSkinnable*, Qt::SizeHint, const QSizeF& ) const override; - private: + protected: QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const override; + QSGNode* updateMenuNode( const QskSkinnable*, QSGNode* ) const; + + QSGNode* updateSeriesSubNode( const QskSkinnable*, + QskAspect::Subcontrol, int index, QSGNode* ) const override; + + private: + class PrivateData; + std::unique_ptr< PrivateData > m_data; }; diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 229b56eb..7335d7be 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -22,6 +22,7 @@ #include "QskTextColors.h" #include "QskTextNode.h" #include "QskTextOptions.h" +#include "QskSkinStateChanger.h" #include #include @@ -563,24 +564,6 @@ QSGNode* QskSkinlet::updateGraphicNode( return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, rect, mirrored ); } -QSizeF QskSkinlet::hintWithoutConstraint( - const QSizeF& hint, const QSizeF& constraint ) const -{ - /* - This method is useful in situations, where a hint has been calculated - from a constraint and we want to return the calculated part only - */ - QSizeF h; - - if ( constraint.width() < 0.0 ) - h.setWidth( hint.width() ); - - if ( constraint.height() < 0.0 ) - h.setHeight( hint.height() ); - - return h; -} - int QskSkinlet::subControlCellIndexAt( const QskSkinnable* skinnable, const QRectF& rect, QskAspect::Subcontrol subControl, const QPointF& pos ) const { @@ -601,6 +584,60 @@ int QskSkinlet::subControlCellIndexAt( const QskSkinnable* skinnable, return -1; } +QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable, + QskAspect::Subcontrol subControl, QSGNode* rootNode ) const +{ + auto node = rootNode ? rootNode->firstChild() : nullptr; + QSGNode* lastNode = nullptr; + + const auto count = subControlCellCount( skinnable, subControl ); + + for( int i = 0; i < count; i++ ) + { + QSGNode* newNode = nullptr; + + { + const auto newStates = subControlCellStates( skinnable, subControl, i ); + + QskSkinStateChanger stateChanger( skinnable ); + stateChanger.setStates( newStates ); + + newNode = updateSeriesSubNode( skinnable, subControl, i, node ); + } + + if ( newNode ) + { + if ( newNode == node ) + { + node = node->nextSibling(); + } + else + { + if ( rootNode == nullptr ) + rootNode = new QSGNode(); + + if ( node ) + rootNode->insertChildNodeBefore( newNode, node ); + else + rootNode->appendChildNode( newNode ); + } + + lastNode = newNode; + } + } + + QskSGNode::removeAllChildNodesAfter( rootNode, lastNode ); + + return rootNode; +} + +QSGNode* QskSkinlet::updateSeriesSubNode( const QskSkinnable*, + QskAspect::Subcontrol, int index, QSGNode* ) const +{ + Q_UNUSED( index ) + return nullptr; +} + QskAspect::States QskSkinlet::subControlCellStates( const QskSkinnable* skinnable, QskAspect::Subcontrol, int index ) const { @@ -608,4 +645,29 @@ QskAspect::States QskSkinlet::subControlCellStates( return skinnable->skinStates(); } +QVariant QskSkinlet::valueAt( const QskSkinnable*, + QskAspect::Subcontrol, int index ) const +{ + Q_UNUSED( index ) + return QVariant(); +} + +QSizeF QskSkinlet::hintWithoutConstraint( + const QSizeF& hint, const QSizeF& constraint ) const +{ + /* + This method is useful in situations, where a hint has been calculated + from a constraint and we want to return the calculated part only + */ + QSizeF h; + + if ( constraint.width() < 0.0 ) + h.setWidth( hint.width() ); + + if ( constraint.height() < 0.0 ) + h.setHeight( hint.height() ); + + return h; +} + #include "moc_QskSkinlet.cpp" diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index 93fc71e5..976ea540 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -53,6 +53,9 @@ class QSK_EXPORT QskSkinlet virtual QskAspect::States subControlCellStates( const QskSkinnable*, QskAspect::Subcontrol, int index ) const; + virtual QVariant valueAt( const QskSkinnable*, + QskAspect::Subcontrol, int index ) const; + const QVector< quint8 >& nodeRoles() const; void setOwnedBySkinnable( bool on ); @@ -130,6 +133,12 @@ class QSK_EXPORT QskSkinlet const QskGraphic&, QskAspect::Subcontrol, Qt::Orientations mirrored = Qt::Orientations() ) const; + QSGNode* updateSeriesNode( const QskSkinnable*, + QskAspect::Subcontrol, QSGNode* ) const; + + virtual QSGNode* updateSeriesSubNode( const QskSkinnable*, + QskAspect::Subcontrol, int index, QSGNode* ) const; + void replaceChildNode( quint8 nodeRole, QSGNode* parentNode, QSGNode* oldNode, QSGNode* newNode ) const;