Improve icon picker, add icon search
This commit is contained in:
@@ -40,8 +40,6 @@ dependencies {
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.palette)
|
||||
|
||||
implementation(libs.androidx.paging.common)
|
||||
|
||||
implementation(libs.materialcomponents.core)
|
||||
|
||||
implementation(libs.bundles.androidx.lifecycle)
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.util.Log
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import de.mm20.launcher2.customattrs.CustomIconPackIcon
|
||||
import de.mm20.launcher2.database.AppDatabase
|
||||
import de.mm20.launcher2.ktx.randomElementOrNull
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -185,18 +186,12 @@ class IconPackManager(
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getIcons(componentName: ComponentName): List<IconPackIcon> {
|
||||
suspend fun getAllIconPackIcons(componentName: ComponentName): List<IconPackIcon> {
|
||||
val iconDao = appDatabase.iconDao()
|
||||
return iconDao.getIconsFromAllPacks(componentName.flattenToString())
|
||||
.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)
|
||||
@@ -242,6 +237,13 @@ class IconPackManager(
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun searchIconPackIcon(query: String): List<IconPackIcon> {
|
||||
val iconDao = appDatabase.iconDao()
|
||||
return iconDao.searchIconPackIcons("%$query%").map {
|
||||
IconPackIcon(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
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,12 +6,11 @@ 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.icons.transformations.transform
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.data.Searchable
|
||||
@@ -117,7 +116,7 @@ class IconRepository(
|
||||
icon = provs.getFirstIcon(searchable, size)
|
||||
|
||||
if (icon != null) {
|
||||
icon = transforms.apply(icon)
|
||||
icon = icon.transform(transforms)
|
||||
|
||||
cache.put(searchable.key + customIcon.hashCode(), icon)
|
||||
send(icon)
|
||||
@@ -181,15 +180,6 @@ class IconRepository(
|
||||
|
||||
val defaultTransformations = transformations.first()
|
||||
|
||||
val defaultTransformedIcon = defaultTransformations.apply(rawIcon)
|
||||
|
||||
suggestions.add(
|
||||
CustomIconWithPreview(
|
||||
defaultTransformedIcon,
|
||||
null,
|
||||
)
|
||||
)
|
||||
|
||||
val customIcons = mutableListOf<CustomIcon>(UnmodifiedSystemDefaultIcon)
|
||||
|
||||
if (rawIcon is StaticLauncherIcon && rawIcon.backgroundLayer is TransparentLayer) {
|
||||
@@ -230,7 +220,7 @@ class IconRepository(
|
||||
val icon = providers.getFirstIcon(searchable, size) ?: rawIcon
|
||||
|
||||
CustomIconWithPreview(
|
||||
preview = transformations.apply(icon),
|
||||
preview = icon.transform(transformations),
|
||||
customIcon = it,
|
||||
)
|
||||
|
||||
@@ -240,7 +230,7 @@ class IconRepository(
|
||||
val providerOptions = mutableListOf<CustomIcon>()
|
||||
|
||||
if (searchable is LauncherApp) {
|
||||
val iconPackIcons = iconPackManager.getIcons(
|
||||
val iconPackIcons = iconPackManager.getAllIconPackIcons(
|
||||
searchable.launcherActivityInfo.componentName
|
||||
)
|
||||
|
||||
@@ -262,7 +252,7 @@ class IconRepository(
|
||||
val icon = providers.getFirstIcon(searchable, size) ?: return@mapNotNull null
|
||||
|
||||
CustomIconWithPreview(
|
||||
preview = defaultTransformations.apply(icon),
|
||||
preview = icon.transform(defaultTransformations),
|
||||
customIcon = it,
|
||||
)
|
||||
|
||||
@@ -273,8 +263,28 @@ class IconRepository(
|
||||
|
||||
}
|
||||
|
||||
suspend fun getAllIconsFromPack(iconPack: String): PagingSource<Int, CustomIconWithPreview> {
|
||||
return IconPackPagingSource(iconPackManager, iconPack, transformations.first())
|
||||
suspend fun getUncustomizedDefaultIcon(searchable: Searchable, size: Int): CustomIconWithPreview? {
|
||||
val icon = iconProviders.first().getFirstIcon(searchable, size)
|
||||
?.transform(transformations.first()) ?: return null
|
||||
return CustomIconWithPreview(
|
||||
customIcon = null,
|
||||
preview = icon
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun searchIconPackIcon(query: String): List<CustomIconWithPreview> {
|
||||
val transformations = this.transformations.first()
|
||||
return iconPackManager.searchIconPackIcon(query).mapNotNull {
|
||||
val componentName = it.componentName ?: return@mapNotNull null
|
||||
|
||||
CustomIconWithPreview(
|
||||
customIcon = CustomIconPackIcon(
|
||||
iconPackPackage = it.iconPack,
|
||||
iconComponentName = componentName.flattenToString(),
|
||||
),
|
||||
preview = iconPackManager.getIcon(it.iconPack, componentName)?.transform(transformations) ?: return@mapNotNull null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCustomIcon(searchable: Searchable, icon: CustomIcon?) {
|
||||
|
||||
+8
-8
@@ -8,17 +8,17 @@ internal interface LauncherIconTransformation {
|
||||
suspend fun transform(icon: StaticLauncherIcon): StaticLauncherIcon
|
||||
}
|
||||
|
||||
internal suspend fun Iterable<LauncherIconTransformation>.apply(icon: LauncherIcon): LauncherIcon {
|
||||
if (icon is StaticLauncherIcon) {
|
||||
var transformedIcon = icon
|
||||
for (transformation in this) {
|
||||
internal suspend fun LauncherIcon.transform(transformations: Iterable<LauncherIconTransformation>): LauncherIcon {
|
||||
if (this is StaticLauncherIcon) {
|
||||
var transformedIcon = this
|
||||
for (transformation in transformations) {
|
||||
transformedIcon = transformation.transform(transformedIcon as StaticLauncherIcon)
|
||||
}
|
||||
return transformedIcon
|
||||
}
|
||||
if (icon is TransformableDynamicLauncherIcon) {
|
||||
icon.setTransformations(this.toList())
|
||||
return icon
|
||||
if (this is TransformableDynamicLauncherIcon) {
|
||||
this.setTransformations(transformations.toList())
|
||||
return this
|
||||
}
|
||||
return icon
|
||||
return this
|
||||
}
|
||||
Reference in New Issue
Block a user