(Absolutely awful) picker for any icon from any pack
This commit is contained in:
@@ -191,6 +191,12 @@ class IconPackManager(
|
||||
.map { IconPackIcon(it) }
|
||||
}
|
||||
|
||||
suspend fun getIcons(iconPack: String, offset: Int, limit: Int): List<IconPackIcon> {
|
||||
val iconDao = appDatabase.iconDao()
|
||||
return iconDao.getIcons(iconPack, offset, limit)
|
||||
.map { IconPackIcon(it) }
|
||||
}
|
||||
|
||||
private suspend fun getIconBack(iconPack: String): String? {
|
||||
val iconDao = appDatabase.iconDao()
|
||||
val iconbacks = iconDao.getIconBacks(iconPack)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package de.mm20.launcher2.icons
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import de.mm20.launcher2.customattrs.CustomIconPackIcon
|
||||
import de.mm20.launcher2.icons.transformations.LauncherIconTransformation
|
||||
import de.mm20.launcher2.icons.transformations.apply
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class IconPackPagingSource(
|
||||
private val iconPackManager: IconPackManager,
|
||||
private val iconPack: String,
|
||||
private val transformations: List<LauncherIconTransformation>
|
||||
) : PagingSource<Int, CustomIconWithPreview>() {
|
||||
override fun getRefreshKey(state: PagingState<Int, CustomIconWithPreview>): Int? {
|
||||
return null
|
||||
}
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, CustomIconWithPreview> {
|
||||
val page = params.key ?: 0
|
||||
|
||||
val icons = withContext(Dispatchers.IO) {
|
||||
iconPackManager.getIcons(iconPack, page, page + params.loadSize)
|
||||
}
|
||||
|
||||
val customIcons = mutableListOf<CustomIconWithPreview>()
|
||||
withContext(Dispatchers.Default) {
|
||||
for (icon in icons) {
|
||||
val data = CustomIconPackIcon(iconPack, icon.componentName?.flattenToString() ?: continue)
|
||||
|
||||
val ic = iconPackManager.getIcon(
|
||||
iconPack,
|
||||
icon.componentName
|
||||
) ?: continue
|
||||
|
||||
customIcons.add(
|
||||
CustomIconWithPreview(
|
||||
preview = transformations.apply(ic),
|
||||
customIcon = data,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return LoadResult.Page(
|
||||
data = customIcons,
|
||||
prevKey = if (page > 0) page - 1 else null,
|
||||
nextKey = if (icons.size == params.loadSize) page + 1 else null
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,10 +6,12 @@ import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.Color
|
||||
import android.util.LruCache
|
||||
import androidx.paging.PagingSource
|
||||
import de.mm20.launcher2.customattrs.*
|
||||
import de.mm20.launcher2.icons.providers.*
|
||||
import de.mm20.launcher2.icons.transformations.LauncherIconTransformation
|
||||
import de.mm20.launcher2.icons.transformations.LegacyToAdaptiveTransformation
|
||||
import de.mm20.launcher2.icons.transformations.apply
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.data.Searchable
|
||||
@@ -112,10 +114,10 @@ class IconRepository(
|
||||
val placeholder = placeholderProvider?.getIcon(searchable, size)
|
||||
placeholder?.let { send(it) }
|
||||
|
||||
icon = getFirstIcon(searchable, size, provs)
|
||||
icon = provs.getFirstIcon(searchable, size)
|
||||
|
||||
if (icon != null) {
|
||||
icon = applyTransformations(icon, transforms)
|
||||
icon = transforms.apply(icon)
|
||||
|
||||
cache.put(searchable.key + customIcon.hashCode(), icon)
|
||||
send(icon)
|
||||
@@ -172,21 +174,17 @@ class IconRepository(
|
||||
suspend fun getCustomIconSuggestions(
|
||||
searchable: Searchable,
|
||||
size: Int
|
||||
): List<CustomIconSuggestion> {
|
||||
val suggestions = mutableListOf<CustomIconSuggestion>()
|
||||
): List<CustomIconWithPreview> {
|
||||
val suggestions = mutableListOf<CustomIconWithPreview>()
|
||||
|
||||
var rawIcon = getFirstIcon(searchable, size, iconProviders.first())
|
||||
|
||||
if (rawIcon == null) {
|
||||
return emptyList()
|
||||
}
|
||||
val rawIcon = iconProviders.first().getFirstIcon(searchable, size) ?: return emptyList()
|
||||
|
||||
val defaultTransformations = transformations.first()
|
||||
|
||||
val defaultTransformedIcon = applyTransformations(rawIcon, defaultTransformations)
|
||||
val defaultTransformedIcon = defaultTransformations.apply(rawIcon)
|
||||
|
||||
suggestions.add(
|
||||
CustomIconSuggestion(
|
||||
CustomIconWithPreview(
|
||||
defaultTransformedIcon,
|
||||
null,
|
||||
)
|
||||
@@ -229,11 +227,11 @@ class IconRepository(
|
||||
val transformations = getTransformations(it) ?: defaultTransformations
|
||||
val providers = getProviders(it)
|
||||
|
||||
val icon = getFirstIcon(searchable, size, providers) ?: rawIcon
|
||||
val icon = providers.getFirstIcon(searchable, size) ?: rawIcon
|
||||
|
||||
CustomIconSuggestion(
|
||||
icon = applyTransformations(icon, transformations),
|
||||
data = it,
|
||||
CustomIconWithPreview(
|
||||
preview = transformations.apply(icon),
|
||||
customIcon = it,
|
||||
)
|
||||
|
||||
}
|
||||
@@ -261,11 +259,11 @@ class IconRepository(
|
||||
providerOptions.mapNotNull {
|
||||
val providers = getProviders(it)
|
||||
|
||||
val icon = getFirstIcon(searchable, size, providers) ?: return@mapNotNull null
|
||||
val icon = providers.getFirstIcon(searchable, size) ?: return@mapNotNull null
|
||||
|
||||
CustomIconSuggestion(
|
||||
icon = applyTransformations(icon, defaultTransformations),
|
||||
data = it,
|
||||
CustomIconWithPreview(
|
||||
preview = defaultTransformations.apply(icon),
|
||||
customIcon = it,
|
||||
)
|
||||
|
||||
}
|
||||
@@ -275,31 +273,8 @@ class IconRepository(
|
||||
|
||||
}
|
||||
|
||||
private suspend fun getFirstIcon(
|
||||
searchable: Searchable,
|
||||
size: Int,
|
||||
providers: List<IconProvider>
|
||||
): LauncherIcon? {
|
||||
for (provider in providers) {
|
||||
val icon = provider.getIcon(searchable, size)
|
||||
if (icon != null) {
|
||||
return icon
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private suspend fun applyTransformations(
|
||||
icon: LauncherIcon,
|
||||
transformations: List<LauncherIconTransformation>
|
||||
): LauncherIcon {
|
||||
var transformedIcon = icon
|
||||
if (transformedIcon is StaticLauncherIcon) {
|
||||
for (transformation in transformations) {
|
||||
transformedIcon = transformation.transform(transformedIcon as StaticLauncherIcon)
|
||||
}
|
||||
}
|
||||
return transformedIcon
|
||||
suspend fun getAllIconsFromPack(iconPack: String): PagingSource<Int, CustomIconWithPreview> {
|
||||
return IconPackPagingSource(iconPackManager, iconPack, transformations.first())
|
||||
}
|
||||
|
||||
fun setCustomIcon(searchable: Searchable, icon: CustomIcon?) {
|
||||
@@ -308,7 +283,7 @@ class IconRepository(
|
||||
|
||||
}
|
||||
|
||||
data class CustomIconSuggestion(
|
||||
val icon: LauncherIcon,
|
||||
val data: CustomIcon?,
|
||||
data class CustomIconWithPreview(
|
||||
val preview: LauncherIcon,
|
||||
val customIcon: CustomIcon?,
|
||||
)
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.mm20.launcher2.icons.providers
|
||||
|
||||
import android.content.ComponentName
|
||||
import de.mm20.launcher2.customattrs.CustomIconPackIcon
|
||||
import de.mm20.launcher2.icons.IconPackManager
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
@@ -11,10 +12,9 @@ class CustomIconPackIconProvider(
|
||||
private val iconPackManager: IconPackManager,
|
||||
) : IconProvider {
|
||||
override suspend fun getIcon(searchable: Searchable, size: Int): LauncherIcon? {
|
||||
if (searchable !is LauncherApp) return null
|
||||
return iconPackManager.getIcon(
|
||||
customIcon.iconPackPackage,
|
||||
searchable.launcherActivityInfo.componentName
|
||||
ComponentName.unflattenFromString(customIcon.iconComponentName) ?: return null
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -5,4 +5,17 @@ import de.mm20.launcher2.search.data.Searchable
|
||||
|
||||
interface IconProvider {
|
||||
suspend fun getIcon(searchable: Searchable, size: Int): LauncherIcon?
|
||||
}
|
||||
|
||||
internal suspend fun Iterable<IconProvider>.getFirstIcon(
|
||||
searchable: Searchable,
|
||||
size: Int
|
||||
): LauncherIcon? {
|
||||
for (provider in this) {
|
||||
val icon = provider.getIcon(searchable, size)
|
||||
if (icon != null) {
|
||||
return icon
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
+11
@@ -1,7 +1,18 @@
|
||||
package de.mm20.launcher2.icons.transformations
|
||||
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.icons.StaticLauncherIcon
|
||||
|
||||
internal interface LauncherIconTransformation {
|
||||
suspend fun transform(icon: StaticLauncherIcon): StaticLauncherIcon
|
||||
}
|
||||
|
||||
internal suspend fun Iterable<LauncherIconTransformation>.apply(icon: LauncherIcon): LauncherIcon {
|
||||
var transformedIcon = icon
|
||||
if (transformedIcon is StaticLauncherIcon) {
|
||||
for (transformation in this) {
|
||||
transformedIcon = transformation.transform(transformedIcon as StaticLauncherIcon)
|
||||
}
|
||||
}
|
||||
return transformedIcon
|
||||
}
|
||||
Reference in New Issue
Block a user