diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml
index 989807a88c..f37ac1db8e 100644
--- a/lawnchair/res/values/strings.xml
+++ b/lawnchair/res/values/strings.xml
@@ -204,4 +204,10 @@
Open External Picker
Quick Actions
Clear All
+ Pick Icon From
+ Experimental Features
+ Per-App Icon Customization
+ May cause Lawnchair to freeze.
+ Font Customization
+ Some text remains unchanged.
diff --git a/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideDao.kt b/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideDao.kt
index ed0fa2a238..49d1174fca 100644
--- a/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideDao.kt
+++ b/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideDao.kt
@@ -17,4 +17,7 @@ interface IconOverrideDao {
@Query("SELECT * FROM iconoverride WHERE target = :target")
fun observeTarget(target: ComponentKey): Flow
+
+ @Query("DELETE FROM iconoverride")
+ fun deleteAll()
}
diff --git a/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideRepository.kt b/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideRepository.kt
index e8cc3d8635..24f93cabcb 100644
--- a/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideRepository.kt
+++ b/lawnchair/src/app/lawnchair/data/iconoverride/IconOverrideRepository.kt
@@ -42,6 +42,11 @@ class IconOverrideRepository(private val context: Context) {
fun observeTarget(target: ComponentKey) = dao.observeTarget(target)
+ fun deleteAll() {
+ dao.deleteAll()
+ reloadIcons()
+ }
+
private fun reloadIcons() {
val las = LauncherAppState.getInstance(context)
val idp = las.invariantDeviceProfile
diff --git a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
index df0df0c877..276ebef029 100644
--- a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
+++ b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
@@ -133,6 +133,7 @@ class PreferenceManager private constructor(private val context: Context) : Base
val recentsActionShare = BoolPref("pref_recentsActionShare", isOnePlusStock)
val recentsActionLens = BoolPref("pref_recentsActionLens", true)
val recentsActionClearAll = BoolPref("pref_clearAllAsAction", false)
+ val enableFontSelection = BoolPref("pref_enableFontSelection", true)
init {
sp.registerOnSharedPreferenceChangeListener(this)
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/ExperimentalFeaturesPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/ExperimentalFeaturesPreferences.kt
new file mode 100644
index 0000000000..491cb3afc3
--- /dev/null
+++ b/lawnchair/src/app/lawnchair/ui/preferences/ExperimentalFeaturesPreferences.kt
@@ -0,0 +1,60 @@
+package app.lawnchair.ui.preferences
+
+import androidx.compose.animation.ExperimentalAnimationApi
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.navigation.NavGraphBuilder
+import app.lawnchair.data.iconoverride.IconOverrideRepository
+import app.lawnchair.font.FontCache
+import app.lawnchair.preferences.getAdapter
+import app.lawnchair.preferences.preferenceManager
+import app.lawnchair.ui.preferences.components.PreferenceGroup
+import app.lawnchair.ui.preferences.components.PreferenceLayout
+import app.lawnchair.ui.preferences.components.SwitchPreference
+import com.android.launcher3.R
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+@ExperimentalAnimationApi
+fun NavGraphBuilder.experimentalFeaturesGraph(route: String) {
+ preferenceGraph(route, { ExperimentalFeaturesPreferences() })
+}
+
+@Composable
+@OptIn(ExperimentalAnimationApi::class)
+fun ExperimentalFeaturesPreferences() {
+ val preferenceManager = preferenceManager()
+ val context = LocalContext.current
+
+ PreferenceLayout(label = stringResource(id = R.string.experimental_features_label)) {
+ PreferenceGroup(isFirstChild = true) {
+ SwitchPreference(
+ adapter = preferenceManager.enableFontSelection.getAdapter(),
+ label = stringResource(id = R.string.font_picker_label),
+ description = stringResource(id = R.string.font_picker_description),
+ onChange = {
+ if (!it) {
+ val fontCache = FontCache.INSTANCE.get(context)
+ preferenceManager.workspaceFont.set(newValue = fontCache.uiText)
+ }
+ }
+ )
+ SwitchPreference(
+ adapter = preferenceManager.enableIconSelection.getAdapter(),
+ label = stringResource(id = R.string.icon_picker_label),
+ description = stringResource(id = R.string.icon_picker_description),
+ onChange = {
+ if (!it) {
+ val iconOverrideRepository = IconOverrideRepository.INSTANCE.get(context)
+
+ CoroutineScope(Dispatchers.IO).launch {
+ iconOverrideRepository.deleteAll()
+ }
+ }
+ }
+ )
+ }
+ }
+}
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/GeneralPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/GeneralPreferences.kt
index 2f32fc2140..87bbec2e2d 100644
--- a/lawnchair/src/app/lawnchair/ui/preferences/GeneralPreferences.kt
+++ b/lawnchair/src/app/lawnchair/ui/preferences/GeneralPreferences.kt
@@ -70,10 +70,12 @@ fun GeneralPreferences() {
description = if (!themedIconsAvailable) stringResource(id = R.string.lawnicons_not_installed_description) else null
)
IconShapePreference()
- FontPreference(
- adapter = prefs.workspaceFont.getAdapter(),
- label = stringResource(id = R.string.font_label)
- )
+ if (prefs.enableFontSelection.get()) {
+ FontPreference(
+ adapter = prefs.workspaceFont.getAdapter(),
+ label = stringResource(id = R.string.font_label),
+ )
+ }
}
PreferenceGroup(
heading = stringResource(id = R.string.colors)
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/Preferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/Preferences.kt
index a3bd7971cf..330e77f598 100644
--- a/lawnchair/src/app/lawnchair/ui/preferences/Preferences.kt
+++ b/lawnchair/src/app/lawnchair/ui/preferences/Preferences.kt
@@ -48,6 +48,7 @@ object Routes {
const val DEBUG_MENU: String = "debugMenu"
const val SELECT_ICON: String = "selectIcon"
const val ICON_PICKER: String = "iconPicker"
+ const val EXPERIMENTAL_FEATURES: String = "experimentalFeatures"
}
val LocalNavController = staticCompositionLocalOf {
@@ -94,6 +95,7 @@ fun Preferences(interactor: PreferenceInteractor = viewModel
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/SwitchPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/SwitchPreference.kt
index baedef2b98..36e41f70c9 100644
--- a/lawnchair/src/app/lawnchair/ui/preferences/components/SwitchPreference.kt
+++ b/lawnchair/src/app/lawnchair/ui/preferences/components/SwitchPreference.kt
@@ -33,7 +33,8 @@ fun SwitchPreference(
label: String,
description: String? = null,
enabled: Boolean = true,
- showDivider: Boolean = false
+ showDivider: Boolean = false,
+ onChange: (Boolean) -> Unit = {},
) {
PreferenceTemplate(
title = { Text(text = label) },
@@ -43,13 +44,19 @@ fun SwitchPreference(
modifier = Modifier
.height(24.dp),
checked = adapter.state.value,
- onCheckedChange = adapter::onChange,
+ onCheckedChange = {
+ adapter.onChange(it)
+ onChange(it)
+ },
enabled = enabled,
colors = SwitchDefaults.colors(checkedThumbColor = MaterialTheme.colorScheme.primary),
)
},
modifier = Modifier
- .clickable(enabled) { adapter.onChange(!adapter.state.value) },
+ .clickable(enabled) {
+ onChange(!adapter.state.value)
+ adapter.onChange(!adapter.state.value)
+ },
enabled = enabled,
showDivider = showDivider
)