diff --git a/kcms/icons/main.h b/kcms/icons/main.h --- a/kcms/icons/main.h +++ b/kcms/icons/main.h @@ -72,7 +72,7 @@ Q_INVOKABLE void setIconSize(int group, int size); Q_INVOKABLE QList availableIconSizes(int group) const; - Q_INVOKABLE QVariantList/*QList*/ previewIcons(const QString &themeName, int size, qreal dpr) const; + Q_INVOKABLE QVariantList/*QList*/ previewIcons(const QString &themeName, int size, qreal dpr, int limit = -1); signals: void iconSizesChanged(); @@ -106,6 +106,9 @@ QStringList m_iconGroups; + // ListView deletes and recreates delegates as you scroll, so once we generated previews, cache them + QHash*/> m_previewCache; + QScopedPointer m_tempInstallFile; QPointer m_newStuffDialog; diff --git a/kcms/icons/main.cpp b/kcms/icons/main.cpp --- a/kcms/icons/main.cpp +++ b/kcms/icons/main.cpp @@ -284,6 +284,7 @@ // reload the display icontheme items KIconLoader::global()->newIconLoader(); m_model->load(); + m_previewCache.clear(); }); } @@ -340,6 +341,7 @@ KIconLoader::global()->newIconLoader(); m_model->load(); + m_previewCache.clear(); } void IconModule::exportToKDE4() @@ -477,8 +479,15 @@ return everythingOk; } -QVariantList IconModule::previewIcons(const QString &themeName, int size, qreal dpr) const +QVariantList IconModule::previewIcons(const QString &themeName, int size, qreal dpr, int limit) { + const QString cacheKey = themeName + QLatin1Char('@') + QString::number(size) + QLatin1Char('@') + QString::number(dpr,'f',1) + QLatin1Char('@') + QString::number(limit); + + auto it = m_previewCache.constFind(cacheKey); + if (it != m_previewCache.constEnd()) { + return *it; + } + KIconTheme theme(themeName); QSvgRenderer renderer; @@ -525,33 +534,45 @@ return QPixmap(); }; - QVariantList pixmaps{ - getBestIcon({QStringLiteral("system-run"), QStringLiteral("exec")}), - getBestIcon({QStringLiteral("folder")}), - getBestIcon({QStringLiteral("document"), QStringLiteral("text-x-generic")}), - getBestIcon({QStringLiteral("user-trash"), QStringLiteral("user-trash-empty")}), - getBestIcon({QStringLiteral("system-help"), QStringLiteral("help-about"), QStringLiteral("help-contents")}), - getBestIcon({QStringLiteral("preferences-system"), QStringLiteral("systemsettings"), QStringLiteral("configure")}), - - getBestIcon({QStringLiteral("text-html")}), - getBestIcon({QStringLiteral("image-x-generic"), QStringLiteral("image-png"), QStringLiteral("image-jpeg")}), - getBestIcon({QStringLiteral("video-x-generic"), QStringLiteral("video-x-theora+ogg"), QStringLiteral("video-mp4")}), - getBestIcon({QStringLiteral("x-office-document")}), - getBestIcon({QStringLiteral("x-office-spreadsheet")}), - getBestIcon({QStringLiteral("x-office-presentation"), QStringLiteral("application-presentation")}), - - getBestIcon({QStringLiteral("user-home")}), - getBestIcon({QStringLiteral("user-desktop"), QStringLiteral("desktop")}), - getBestIcon({QStringLiteral("folder-image"), QStringLiteral("folder-images"), QStringLiteral("folder-pictures"), QStringLiteral("folder-picture")}), - getBestIcon({QStringLiteral("folder-documents")}), - getBestIcon({QStringLiteral("folder-download"), QStringLiteral("folder-downloads")}), - getBestIcon({QStringLiteral("folder-video"), QStringLiteral("folder-videos")}) + static QVector s_previewIcons{ + {QStringLiteral("system-run"), QStringLiteral("exec")}, + {QStringLiteral("folder")}, + {QStringLiteral("document"), QStringLiteral("text-x-generic")}, + {QStringLiteral("user-trash"), QStringLiteral("user-trash-empty")}, + {QStringLiteral("system-help"), QStringLiteral("help-about"), QStringLiteral("help-contents")}, + {QStringLiteral("preferences-system"), QStringLiteral("systemsettings"), QStringLiteral("configure")}, + + {QStringLiteral("text-html")}, + {QStringLiteral("image-x-generic"), QStringLiteral("image-png"), QStringLiteral("image-jpeg")}, + {QStringLiteral("video-x-generic"), QStringLiteral("video-x-theora+ogg"), QStringLiteral("video-mp4")}, + {QStringLiteral("x-office-document")}, + {QStringLiteral("x-office-spreadsheet")}, + {QStringLiteral("x-office-presentation"), QStringLiteral("application-presentation")}, + + {QStringLiteral("user-home")}, + {QStringLiteral("user-desktop"), QStringLiteral("desktop")}, + {QStringLiteral("folder-image"), QStringLiteral("folder-images"), QStringLiteral("folder-pictures"), QStringLiteral("folder-picture")}, + {QStringLiteral("folder-documents")}, + {QStringLiteral("folder-download"), QStringLiteral("folder-downloads")}, + {QStringLiteral("folder-video"), QStringLiteral("folder-videos")} }; - // remove missing icons - pixmaps.erase(std::remove_if(pixmaps.begin(), pixmaps.end(), [](const QVariant &pixmapVariant) { - return pixmapVariant.value().isNull(); - }), pixmaps.end()); + QVariantList pixmaps; + + for (const QStringList &iconNames : s_previewIcons) { + QPixmap pix = getBestIcon(iconNames); + if (pix.isNull()) { + continue; + } + + pixmaps.append(pix); + + if (limit > -1 && pixmaps.count() >= limit) { + break; + } + } + + m_previewCache.insert(cacheKey, pixmaps); return pixmaps; } diff --git a/kcms/icons/package/contents/ui/main.qml b/kcms/icons/package/contents/ui/main.qml --- a/kcms/icons/package/contents/ui/main.qml +++ b/kcms/icons/package/contents/ui/main.qml @@ -89,6 +89,11 @@ } } onTriggered: { + if (!thumbFlow.allPreviesLoaded) { + thumbFlow.loadPreviews(-1 /*no limit*/); + thumbFlow.allPreviesLoaded = true; + } + ++thumbFlow.currentPage; if (thumbFlow.currentPage >= thumbFlow.pageCount) { stop(); @@ -102,6 +107,8 @@ // undefined is "didn't load preview yet" // empty array is "no preview available" property var previews + // initially we only load 6 and when the animation starts we'll load the rest + property bool allPreviesLoaded: false property int currentPage readonly property int pageCount: Math.ceil(thumbRepeater.count / (thumbFlow.columns * thumbFlow.rows)) @@ -112,6 +119,10 @@ readonly property int columns: 3 readonly property int rows: 2 + function loadPreviews(limit) { + previews = kcm.previewIcons(model.themeName, Math.min(thumbFlow.iconWidth, thumbFlow.iconHeight), Screen.devicePixelRatio, limit); + } + width: parent.width y: -currentPage * iconHeight * rows @@ -142,7 +153,8 @@ Component.onCompleted: { // avoid reloading it when icon sizes or dpr changes on startup Qt.callLater(function() { - previews = kcm.previewIcons(model.themeName, Math.min(thumbFlow.iconWidth, thumbFlow.iconHeight), Screen.devicePixelRatio) + // We show 6 icons initially (3x2 grid), only load those + thumbFlow.loadPreviews(6 /*limit*/); }); } }