diff --git a/lawnchair/src/app/lawnchair/icons/IconPackProvider.kt b/lawnchair/src/app/lawnchair/icons/IconPackProvider.kt index ba78ae289e..256f0b3acc 100644 --- a/lawnchair/src/app/lawnchair/icons/IconPackProvider.kt +++ b/lawnchair/src/app/lawnchair/icons/IconPackProvider.kt @@ -10,6 +10,7 @@ import android.graphics.drawable.InsetDrawable import android.os.Build import android.os.Process import android.os.UserHandle +import app.lawnchair.util.getThemedIconPacksInstalled import com.android.launcher3.icons.ClockDrawableWrapper import com.android.launcher3.icons.ThemedIconDrawable import com.android.launcher3.util.MainThreadInitializedObject @@ -47,14 +48,16 @@ class IconPackProvider(private val context: Context) : SafeCloseable { iconPack.loadBlocking() val packageManager = context.packageManager val drawable = iconPack.getIcon(iconEntry, iconDpi) ?: return null - val shouldTintBackgrounds = context.shouldTintIconPackBackgrounds() + val themedIconPacks = packageManager.getThemedIconPacksInstalled(context) + val isThemedIconsEnabled = + context.isThemedIconsEnabled() && (iconEntry.packPackageName in themedIconPacks) val clockMetadata = if (user == Process.myUserHandle()) iconPack.getClock(iconEntry) else null try { if (clockMetadata != null) { val clockDrawable: ClockDrawableWrapper = ClockDrawableWrapper.forMeta(Build.VERSION.SDK_INT, clockMetadata) { - if (shouldTintBackgrounds) { + if (isThemedIconsEnabled) { wrapThemedData( packageManager, iconEntry, @@ -64,20 +67,22 @@ class IconPackProvider(private val context: Context) : SafeCloseable { drawable } } - return if (shouldTintBackgrounds && context.shouldTransparentBGIcons()) { - clockDrawable.foreground - } else { - CustomAdaptiveIconDrawable( - clockDrawable.background, - clockDrawable.foreground, - ) + if (clockDrawable != null) { + return if (isThemedIconsEnabled && context.shouldTransparentBGIcons()) { + clockDrawable.foreground + } else { + CustomAdaptiveIconDrawable( + clockDrawable.background, + clockDrawable.foreground, + ) + } } } - } catch (t: Throwable) { + } catch (_: Throwable) { // Ignore } - if (shouldTintBackgrounds) { + if (isThemedIconsEnabled) { return wrapThemedData(packageManager, iconEntry, drawable) } return drawable @@ -89,27 +94,22 @@ class IconPackProvider(private val context: Context) : SafeCloseable { drawable: Drawable, ): Drawable? { val themedColors: IntArray = ThemedIconDrawable.getThemedColors(context) - try { - val res = packageManager.getResourcesForApplication(iconEntry.packPackageName) + val res = packageManager.getResourcesForApplication(iconEntry.packPackageName) - @SuppressLint("DiscouragedApi") - val resId = res.getIdentifier(iconEntry.name, "drawable", iconEntry.packPackageName) - val bg: Drawable = ColorDrawable(themedColors[0]) - val td = ThemedIconDrawable.ThemeData(res, iconEntry.packPackageName, resId) - - return if (drawable is AdaptiveIconDrawable) { - if (context.shouldTransparentBGIcons() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && drawable.monochrome != null) { - drawable.monochrome?.apply { setTint(themedColors[1]) } - } else { - val foregroundDr = drawable.foreground.apply { setTint(themedColors[1]) } - CustomAdaptiveIconDrawable(bg, foregroundDr) - } + @SuppressLint("DiscouragedApi") + val resId = res.getIdentifier(iconEntry.name, "drawable", iconEntry.packPackageName) + val bg: Drawable = ColorDrawable(themedColors[0]) + val td = ThemedIconDrawable.ThemeData(res, iconEntry.packPackageName, resId) + return if (drawable is AdaptiveIconDrawable) { + if (context.shouldTransparentBGIcons() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && drawable.monochrome != null) { + drawable.monochrome?.apply { setTint(themedColors[1]) } } else { - val iconFromPack = InsetDrawable(drawable, .3f).apply { setTint(themedColors[1]) } - td.wrapDrawable(CustomAdaptiveIconDrawable(bg, iconFromPack), 0) + val foregroundDr = drawable.foreground.apply { setTint(themedColors[1]) } + CustomAdaptiveIconDrawable(bg, foregroundDr) } - } catch (_: Exception) { - return drawable + } else { + val iconFromPack = InsetDrawable(drawable, .3f).apply { setTint(themedColors[1]) } + td.wrapDrawable(CustomAdaptiveIconDrawable(bg, iconFromPack), 0) } } diff --git a/lawnchair/src/app/lawnchair/icons/LawnchairIconProvider.kt b/lawnchair/src/app/lawnchair/icons/LawnchairIconProvider.kt index 1092b2de91..b872fa2737 100644 --- a/lawnchair/src/app/lawnchair/icons/LawnchairIconProvider.kt +++ b/lawnchair/src/app/lawnchair/icons/LawnchairIconProvider.kt @@ -19,6 +19,7 @@ import android.content.res.Resources import android.graphics.drawable.AdaptiveIconDrawable import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable +import android.os.Build import android.os.Handler import android.os.UserHandle import android.os.UserManager @@ -33,7 +34,6 @@ import app.lawnchair.util.getPackageVersionCode import app.lawnchair.util.isPackageInstalled import com.android.launcher3.BuildConfig import com.android.launcher3.R -import com.android.launcher3.Utilities import com.android.launcher3.icons.IconProvider import com.android.launcher3.icons.ThemedIconDrawable import com.android.launcher3.util.ComponentKey @@ -49,31 +49,25 @@ class LawnchairIconProvider @JvmOverloads constructor( private val prefs = PreferenceManager.getInstance(context) private val iconPackPref = prefs.iconPackPackage private val themedIconPackPref = prefs.themedIconPackPackage - + private val drawerThemedIcons get() = prefs.drawerThemedIcons private val iconPackProvider = IconPackProvider.INSTANCE.get(context) private val overrideRepo = IconOverrideRepository.INSTANCE.get(context) - - private val iconPack - get() = iconPackProvider.getIconPack(iconPackPref.get())?.apply { loadBlocking() } - private val themedIconPack - get() = iconPackProvider.getIconPack(themedIconPackPref.get())?.apply { loadBlocking() } - - private var isOlderLawniconsInstalled = context.packageManager.getPackageVersionCode(LAWNICONS_PACKAGE_NAME) in 1..3 - + private val iconPack get() = iconPackProvider.getIconPack(iconPackPref.get())?.apply { loadBlocking() } + private val themedIconPack get() = iconPackProvider.getIconPack(themedIconPackPref.get())?.apply { loadBlocking() } + private var isOlderLawnIconsInstalled = context.packageManager.getPackageVersionCode(LAWNICONS_PACKAGE_NAME) in 1..3 private var iconPackVersion = 0L - private var themeMapName: String = "" private var _themeMap: Map? = null val themeMap: Map get() { - if (!context.isThemedIconsEnabled()) { + if (drawerThemedIcons.get() && !(isOlderLawnIconsInstalled)) { _themeMap = DISABLED_MAP } if (_themeMap == null) { _themeMap = createThemedIconMap() } - if (isOlderLawniconsInstalled) { + if (isOlderLawnIconsInstalled && themedIconPackPref.get() == LAWNICONS_PACKAGE_NAME) { themeMapName = themedIconPackPref.get() _themeMap = createThemedIconMap() } @@ -89,9 +83,9 @@ class LawnchairIconProvider @JvmOverloads constructor( setIconThemeSupported(supportsIconTheme) } - override fun setIconThemeSupported(isSupported: Boolean) { - _themeMap = if (isSupported && isOlderLawniconsInstalled) null else DISABLED_MAP - } +// override fun setIconThemeSupported(isSupported: Boolean) { +// _themeMap = if (isSupported && isOlderLawnIconsInstalled) null else DISABLED_MAP +// } private fun resolveIconEntry(componentName: ComponentName, user: UserHandle): IconEntry? { val componentKey = ComponentKey(componentName, user) @@ -155,43 +149,25 @@ class LawnchairIconProvider @JvmOverloads constructor( } } val icon = resolvedEntry?.let { iconPackProvider.getDrawable(it, iconDpi, user) } - val td = themeData + var td = themeData if (icon != null) return if (td != null) td.wrapDrawable(icon, iconType) else icon - - // use default icon from system var defaultIcon = super.getIconWithOverrides(packageName, component, user, iconDpi, fallback) - - if ((context.shouldTintIconPackBackgrounds() && defaultIcon is AdaptiveIconDrawable) || (context.isThemedIconsEnabled() && defaultIcon is AdaptiveIconDrawable)) { - if (Utilities.ATLEAST_T && defaultIcon.monochrome != null) { - defaultIcon = defaultIcon.monochrome - return if (td != null) { - td.wrapDrawable(defaultIcon, iconType) - } else { - val themedColors = ThemedIconDrawable.getThemedColors(context) - if (context.shouldTransparentBGIcons()) { - return defaultIcon.apply { setTint(themedColors[1]) } - } - CustomAdaptiveIconDrawable( - ColorDrawable(themedColors[0]), - defaultIcon.apply { setTint(themedColors[1]) }, - ) - } + if (context.isThemedIconsEnabled() && defaultIcon is AdaptiveIconDrawable && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && defaultIcon.monochrome != null + ) { + defaultIcon = defaultIcon.monochrome + return if (td != null) { + td.wrapDrawable(defaultIcon, iconType) } else { - val iconCompat = ThemedIconCompat.getThemedIcon(context, componentName) ?: return defaultIcon - - return if (td != null) { - td.wrapDrawable(iconCompat, iconType) - } else { - val themedColors = ThemedIconDrawable.getThemedColors(context) - if (context.shouldTransparentBGIcons()) { - return iconCompat.apply { setTint(themedColors[1]) } - } - CustomAdaptiveIconDrawable( - ColorDrawable(themedColors[0]), - iconCompat.apply { setTint(themedColors[1]) }, - ) + val themedColors = ThemedIconDrawable.getThemedColors(context) + if (context.shouldTransparentBGIcons()) { + return defaultIcon.apply { setTint(themedColors[1]) } } + CustomAdaptiveIconDrawable( + ColorDrawable(themedColors[0]), + defaultIcon.apply { setTint(themedColors[1]) }, + ) } } return defaultIcon @@ -392,13 +368,17 @@ class LawnchairIconProvider @JvmOverloads constructor( } } + updateMapFromResources( + resources = context.resources, + packageName = context.packageName, + ) if (context.packageManager.isPackageInstalled(packageName = themeMapName)) { iconPackVersion = context.packageManager.getPackageVersionCode(themeMapName) updateMapFromResources( resources = context.packageManager.getResourcesForApplication(themeMapName), packageName = themeMapName, ) - if (isOlderLawniconsInstalled) { + if (isOlderLawnIconsInstalled) { updateMapWithDynamicIcons(context, map) } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/IconPackPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/IconPackPreferences.kt index 4feb566a09..aa886a15da 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/IconPackPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/IconPackPreferences.kt @@ -19,26 +19,20 @@ package app.lawnchair.ui.preferences.destinations import android.content.res.Configuration import android.graphics.drawable.Drawable import androidx.annotation.StringRes -import androidx.compose.animation.animateContentSize import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize 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.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.pager.HorizontalPager -import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -47,11 +41,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.key -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -68,9 +60,8 @@ import app.lawnchair.ui.preferences.components.DummyLauncherLayout import app.lawnchair.ui.preferences.components.WallpaperPreview import app.lawnchair.ui.preferences.components.controls.ListPreference import app.lawnchair.ui.preferences.components.controls.ListPreferenceEntry -import app.lawnchair.ui.preferences.components.controls.SwitchPreference import app.lawnchair.ui.preferences.components.invariantDeviceProfile -import app.lawnchair.ui.preferences.components.layout.Chip +import app.lawnchair.ui.preferences.components.layout.ExpandAndShrink import app.lawnchair.ui.preferences.components.layout.NestedScrollStretch import app.lawnchair.ui.preferences.components.layout.PreferenceGroup import app.lawnchair.ui.preferences.components.layout.PreferenceLayout @@ -79,7 +70,6 @@ import app.lawnchair.util.getThemedIconPacksInstalled import app.lawnchair.util.isPackageInstalled import com.android.launcher3.R import com.google.accompanist.drawablepainter.rememberDrawablePainter -import kotlinx.coroutines.launch data class IconPackInfo( val name: String, @@ -115,8 +105,6 @@ fun IconPackPreferences( modifier: Modifier = Modifier, ) { val prefs = preferenceManager() - val context = LocalContext.current - val iconPackAdapter = prefs.iconPackPackage.getAdapter() val themedIconPackAdapter = prefs.themedIconPackPackage.getAdapter() val themedIconsAdapter = prefs.themedIcons.getAdapter() @@ -124,7 +112,6 @@ fun IconPackPreferences( val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT val scrollState = rememberScrollState() val drawerThemedIconsEnabled = drawerThemedIconsAdapter.state.value - val tintIconpack = prefs.tintIconPackBackgrounds.getAdapter() PreferenceLayout( label = stringResource(id = R.string.icon_style_label), @@ -146,7 +133,7 @@ fun IconPackPreferences( .clip(MaterialTheme.shapes.large), ) { WallpaperPreview(modifier = Modifier.fillMaxSize()) - key(iconPackAdapter.state.value, themedIconPackAdapter.state.value, themedIconsAdapter.state.value, tintIconpack.state.value) { + key(iconPackAdapter.state.value, themedIconPackAdapter.state.value, themedIconsAdapter.state.value) { DummyLauncherLayout( idp = invariantDeviceProfile(), modifier = Modifier.fillMaxSize(), @@ -156,99 +143,75 @@ fun IconPackPreferences( } } Column { - val pagerState = rememberPagerState( - initialPage = 0, - pageCount = { 2 }, - ) - - val scope = rememberCoroutineScope() - val scrollToPage = - { page: Int -> scope.launch { pagerState.animateScrollToPage(page) } } - - Row( - horizontalArrangement = Arrangement.spacedBy(space = 8.dp), - modifier = Modifier.padding(horizontal = 16.dp), - ) { - Chip( - label = stringResource(id = R.string.icon_pack), - onClick = { scrollToPage(0) }, - currentOffset = pagerState.currentPage + pagerState.currentPageOffsetFraction, - page = 0, - ) - Chip( - label = stringResource(id = R.string.themed_icon_pack), - onClick = { scrollToPage(1) }, - currentOffset = pagerState.currentPage + pagerState.currentPageOffsetFraction, - page = 1, - ) - } - - Spacer(Modifier.height(16.dp)) - - HorizontalPager( - state = pagerState, - verticalAlignment = Alignment.Top, - modifier = Modifier.animateContentSize(), - ) { page -> - when (page) { - 0 -> { - PreferenceGroup { - IconPackGrid( - adapter = iconPackAdapter, - false, - ) - SwitchPreference( - adapter = prefs.tintIconPackBackgrounds.getAdapter(), - label = stringResource(id = R.string.themed_icon_pack_tint), - ) - } - } - 1 -> { - val packageManager = context.packageManager - - PreferenceGroup { - val themedIconsAvailable = packageManager - .getThemedIconPacksInstalled(LocalContext.current) - .any { packageManager.isPackageInstalled(it) } || - packageManager - .isPackageInstalled(Constants.LAWNICONS_PACKAGE_NAME) - - if (themedIconsAvailable && themedIconsAdapter.state.value) { - IconPackGrid( - adapter = themedIconPackAdapter, - true, - ) - } - ListPreference( - enabled = themedIconsAvailable, - label = stringResource(id = R.string.themed_icon_title), - entries = ThemedIconsState.entries.map { - ListPreferenceEntry( - value = it, - label = { stringResource(id = it.labelResourceId) }, - ) - }, - value = ThemedIconsState.getForSettings( - themedIcons = themedIconsAdapter.state.value, - drawerThemedIcons = drawerThemedIconsEnabled, - ), - onValueChange = { - themedIconsAdapter.onChange(newValue = it.themedIcons) - drawerThemedIconsAdapter.onChange(newValue = it.drawerThemedIcons) - - iconPackAdapter.onChange(newValue = iconPackAdapter.state.value) - themedIconPackAdapter.onChange(newValue = themedIconPackAdapter.state.value) - }, - description = if (themedIconsAvailable.not()) { - stringResource(id = R.string.lawnicons_not_installed_description) - } else { - null - }, - ) - } - } + ExpandAndShrink(visible = !drawerThemedIconsEnabled) { + PreferenceGroup( + heading = stringResource(id = R.string.icon_pack), + ) { + IconPackGrid( + adapter = iconPackAdapter, + themedIconsAdapter.state.value, + false, + ) } } + ExpandAndShrink(visible = themedIconsAdapter.state.value && !drawerThemedIconsEnabled) { + PreferenceGroup( + heading = stringResource(id = R.string.themed_icon_pack), + ) { + IconPackGrid( + adapter = themedIconPackAdapter, + drawerThemedIconsEnabled, + true, + ) + } + } + ExpandAndShrink(visible = drawerThemedIconsEnabled) { + PreferenceGroup( + heading = stringResource(id = R.string.themed_icon_pack), + ) { + IconPackGrid( + adapter = iconPackAdapter, + drawerThemedIconsEnabled, + true, + ) + } + } + PreferenceGroup { + val themedIconsAvailable = LocalContext.current.packageManager + .getThemedIconPacksInstalled(LocalContext.current) + .any { LocalContext.current.packageManager.isPackageInstalled(it) } || + LocalContext.current.packageManager + .isPackageInstalled(Constants.LAWNICONS_PACKAGE_NAME) + ListPreference( + enabled = themedIconsAvailable, + label = stringResource(id = R.string.themed_icon_title), + entries = ThemedIconsState.entries.map { + ListPreferenceEntry( + value = it, + label = { stringResource(id = it.labelResourceId) }, + ) + }.toMutableList(), + value = ThemedIconsState.getForSettings( + themedIcons = themedIconsAdapter.state.value, + drawerThemedIcons = drawerThemedIconsEnabled, + ), + onValueChange = { + themedIconsAdapter.onChange(newValue = it.themedIcons) + drawerThemedIconsAdapter.onChange(newValue = it.drawerThemedIcons) + iconPackAdapter.onChange(newValue = iconPackAdapter.state.value) + if (it.themedIcons && !it.drawerThemedIcons) { + themedIconPackAdapter.onChange(newValue = themedIconPackAdapter.state.value) + } else { + themedIconPackAdapter.onChange(newValue = "") + } + }, + description = if (themedIconsAvailable.not()) { + stringResource(id = R.string.lawnicons_not_installed_description) + } else { + null + }, + ) + } } } } @@ -256,21 +219,25 @@ fun IconPackPreferences( @Composable fun IconPackGrid( adapter: PreferenceAdapter, + drawerThemedIcons: Boolean, isThemedIconPack: Boolean, modifier: Modifier = Modifier, ) { - val preferenceInteractor = LocalPreferenceInteractor.current - - val iconPacks by preferenceInteractor.iconPacks.collectAsStateWithLifecycle() - val themedIconPacks by preferenceInteractor.themedIconPacks.collectAsStateWithLifecycle() - + val iconPacks by LocalPreferenceInteractor.current.iconPacks.collectAsStateWithLifecycle() + val themedIconPacks by LocalPreferenceInteractor.current.themedIconPacks.collectAsStateWithLifecycle() val lazyListState = rememberLazyListState() val padding = 12.dp + var iconPacksLocal = iconPacks + val themedIconPacksName = themedIconPacks.map { it.name } - val iconPacksLocal = if (isThemedIconPack) { - themedIconPacks.filter { it.packageName != "" } - } else { - iconPacks + if (isThemedIconPack) { + iconPacksLocal = if (drawerThemedIcons) { + themedIconPacks + } else { + themedIconPacks.filter { it.packageName != "" } + } + } else if (drawerThemedIcons) { + iconPacksLocal = iconPacks.filter { it.packageName == "" || !themedIconPacksName.contains(it.name) } } val selectedPack = adapter.state.value @@ -292,9 +259,7 @@ fun IconPackGrid( state = lazyListState, horizontalArrangement = Arrangement.spacedBy(space = padding), contentPadding = PaddingValues(horizontal = padding), - modifier = Modifier - .padding(bottom = 6.dp, top = 6.dp) - .fillMaxWidth(), + modifier = Modifier.padding(bottom = 6.dp, top = 6.dp).fillMaxWidth(), ) { itemsIndexed(iconPacksLocal, { _, item -> item.packageName }) { index, item -> IconPackItem( @@ -341,7 +306,7 @@ fun IconPackItem( Surface( onClick = onClick, shape = MaterialTheme.shapes.large, - color = if (selected) MaterialTheme.colorScheme.surfaceContainerHighest else Color.Transparent, + tonalElevation = if (selected) 2.dp else 0.dp, modifier = modifier, ) { Column( diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java index 0c5d7c741b..2c60485457 100644 --- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java +++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java @@ -321,8 +321,9 @@ public abstract class ItemInfoWithIcon extends ItemInfo { * Returns a FastBitmapDrawable with the icon and context theme applied */ public FastBitmapDrawable newIcon(Context context, boolean applyTheme) { - return applyTheme && PreferenceManager.getInstance(context).getThemedIcons().get() - ? bitmap.newIcon(context) : bitmap.newIcon(context, BitmapInfo.FLAG_NO_BADGE); + var prefs = PreferenceManager.getInstance(context); + var isThemed = applyTheme && prefs.getThemedIcons().get(); + return newIcon(context, isThemed ? BitmapInfo.FLAG_THEMED : BitmapInfo.FLAG_NO_BADGE); } /**