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 authored and nirvn committed Jan 18, 2019
1 parent f6ddc62 commit b55b0ec
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 b55b0ec

Please sign in to comment.