Add 2x icons for retina displays.

This change updates the mode selector/fancyactionbar
in Qt Creator with new high-resolution icons.

Set Qt::AA_UseHighDpiImages on Qt 5.1 and higher to
make QIcon generate high-dpi pixmaps. Add "@2x" mode
images.

Update StyleHelper::drawIconWithShadow to handle high-dpi
pixmaps. The shadow-drawing algorithm is kept in device
pixels.

Change-Id: I411b7a24e534a2d75a1bbdc4d10219dcbea26bed
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
This commit is contained in:
Morten Johan Sørvig
2013-01-16 22:06:59 +01:00
parent 87284f7df8
commit 3779147ffc
13 changed files with 45 additions and 8 deletions

View File

@@ -35,6 +35,7 @@
#include <QPainter>
#include <QApplication>
#include <QStyleOption>
#include <qmath.h>
// Clamps float color values within (0, 255)
static int clamp(float x)
@@ -363,15 +364,32 @@ void StyleHelper::menuGradient(QPainter *painter, const QRect &spanRect, const Q
}
}
static qreal pixmapDevicePixelRatio(const QPixmap &pixmap)
{
#if QT_VERSION > 0x050000
return pixmap.devicePixelRatio();
#else
return 1.0;
#endif
}
// Draws a cached pixmap with shadow
void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
QPainter *p, QIcon::Mode iconMode, int radius, const QColor &color, const QPoint &offset)
QPainter *p, QIcon::Mode iconMode, int dipRadius, const QColor &color, const QPoint &dipOffset)
{
QPixmap cache;
QString pixmapName = QString::fromLatin1("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());
if (!QPixmapCache::find(pixmapName, cache)) {
// 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.
QPixmap px = icon.pixmap(rect.size());
int devicePixelRatio = qCeil(pixmapDevicePixelRatio(px));
int radius = dipRadius * devicePixelRatio;
QPoint offset = dipOffset * devicePixelRatio;
cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
cache.fill(Qt::transparent);
@@ -396,7 +414,7 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
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
@@ -423,13 +441,17 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
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);
#if QT_VERSION > 0x050000
cache.setDevicePixelRatio(devicePixelRatio);
#endif
QPixmapCache::insert(pixmapName, cache);
}
QRect targetRect = cache.rect();
targetRect.moveCenter(rect.center());
p->drawPixmap(targetRect.topLeft() - offset, cache);
targetRect.setSize(targetRect.size() / pixmapDevicePixelRatio(cache));
targetRect.moveCenter(rect.center() - dipOffset);
p->drawPixmap(targetRect, cache);
}
// Draws a CSS-like border image where the defined borders are not stretched