diff --git a/examples/colorswitch/Theme.cpp b/examples/colorswitch/Theme.cpp index 0fae6267..a24a66bc 100644 --- a/examples/colorswitch/Theme.cpp +++ b/examples/colorswitch/Theme.cpp @@ -38,7 +38,7 @@ namespace QskSkinHintTableEditor ed( &newSkin->hintTable() ); - ed.setColor( QskListView::CellSelected, m_accent.darker( 130 ) ); + ed.setColor( QskListView::Cell | QskListView::Selected, m_accent.darker( 130 ) ); ed.setBoxBorderColors( QskFocusIndicator::Panel, m_accent.darker( 150 ) ); } diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 4cb8a909..c33c2596 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -740,8 +740,8 @@ void Editor::setupListView() setColor( Q::Cell, m_pal.baseColor ); setColor( Q::Text, m_pal.textColor ); - setColor( Q::CellSelected, m_pal.accentColor ); - setColor( Q::TextSelected, m_pal.contrastColor ); + setColor( Q::Cell | Q::Selected, m_pal.accentColor ); + setColor( Q::Text | Q::Selected, m_pal.contrastColor ); } void Editor::setupSubWindow() diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 619d6dda..f462cbd1 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -804,8 +804,8 @@ void Editor::setupListView() setColor( Q::Text, m_pal.themeForeground ); setColor( Q::Cell, m_pal.contrasted ); - setColor( Q::CellSelected, m_pal.highlighted ); - setColor( Q::TextSelected, m_pal.highlightedText ); + setColor( Q::Cell | Q::Selected, m_pal.highlighted ); + setColor( Q::Text | Q::Selected, m_pal.highlightedText ); } void Editor::setupSubWindow() diff --git a/src/controls/QskListView.cpp b/src/controls/QskListView.cpp index 13efb44e..6f9f7284 100644 --- a/src/controls/QskListView.cpp +++ b/src/controls/QskListView.cpp @@ -9,8 +9,8 @@ QSK_SUBCONTROL( QskListView, Cell ) QSK_SUBCONTROL( QskListView, Text ) -QSK_SUBCONTROL( QskListView, CellSelected ) -QSK_SUBCONTROL( QskListView, TextSelected ) + +QSK_STATE( QskListView, Selected, QskAspect::FirstUserState ) class QskListView::PrivateData { @@ -147,12 +147,6 @@ QskColorFilter QskListView::graphicFilterAt( int row, int col ) const return QskColorFilter(); } -QskAspect::Subcontrol QskListView::textSubControlAt( int row, int col ) const -{ - Q_UNUSED( col ); - return ( row == selectedRow() ) ? TextSelected : Text; -} - void QskListView::keyPressEvent( QKeyEvent* event ) { if ( m_data->selectionMode == NoSelection ) diff --git a/src/controls/QskListView.h b/src/controls/QskListView.h index 15e90799..bed6adeb 100644 --- a/src/controls/QskListView.h +++ b/src/controls/QskListView.h @@ -31,15 +31,8 @@ class QSK_EXPORT QskListView : public QskScrollView using Inherited = QskScrollView; public: - /* - Everything, that can have a skin state, needs to be a QskSkinnable. - Of course this is no option for the cells considering that we might - have many, many of them. - So for the moment we simply use Cell/Text and CellSelected/TextSelected - as workaround until we found a solution that fits into the design. - TODO ... - */ - QSK_SUBCONTROLS( Cell, Text, CellSelected, TextSelected ) + QSK_SUBCONTROLS( Cell, Text ) + QSK_STATES( Selected ) enum SelectionMode { @@ -76,7 +69,6 @@ class QSK_EXPORT QskListView : public QskScrollView #if 1 virtual QskColorFilter graphicFilterAt( int row, int col ) const; - virtual QskAspect::Subcontrol textSubControlAt( int row, int col ) const; #endif public Q_SLOTS: diff --git a/src/controls/QskListViewSkinlet.cpp b/src/controls/QskListViewSkinlet.cpp index 0169a9f7..b70387d8 100644 --- a/src/controls/QskListViewSkinlet.cpp +++ b/src/controls/QskListViewSkinlet.cpp @@ -15,13 +15,36 @@ #include #include +namespace +{ + class StateChanger + { + public: + StateChanger( const QskSkinnable* skinnable, QskAspect::States states ) + : m_skinnable( const_cast< QskSkinnable* >( skinnable ) ) + , m_oldStates( skinnable->skinStates() ) + { + if ( states ) + m_skinnable->replaceSkinStates( m_oldStates | states ); + } + + ~StateChanger() + { + if ( m_oldStates != m_skinnable->skinStates() ) + m_skinnable->replaceSkinStates( m_oldStates ); + } + + private: + QskSkinnable* m_skinnable; + QskAspect::States m_oldStates; + }; +} + class QskListViewNode final : public QSGTransformNode { public: inline QskListViewNode( int columnCount ) : m_columnCount( columnCount ) - , m_rowMin( -1 ) - , m_rowMax( -1 ) { m_backgroundNode.setFlag( QSGNode::OwnedByParent, false ); appendChildNode( &m_backgroundNode ); @@ -78,8 +101,8 @@ class QskListViewNode final : public QSGTransformNode private: int m_columnCount; - int m_rowMin; - int m_rowMax; + int m_rowMin = -1; + int m_rowMax = -1; QSGNode m_backgroundNode; QSGNode m_foregroundNode; @@ -97,7 +120,7 @@ QSGNode* QskListViewSkinlet::updateContentsNode( { const auto listView = static_cast< const QskListView* >( scrollView ); - auto* listViewNode = static_cast< QskListViewNode* >( node ); + auto listViewNode = static_cast< QskListViewNode* >( node ); if ( listViewNode == nullptr ) listViewNode = new QskListViewNode( listView->columnCount() ); @@ -162,7 +185,8 @@ void QskListViewSkinlet::updateBackgroundNodes( if ( rowSelected >= rowMin && rowSelected <= rowMax ) { - const QColor color = listView->color( QskListView::CellSelected ); + const StateChanger stateChanger( listView, QskListView::Selected ); + const QColor color = listView->color( QskListView::Cell ); if ( rowNode == nullptr ) { @@ -434,6 +458,12 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView, { using namespace QskSGNode; + QskAspect::States rowStates; + if ( row == listView->selectedRow() ) + rowStates |= QskListView::Selected; + + StateChanger stateChanger( listView, rowStates ); + QSGNode* newNode = nullptr; #if 1 @@ -466,10 +496,8 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView, if ( nodeRole( contentNode ) == TextRole ) newNode = contentNode; - auto subControl = listView->textSubControlAt( row, col ); - newNode = updateTextNode( listView, newNode, rect, alignment, - value.toString(), listView->textOptions(), subControl ); + value.toString(), listView->textOptions(), QskListView::Text ); if ( newNode ) setNodeRole( newNode, TextRole );