From 5922c2092291ca12af228996dd441eb2b36dce88 Mon Sep 17 00:00:00 2001 From: RichardLuo <22096448+RichardLuo0@users.noreply.github.com> Date: Mon, 2 Dec 2024 00:11:05 +0800 Subject: [PATCH] feat: all fallback settings as one --- README.md | 12 +- .../globalIconPack/CustomIconPack.kt | 116 ++++++------------ .../richardluo/globalIconPack/MainActivity.kt | 24 +--- app/src/main/res/values/strings.xml | 6 +- 4 files changed, 49 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 87723bc..6fe8dc0 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,10 @@ This module is designed to extend the customization of icon packs throughout the ## Installation 1. Install the apk. -2. Open Global Icon Pack. Remember to fill the `Icon pack` settings with an icon pack package name. -3. Select the recommend apps in lsposed (Other launcher/apps may also work, depending on the api they use) -4. For pixel launcher and probably other similar launcher 3 based launcher, you will need to delete `/data/data/com.google.android.apps.nexuslauncher/databases/app_icons.db` and then restart the launcher through its settings page. - -## Settings -* `Icon pack`: The package name to be used as icon pack. -* `No force shape`: This setting is specific to pixel launcher. Turning it on will prevent it from forcing a uniform icon shape. -* `Icon pack settings`: This section controls whether to use "fallback" elements such as masks. Some icon packs include predefined masks or backgrounds that ensure all icons have a consistent shape or style, even for apps that don't have dedicated icons in the pack. You can choose to enable or disable them. +2. Select the recommend apps in lsposed (Other launcher/apps may also work, depending on the api they use) +3. Open Global Icon Pack. Fill the `Icon pack` settings with an icon pack package name. +4. For pixel launcher and probably other similar launcher 3 based launcher, you will need to delete `/data/data/com.google.android.apps.nexuslauncher/databases/app_icons.db` then restart the launcher through its settings page. +5. Recent screen will use your default launcher unless you use quickswitch. So you will need to select pixel launcher for that to work. ## Known Issues * ~~When clicking an app, Pixel Launcher triggers an animation, whose starting frame displays an icon with a white border.~~ diff --git a/app/src/main/kotlin/com/richardluo/globalIconPack/CustomIconPack.kt b/app/src/main/kotlin/com/richardluo/globalIconPack/CustomIconPack.kt index 80e0e7e..335af7d 100644 --- a/app/src/main/kotlin/com/richardluo/globalIconPack/CustomIconPack.kt +++ b/app/src/main/kotlin/com/richardluo/globalIconPack/CustomIconPack.kt @@ -29,9 +29,9 @@ class CustomIconPack(pm: PackageManager, private val pref: SharedPreferences) { private val iconEntryList = mutableListOf() // Fallback settings from icon pack - private var iconBack: Bitmap? = null - private var iconUpon: Bitmap? = null - private var iconMask: Bitmap? = null + private var iconBacks = mutableListOf() + private var iconUpons = mutableListOf() + private var iconMasks = mutableListOf() private var iconScale: Float = 1f private var globalScale: Float = pref.getFloat("scale", 1f) @@ -62,9 +62,9 @@ class CustomIconPack(pm: PackageManager, private val pref: SharedPreferences) { IconHelper.processIcon( packResources, baseIcon, - iconBack, - iconUpon, - iconMask, + iconBacks.randomOrNull(), + iconUpons.randomOrNull(), + iconMasks.randomOrNull(), iconScale * globalScale, ) @@ -75,83 +75,47 @@ class CustomIconPack(pm: PackageManager, private val pref: SharedPreferences) { val compStartLength = compStart.length val compEnd = "}" val compEndLength = compEnd.length + + fun addFallback(parseXml: XmlPullParser, list: MutableList) { + if (!pref.getBoolean("iconFallback", true)) return + for (i in 0 until parseXml.attributeCount) if (parseXml.getAttributeName(i).startsWith("img")) + packResources + .getIdentifier(parseXml.getAttributeValue(i), "drawable", packPackageName) + .takeIf { it != 0 } + ?.let { getDrawable(packResources, it, null)?.toBitmap() } + ?.let { list.add(it) } + } + + fun addIcon(parseXml: XmlPullParser, iconType: IconType) { + var componentName: String = parseXml["component"] ?: return + val drawableName = + parseXml[if (iconType == IconType.Calendar) "prefix" else "drawable"] ?: return + if (componentName.startsWith(compStart) && componentName.endsWith(compEnd)) { + componentName = + componentName.substring(compStartLength, componentName.length - compEndLength) + } + ComponentName.unflattenFromString(componentName)?.let { cn -> + val iconEntry = IconEntry(drawableName, iconType) + addIconEntry(cn, iconEntry) + // TODO Use the first icon as app icon. I don't see a better way. + addIconEntry(getComponentName(cn.packageName), iconEntry) + } + } + try { val clockMetaMap = mutableMapOf() while (parseXml.next() != XmlPullParser.END_DOCUMENT) { if (parseXml.eventType != XmlPullParser.START_TAG) continue - val name = parseXml.name - when (name) { - "iconback" -> { - if (!pref.getBoolean("iconBack", true)) continue - for (i in 0 until parseXml.attributeCount) { - if (parseXml.getAttributeName(i).startsWith("img")) { - val imgName = parseXml.getAttributeValue(i) - val id = packResources.getIdentifier(imgName, "drawable", packPackageName) - if (id != 0) iconBack = getDrawable(packResources, id, null)?.toBitmap() - } - } - } - - "iconupon" -> { - if (!pref.getBoolean("iconUpon", true)) continue - for (i in 0 until parseXml.attributeCount) { - if (parseXml.getAttributeName(i).startsWith("img")) { - val imgName = parseXml.getAttributeValue(i) - val id = packResources.getIdentifier(imgName, "drawable", packPackageName) - if (id != 0) iconUpon = getDrawable(packResources, id, null)?.toBitmap() - } - } - } - - "iconmask" -> { - if (!pref.getBoolean("iconMask", true)) continue - for (i in 0 until parseXml.attributeCount) { - if (parseXml.getAttributeName(i).startsWith("img")) { - val imgName = parseXml.getAttributeValue(i) - val id = packResources.getIdentifier(imgName, "drawable", packPackageName) - if (id != 0) iconMask = getDrawable(packResources, id, null)?.toBitmap() - } - } - } - + when (parseXml.name) { + "iconback" -> addFallback(parseXml, iconBacks) + "iconupon" -> addFallback(parseXml, iconUpons) + "iconmask" -> addFallback(parseXml, iconMasks) "scale" -> { - if (!pref.getBoolean("iconScale", true)) continue + if (!pref.getBoolean("iconFallback", true)) continue iconScale = parseXml.getAttributeValue(null, "factor")?.toFloatOrNull() ?: 1f } - - "item" -> { - var componentName: String? = parseXml["component"] - val drawableName = parseXml["drawable"] - if (componentName != null && drawableName != null) { - if (componentName.startsWith(compStart) && componentName.endsWith(compEnd)) { - componentName = - componentName.substring(compStartLength, componentName.length - compEndLength) - } - ComponentName.unflattenFromString(componentName)?.let { cn -> - val iconEntry = IconEntry(drawableName, IconType.Normal) - addIconEntry(cn, iconEntry) - // TODO Use the first icon as app icon. I don't see a better way. - addIconEntry(getComponentName(cn.packageName), iconEntry) - } - } - } - - "calendar" -> { - var componentName: String? = parseXml["component"] - val drawableName = parseXml["prefix"] - if (componentName != null && drawableName != null) { - if (componentName.startsWith(compStart) && componentName.endsWith(compEnd)) { - componentName = - componentName.substring(compStartLength, componentName.length - compEndLength) - } - ComponentName.unflattenFromString(componentName)?.let { cn -> - val iconEntry = IconEntry(drawableName, IconType.Calendar) - addIconEntry(cn, iconEntry) - addIconEntry(getComponentName(cn.packageName), iconEntry) - } - } - } - + "item" -> addIcon(parseXml, IconType.Normal) + "calendar" -> addIcon(parseXml, IconType.Calendar) "dynamic-clock" -> { val drawableName = parseXml["drawable"] if (drawableName != null) { diff --git a/app/src/main/kotlin/com/richardluo/globalIconPack/MainActivity.kt b/app/src/main/kotlin/com/richardluo/globalIconPack/MainActivity.kt index a9bb2d5..372bceb 100644 --- a/app/src/main/kotlin/com/richardluo/globalIconPack/MainActivity.kt +++ b/app/src/main/kotlin/com/richardluo/globalIconPack/MainActivity.kt @@ -118,28 +118,10 @@ fun SampleScreen() { title = { Text(text = stringResource(R.string.iconPackSettings)) }, ) switchPreference( - key = "iconBack", + key = "iconFallback", defaultValue = true, - title = { Text(text = stringResource(R.string.iconBack)) }, - summary = { Text(text = if (it) "On" else "Off") }, - ) - switchPreference( - key = "iconUpon", - defaultValue = true, - title = { Text(text = stringResource(R.string.iconUpon)) }, - summary = { Text(text = if (it) "On" else "Off") }, - ) - switchPreference( - key = "iconMask", - defaultValue = true, - title = { Text(text = stringResource(R.string.iconMask)) }, - summary = { Text(text = if (it) "On" else "Off") }, - ) - switchPreference( - key = "iconScale", - defaultValue = true, - title = { Text(text = stringResource(R.string.iconScale)) }, - summary = { Text(text = if (it) "On" else "Off") }, + title = { Text(text = stringResource(R.string.iconFallback)) }, + summary = { Text(text = stringResource(R.string.iconFallbackSummary)) }, ) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd0e947..f158b81 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,8 +15,6 @@ Force load clock and calendar icon Icon pack settings - Icon back - Icon upon - Icon mask - Scale + Fallback + Apply background, mask, and scale from the icon pack to apps without dedicated icons. \ No newline at end of file