Add preference to disable themed icons for themed icon packs
This commit is contained in:
parent
6f6d6451a9
commit
70b406eb5c
@ -4,21 +4,24 @@ import android.graphics.drawable.ColorDrawable
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.basicMarquee
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
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.GridCells
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.FormatPaint
|
import androidx.compose.material.icons.rounded.FormatPaint
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.FilledIconToggleButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@ -34,6 +37,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@ -249,6 +253,7 @@ fun AppearanceSettingsScreen() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val iconPackPackage by viewModel.iconPack.observeAsState()
|
val iconPackPackage by viewModel.iconPack.observeAsState()
|
||||||
|
val iconPackThemed by viewModel.iconPackThemed.collectAsState(true)
|
||||||
val installedIconPacks by viewModel.installedIconPacks.collectAsState(emptyList())
|
val installedIconPacks by viewModel.installedIconPacks.collectAsState(emptyList())
|
||||||
val iconPack by remember {
|
val iconPack by remember {
|
||||||
derivedStateOf { installedIconPacks.firstOrNull { it.packageName == iconPackPackage } }
|
derivedStateOf { installedIconPacks.firstOrNull { it.packageName == iconPackPackage } }
|
||||||
@ -256,56 +261,88 @@ fun AppearanceSettingsScreen() {
|
|||||||
val items = installedIconPacks.map {
|
val items = installedIconPacks.map {
|
||||||
it.name to it
|
it.name to it
|
||||||
}
|
}
|
||||||
ListPreference(
|
Row(
|
||||||
title = stringResource(R.string.preference_icon_pack),
|
verticalAlignment = (Alignment.CenterVertically)
|
||||||
items = items,
|
) {
|
||||||
summary = if (items.size <= 1) {
|
Box(
|
||||||
stringResource(R.string.preference_icon_pack_summary_empty)
|
modifier = Modifier.weight(1f)
|
||||||
} else {
|
) {
|
||||||
iconPack?.name ?: "System"
|
ListPreference(
|
||||||
},
|
title = stringResource(R.string.preference_icon_pack),
|
||||||
enabled = installedIconPacks.size > 1,
|
items = items,
|
||||||
value = iconPack,
|
summary = if (items.size <= 1) {
|
||||||
onValueChanged = {
|
stringResource(R.string.preference_icon_pack_summary_empty)
|
||||||
if (it != null) viewModel.setIconPack(it.packageName)
|
} else {
|
||||||
},
|
iconPack?.name ?: "System"
|
||||||
itemLabel = {
|
},
|
||||||
Column(
|
enabled = installedIconPacks.size > 1,
|
||||||
verticalArrangement = Arrangement.Center,
|
value = iconPack,
|
||||||
) {
|
onValueChanged = {
|
||||||
Text(
|
if (it != null) viewModel.setIconPack(it.packageName)
|
||||||
text = it.label,
|
},
|
||||||
maxLines = 1,
|
itemLabel = {
|
||||||
overflow = TextOverflow.Ellipsis,
|
Column(
|
||||||
)
|
verticalArrangement = Arrangement.Center,
|
||||||
if (it.value?.themed == true) {
|
|
||||||
Surface(
|
|
||||||
shape = MaterialTheme.shapes.extraSmall,
|
|
||||||
color = MaterialTheme.colorScheme.tertiary,
|
|
||||||
modifier = Modifier.padding(top = 4.dp)
|
|
||||||
) {
|
) {
|
||||||
Row(
|
Text(
|
||||||
modifier = Modifier.padding(horizontal = 4.dp),
|
text = it.label,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
maxLines = 1,
|
||||||
) {
|
overflow = TextOverflow.Ellipsis,
|
||||||
Icon(
|
)
|
||||||
modifier = Modifier
|
if (it.value?.themed == true) {
|
||||||
.size(20.dp)
|
Surface(
|
||||||
.padding(end = 4.dp),
|
shape = MaterialTheme.shapes.extraSmall,
|
||||||
imageVector = Icons.Rounded.FormatPaint,
|
color = MaterialTheme.colorScheme.tertiary,
|
||||||
contentDescription = null,
|
modifier = Modifier.padding(top = 4.dp)
|
||||||
)
|
) {
|
||||||
Text(
|
Row(
|
||||||
text = stringResource(R.string.icon_pack_dynamic_colors),
|
modifier = Modifier.padding(horizontal = 4.dp),
|
||||||
style = MaterialTheme.typography.labelSmall
|
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)) {
|
PreferenceCategory(stringResource(R.string.preference_category_searchbar)) {
|
||||||
val searchBarStyle by viewModel.searchBarStyle.observeAsState()
|
val searchBarStyle by viewModel.searchBarStyle.observeAsState()
|
||||||
|
|||||||
@ -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.SearchBarSettings.SearchBarColors
|
||||||
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings
|
import de.mm20.launcher2.preferences.Settings.SystemBarsSettings
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.shareIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
@ -199,12 +201,29 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val installedIconPacks: Flow<List<IconPack>> = iconRepository.getInstalledIconPacks().map {
|
val installedIconPacks: Flow<List<IconPack>> = iconRepository.getInstalledIconPacks().map {
|
||||||
listOf(IconPack(
|
listOf(
|
||||||
|
IconPack(
|
||||||
name = "System",
|
name = "System",
|
||||||
packageName = "",
|
packageName = "",
|
||||||
version = "",
|
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()
|
val iconPack = dataStore.data.map { it.icons.iconPack }.asLiveData()
|
||||||
fun setIconPack(iconPack: String) {
|
fun setIconPack(iconPack: String) {
|
||||||
|
|||||||
@ -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>> {
|
internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
|
||||||
return listOf(
|
return listOf(
|
||||||
@ -39,5 +39,6 @@ internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
|
|||||||
Migration_10_11(),
|
Migration_10_11(),
|
||||||
Migration_11_12(),
|
Migration_11_12(),
|
||||||
Migration_12_13(),
|
Migration_12_13(),
|
||||||
|
Migration_13_14(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -145,6 +145,7 @@ fun createFactorySettings(context: Context): Settings {
|
|||||||
.setShape(Settings.IconSettings.IconShape.PlatformDefault)
|
.setShape(Settings.IconSettings.IconShape.PlatformDefault)
|
||||||
.setThemedIcons(false)
|
.setThemedIcons(false)
|
||||||
.setIconPack("")
|
.setIconPack("")
|
||||||
|
.setIconPackThemed(true)
|
||||||
)
|
)
|
||||||
.setEasterEgg(false)
|
.setEasterEgg(false)
|
||||||
.setSystemBars(
|
.setSystemBars(
|
||||||
|
|||||||
@ -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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -246,6 +246,7 @@ message Settings {
|
|||||||
reserved 4;
|
reserved 4;
|
||||||
bool adaptify = 5;
|
bool adaptify = 5;
|
||||||
bool force_themed = 6;
|
bool force_themed = 6;
|
||||||
|
bool icon_pack_themed = 7;
|
||||||
}
|
}
|
||||||
IconSettings icons = 21;
|
IconSettings icons = 21;
|
||||||
|
|
||||||
|
|||||||
@ -87,6 +87,7 @@ class IconPackManager(
|
|||||||
iconPack: String,
|
iconPack: String,
|
||||||
packageName: String,
|
packageName: String,
|
||||||
activityName: String?,
|
activityName: String?,
|
||||||
|
allowThemed: Boolean = true
|
||||||
): LauncherIcon? {
|
): LauncherIcon? {
|
||||||
val res = try {
|
val res = try {
|
||||||
context.packageManager.getResourcesForApplication(iconPack)
|
context.packageManager.getResourcesForApplication(iconPack)
|
||||||
@ -100,11 +101,11 @@ class IconPackManager(
|
|||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
if (icon is CalendarIcon) {
|
if (icon is CalendarIcon) {
|
||||||
return getIconPackCalendarIcon(icon, res)
|
return getIconPackCalendarIcon(icon, res, allowThemed)
|
||||||
} else if (icon is AppIcon) {
|
} else if (icon is AppIcon) {
|
||||||
return getIconPackStaticIcon(icon, res)
|
return getIconPackStaticIcon(icon, res, allowThemed)
|
||||||
} else if (icon is ClockIcon) {
|
} else if (icon is ClockIcon) {
|
||||||
return getIconPackClockIcon(icon, res)
|
return getIconPackClockIcon(icon, res, allowThemed)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -241,6 +242,7 @@ class IconPackManager(
|
|||||||
private fun getIconPackStaticIcon(
|
private fun getIconPackStaticIcon(
|
||||||
icon: AppIcon,
|
icon: AppIcon,
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
|
allowThemed: Boolean,
|
||||||
): LauncherIcon? {
|
): LauncherIcon? {
|
||||||
val resId =
|
val resId =
|
||||||
resources.getIdentifier(icon.drawable, "drawable", icon.iconPack).takeIf { it != 0 }
|
resources.getIdentifier(icon.drawable, "drawable", icon.iconPack).takeIf { it != 0 }
|
||||||
@ -250,8 +252,9 @@ class IconPackManager(
|
|||||||
} catch (e: Resources.NotFoundException) {
|
} catch (e: Resources.NotFoundException) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
val themed = icon.themed && allowThemed
|
||||||
return when {
|
return when {
|
||||||
icon.themed && drawable is AdaptiveIconDrawable -> {
|
themed && drawable is AdaptiveIconDrawable -> {
|
||||||
if (isAtLeastApiLevel(33) && drawable.monochrome != null) {
|
if (isAtLeastApiLevel(33) && drawable.monochrome != null) {
|
||||||
return StaticLauncherIcon(
|
return StaticLauncherIcon(
|
||||||
foregroundLayer = TintedIconLayer(
|
foregroundLayer = TintedIconLayer(
|
||||||
@ -271,7 +274,7 @@ class IconPackManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
icon.themed -> {
|
themed -> {
|
||||||
return StaticLauncherIcon(
|
return StaticLauncherIcon(
|
||||||
foregroundLayer = TintedIconLayer(
|
foregroundLayer = TintedIconLayer(
|
||||||
icon = drawable,
|
icon = drawable,
|
||||||
@ -313,6 +316,7 @@ class IconPackManager(
|
|||||||
private fun getIconPackCalendarIcon(
|
private fun getIconPackCalendarIcon(
|
||||||
icon: CalendarIcon,
|
icon: CalendarIcon,
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
|
allowThemed: Boolean,
|
||||||
): LauncherIcon? {
|
): LauncherIcon? {
|
||||||
val drawableIds = icon.drawables.map {
|
val drawableIds = icon.drawables.map {
|
||||||
val id = resources.getIdentifier(it, "drawable", icon.iconPack)
|
val id = resources.getIdentifier(it, "drawable", icon.iconPack)
|
||||||
@ -321,7 +325,7 @@ class IconPackManager(
|
|||||||
}.toIntArray()
|
}.toIntArray()
|
||||||
|
|
||||||
|
|
||||||
if (icon.themed) {
|
if (icon.themed && allowThemed) {
|
||||||
return ThemedDynamicCalendarIcon(
|
return ThemedDynamicCalendarIcon(
|
||||||
resources = resources,
|
resources = resources,
|
||||||
resourceIds = drawableIds,
|
resourceIds = drawableIds,
|
||||||
@ -336,6 +340,7 @@ class IconPackManager(
|
|||||||
private fun getIconPackClockIcon(
|
private fun getIconPackClockIcon(
|
||||||
icon: ClockIcon,
|
icon: ClockIcon,
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
|
allowThemed: Boolean,
|
||||||
): LauncherIcon? {
|
): LauncherIcon? {
|
||||||
var drawable = try {
|
var drawable = try {
|
||||||
resources.getIdentifier(icon.drawable, "drawable", icon.iconPack).takeIf { it != 0 }
|
resources.getIdentifier(icon.drawable, "drawable", icon.iconPack).takeIf { it != 0 }
|
||||||
@ -362,8 +367,10 @@ class IconPackManager(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val themed = icon.themed && allowThemed
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
icon.themed && drawable is AdaptiveIconDrawable -> {
|
themed && drawable is AdaptiveIconDrawable -> {
|
||||||
StaticLauncherIcon(
|
StaticLauncherIcon(
|
||||||
foregroundLayer = TintedClockLayer(
|
foregroundLayer = TintedClockLayer(
|
||||||
defaultHour = icon.config.defaultHour,
|
defaultHour = icon.config.defaultHour,
|
||||||
@ -376,7 +383,7 @@ class IconPackManager(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
icon.themed -> {
|
themed -> {
|
||||||
StaticLauncherIcon(
|
StaticLauncherIcon(
|
||||||
foregroundLayer = TintedClockLayer(
|
foregroundLayer = TintedClockLayer(
|
||||||
defaultHour = icon.config.defaultHour,
|
defaultHour = icon.config.defaultHour,
|
||||||
|
|||||||
@ -109,7 +109,8 @@ class IconRepository(
|
|||||||
IconPackIconProvider(
|
IconPackIconProvider(
|
||||||
context,
|
context,
|
||||||
pack,
|
pack,
|
||||||
iconPackManager
|
iconPackManager,
|
||||||
|
settings.iconPackThemed,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -12,11 +12,12 @@ class IconPackIconProvider(
|
|||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val iconPack: IconPack,
|
private val iconPack: IconPack,
|
||||||
private val iconPackManager: IconPackManager,
|
private val iconPackManager: IconPackManager,
|
||||||
|
private val allowThemed: Boolean,
|
||||||
): IconProvider {
|
): IconProvider {
|
||||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
|
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
|
||||||
if (searchable !is LauncherApp) return null
|
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(
|
?: iconPackManager.generateIcon(
|
||||||
context,
|
context,
|
||||||
iconPack.packageName,
|
iconPack.packageName,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user