┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMéven Car <[email protected]>2025-01-14 18:52:36 +0100
committerMéven Car <[email protected]>2025-01-17 11:07:40 +0100
commit961e6270e4401a6c7512df3a2e3efd09a25df962 (patch)
treee282410c9546d0b636ca156848f6b75da722da61 /src
parent9a44aad838e111175b57a7ff14a9f6d2f44c5b65 (diff)
Refactor Overlay Handling
Now all overlays icons in kitemviews are added in KStandardItemListWidget::updatePixmapCache. data[iconOverlays] now contains icon names. DolphinFileItemListWidget::refreshCache is the sole responsible of setting the overlays either coming from KFileItemModelRolesUpdater or KVersionControlPlugin. This garantees consistency in rendering. BUG: 497372
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp10
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.h2
-rw-r--r--src/kitemviews/kstandarditemlistwidget.cpp88
-rw-r--r--src/kitemviews/kstandarditemlistwidget.h14
-rw-r--r--src/panels/information/informationpanelcontent.cpp19
-rw-r--r--src/views/dolphinfileitemlistwidget.cpp35
-rw-r--r--src/views/dolphinfileitemlistwidget.h2
7 files changed, 102 insertions, 68 deletions
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 92bf2bf8d..97b51ae84 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -552,7 +552,7 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem &item, const QPi
}
QHash<QByteArray, QVariant> data = rolesData(item, index);
- data.insert("iconPixmap", transformPreviewPixmap(pixmap, data["iconOverlays"].toStringList()));
+ data.insert("iconPixmap", transformPreviewPixmap(pixmap));
disconnect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
m_model->setData(index, data);
@@ -630,7 +630,7 @@ void KFileItemModelRolesUpdater::slotHoverSequenceGotPreview(const KFileItem &it
if (wap < 0.0f || loadedIndex < static_cast<int>(wap)) {
// Add the preview to the model data
- const QPixmap scaledPixmap = transformPreviewPixmap(pixmap, data["iconOverlays"].toStringList());
+ const QPixmap scaledPixmap = transformPreviewPixmap(pixmap);
pixmaps.append(scaledPixmap);
data["hoverSequencePixmaps"] = QVariant::fromValue(pixmaps);
@@ -1001,7 +1001,7 @@ void KFileItemModelRolesUpdater::startPreviewJob()
m_previewJob = job;
}
-QPixmap KFileItemModelRolesUpdater::transformPreviewPixmap(const QPixmap &pixmap, const QStringList &overlays)
+QPixmap KFileItemModelRolesUpdater::transformPreviewPixmap(const QPixmap &pixmap)
{
QPixmap scaledPixmap = pixmap;
@@ -1042,10 +1042,6 @@ QPixmap KFileItemModelRolesUpdater::transformPreviewPixmap(const QPixmap &pixmap
scaledPixmap.setDevicePixelRatio(m_devicePixelRatio);
}
- if (!overlays.isEmpty()) {
- scaledPixmap = KIconUtils::addOverlays(scaledPixmap, overlays).pixmap(cacheSize(), m_devicePixelRatio);
- }
-
return scaledPixmap;
}
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h
index 28a70cda3..3480713ee 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -299,7 +299,7 @@ private:
* @param overlays the overlays to add to the pixmap
* @return The scaled and decorated preview image.
*/
- QPixmap transformPreviewPixmap(const QPixmap &pixmap, const QStringList &overlays);
+ QPixmap transformPreviewPixmap(const QPixmap &pixmap);
/**
* Starts a PreviewJob for loading the next hover sequence image.
diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp
index aebcfa7d4..dd0ad8dc4 100644
--- a/src/kitemviews/kstandarditemlistwidget.cpp
+++ b/src/kitemviews/kstandarditemlistwidget.cpp
@@ -276,7 +276,7 @@ KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant *infor
, m_expansionArea()
, m_customTextColor()
, m_additionalInfoTextColor()
- , m_overlay()
+ , m_overlays()
, m_rating()
, m_roleEditor(nullptr)
, m_oldRoleEditor(nullptr)
@@ -737,16 +737,21 @@ QColor KStandardItemListWidget::textColor(const QWidget &widget) const
return styleOption().palette.color(group, role);
}
-void KStandardItemListWidget::setOverlay(const QPixmap &overlay)
+void KStandardItemListWidget::setOverlays(QHash<Qt::Corner, QString> &overlays)
{
- m_overlay = overlay;
+ if (overlays == m_overlays) {
+ return;
+ }
+
+ m_overlays = overlays;
m_dirtyContent = true;
+ m_dirtyContentRoles.insert("iconOverlays");
update();
}
-QPixmap KStandardItemListWidget::overlay() const
+QHash<Qt::Corner, QString> KStandardItemListWidget::overlays() const
{
- return m_overlay;
+ return m_overlays;
}
QString KStandardItemListWidget::roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values) const
@@ -1105,14 +1110,18 @@ void KStandardItemListWidget::updatePixmapCache()
const QStringList overlays = values["iconOverlays"].toStringList();
const bool hasFocus = scene()->views()[0]->parentWidget()->hasFocus();
m_pixmap = pixmapForIcon(iconName,
- overlays,
- maxIconHeight,
+ m_overlays,
+ QSize(maxIconWidth, maxIconHeight),
m_layout != IconsLayout && isActiveWindow() && isSelected() && hasFocus ? QIcon::Selected : QIcon::Normal);
- } else if (m_pixmap.width() / m_pixmap.devicePixelRatio() != maxIconWidth || m_pixmap.height() / m_pixmap.devicePixelRatio() != maxIconHeight) {
- // A custom pixmap has been applied. Assure that the pixmap
- // is scaled to the maximum available size.
- KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight) * dpr);
+ } else {
+ if (!m_overlays.isEmpty()) {
+ m_pixmap = addOverlays(m_pixmap, m_overlays, QSize(maxIconWidth, maxIconHeight), dpr);
+ } else if (m_pixmap.width() / m_pixmap.devicePixelRatio() != maxIconWidth || m_pixmap.height() / m_pixmap.devicePixelRatio() != maxIconHeight) {
+ // A custom pixmap has been applied. Assure that the pixmap
+ // is scaled to the maximum available size.
+ KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight) * dpr);
+ }
}
if (m_pixmap.isNull()) {
@@ -1140,11 +1149,6 @@ void KStandardItemListWidget::updatePixmapCache()
}
}
- if (!m_overlay.isNull()) {
- QPainter painter(&m_pixmap);
- painter.drawPixmap(0, (m_pixmap.height() - m_overlay.height()) / m_pixmap.devicePixelRatio(), m_overlay);
- }
-
int scaledIconSize = 0;
if (iconOnTop) {
const TextInfo *textInfo = m_textInfo.value("text");
@@ -1538,6 +1542,25 @@ void KStandardItemListWidget::updateAdditionalInfoTextColor()
QColor((c1.red() * p1 + c2.red() * p2) / 100, (c1.green() * p1 + c2.green() * p2) / 100, (c1.blue() * p1 + c2.blue() * p2) / 100);
}
+QPixmap KStandardItemListWidget::addOverlays(const QPixmap &pixmap,
+ const QHash<Qt::Corner, QString> &overlays,
+ const QSize &size,
+ qreal devicePixelRatioF,
+ QIcon::Mode mode) const
+{
+ if (overlays.isEmpty()) {
+ return pixmap;
+ }
+
+ QHash<Qt::Corner, QIcon> overlayIcons;
+
+ for (const auto &[corner, overlay] : overlays.asKeyValueRange()) {
+ overlayIcons.insert(corner, QIcon::fromTheme(overlay));
+ }
+
+ return KIconUtils::addOverlays(pixmap, overlayIcons).pixmap(size, devicePixelRatioF, mode);
+}
+
void KStandardItemListWidget::drawPixmap(QPainter *painter, const QPixmap &pixmap)
{
if (m_scaledPixmapSize != pixmap.size() / pixmap.devicePixelRatio()) {
@@ -1625,15 +1648,16 @@ void KStandardItemListWidget::closeRoleEditor()
m_roleEditor = nullptr;
}
-QPixmap KStandardItemListWidget::pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode) const
+QPixmap KStandardItemListWidget::pixmapForIcon(const QString &name, const QHash<Qt::Corner, QString> &overlays, const QSize &size, QIcon::Mode mode) const
{
static const QIcon fallbackIcon = QIcon::fromTheme(QStringLiteral("unknown"));
const qreal dpr = KItemViewsUtils::devicePixelRatio(this);
- size *= dpr;
+ int iconHeight = size.height();
+ QSize iconSize = QSize(iconHeight, iconHeight);
- const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QLatin1Char(':')) % ":" % QString::number(size) % "@" % QString::number(dpr)
- % ":" % QString::number(mode);
+ const QString key = "KStandardItemListWidget:" % name % ":" % overlays.values().join(QLatin1Char(':')) % ":" % QString::number(iconHeight) % "@"
+ % QString::number(dpr) % ":" % QString::number(mode);
QPixmap pixmap;
if (!QPixmapCache::find(key, &pixmap)) {
@@ -1641,26 +1665,18 @@ QPixmap KStandardItemListWidget::pixmapForIcon(const QString &name, const QStrin
if (icon.isNull()) {
icon = QIcon(name);
}
- if (icon.isNull() || icon.pixmap(size / dpr, size / dpr, mode).isNull()) {
+ if (!icon.isNull()) {
+ pixmap = icon.pixmap(iconSize, dpr, mode);
+ }
+ if (pixmap.isNull()) {
icon = fallbackIcon;
+ pixmap = icon.pixmap(iconSize, dpr, mode);
}
-
- pixmap = icon.pixmap(QSize(size / dpr, size / dpr), dpr, mode);
- if (pixmap.width() != size || pixmap.height() != size) {
- KPixmapModifier::scale(pixmap, QSize(size, size));
+ if (pixmap.width() != iconHeight * dpr || pixmap.height() != iconHeight * dpr) {
+ KPixmapModifier::scale(pixmap, iconSize * dpr);
}
- // Strangely KFileItem::overlays() returns empty string-values, so
- // we need to check first whether an overlay must be drawn at all.
- for (const QString &overlay : overlays) {
- if (!overlay.isEmpty()) {
- // There is at least one overlay, draw all overlays above m_pixmap
- // and cancel the check
- const QSize size = pixmap.size();
- pixmap = KIconUtils::addOverlays(pixmap, overlays).pixmap(size, dpr, mode);
- break;
- }
- }
+ pixmap = addOverlays(pixmap, overlays, size, dpr, mode);
QPixmapCache::insert(key, pixmap);
}
diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h
index d4a4f1231..3e542b4c5 100644
--- a/src/kitemviews/kstandarditemlistwidget.h
+++ b/src/kitemviews/kstandarditemlistwidget.h
@@ -158,8 +158,8 @@ protected:
void setTextColor(const QColor &color);
QColor textColor(const QWidget &widget) const;
- void setOverlay(const QPixmap &overlay);
- QPixmap overlay() const;
+ void setOverlays(QHash<Qt::Corner, QString> &overlay);
+ QHash<Qt::Corner, QString> overlays() const;
/**
* @see KStandardItemListWidgetInformant::roleText().
@@ -212,6 +212,12 @@ private:
void updateCompactLayoutTextCache();
void updateDetailsLayoutTextCache();
+ QPixmap addOverlays(const QPixmap &pixmap,
+ const QHash<Qt::Corner, QString> &overlays,
+ const QSize &size,
+ qreal devicePixelRatioF,
+ QIcon::Mode mode = QIcon::Normal) const;
+
void drawPixmap(QPainter *painter, const QPixmap &pixmap);
/** Draw the lines and arrows that visualize the expanded state and level of this row. */
void drawSiblingsInformation(QPainter *painter);
@@ -231,7 +237,7 @@ private:
*/
void closeRoleEditor();
- QPixmap pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode) const;
+ QPixmap pixmapForIcon(const QString &name, const QHash<Qt::Corner, QString> &overlays, const QSize &size, QIcon::Mode mode) const;
/**
* @return Preferred size of the rating-image based on the given
@@ -283,7 +289,7 @@ private:
QColor m_customTextColor;
QColor m_additionalInfoTextColor;
- QPixmap m_overlay;
+ QHash<Qt::Corner, QString> m_overlays;
QPixmap m_rating;
KItemListRoleEditor *m_roleEditor;
diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp
index b112b2caf..14a470b11 100644
--- a/src/panels/information/informationpanelcontent.cpp
+++ b/src/panels/information/informationpanelcontent.cpp
@@ -362,8 +362,23 @@ void InformationPanelContent::showPreview(const KFileItem &item, const QPixmap &
{
m_outdatedPreviewTimer->stop();
- QPixmap p = KIconUtils::addOverlays(pixmap, item.overlays()).pixmap(m_preview->size(), devicePixelRatioF());
- p.setDevicePixelRatio(devicePixelRatioF());
+ QPixmap p = pixmap;
+ if (!item.overlays().isEmpty()) {
+ // Avoid scaling the images that are smaller than the preview size, to be consistent when there is no overlays
+ if (pixmap.height() < m_preview->height() && pixmap.width() < m_preview->width()) {
+ p = QPixmap(m_preview->size() * devicePixelRatioF());
+ p.fill(Qt::transparent);
+ p.setDevicePixelRatio(devicePixelRatioF());
+
+ QPainter painter(&p);
+ painter.drawPixmap(QPointF{m_preview->width() / 2.0 - pixmap.width() / pixmap.devicePixelRatioF() / 2,
+ m_preview->height() / 2.0 - pixmap.height() / pixmap.devicePixelRatioF() / 2}
+ .toPoint(),
+ pixmap);
+ }
+ p = KIconUtils::addOverlays(p, item.overlays()).pixmap(m_preview->size(), devicePixelRatioF());
+ p.setDevicePixelRatio(devicePixelRatioF());
+ }
if (m_isVideo) {
// adds a play arrow overlay
diff --git a/src/views/dolphinfileitemlistwidget.cpp b/src/views/dolphinfileitemlistwidget.cpp
index 11c88d402..7ad242f3f 100644
--- a/src/views/dolphinfileitemlistwidget.cpp
+++ b/src/views/dolphinfileitemlistwidget.cpp
@@ -24,6 +24,7 @@ void DolphinFileItemListWidget::refreshCache()
{
QColor color;
const QHash<QByteArray, QVariant> values = data();
+ QHash<Qt::Corner, QString> overlays;
if (values.contains("version")) {
// The item is under version control. Apply the text color corresponding
// to its version state.
@@ -70,27 +71,28 @@ void DolphinFileItemListWidget::refreshCache()
(tintColor.blue() + textColor.blue()) / 2,
(tintColor.alpha() + textColor.alpha()) / 2);
- setOverlay(overlayForState(version, styleOption().iconSize));
- } else if (!overlay().isNull()) {
- setOverlay(QPixmap());
+ overlays.insert(Qt::Corner::BottomLeftCorner, overlayForState(version));
}
+ if (values.contains("iconOverlays")) {
+ const auto corners = {Qt::Corner::BottomRightCorner, Qt::Corner::TopLeftCorner, Qt::Corner::TopRightCorner};
+ const auto iconOverlays = values.value("iconOverlays").toStringList();
+ auto overlaysIt = iconOverlays.constBegin();
+ for (const auto &corner : corners) {
+ if (overlaysIt == iconOverlays.constEnd()) {
+ break;
+ }
+ overlays.insert(corner, *overlaysIt);
+ overlaysIt = ++overlaysIt;
+ }
+ }
+
+ setOverlays(overlays);
setTextColor(color);
}
-QPixmap DolphinFileItemListWidget::overlayForState(KVersionControlPlugin::ItemVersion version, int size) const
+QString DolphinFileItemListWidget::overlayForState(KVersionControlPlugin::ItemVersion version) const
{
- int overlayHeight = KIconLoader::SizeSmall;
- if (size >= KIconLoader::SizeEnormous) {
- overlayHeight = KIconLoader::SizeMedium;
- } else if (size >= KIconLoader::SizeLarge) {
- overlayHeight = KIconLoader::SizeSmallMedium;
- } else if (size >= KIconLoader::SizeMedium) {
- overlayHeight = KIconLoader::SizeSmall;
- } else {
- overlayHeight = KIconLoader::SizeSmall / 2;
- }
-
QString iconName;
switch (version) {
case KVersionControlPlugin::NormalVersion:
@@ -123,8 +125,7 @@ QPixmap DolphinFileItemListWidget::overlayForState(KVersionControlPlugin::ItemVe
break;
}
- const qreal dpr = KItemViewsUtils::devicePixelRatio(this);
- return QIcon::fromTheme(iconName).pixmap(QSize(overlayHeight, overlayHeight), dpr);
+ return iconName;
}
#include "moc_dolphinfileitemlistwidget.cpp"
diff --git a/src/views/dolphinfileitemlistwidget.h b/src/views/dolphinfileitemlistwidget.h
index 92fc66fcc..af15074d5 100644
--- a/src/views/dolphinfileitemlistwidget.h
+++ b/src/views/dolphinfileitemlistwidget.h
@@ -29,7 +29,7 @@ protected:
void refreshCache() override;
private:
- QPixmap overlayForState(KVersionControlPlugin::ItemVersion version, int size) const;
+ QString overlayForState(KVersionControlPlugin::ItemVersion version) const;
};
#endif