From 70b406eb5c677a89b87ad566559bfcb0977cbb4b Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Wed, 15 Mar 2023 17:02:16 +0100 Subject: [PATCH] Add preference to disable themed icons for themed icon packs --- .../appearance/AppearanceSettingsScreen.kt | 127 +++++++++++------- .../appearance/AppearanceSettingsScreenVM.kt | 23 +++- .../mm20/launcher2/preferences/DataStore.kt | 3 +- .../de/mm20/launcher2/preferences/Defaults.kt | 1 + .../preferences/migrations/Migration_13_14.kt | 13 ++ .../preferences/src/main/proto/settings.proto | 1 + .../mm20/launcher2/icons/IconPackManager.kt | 23 ++-- .../de/mm20/launcher2/icons/IconRepository.kt | 3 +- .../icons/providers/IconPackIconProvider.kt | 3 +- 9 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_13_14.kt diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt index 843fb290..9e19df59 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt @@ -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() diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt index 7daa4916..54be118d 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt @@ -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> = 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) { diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt index a805aae5..532e4adc 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt @@ -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> { return listOf( @@ -39,5 +39,6 @@ internal fun getMigrations(context: Context): List> { Migration_10_11(), Migration_11_12(), Migration_12_13(), + Migration_13_14(), ) } \ No newline at end of file diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt index f7fe34d9..6fb4bf5f 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt @@ -145,6 +145,7 @@ fun createFactorySettings(context: Context): Settings { .setShape(Settings.IconSettings.IconShape.PlatformDefault) .setThemedIcons(false) .setIconPack("") + .setIconPackThemed(true) ) .setEasterEgg(false) .setSystemBars( diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_13_14.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_13_14.kt new file mode 100644 index 00000000..03bf61d4 --- /dev/null +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_13_14.kt @@ -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) + ) + } +} \ No newline at end of file diff --git a/core/preferences/src/main/proto/settings.proto b/core/preferences/src/main/proto/settings.proto index 40541a4e..2e6c2f10 100644 --- a/core/preferences/src/main/proto/settings.proto +++ b/core/preferences/src/main/proto/settings.proto @@ -246,6 +246,7 @@ message Settings { reserved 4; bool adaptify = 5; bool force_themed = 6; + bool icon_pack_themed = 7; } IconSettings icons = 21; diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt index e0126330..c842acb9 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt @@ -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, diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt index b5fa2914..bd257d0d 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt @@ -109,7 +109,8 @@ class IconRepository( IconPackIconProvider( context, pack, - iconPackManager + iconPackManager, + settings.iconPackThemed, ) ) } else { diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/IconPackIconProvider.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/IconPackIconProvider.kt index a37aaf3f..e0fe07e0 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/IconPackIconProvider.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/IconPackIconProvider.kt @@ -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,