Apply themed icon colors in UI layer, not in icon repository

This commit is contained in:
MM20 2022-04-11 20:04:19 +02:00
parent 8c6b6c5e91
commit 840c7db690
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
8 changed files with 65 additions and 81 deletions

View File

@ -8,11 +8,12 @@ import androidx.palette.graphics.Palette
import java.lang.ref.WeakReference
open class LauncherIcon(
foreground: Drawable,
background: Drawable? = null,
foregroundScale: Float = 1f,
backgroundScale: Float = 1f,
var autoGenerateBackgroundMode: Int = BACKGROUND_WHITE
foreground: Drawable,
background: Drawable? = null,
foregroundScale: Float = 1f,
backgroundScale: Float = 1f,
var autoGenerateBackgroundMode: Int = BACKGROUND_WHITE,
val isThemeable: Boolean = false,
) {
var foreground = foreground

View File

@ -15,6 +15,7 @@ class ClockDynamicLauncherIcon(
background: Drawable?,
foregroundScale: Float,
backgroundScale: Float,
isThemeable: Boolean = false,
val hourLayer: Int,
val minuteLayer: Int,
val secondLayer: Int
@ -22,7 +23,8 @@ class ClockDynamicLauncherIcon(
foreground,
background,
foregroundScale,
backgroundScale
backgroundScale,
isThemeable = isThemeable
) {

View File

@ -7,13 +7,14 @@ abstract class DynamicLauncherIcon(
foreground: Drawable,
background: Drawable?,
foregroundScale: Float,
backgroundScale: Float
)
: LauncherIcon(
foreground,
background,
foregroundScale,
backgroundScale,
backgroundScale: Float,
isThemeable: Boolean = false
) : LauncherIcon(
foreground,
background,
foregroundScale,
backgroundScale,
isThemeable = isThemeable
) {
abstract fun update(context: Context)

View File

@ -4,15 +4,15 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Resources
import android.util.LruCache
import android.util.TypedValue
import de.mm20.launcher2.icons.providers.*
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.search.data.Searchable
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
class IconRepository(
val context: Context,
@ -31,8 +31,6 @@ class IconRepository(
private val cache = LruCache<String, LauncherIcon>(200)
private val themeColors = MutableStateFlow(ThemeColors())
private var iconProviders: MutableStateFlow<List<IconProvider>> = MutableStateFlow(listOf())
private lateinit var placeholderProvider: IconProvider
@ -49,30 +47,34 @@ class IconRepository(
scope.launch {
dataStore.data.map { it.icons }.distinctUntilChanged().collectLatest { settings ->
themeColors.collectLatest { colors ->
val placeholderProvider = if (settings.themedIcons) {
ThemedPlaceholderIconProvider(context, colors)
} else {
PlaceholderIconProvider(context)
}
val providers = mutableListOf<IconProvider>()
if (settings.themedIcons) {
providers.add(ThemedIconProvider(context, colors))
}
if (settings.iconPack.isNotBlank()) {
providers.add(IconPackIconProvider(context, settings.iconPack, settings.legacyIconBg))
}
providers.add(GoogleClockIconProvider(context))
providers.add(CalendarIconProvider(context))
providers.add(SystemIconProvider(context, settings.legacyIconBg))
providers.add(placeholderProvider)
cache.evictAll()
this@IconRepository.placeholderProvider = placeholderProvider
iconProviders.value = providers
val placeholderProvider = if (settings.themedIcons) {
ThemedPlaceholderIconProvider(context)
} else {
PlaceholderIconProvider(context)
}
val providers = mutableListOf<IconProvider>()
if (settings.themedIcons) {
providers.add(ThemedIconProvider(context))
}
if (settings.iconPack.isNotBlank()) {
providers.add(
IconPackIconProvider(
context,
settings.iconPack,
settings.legacyIconBg
)
)
}
providers.add(GoogleClockIconProvider(context))
providers.add(CalendarIconProvider(context))
providers.add(SystemIconProvider(context, settings.legacyIconBg))
providers.add(placeholderProvider)
cache.evictAll()
this@IconRepository.placeholderProvider = placeholderProvider
iconProviders.value = providers
}
}
}
@ -120,19 +122,4 @@ class IconRepository(
return iconPackManager.getInstalledIconPacks()
}
fun applyTheme(theme: Resources.Theme) {
val typedValue = TypedValue()
val bgColor = theme.resolveAttribute(R.attr.colorPrimaryContainer, typedValue, true).let {
typedValue.data
}
val fgColor = theme.resolveAttribute(R.attr.colorOnPrimaryContainer, typedValue, true).let {
typedValue.data
}
themeColors.value = ThemeColors(foreground = fgColor, background = bgColor)
}
}
internal data class ThemeColors(
val foreground: Int = 0xFFFFFFFF.toInt(),
val background: Int = 0xFF000000.toInt(),
)
}

View File

@ -2,6 +2,7 @@ package de.mm20.launcher2.icons
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
@ -14,13 +15,13 @@ class ThemedCalendarDynamicLauncherIcon(
foregroundScale: Float,
val packageName: String,
val foregroundIds: IntArray,
val foregroundTint: Int,
background: Drawable,
) : DynamicLauncherIcon(
foreground = ColorDrawable(0),
background = background,
foregroundScale = foregroundScale,
backgroundScale = 1f,
isThemeable = true,
) {
var currentDay = 0
@ -36,7 +37,6 @@ class ThemedCalendarDynamicLauncherIcon(
Executors.newSingleThreadExecutor().execute {
val currentDayDrawable = resources.getDrawableOrNull(foregroundIds[day - 1])
?: return@execute
currentDayDrawable.setTint(foregroundTint)
foreground = currentDayDrawable
}
currentDay = day

View File

@ -3,11 +3,10 @@ package de.mm20.launcher2.icons.providers
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.LayerDrawable
import android.util.TypedValue
import androidx.core.content.res.ResourcesCompat
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.database.AppDatabase
@ -18,7 +17,6 @@ import de.mm20.launcher2.search.data.Searchable
internal class ThemedIconProvider(
private val context: Context,
private val colors: ThemeColors,
) : IconProvider {
override suspend fun getIcon(searchable: Searchable, size: Int): LauncherIcon? {
@ -49,11 +47,11 @@ internal class ThemedIconProvider(
private fun getStaticIcon(resources: Resources, resId: Int): LauncherIcon? {
try {
val fg = ResourcesCompat.getDrawable(resources, resId, null) ?: return null
fg.setTint(colors.foreground)
return LauncherIcon(
foreground = fg,
foregroundScale = 0.5f,
background = ColorDrawable(colors.background)
background = ColorDrawable(Color.WHITE),
isThemeable = true
)
} catch (e: Resources.NotFoundException) {
return null
@ -85,15 +83,15 @@ internal class ThemedIconProvider(
i++
}
if (drawable != null && minuteIndex != null && hourIndex != null) {
drawable.setTint(colors.foreground)
return ClockDynamicLauncherIcon(
foreground = drawable,
background = ColorDrawable(colors.background),
background = ColorDrawable(Color.WHITE),
foregroundScale = 1.5f,
backgroundScale = 1f,
hourLayer = hourIndex,
minuteLayer = minuteIndex,
secondLayer = -1,
isThemeable = true,
)
}
} catch (e: Resources.NotFoundException) {
@ -111,13 +109,12 @@ internal class ThemedIconProvider(
if (array.length() != 31) return null
return ThemedCalendarDynamicLauncherIcon(
background = ColorDrawable(colors.background),
foregroundScale = 0.5f,
packageName = iconProviderPackage,
foregroundIds = IntArray(31) {
array.getResourceId(it, 0).takeIf { it != 0 } ?: return null
},
foregroundTint = colors.foreground,
foregroundScale = 0.5f,
background = ColorDrawable(Color.WHITE),
)
} catch (e: Resources.NotFoundException) {

View File

@ -1,24 +1,23 @@
package de.mm20.launcher2.icons.providers
import android.content.Context
import android.content.res.Configuration
import android.util.TypedValue
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.icons.R
import de.mm20.launcher2.icons.ThemeColors
import de.mm20.launcher2.search.data.Searchable
internal class ThemedPlaceholderIconProvider(
private val context: Context,
private val colors: ThemeColors,
) : IconProvider {
override suspend fun getIcon(searchable: Searchable, size: Int): LauncherIcon {
val icon = searchable.getPlaceholderIcon(context)
icon.foreground.setTint(colors.foreground)
icon.background?.setTint(colors.background)
return icon
return LauncherIcon(
foreground = icon.foreground,
foregroundScale = icon.foregroundScale,
background = icon.background,
backgroundScale = icon.backgroundScale,
isThemeable = true
)
}
}

View File

@ -36,9 +36,6 @@ class LauncherActivity : BaseActivity() {
viewModel.setDarkMode(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
val iconRepository: IconRepository by inject()
iconRepository.applyTheme(theme)
binding = ActivityLauncherBinding.inflate(LayoutInflater.from(this))
setContentView(binding.root)