qt: implement authentic icon grayscaling

This commit is contained in:
David Hrdlička
2025-03-28 22:11:26 +01:00
parent 18fbb25c24
commit f422a9ce3d
2 changed files with 44 additions and 0 deletions

View File

@@ -18,6 +18,9 @@
#include <QComboBox> #include <QComboBox>
#include <QAbstractItemView> #include <QAbstractItemView>
#include <QPixmap>
#include <QIcon>
#include <QStyleOption>
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
#include <dwmapi.h> #include <dwmapi.h>
@@ -66,3 +69,40 @@ StyleOverride::polish(QWidget *widget)
qobject_cast<QComboBox *>(widget)->view()->setMinimumWidth(widget->minimumSizeHint().width()); qobject_cast<QComboBox *>(widget)->view()->setMinimumWidth(widget->minimumSizeHint().width());
} }
} }
QPixmap
StyleOverride::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const
{
if (iconMode != QIcon::Disabled) {
return QProxyStyle::generatedIconPixmap(iconMode, pixmap, option);
}
auto image = pixmap.toImage();
for (int y = 0; y < image.height(); y++) {
for (int x = 0; x < image.width(); x++) {
// checkerboard transparency
if (((x ^ y) & 1) == 0) {
image.setPixelColor(x, y, Qt::transparent);
continue;
}
auto color = image.pixelColor(x, y);
// convert to grayscale using the NTSC formula
auto avg = 0.0;
avg += color.blueF() * 0.114;
avg += color.greenF() * 0.587;
avg += color.redF() * 0.299;
color.setRedF(avg);
color.setGreenF(avg);
color.setBlueF(avg);
image.setPixelColor(x, y, color);
}
}
return QPixmap::fromImage(image);
}

View File

@@ -4,6 +4,9 @@
#include <QProxyStyle> #include <QProxyStyle>
#include <QWidget> #include <QWidget>
#include <QLayout> #include <QLayout>
#include <QPixmap>
#include <QIcon>
#include <QStyleOption>
class StyleOverride : public QProxyStyle { class StyleOverride : public QProxyStyle {
public: public:
@@ -14,6 +17,7 @@ public:
QStyleHintReturn *returnData = nullptr) const override; QStyleHintReturn *returnData = nullptr) const override;
void polish(QWidget *widget) override; void polish(QWidget *widget) override;
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const override;
}; };
#endif #endif