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.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()
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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(),
|
||||
)
|
||||
}
|
||||
@ -145,6 +145,7 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setShape(Settings.IconSettings.IconShape.PlatformDefault)
|
||||
.setThemedIcons(false)
|
||||
.setIconPack("")
|
||||
.setIconPackThemed(true)
|
||||
)
|
||||
.setEasterEgg(false)
|
||||
.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;
|
||||
bool adaptify = 5;
|
||||
bool force_themed = 6;
|
||||
bool icon_pack_themed = 7;
|
||||
}
|
||||
IconSettings icons = 21;
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -109,7 +109,8 @@ class IconRepository(
|
||||
IconPackIconProvider(
|
||||
context,
|
||||
pack,
|
||||
iconPackManager
|
||||
iconPackManager,
|
||||
settings.iconPackThemed,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user