File 0004-Add-HiDPI-support-for-thumbnails.patch of Package gwenview5
From 31a3e2acc90c00d0dccc6fe40a5b6229b35138b0 Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
Date: Sun, 7 Apr 2019 08:01:19 -0600
Subject: [PATCH] Add HiDPI support for thumbnails
Summary:
The idea is to localize changes in ThumbnailView as much as possible:
ThumbnailView::thumbnailSize() returns the size in device independent
pixels, i.e. it seems from the outside that ThumbnailView behaves as
well as before this change. But, of course, item delegates must take
into account that ThumbnailView::thumbnailForIndex() will return
a pixmap with the devicePixelRatio set.
CCBUG: 373178
Reviewers: #gwenview, ngraham
Reviewed By: #gwenview, ngraham
Subscribers: ngraham
Tags: #gwenview
Differential Revision: https://phabricator.kde.org/D20267
---
lib/thumbnailview/previewitemdelegate.cpp | 18 +++++++++++-------
lib/thumbnailview/thumbnailbarview.cpp | 17 ++++++++++-------
lib/thumbnailview/thumbnailslider.cpp | 2 +-
lib/thumbnailview/thumbnailview.cpp | 26 ++++++++++++++++----------
4 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/lib/thumbnailview/previewitemdelegate.cpp b/lib/thumbnailview/previewitemdelegate.cpp
index ae103b68..b7f0a4eb 100644
--- a/lib/thumbnailview/previewitemdelegate.cpp
+++ b/lib/thumbnailview/previewitemdelegate.cpp
@@ -164,7 +164,8 @@ struct PreviewItemDelegatePrivate
const int posX = mContextBarActions == PreviewItemDelegate::SelectionAction
? 0
: (rect.width() - mContextBar->width()) / 2;
- const int posY = qMax(CONTEXTBAR_MARGIN, mThumbnailSize.height() - thumbnailPix.height() - mContextBar->height());
+ const int thumbnailPixHeight = qRound(thumbnailPix.height() / thumbnailPix.devicePixelRatio());
+ const int posY = qMax(CONTEXTBAR_MARGIN, mThumbnailSize.height() - thumbnailPixHeight - mContextBar->height());
mContextBar->move(rect.topLeft() + QPoint(posX, posY));
mContextBar->show();
}
@@ -317,13 +318,15 @@ struct PreviewItemDelegatePrivate
{
const QPoint shadowOffset(-SHADOW_SIZE, -SHADOW_SIZE + 1);
- int key = rect.height() * 1000 + rect.width();
+ const auto dpr = painter->device()->devicePixelRatioF();
+ int key = qRound((rect.height() * 1000 + rect.width()) * dpr);
ShadowCache::Iterator it = mShadowCache.find(key);
if (it == mShadowCache.end()) {
QSize size = QSize(rect.width() + 2 * SHADOW_SIZE, rect.height() + 2 * SHADOW_SIZE);
QColor color(0, 0, 0, SHADOW_STRENGTH);
- QPixmap shadow = PaintUtils::generateFuzzyRect(size, color, SHADOW_SIZE);
+ QPixmap shadow = PaintUtils::generateFuzzyRect(size * dpr, color, qRound(SHADOW_SIZE * dpr));
+ shadow.setDevicePixelRatio(dpr);
it = mShadowCache.insert(key, shadow);
}
painter->drawPixmap(rect.topLeft() + shadowOffset, it.value());
@@ -688,6 +691,7 @@ void PreviewItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
int thumbnailHeight = d->mThumbnailSize.height();
QSize fullSize;
QPixmap thumbnailPix = d->mView->thumbnailForIndex(index, &fullSize);
+ QSize thumbnailSize = thumbnailPix.size() / thumbnailPix.devicePixelRatio();
const KFileItem fileItem = fileItemForIndex(index);
const bool opaque = !thumbnailPix.hasAlphaChannel();
const bool isDirOrArchive = ArchiveUtils::fileItemIsDirOrArchive(fileItem);
@@ -739,10 +743,10 @@ void PreviewItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
// Compute thumbnailRect
QRect thumbnailRect = QRect(
- rect.left() + (rect.width() - thumbnailPix.width()) / 2,
- rect.top() + (thumbnailHeight - thumbnailPix.height()) + ITEM_MARGIN,
- thumbnailPix.width(),
- thumbnailPix.height());
+ rect.left() + (rect.width() - thumbnailSize.width()) / 2,
+ rect.top() + (thumbnailHeight - thumbnailSize.height()) + ITEM_MARGIN,
+ thumbnailSize.width(),
+ thumbnailSize.height());
// Draw background
const QRect backgroundRect = thumbnailRect.adjusted(-ITEM_MARGIN, -ITEM_MARGIN, ITEM_MARGIN, ITEM_MARGIN);
diff --git a/lib/thumbnailview/thumbnailbarview.cpp b/lib/thumbnailview/thumbnailbarview.cpp
index 89c05c1d..9ab4128d 100644
--- a/lib/thumbnailview/thumbnailbarview.cpp
+++ b/lib/thumbnailview/thumbnailbarview.cpp
@@ -102,13 +102,15 @@ struct ThumbnailBarItemDelegatePrivate
{
const QPoint shadowOffset(-SHADOW_SIZE, -SHADOW_SIZE + 1);
- int key = rect.height() * 1000 + rect.width();
+ const auto dpr = painter->device()->devicePixelRatioF();
+ int key = qRound((rect.height() * 1000 + rect.width()) * dpr);
ShadowCache::Iterator it = mShadowCache.find(key);
if (it == mShadowCache.end()) {
QSize size = QSize(rect.width() + 2 * SHADOW_SIZE, rect.height() + 2 * SHADOW_SIZE);
QColor color(0, 0, 0, SHADOW_STRENGTH);
- QPixmap shadow = PaintUtils::generateFuzzyRect(size, color, SHADOW_SIZE);
+ QPixmap shadow = PaintUtils::generateFuzzyRect(size * dpr, color, qRound(SHADOW_SIZE * dpr));
+ shadow.setDevicePixelRatio(dpr);
it = mShadowCache.insert(key, shadow);
}
painter->drawPixmap(rect.topLeft() + shadowOffset, it.value());
@@ -175,7 +177,7 @@ QSize ThumbnailBarItemDelegate::sizeHint(const QStyleOptionViewItem & /*option*/
size = d->mView->gridSize();
} else {
QPixmap thumbnailPix = d->mView->thumbnailForIndex(index);
- size = thumbnailPix.size();
+ size = thumbnailPix.size() / thumbnailPix.devicePixelRatio();
size.rwidth() += ITEM_MARGIN * 2;
size.rheight() += ITEM_MARGIN * 2;
}
@@ -203,6 +205,7 @@ void ThumbnailBarItemDelegate::paint(QPainter * painter, const QStyleOptionViewI
bool isSelected = option.state & QStyle::State_Selected;
bool isCurrent = d->mView->selectionModel()->currentIndex() == index;
QPixmap thumbnailPix = d->mView->thumbnailForIndex(index);
+ QSize thumbnailSize = thumbnailPix.size() / thumbnailPix.devicePixelRatio();
QRect rect = option.rect;
QStyleOptionViewItem opt = option;
@@ -219,10 +222,10 @@ void ThumbnailBarItemDelegate::paint(QPainter * painter, const QStyleOptionViewI
// Draw thumbnail
if (!thumbnailPix.isNull()) {
QRect thumbnailRect = QRect(
- rect.left() + (rect.width() - thumbnailPix.width()) / 2,
- rect.top() + (rect.height() - thumbnailPix.height()) / 2 - 1,
- thumbnailPix.width(),
- thumbnailPix.height());
+ rect.left() + (rect.width() - thumbnailSize.width()) / 2,
+ rect.top() + (rect.height() - thumbnailSize.height()) / 2 - 1,
+ thumbnailSize.width(),
+ thumbnailSize.height());
if (!thumbnailPix.hasAlphaChannel()) {
d->drawShadow(painter, thumbnailRect);
diff --git a/lib/thumbnailview/thumbnailslider.cpp b/lib/thumbnailview/thumbnailslider.cpp
index 2c7fa2c9..03fabe26 100644
--- a/lib/thumbnailview/thumbnailslider.cpp
+++ b/lib/thumbnailview/thumbnailslider.cpp
@@ -65,7 +65,7 @@ void ThumbnailSlider::slotActionTriggered(int actionTriggered)
void ThumbnailSlider::updateToolTip()
{
// FIXME: i18n?
- const int size = slider()->sliderPosition();
+ const int size = qRound(slider()->sliderPosition() * devicePixelRatioF());
const QString text = QStringLiteral("%1 x %2").arg(size).arg(size);
slider()->setToolTip(text);
}
diff --git a/lib/thumbnailview/thumbnailview.cpp b/lib/thumbnailview/thumbnailview.cpp
index c2215f48..b95bc439 100644
--- a/lib/thumbnailview/thumbnailview.cpp
+++ b/lib/thumbnailview/thumbnailview.cpp
@@ -363,11 +363,12 @@ void ThumbnailView::updateThumbnailSize()
{
QSize value = d->mThumbnailSize;
// mWaitingThumbnail
+ const auto dpr = devicePixelRatioF();
int waitingThumbnailSize;
- if (value.width() > 64) {
- waitingThumbnailSize = 48;
+ if (value.width() > 64 * dpr) {
+ waitingThumbnailSize = qRound(48 * dpr);
} else {
- waitingThumbnailSize = 32;
+ waitingThumbnailSize = qRound(32 * dpr);
}
QPixmap icon = DesktopIcon(QStringLiteral("chronometer"), waitingThumbnailSize);
QPixmap pix(value);
@@ -377,6 +378,7 @@ void ThumbnailView::updateThumbnailSize()
painter.drawPixmap((value.width() - icon.width()) / 2, (value.height() - icon.height()) / 2, icon);
painter.end();
d->mWaitingThumbnail = pix;
+ d->mWaitingThumbnail.setDevicePixelRatio(dpr);
// Stop smoothing
d->mSmoothThumbnailTimer.stop();
@@ -390,8 +392,8 @@ void ThumbnailView::updateThumbnailSize()
it.value().mAdjustedPix = QPixmap();
}
- emit thumbnailSizeChanged(value);
- emit thumbnailWidthChanged(value.width());
+ emit thumbnailSizeChanged(value / dpr);
+ emit thumbnailWidthChanged(qRound(value.width() / dpr));
if (d->mScaleMode != ScaleToFit) {
scheduleDelayedItemsLayout();
}
@@ -400,11 +402,14 @@ void ThumbnailView::updateThumbnailSize()
void ThumbnailView::setThumbnailWidth(int width)
{
- if(d->mThumbnailSize.width() == width) {
+ const auto dpr = devicePixelRatioF();
+ const qreal newWidthF = width * dpr;
+ const int newWidth = qRound(newWidthF);
+ if(d->mThumbnailSize.width() == newWidth) {
return;
}
- int height = round((qreal)width / d->mThumbnailAspectRatio);
- d->mThumbnailSize = QSize(width, height);
+ int height = qRound(newWidthF / d->mThumbnailAspectRatio);
+ d->mThumbnailSize = QSize(newWidth, height);
updateThumbnailSize();
}
@@ -427,7 +432,7 @@ qreal ThumbnailView::thumbnailAspectRatio() const
QSize ThumbnailView::thumbnailSize() const
{
- return d->mThumbnailSize;
+ return d->mThumbnailSize / devicePixelRatioF();
}
void ThumbnailView::setThumbnailViewHelper(AbstractThumbnailViewHelper* helper)
@@ -654,6 +659,7 @@ QPixmap ThumbnailView::thumbnailForIndex(const QModelIndex& index, QSize* fullSi
if (fullSize) {
*fullSize = thumbnail.mRealFullSize;
}
+ thumbnail.mAdjustedPix.setDevicePixelRatio(devicePixelRatioF());
return thumbnail.mAdjustedPix;
}
@@ -763,7 +769,7 @@ void ThumbnailView::wheelEvent(QWheelEvent* event)
// setThumbnailSize() does not work
//verticalScrollBar()->setSingleStep(d->mThumbnailSize / 5);
if (event->modifiers() == Qt::ControlModifier) {
- int width = d->mThumbnailSize.width() + (event->delta() > 0 ? 1 : -1) * WHEEL_ZOOM_MULTIPLIER;
+ int width = thumbnailSize().width() + (event->delta() > 0 ? 1 : -1) * WHEEL_ZOOM_MULTIPLIER;
width = qMax(int(MinThumbnailSize), qMin(width, int(MaxThumbnailSize)));
setThumbnailWidth(width);
} else {
--
2.16.4