Skip to content

Commit 2ec0513

Browse files
committedDec 29, 2018
Add custom QStyle override to allow more flexibility with theming
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).
1 parent 29da7bb commit 2ec0513

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed
 

‎python/gui/auto_generated/qgsproxystyle.sip.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ The base style for the QProxyStyle will be set to match the current QGIS applica
3131
%End
3232
};
3333

34+
3435
/************************************************************************
3536
* This file has been generated automatically from *
3637
* *

‎src/app/main.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef SInt32 SRefCon;
9999
#include "qgsziputils.h"
100100
#include "qgsversionmigration.h"
101101
#include "qgsfirstrundialog.h"
102+
#include "qgsproxystyle.h"
102103

103104
#include "qgsuserprofilemanager.h"
104105
#include "qgsuserprofile.h"
@@ -1249,11 +1250,17 @@ int main( int argc, char *argv[] )
12491250
}
12501251
if ( !desiredStyle.isEmpty() )
12511252
{
1252-
QApplication::setStyle( desiredStyle );
1253+
QApplication::setStyle( new QgsAppStyle( desiredStyle ) );
12531254

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

12581265
// set authentication database directory
12591266
if ( !authdbdirectory.isEmpty() )

‎src/gui/qgsproxystyle.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
***************************************************************************/
1515

1616
#include "qgsproxystyle.h"
17+
#include "qgsimageoperation.h"
1718
#include <QStyleFactory>
1819
#include <QStyle>
20+
#include <QStyleOption>
1921
#include <QApplication>
2022

2123
QgsProxyStyle::QgsProxyStyle( QWidget *parent )
22-
: QProxyStyle( nullptr ) // no base style yet - it transfer ownership, so we need a NEW QStyle object for the base style
24+
: QProxyStyle( nullptr ) // no base style yet - it transfers ownership, so we need a NEW QStyle object for the base style
2325
{
2426
// get application style
2527
QString appStyle = QApplication::style()->objectName();
@@ -32,3 +34,44 @@ QgsProxyStyle::QgsProxyStyle( QWidget *parent )
3234
// set lifetime to match parent widget's
3335
setParent( parent );
3436
}
37+
38+
///@cond PRIVATE
39+
40+
//
41+
// QgsAppStyle
42+
//
43+
44+
QgsAppStyle::QgsAppStyle( const QString &base )
45+
: QProxyStyle( nullptr ) // no base style yet - it transfers ownership, so we need a NEW QStyle object for the base style
46+
{
47+
if ( !base.isEmpty() )
48+
{
49+
if ( QStyle *style = QStyleFactory::create( base ) )
50+
setBaseStyle( style );
51+
}
52+
}
53+
54+
QPixmap QgsAppStyle::generatedIconPixmap( QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt ) const
55+
{
56+
switch ( iconMode )
57+
{
58+
case QIcon::Disabled:
59+
{
60+
// override disabled icon style, with something which works better across different light/dark themes.
61+
// the default Qt style here only works nicely for light themes.
62+
QImage im = pixmap.toImage().convertToFormat( QImage::Format_ARGB32 );
63+
QgsImageOperation::adjustHueSaturation( im, 0.2 );
64+
QgsImageOperation::multiplyOpacity( im, 0.3 );
65+
return QPixmap::fromImage( im );
66+
}
67+
68+
case QIcon::Normal:
69+
case QIcon::Active:
70+
case QIcon::Selected:
71+
break;
72+
73+
}
74+
return QProxyStyle::generatedIconPixmap( iconMode, pixmap, opt );
75+
}
76+
77+
///@endcond

‎src/gui/qgsproxystyle.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,25 @@ class GUI_EXPORT QgsProxyStyle : public QProxyStyle
4141
explicit QgsProxyStyle( QWidget *parent SIP_TRANSFER );
4242
};
4343

44+
///@cond PRIVATE
45+
#ifndef SIP_RUN
46+
47+
/**
48+
* Application style, applies custom style overrides for the QGIS application.
49+
* \ingroup gui
50+
*/
51+
class GUI_EXPORT QgsAppStyle : public QProxyStyle
52+
{
53+
Q_OBJECT
54+
55+
public:
56+
57+
explicit QgsAppStyle( const QString &base );
58+
QPixmap generatedIconPixmap( QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt ) const override;
59+
60+
};
61+
62+
#endif
63+
///@endcond
64+
4465
#endif // QGSPROXYSTYLE_H

0 commit comments

Comments
 (0)
Please sign in to comment.