From 582d49200f9d6e74485cef6a8b2e5f0b2e4cf695 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Sun, 17 Aug 2014 21:09:35 +0200 Subject: [PATCH] Change color for checkboxes and radiobuttons in lists, when list has focus and corresponding QModelIndex is selected --- kstyle/breezestyle.cpp | 100 ++++++++++++++++++++++++++++++++++------- kstyle/breezestyle.h | 15 ++++++- 2 files changed, 97 insertions(+), 18 deletions(-) diff --git a/kstyle/breezestyle.cpp b/kstyle/breezestyle.cpp index b39f4674..5eb5bc14 100644 --- a/kstyle/breezestyle.cpp +++ b/kstyle/breezestyle.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -3049,7 +3048,11 @@ namespace Breeze bool Style::drawIndicatorCheckBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const { - // get rect + // copy rect and palette + const QRect& rect( option->rect ); + const QPalette& palette( option->palette ); + + // store flags const State& state( option->state ); const bool enabled( state & State_Enabled ); const bool mouseOver( enabled && ( state & State_MouseOver ) ); @@ -3061,22 +3064,28 @@ namespace Breeze if( state & State_NoChange ) checkBoxState = CheckPartial; else if( state & State_On ) checkBoxState = CheckOn; + // detect checkboxes in lists + const bool isSelectedItem( this->isSelectedItem( widget, rect.center() ) ); + // animation state _animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); - const AnimationMode mode( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ? AnimationHover:AnimationNone ); - const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); - _animations->widgetStateEngine().updateState( widget, AnimationPressed, checkBoxState != CheckOff ); if( _animations->widgetStateEngine().isAnimated( widget, AnimationPressed ) ) checkBoxState = CheckAnimated; const qreal animation( _animations->widgetStateEngine().opacity( widget, AnimationPressed ) ); - // colors - const QPalette& palette( option->palette ); - const QColor color( _helper->checkBoxIndicatorColor( palette, mouseOver, enabled && active, opacity, mode ) ); const QColor shadow( _helper->shadowColor( palette ) ); + QColor color; + if( isSelectedItem ) color = palette.color( QPalette::HighlightedText ); + else { + + const AnimationMode mode( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ? AnimationHover:AnimationNone ); + const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); + color = _helper->checkBoxIndicatorColor( palette, mouseOver, enabled && active, opacity, mode ); + + } // render - _helper->renderCheckBox( painter, option->rect, color, shadow, sunken, checkBoxState, animation ); + _helper->renderCheckBox( painter, rect, color, shadow, sunken, checkBoxState, animation ); return true; } @@ -3085,31 +3094,43 @@ namespace Breeze bool Style::drawIndicatorRadioButtonPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const { - // get rect + // copy rect and palette + const QRect& rect( option->rect ); + const QPalette& palette( option->palette ); + + // store flags const State& state( option->state ); const bool enabled( state & State_Enabled ); const bool mouseOver( enabled && ( state & State_MouseOver ) ); const bool sunken( state & State_Sunken ); const bool checked( state & State_On ); + // radio button state RadioButtonState radioButtonState( state & State_On ? RadioOn:RadioOff ); + // detect radiobuttons in lists + const bool isSelectedItem( this->isSelectedItem( widget, rect.center() ) ); + // animation state _animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); - const AnimationMode mode( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ? AnimationHover:AnimationNone ); - const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); - _animations->widgetStateEngine().updateState( widget, AnimationPressed, radioButtonState != RadioOff ); if( _animations->widgetStateEngine().isAnimated( widget, AnimationPressed ) ) radioButtonState = RadioAnimated; const qreal animation( _animations->widgetStateEngine().opacity( widget, AnimationPressed ) ); // colors - const QPalette& palette( option->palette ); - const QColor color( _helper->checkBoxIndicatorColor( palette, mouseOver, enabled && checked, opacity, mode ) ); const QColor shadow( _helper->shadowColor( palette ) ); + QColor color; + if( isSelectedItem ) color = palette.color( QPalette::HighlightedText ); + else { + + const AnimationMode mode( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ? AnimationHover:AnimationNone ); + const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); + color = _helper->checkBoxIndicatorColor( palette, mouseOver, enabled && checked, opacity, mode ); + + } // render - _helper->renderRadioButton( painter, option->rect, color, shadow, sunken, radioButtonState, animation ); + _helper->renderRadioButton( painter, rect, color, shadow, sunken, radioButtonState, animation ); return true; @@ -5589,7 +5610,7 @@ namespace Breeze } //______________________________________________________________________________ - QWidget* Style::scrollBarParent( const QWidget* widget ) const + const QWidget* Style::scrollBarParent( const QWidget* widget ) const { // check widget and parent @@ -5852,4 +5873,49 @@ namespace Breeze } + //______________________________________________________________________________ + const QAbstractItemView* Style::itemViewParent( const QWidget* widget ) const + { + + const QAbstractItemView* itemView( nullptr ); + + // check widget directly + if( ( itemView = qobject_cast( widget ) ) ) return itemView; + + // check widget grand-parent + else if( + widget && + widget->parentWidget() && + ( itemView = qobject_cast( widget->parentWidget()->parentWidget() ) ) && + itemView->viewport() == widget->parentWidget() ) + { return itemView; } + + // return null otherwise + else return nullptr; + } + + //____________________________________________________________________ + bool Style::isSelectedItem( const QWidget* widget, const QPoint& localPosition ) const + { + + // get relevant itemview parent and check + const QAbstractItemView* itemView( itemViewParent( widget ) ); + if( !( itemView && itemView->hasFocus() && itemView->selectionModel() ) ) return false; + + #if QT_VERSION >= 0x050000 + QPoint position = widget->mapTo( itemView, localPosition ); + #else + // qt4 misses a const for mapTo argument, although nothing is actually changed to the passed widget + QPoint position = widget->mapTo( const_cast( itemView ), localPosition ); + #endif + + // get matching QModelIndex and check + const QModelIndex index( itemView->indexAt( position ) ); + if( !index.isValid() ) return false; + + // check whether index is selected + return itemView->selectionModel()->isSelected( index ); + + } + } diff --git a/kstyle/breezestyle.h b/kstyle/breezestyle.h index 0960f3c8..5e39c34b 100644 --- a/kstyle/breezestyle.h +++ b/kstyle/breezestyle.h @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -377,7 +378,7 @@ namespace Breeze //! returns relevant scrollbar parent /*! needed to detect parent focus */ - QWidget* scrollBarParent( const QWidget* ) const; + const QWidget* scrollBarParent( const QWidget* ) const; //! returns true if given scrollbar arrow is animated QColor scrollBarArrowColor( const QStyleOptionSlider*, const SubControl&, const QWidget* ) const; @@ -423,6 +424,18 @@ namespace Breeze //! create title bar button icon QIcon titleBarButtonIcon( StandardPixmap, const QStyleOption*, const QWidget* ) const; + //! returns item view parent if any + /*! needed to have correct color on focused checkboxes and radiobuttons */ + const QAbstractItemView* itemViewParent( const QWidget* ) const; + + //! returns true if a given widget is a selected item in a focused list + /*! + This is necessary to have the correct colors used for e.g. checkboxes and radiobuttons in lists + @param widget The widget to be checked + @param position Used to find the relevant QModelIndex + */ + bool isSelectedItem( const QWidget*, const QPoint& ) const; + private: //!@name scrollbar button types (for addLine and subLine )