Skip to content

Commit

Permalink
Add custom QStyle override to allow more flexibility with theming
Browse files Browse the repository at this point in the history
Allows us to apply custom style overrides. Initially, this just
improves the appearance of disabled icons on dark themes.

The default Qt style method of displaying disabled icons only
works well on light backgrounds, on dark backgrounds it makes the
icons stand out due to the extreme contrast between the background
and the lightened icons.

Replace with a custom approach which desaturates icons and reduces
their opacity. This arguably also improves their appearance on
light themes too (I think so).
  • Loading branch information
nyalldawson committed Dec 29, 2018
1 parent 29da7bb commit 2ec0513
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
1 change: 1 addition & 0 deletions python/gui/auto_generated/qgsproxystyle.sip.in
Expand Up @@ -31,6 +31,7 @@ The base style for the QProxyStyle will be set to match the current QGIS applica
%End
};


/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
9 changes: 8 additions & 1 deletion src/app/main.cpp
Expand Up @@ -99,6 +99,7 @@ typedef SInt32 SRefCon;
#include "qgsziputils.h"
#include "qgsversionmigration.h"
#include "qgsfirstrundialog.h"
#include "qgsproxystyle.h"

#include "qgsuserprofilemanager.h"
#include "qgsuserprofile.h"
Expand Down Expand Up @@ -1249,11 +1250,17 @@ int main( int argc, char *argv[] )
}
if ( !desiredStyle.isEmpty() )
{
QApplication::setStyle( desiredStyle );
QApplication::setStyle( new QgsAppStyle( desiredStyle ) );

if ( activeStyleName != desiredStyle )
settings.setValue( QStringLiteral( "qgis/style" ), desiredStyle );
}
else
{
// even if user has not set a style, we need to override the application style with the QgsAppStyle proxy
// based on the default style (or we miss custom style tweaks)
QApplication::setStyle( new QgsAppStyle( activeStyleName ) );
}

// set authentication database directory
if ( !authdbdirectory.isEmpty() )
Expand Down
45 changes: 44 additions & 1 deletion src/gui/qgsproxystyle.cpp
Expand Up @@ -14,12 +14,14 @@
***************************************************************************/

#include "qgsproxystyle.h"
#include "qgsimageoperation.h"
#include <QStyleFactory>
#include <QStyle>
#include <QStyleOption>
#include <QApplication>

QgsProxyStyle::QgsProxyStyle( QWidget *parent )
: QProxyStyle( nullptr ) // no base style yet - it transfer ownership, so we need a NEW QStyle object for the base style
: QProxyStyle( nullptr ) // no base style yet - it transfers ownership, so we need a NEW QStyle object for the base style
{
// get application style
QString appStyle = QApplication::style()->objectName();
Expand All @@ -32,3 +34,44 @@ QgsProxyStyle::QgsProxyStyle( QWidget *parent )
// set lifetime to match parent widget's
setParent( parent );
}

///@cond PRIVATE

//
// QgsAppStyle
//

QgsAppStyle::QgsAppStyle( const QString &base )
: QProxyStyle( nullptr ) // no base style yet - it transfers ownership, so we need a NEW QStyle object for the base style
{
if ( !base.isEmpty() )
{
if ( QStyle *style = QStyleFactory::create( base ) )
setBaseStyle( style );
}
}

QPixmap QgsAppStyle::generatedIconPixmap( QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt ) const
{
switch ( iconMode )
{
case QIcon::Disabled:
{
// override disabled icon style, with something which works better across different light/dark themes.
// the default Qt style here only works nicely for light themes.
QImage im = pixmap.toImage().convertToFormat( QImage::Format_ARGB32 );
QgsImageOperation::adjustHueSaturation( im, 0.2 );
QgsImageOperation::multiplyOpacity( im, 0.3 );
return QPixmap::fromImage( im );
}

case QIcon::Normal:
case QIcon::Active:
case QIcon::Selected:
break;

}
return QProxyStyle::generatedIconPixmap( iconMode, pixmap, opt );
}

///@endcond
21 changes: 21 additions & 0 deletions src/gui/qgsproxystyle.h
Expand Up @@ -41,4 +41,25 @@ class GUI_EXPORT QgsProxyStyle : public QProxyStyle
explicit QgsProxyStyle( QWidget *parent SIP_TRANSFER );
};

///@cond PRIVATE
#ifndef SIP_RUN

/**
* Application style, applies custom style overrides for the QGIS application.
* \ingroup gui
*/
class GUI_EXPORT QgsAppStyle : public QProxyStyle
{
Q_OBJECT

public:

explicit QgsAppStyle( const QString &base );
QPixmap generatedIconPixmap( QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt ) const override;

};

#endif
///@endcond

#endif // QGSPROXYSTYLE_H

0 comments on commit 2ec0513

Please sign in to comment.