Retina support for covers in views.
This commit is contained in:
committed by
craig.p.drummond
parent
3321f64195
commit
0e05af098b
@@ -60,10 +60,9 @@
|
||||
#include <QFont>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QTimer>
|
||||
#include <QCoreApplication>
|
||||
#include <QApplication>
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
#include <KDE/KStandardDirs>
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
GLOBAL_STATIC(Covers, instance)
|
||||
@@ -95,6 +94,12 @@ static bool fetchCovers=true;
|
||||
static QString constCoverInTagPrefix=QLatin1String("{tag}");
|
||||
static QString constNoCover=QLatin1String("{nocover}");
|
||||
|
||||
#if QT_VERSION >= 0x050100
|
||||
static double devicePixelRatio=1.0;
|
||||
// Only scale images to device pixel ratio if un-scaled size is less then 300pixels.
|
||||
static const int constRetinaScaleMaxSize=300;
|
||||
#endif
|
||||
|
||||
static QImage scale(const Song &song, const QImage &img, int size)
|
||||
{
|
||||
if (song.isArtistImageRequest()) {
|
||||
@@ -1004,7 +1009,13 @@ void CoverLoader::load()
|
||||
QList<LoadedCover> covers;
|
||||
foreach (const LoadedCover &s, toDo) {
|
||||
DBUG << s.song.artist << s.song.albumId() << s.song.size;
|
||||
covers.append(LoadedCover(s.song, loadScaledCover(s.song, s.song.size)));
|
||||
int size=s.song.size;
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size<constRetinaScaleMaxSize) {
|
||||
size*=devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
covers.append(LoadedCover(s.song, loadScaledCover(s.song, size)));
|
||||
}
|
||||
if (!covers.isEmpty()) {
|
||||
DBUG << "loaded" << covers.count();
|
||||
@@ -1021,6 +1032,11 @@ Covers::Covers()
|
||||
, locator(0)
|
||||
, loader(0)
|
||||
{
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (Settings::self()->retinaSupport()) {
|
||||
devicePixelRatio=qApp->devicePixelRatio();
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_UBUNTU
|
||||
cache.setMaxCost(20*1024*1024); // Not used?
|
||||
cacheScaledCovers=false;
|
||||
@@ -1133,6 +1149,12 @@ QPixmap * Covers::get(const Song &song, int size, bool urgent)
|
||||
size=22;
|
||||
}
|
||||
|
||||
int origSize=size;
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size<constRetinaScaleMaxSize) {
|
||||
size*=devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
if (!song.isUnknown()) {
|
||||
key=cacheKey(song, size);
|
||||
pix=cache.object(key);
|
||||
@@ -1156,6 +1178,12 @@ QPixmap * Covers::get(const Song &song, int size, bool urgent)
|
||||
}
|
||||
#endif
|
||||
if (pix) {
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size!=origSize) {
|
||||
pix->setDevicePixelRatio(devicePixelRatio);
|
||||
DBUG << "Set pixel ratio of cover" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
cache.insert(key, pix, 1);
|
||||
cacheSizes.insert(size);
|
||||
}
|
||||
@@ -1167,25 +1195,44 @@ QPixmap * Covers::get(const Song &song, int size, bool urgent)
|
||||
if (cached.isNull()) {
|
||||
Image img=findImage(song, false);
|
||||
if (!img.img.isNull()) {
|
||||
return saveScaledCover(scale(song, img.img, size), song, size);
|
||||
pix=saveScaledCover(scale(song, img.img, size), song, size);
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size!=origSize) {
|
||||
pix->setDevicePixelRatio(devicePixelRatio);
|
||||
DBUG << "Set pixel ratio of saved scaled cover" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
return pix;
|
||||
} else if (constNoCover==img.fileName) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
pix=new QPixmap(QPixmap::fromImage(cached));
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size!=origSize) {
|
||||
pix->setDevicePixelRatio(devicePixelRatio);
|
||||
DBUG << "Set pixel ratio of loaded scaled cover" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
cache.insert(key, pix);
|
||||
cacheSizes.insert(size);
|
||||
return pix;
|
||||
}
|
||||
}
|
||||
if (cacheScaledCovers) {
|
||||
tryToLoad(setSizeRequest(song, size));
|
||||
tryToLoad(setSizeRequest(song, origSize));
|
||||
} else {
|
||||
tryToLocate(setSizeRequest(song, size));
|
||||
tryToLocate(setSizeRequest(song, origSize));
|
||||
}
|
||||
|
||||
// Create a dummy image so that we dont keep on locating/loading/downloading files that do not exist!
|
||||
pix=new QPixmap(1, 1);
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size!=origSize) {
|
||||
pix->setDevicePixelRatio(devicePixelRatio);
|
||||
DBUG << "Set pixel ratio of dummy cover" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
cache.insert(key, pix, 1);
|
||||
cacheSizes.insert(size);
|
||||
}
|
||||
@@ -1215,6 +1262,12 @@ QPixmap * Covers::get(const Song &song, int size, bool urgent)
|
||||
? Icons::self()->podcastIcon
|
||||
: Icons::self()->albumIcon;
|
||||
pix=new QPixmap(icn.pixmap(size, size).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size!=origSize) {
|
||||
pix->setDevicePixelRatio(devicePixelRatio);
|
||||
DBUG << "Set pixel ratio of dummy pixmap" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
cache.insert(key, pix, 1);
|
||||
cacheSizes.insert(size);
|
||||
}
|
||||
@@ -1250,10 +1303,20 @@ void Covers::updateCache(const Song &song, const QImage &img, bool dummyEntriesO
|
||||
QPixmap *pix(cache.object(key));
|
||||
|
||||
if (pix && (!dummyEntriesOnly || pix->width()<2)) {
|
||||
#if QT_VERSION >= 0x050100
|
||||
double pixRatio=pix->devicePixelRatio();
|
||||
#endif
|
||||
cache.remove(key);
|
||||
if (!img.isNull()) {
|
||||
DBUG_CLASS("Covers");
|
||||
if (saveScaledCover(scale(song, img, s), song, s) && emitLoaded) {
|
||||
QPixmap *p=saveScaledCover(scale(song, img, s), song, s);
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (p) {
|
||||
p->setDevicePixelRatio(pixRatio);
|
||||
DBUG << "Set pixel ratio of updated cached pixmap" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
if (pix && emitLoaded) {
|
||||
emit loaded(song, s);
|
||||
}
|
||||
}
|
||||
@@ -1648,8 +1711,22 @@ void Covers::loaded(const QList<LoadedCover> &covers)
|
||||
{
|
||||
foreach (const LoadedCover &cvr, covers) {
|
||||
if (!cvr.img.isNull()) {
|
||||
cache.insert(cacheKey(cvr.song, cvr.song.size), new QPixmap(QPixmap::fromImage(cvr.img)));
|
||||
cacheSizes.insert(cvr.song.size);
|
||||
int size=cvr.song.size;
|
||||
#if QT_VERSION >= 0x050100
|
||||
int origSize=size;
|
||||
if (size<constRetinaScaleMaxSize) {
|
||||
size*=devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
QPixmap *pix=new QPixmap(QPixmap::fromImage(cvr.img));
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (size!=origSize) {
|
||||
pix->setDevicePixelRatio(devicePixelRatio);
|
||||
DBUG << "Set pixel ratio of loaded pixmap" << devicePixelRatio;
|
||||
}
|
||||
#endif
|
||||
cache.insert(cacheKey(cvr.song, size), pix);
|
||||
cacheSizes.insert(size);
|
||||
emit loaded(cvr.song, cvr.song.size);
|
||||
} else { // Failed to load a scaled cover, try locating non-scaled cover...
|
||||
tryToLocate(cvr.song);
|
||||
|
||||
@@ -426,73 +426,74 @@ public:
|
||||
bool active=option.state&QStyle::State_Active;
|
||||
bool mouseOver=underMouse && option.state&QStyle::State_MouseOver;
|
||||
|
||||
if (!gtk && 1==text.count()) {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
if (mouseOver && gtk) {
|
||||
GtkStyle::drawSelection(option, painter, selected ? 0.75 : 0.25);
|
||||
} else {
|
||||
if (mouseOver && gtk) {
|
||||
GtkStyle::drawSelection(option, painter, selected ? 0.75 : 0.25);
|
||||
} else {
|
||||
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0L);
|
||||
}
|
||||
QRect r(option.rect);
|
||||
r.adjust(4, 0, -4, 0);
|
||||
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0L);
|
||||
}
|
||||
QRect r(option.rect);
|
||||
r.adjust(4, 0, -4, 0);
|
||||
|
||||
if (!noIcons) {
|
||||
QPixmap pix;
|
||||
if (index.data(Cantata::Role_ListImage).toBool()) {
|
||||
Song cSong=index.data(Cantata::Role_CoverSong).value<Song>();
|
||||
if (!cSong.isEmpty()) {
|
||||
QPixmap *cp=Covers::self()->get(cSong, listCoverSize);
|
||||
if (cp) {
|
||||
pix=*cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pix.isNull()) {
|
||||
pix=index.data(Qt::DecorationRole).value<QIcon>().pixmap(simpleViewDecorationSize, simpleViewDecorationSize);
|
||||
}
|
||||
|
||||
if (!pix.isNull()) {
|
||||
int adjust=qMax(pix.width(), pix.height());
|
||||
if (rtl) {
|
||||
painter->drawPixmap(r.x()+r.width()-pix.width(), r.y()+((r.height()-pix.height())/2), pix.width(), pix.height(), pix);
|
||||
r.adjust(3, 0, -(3+adjust), 0);
|
||||
} else {
|
||||
painter->drawPixmap(r.x(), r.y()+((r.height()-pix.height())/2), pix.width(), pix.height(), pix);
|
||||
r.adjust(adjust+3, 0, -3, 0);
|
||||
if (!noIcons) {
|
||||
QPixmap pix;
|
||||
if (index.data(Cantata::Role_ListImage).toBool()) {
|
||||
Song cSong=index.data(Cantata::Role_CoverSong).value<Song>();
|
||||
if (!cSong.isEmpty()) {
|
||||
QPixmap *cp=Covers::self()->get(cSong, listCoverSize);
|
||||
if (cp) {
|
||||
pix=*cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (text.count()>0) {
|
||||
QFont textFont(QApplication::font());
|
||||
QFontMetrics textMetrics(textFont);
|
||||
int textHeight=textMetrics.height();
|
||||
QColor color(option.palette.color(active ? QPalette::Active : QPalette::Inactive, selected ? QPalette::HighlightedText : QPalette::Text));
|
||||
QTextOption textOpt(Qt::AlignVCenter);
|
||||
QRect textRect(r.x(), r.y()+((r.height()-textHeight)/2), r.width(), textHeight);
|
||||
QString str=textMetrics.elidedText(text.at(0), Qt::ElideRight, textRect.width(), QPalette::WindowText);
|
||||
|
||||
painter->save();
|
||||
painter->setPen(color);
|
||||
painter->setFont(textFont);
|
||||
painter->drawText(textRect, str, textOpt);
|
||||
|
||||
if (text.count()>1) {
|
||||
int mainWidth=textMetrics.width(str);
|
||||
text.takeFirst();
|
||||
str=text.join(" - ");
|
||||
textRect=QRect(r.x()+(mainWidth+8), r.y()+((r.height()-textHeight)/2), r.width()-(mainWidth+8), textHeight);
|
||||
if (textRect.width()>4) {
|
||||
str = textMetrics.elidedText(str, Qt::ElideRight, textRect.width(), QPalette::WindowText);
|
||||
color.setAlphaF(subTextAlpha(selected));
|
||||
painter->setPen(color);
|
||||
painter->drawText(textRect, str, textOpt/*QTextOption(Qt::AlignVCenter|Qt::AlignRight)*/);
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
if (pix.isNull()) {
|
||||
pix=index.data(Qt::DecorationRole).value<QIcon>().pixmap(simpleViewDecorationSize, simpleViewDecorationSize);
|
||||
}
|
||||
|
||||
if (!pix.isNull()) {
|
||||
#if QT_VERSION >= 0x050100
|
||||
QSize layoutSize = pix.size() / pix.devicePixelRatio();
|
||||
#else
|
||||
QSize layoutSize = pix.size();
|
||||
#endif
|
||||
int adjust=qMax(layoutSize.width(), layoutSize.height());
|
||||
if (rtl) {
|
||||
painter->drawPixmap(r.x()+r.width()-layoutSize.width(), r.y()+((r.height()-layoutSize.height())/2), layoutSize.width(), layoutSize.height(), pix);
|
||||
r.adjust(3, 0, -(3+adjust), 0);
|
||||
} else {
|
||||
painter->drawPixmap(r.x(), r.y()+((r.height()-layoutSize.height())/2), layoutSize.width(), layoutSize.height(), pix);
|
||||
r.adjust(adjust+3, 0, -3, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (text.count()>0) {
|
||||
QFont textFont(QApplication::font());
|
||||
QFontMetrics textMetrics(textFont);
|
||||
int textHeight=textMetrics.height();
|
||||
QColor color(option.palette.color(active ? QPalette::Active : QPalette::Inactive, selected ? QPalette::HighlightedText : QPalette::Text));
|
||||
QTextOption textOpt(Qt::AlignVCenter);
|
||||
QRect textRect(r.x(), r.y()+((r.height()-textHeight)/2), r.width(), textHeight);
|
||||
QString str=textMetrics.elidedText(text.at(0), Qt::ElideRight, textRect.width(), QPalette::WindowText);
|
||||
|
||||
painter->save();
|
||||
painter->setPen(color);
|
||||
painter->setFont(textFont);
|
||||
painter->drawText(textRect, str, textOpt);
|
||||
|
||||
if (text.count()>1) {
|
||||
int mainWidth=textMetrics.width(str);
|
||||
text.takeFirst();
|
||||
str=text.join(" - ");
|
||||
textRect=QRect(r.x()+(mainWidth+8), r.y()+((r.height()-textHeight)/2), r.width()-(mainWidth+8), textHeight);
|
||||
if (textRect.width()>4) {
|
||||
str = textMetrics.elidedText(str, Qt::ElideRight, textRect.width(), QPalette::WindowText);
|
||||
color.setAlphaF(subTextAlpha(selected));
|
||||
painter->setPen(color);
|
||||
painter->drawText(textRect, str, textOpt/*QTextOption(Qt::AlignVCenter|Qt::AlignRight)*/);
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
if (mouseOver || Utils::touchFriendly()) {
|
||||
|
||||
Reference in New Issue
Block a user