GUI: tool selector: fix icon sizes for high DPI factors other than 100%/200%

Fixes #3229.
This commit is contained in:
Moritz Bunkus 2021-11-18 20:34:51 +01:00
parent b41d623d6a
commit b0b487e2be
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
3 changed files with 26 additions and 22 deletions

View File

@ -5,6 +5,11 @@
* MKVToolNix GUI: language dialog: when the user switches between the two edit
modes, the mode's corresponding first control is automatically focussed.
## Bug fixes
* MKVToolNix: high DPI scaling: fixed the icons in the tool selector having
the wrong size for scaling factors other than 100% or 200%. Fixes #3229.
# Version 63.0.0 "Everything" 2021-11-14

View File

@ -371,31 +371,27 @@ StyleHelper::drawIconWithShadow(QIcon const &icon,
QRect const &rect,
QPainter *p,
QIcon::Mode iconMode,
int radius,
int dipRadius,
QColor const &color,
QPoint const &offset) {
QPoint const &dipOffset) {
QPixmap cache;
QString pixmapName = QString("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());
auto const devicePixelRatio = p->device()->devicePixelRatioF();
QString pixmapName = Q("icon %0 %1 %2 %3").arg(icon.cacheKey()).arg(iconMode).arg(rect.height()).arg(devicePixelRatio);
if (!QPixmapCache::find(pixmapName, &cache)) {
QPixmap px = icon.pixmap(rect.size());
// High-dpi support: The in parameters (rect, radius, offset) are in
// device-independent pixels. The call to QIcon::pixmap() below might
// return a high-dpi pixmap, which will in that case have a devicePixelRatio
// different than 1. The shadow drawing caluculations are done in device
// pixels.
QWindow *window = dynamic_cast<QWidget*>(p->device())->window()->windowHandle();
QPixmap px = icon.pixmap(window, rect.size(), iconMode);
int radius = dipRadius * devicePixelRatio;
QPoint offset = dipOffset * devicePixelRatio;
cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
cache.fill(Qt::transparent);
QPainter cachePainter(&cache);
if (iconMode == QIcon::Disabled) {
QImage im = px.toImage().convertToFormat(QImage::Format_ARGB32);
for (int y=0; y<im.height(); ++y) {
QRgb *scanLine = (QRgb*)im.scanLine(y);
for (int x=0; x<im.width(); ++x) {
QRgb pixel = *scanLine;
char intensity = qGray(pixel);
*scanLine = qRgba(intensity, intensity, intensity, qAlpha(pixel));
++scanLine;
}
}
px = QPixmap::fromImage(im);
}
// Draw shadow
QImage tmp(px.size() + QSize(radius * 2, radius * 2 + 1), QImage::Format_ARGB32_Premultiplied);
@ -403,7 +399,7 @@ StyleHelper::drawIconWithShadow(QIcon const &icon,
QPainter tmpPainter(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
tmpPainter.drawPixmap(QPoint(radius, radius), px);
tmpPainter.drawPixmap(QRect(radius, radius, px.width(), px.height()), px);
tmpPainter.end();
// blur the alpha channel
@ -430,13 +426,16 @@ StyleHelper::drawIconWithShadow(QIcon const &icon,
cachePainter.drawImage(QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp);
// Draw the actual pixmap...
cachePainter.drawPixmap(QPoint(radius, radius) + offset, px);
cachePainter.drawPixmap(QRect(QPoint(radius, radius) + offset, QSize(px.width(), px.height())), px);
cachePainter.end();
cache.setDevicePixelRatio(devicePixelRatio);
QPixmapCache::insert(pixmapName, cache);
}
QRect targetRect = cache.rect();
targetRect.moveCenter(rect.center());
p->drawPixmap(targetRect.topLeft() - offset, cache);
targetRect.setSize(targetRect.size() / cache.devicePixelRatio());
targetRect.moveCenter(rect.center() - dipOffset);
p->drawPixmap(targetRect, cache);
}
// Draws a CSS-like border image where the defined borders are not stretched

View File

@ -69,7 +69,7 @@ public:
static void menuGradient(QPainter *painter, QRect const &spanRect, QRect const &clipRect);
static bool usePixmapCache();
static void drawIconWithShadow(QIcon const &icon, QRect const &rect, QPainter *p, QIcon::Mode iconMode, int radius = 3, QColor const &color = QColor(0, 0, 0, 130), QPoint const &offset = QPoint(1, -2));
static void drawIconWithShadow(QIcon const &icon, QRect const &rect, QPainter *p, QIcon::Mode iconMode, int dipRadius = 3, QColor const &color = QColor(0, 0, 0, 130), QPoint const &dipOffset = QPoint(1, -2));
static void drawCornerImage(QImage const &img, QPainter *painter, QRect rect, int left = 0, int top = 0, int right = 0, int bottom = 0);
static void tintImage(QImage &img, QColor const &tintColor);