Add preference to disable themed icons for themed icon packs

This commit is contained in:
MM20 2023-03-15 17:02:16 +01:00
parent 6f6d6451a9
commit 70b406eb5c
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
9 changed files with 139 additions and 58 deletions

View File

@ -4,21 +4,24 @@ import android.graphics.drawable.ColorDrawable
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.FormatPaint
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.FilledIconToggleButton
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
@ -34,6 +37,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@ -249,6 +253,7 @@ fun AppearanceSettingsScreen() {
)
val iconPackPackage by viewModel.iconPack.observeAsState()
val iconPackThemed by viewModel.iconPackThemed.collectAsState(true)
val installedIconPacks by viewModel.installedIconPacks.collectAsState(emptyList())
val iconPack by remember {
derivedStateOf { installedIconPacks.firstOrNull { it.packageName == iconPackPackage } }
@ -256,56 +261,88 @@ fun AppearanceSettingsScreen() {
val items = installedIconPacks.map {
it.name to it
}
ListPreference(
title = stringResource(R.string.preference_icon_pack),
items = items,
summary = if (items.size <= 1) {
stringResource(R.string.preference_icon_pack_summary_empty)
} else {
iconPack?.name ?: "System"
},
enabled = installedIconPacks.size > 1,
value = iconPack,
onValueChanged = {
if (it != null) viewModel.setIconPack(it.packageName)
},
itemLabel = {
Column(
verticalArrangement = Arrangement.Center,
) {
Text(
text = it.label,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
if (it.value?.themed == true) {
Surface(
shape = MaterialTheme.shapes.extraSmall,
color = MaterialTheme.colorScheme.tertiary,
modifier = Modifier.padding(top = 4.dp)
Row(
verticalAlignment = (Alignment.CenterVertically)
) {
Box(
modifier = Modifier.weight(1f)
) {
ListPreference(
title = stringResource(R.string.preference_icon_pack),
items = items,
summary = if (items.size <= 1) {
stringResource(R.string.preference_icon_pack_summary_empty)
} else {
iconPack?.name ?: "System"
},
enabled = installedIconPacks.size > 1,
value = iconPack,
onValueChanged = {
if (it != null) viewModel.setIconPack(it.packageName)
},
itemLabel = {
Column(
verticalArrangement = Arrangement.Center,
) {
Row(
modifier = Modifier.padding(horizontal = 4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier
.size(20.dp)
.padding(end = 4.dp),
imageVector = Icons.Rounded.FormatPaint,
contentDescription = null,
)
Text(
text = stringResource(R.string.icon_pack_dynamic_colors),
style = MaterialTheme.typography.labelSmall
)
Text(
text = it.label,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
if (it.value?.themed == true) {
Surface(
shape = MaterialTheme.shapes.extraSmall,
color = MaterialTheme.colorScheme.tertiary,
modifier = Modifier.padding(top = 4.dp)
) {
Row(
modifier = Modifier.padding(horizontal = 4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier
.size(20.dp)
.padding(end = 4.dp),
imageVector = Icons.Rounded.FormatPaint,
contentDescription = null,
)
Text(
text = stringResource(R.string.icon_pack_dynamic_colors),
style = MaterialTheme.typography.labelSmall
)
}
}
}
}
}
)
}
if (iconPack?.themed == true) {
Box(
modifier = Modifier
.height(36.dp)
.width(1.dp)
.alpha(0.38f)
.background(LocalContentColor.current)
)
Box(
modifier = Modifier
.padding(12.dp)
) {
FilledIconToggleButton(
checked = iconPackThemed,
onCheckedChange = {
viewModel.setIconPackThemed(it)
}) {
Icon(
Icons.Rounded.FormatPaint,
stringResource(R.string.icon_pack_dynamic_colors)
)
}
}
}
)
}
}
PreferenceCategory(stringResource(R.string.preference_category_searchbar)) {
val searchBarStyle by viewModel.searchBarStyle.observeAsState()

View File

@ -20,7 +20,9 @@ import de.mm20.launcher2.preferences.Settings.SearchBarSettings
import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarColors
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@ -199,12 +201,29 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
}
val installedIconPacks: Flow<List<IconPack>> = iconRepository.getInstalledIconPacks().map {
listOf(IconPack(
listOf(
IconPack(
name = "System",
packageName = "",
version = "",
)) + it
)
) + it
}
val iconPackThemed = dataStore.data.map { it.icons.iconPackThemed }
fun setIconPackThemed(iconPackThemed: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setIcons(
it.icons
.toBuilder()
.setIconPackThemed(iconPackThemed)
)
.build()
}
}
}
val iconPack = dataStore.data.map { it.icons.iconPack }.asLiveData()
fun setIconPack(iconPack: String) {

View File

@ -22,7 +22,7 @@ internal val Context.dataStore: LauncherDataStore by dataStore(
}
)
internal const val SchemaVersion = 13
internal const val SchemaVersion = 14
internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
return listOf(
@ -39,5 +39,6 @@ internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
Migration_10_11(),
Migration_11_12(),
Migration_12_13(),
Migration_13_14(),
)
}

View File

@ -145,6 +145,7 @@ fun createFactorySettings(context: Context): Settings {
.setShape(Settings.IconSettings.IconShape.PlatformDefault)
.setThemedIcons(false)
.setIconPack("")
.setIconPackThemed(true)
)
.setEasterEgg(false)
.setSystemBars(

View File

@ -0,0 +1,13 @@
package de.mm20.launcher2.preferences.migrations
import de.mm20.launcher2.preferences.Settings
class Migration_13_14 : VersionedMigration(13, 14) {
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
return builder
.setIcons(
builder.icons.toBuilder()
.setIconPackThemed(true)
)
}
}

View File

@ -246,6 +246,7 @@ message Settings {
reserved 4;
bool adaptify = 5;
bool force_themed = 6;
bool icon_pack_themed = 7;
}
IconSettings icons = 21;

View File

@ -87,6 +87,7 @@ class IconPackManager(
iconPack: String,
packageName: String,
activityName: String?,
allowThemed: Boolean = true
): LauncherIcon? {
val res = try {
context.packageManager.getResourcesForApplication(iconPack)
@ -100,11 +101,11 @@ class IconPackManager(
?: return null
if (icon is CalendarIcon) {
return getIconPackCalendarIcon(icon, res)
return getIconPackCalendarIcon(icon, res, allowThemed)
} else if (icon is AppIcon) {
return getIconPackStaticIcon(icon, res)
return getIconPackStaticIcon(icon, res, allowThemed)
} else if (icon is ClockIcon) {
return getIconPackClockIcon(icon, res)
return getIconPackClockIcon(icon, res, allowThemed)
}
return null
}
@ -241,6 +242,7 @@ class IconPackManager(
private fun getIconPackStaticIcon(
icon: AppIcon,
resources: Resources,
allowThemed: Boolean,
): LauncherIcon? {
val resId =
resources.getIdentifier(icon.drawable, "drawable", icon.iconPack).takeIf { it != 0 }
@ -250,8 +252,9 @@ class IconPackManager(
} catch (e: Resources.NotFoundException) {
return null
}
val themed = icon.themed && allowThemed
return when {
icon.themed && drawable is AdaptiveIconDrawable -> {
themed && drawable is AdaptiveIconDrawable -> {
if (isAtLeastApiLevel(33) && drawable.monochrome != null) {
return StaticLauncherIcon(
foregroundLayer = TintedIconLayer(
@ -271,7 +274,7 @@ class IconPackManager(
}
}
icon.themed -> {
themed -> {
return StaticLauncherIcon(
foregroundLayer = TintedIconLayer(
icon = drawable,
@ -313,6 +316,7 @@ class IconPackManager(
private fun getIconPackCalendarIcon(
icon: CalendarIcon,
resources: Resources,
allowThemed: Boolean,
): LauncherIcon? {
val drawableIds = icon.drawables.map {
val id = resources.getIdentifier(it, "drawable", icon.iconPack)
@ -321,7 +325,7 @@ class IconPackManager(
}.toIntArray()
if (icon.themed) {
if (icon.themed && allowThemed) {
return ThemedDynamicCalendarIcon(
resources = resources,
resourceIds = drawableIds,
@ -336,6 +340,7 @@ class IconPackManager(
private fun getIconPackClockIcon(
icon: ClockIcon,
resources: Resources,
allowThemed: Boolean,
): LauncherIcon? {
var drawable = try {
resources.getIdentifier(icon.drawable, "drawable", icon.iconPack).takeIf { it != 0 }
@ -362,8 +367,10 @@ class IconPackManager(
)
}
val themed = icon.themed && allowThemed
return when {
icon.themed && drawable is AdaptiveIconDrawable -> {
themed && drawable is AdaptiveIconDrawable -> {
StaticLauncherIcon(
foregroundLayer = TintedClockLayer(
defaultHour = icon.config.defaultHour,
@ -376,7 +383,7 @@ class IconPackManager(
)
}
icon.themed -> {
themed -> {
StaticLauncherIcon(
foregroundLayer = TintedClockLayer(
defaultHour = icon.config.defaultHour,

View File

@ -109,7 +109,8 @@ class IconRepository(
IconPackIconProvider(
context,
pack,
iconPackManager
iconPackManager,
settings.iconPackThemed,
)
)
} else {

View File

@ -12,11 +12,12 @@ class IconPackIconProvider(
private val context: Context,
private val iconPack: IconPack,
private val iconPackManager: IconPackManager,
private val allowThemed: Boolean,
): IconProvider {
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
if (searchable !is LauncherApp) return null
return iconPackManager.getIcon(iconPack.packageName, searchable.`package`, searchable.activity)
return iconPackManager.getIcon(iconPack.packageName, searchable.`package`, searchable.activity, allowThemed)
?: iconPackManager.generateIcon(
context,
iconPack.packageName,