Apply themed icon colors in UI layer, not in icon repository
This commit is contained in:
parent
8c6b6c5e91
commit
840c7db690
@ -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
|
||||
|
||||
@ -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
|
||||
) {
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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(),
|
||||
)
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@ -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)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user