From 89fbc3056cd3911d5fa100c421d1427a792482b4 Mon Sep 17 00:00:00 2001
From: MM20 <15646950+MM2-0@users.noreply.github.com>
Date: Thu, 3 Jul 2025 21:16:09 +0200
Subject: [PATCH] Change search bar style preference
---
.../homescreen/HomescreenSettingsScreen.kt | 262 ++++++++++++------
core/i18n/src/main/res/values/strings.xml | 3 +
2 files changed, 179 insertions(+), 86 deletions(-)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt
index b1497c23..de896f09 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt
@@ -3,33 +3,55 @@ package de.mm20.launcher2.ui.settings.homescreen
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.Row
+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.pager.HorizontalPager
-import androidx.compose.foundation.pager.rememberPagerState
-import androidx.compose.material3.AlertDialog
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Circle
+import androidx.compose.material.icons.rounded.AutoAwesome
+import androidx.compose.material.icons.rounded.CheckCircle
+import androidx.compose.material.icons.rounded.DarkMode
+import androidx.compose.material.icons.rounded.LightMode
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SegmentedButton
+import androidx.compose.material3.SegmentedButtonDefaults
+import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
+import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
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.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
-import com.google.accompanist.pager.HorizontalPagerIndicator
+import de.mm20.launcher2.preferences.ClockWidgetColors
import de.mm20.launcher2.preferences.SearchBarColors
import de.mm20.launcher2.preferences.SearchBarStyle
import de.mm20.launcher2.preferences.SystemBarColors
import de.mm20.launcher2.ui.R
+import de.mm20.launcher2.ui.component.BottomSheetDialog
import de.mm20.launcher2.ui.component.SearchBar
import de.mm20.launcher2.ui.component.SearchBarLevel
import de.mm20.launcher2.ui.component.preferences.ListPreference
@@ -39,9 +61,9 @@ import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
import de.mm20.launcher2.ui.component.preferences.SliderPreference
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
import de.mm20.launcher2.ui.launcher.widgets.clock.ConfigureClockWidgetSheet
+import de.mm20.launcher2.ui.locals.LocalDarkTheme
import de.mm20.launcher2.ui.locals.LocalNavController
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.isActive
+import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
@Composable
fun HomescreenSettingsScreen() {
@@ -124,24 +146,14 @@ fun HomescreenSettingsScreen() {
title = stringResource(R.string.preference_search_bar_style),
summary = stringResource(R.string.preference_search_bar_style_summary),
value = searchBarStyle,
- onValueChanged = {
+ colors = searchBarColor,
+ onStyleChanged = {
viewModel.setSearchBarStyle(it)
+ },
+ onColorsChanged = {
+ viewModel.setSearchBarColor(it)
}
)
- AnimatedVisibility(searchBarStyle == SearchBarStyle.Transparent) {
- ListPreference(
- title = stringResource(R.string.preference_search_bar_color),
- value = searchBarColor,
- items = listOf(
- stringResource(R.string.preference_system_bar_icons_auto) to SearchBarColors.Auto,
- stringResource(R.string.preference_system_bar_icons_light) to SearchBarColors.Light,
- stringResource(R.string.preference_system_bar_icons_dark) to SearchBarColors.Dark,
- ),
- onValueChanged = {
- if (it != null) viewModel.setSearchBarColor(it)
- }
- )
- }
ListPreference(
title = stringResource(R.string.preference_layout_search_bar_position),
@@ -275,7 +287,9 @@ fun SearchBarStylePreference(
title: String,
summary: String? = null,
value: SearchBarStyle?,
- onValueChanged: (SearchBarStyle) -> Unit
+ colors: SearchBarColors?,
+ onStyleChanged: (SearchBarStyle) -> Unit,
+ onColorsChanged: (SearchBarColors) -> Unit
) {
var showDialog by remember { mutableStateOf(false) }
Preference(title = title, summary = summary, onClick = { showDialog = true })
@@ -283,70 +297,146 @@ fun SearchBarStylePreference(
val styles = remember {
SearchBarStyle.entries
}
- val pagerState = rememberPagerState(initialPage = styles.indexOf(value)) { styles.size }
- var level by remember { mutableStateOf(SearchBarLevel.Resting) }
- var previewSearchValue by remember { mutableStateOf("") }
- LaunchedEffect(null) {
- while (isActive) {
- delay(2000)
- level = SearchBarLevel.Active
- delay(1000)
- previewSearchValue = "A"
- delay(100)
- previewSearchValue = "AB"
- delay(100)
- previewSearchValue = "ABC"
- delay(800)
- level = SearchBarLevel.Raised
- delay(2000)
- level = SearchBarLevel.Resting
- previewSearchValue = ""
+ val darkColors = LocalPreferDarkContentOverWallpaper.current && colors == SearchBarColors.Auto || colors == SearchBarColors.Dark
+
+ BottomSheetDialog(
+ onDismissRequest = {
+ showDialog = false
+ }
+ ) {
+ Box(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .padding(it)
+ ) {
+ Column(
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ ) {
+ for (style in styles) {
+ Column {
+ Row(
+ modifier = Modifier
+ .padding(top = 8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Text(
+ text = stringResource(
+ when(style) {
+ SearchBarStyle.Transparent -> R.string.preference_search_bar_style_transparent
+ SearchBarStyle.Solid -> R.string.preference_search_bar_style_solid
+ SearchBarStyle.Hidden -> R.string.preference_search_bar_style_hidden
+ }
+ ),
+ style = MaterialTheme.typography.titleSmall,
+ color = MaterialTheme.colorScheme.secondary,
+ modifier = Modifier.weight(1f),
+ )
+ IconButton(
+ onClick = {
+ onStyleChanged(style)
+ }
+ ) {
+ Icon(
+ if (style == value) Icons.Rounded.CheckCircle else Icons.Outlined.Circle,
+ contentDescription = null,
+ tint = if (style == value) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface,
+ )
+ }
+ }
+ Box(
+ modifier = Modifier
+ .border(
+ if (style == value) 4.dp else 2.dp,
+ if (style == value) MaterialTheme.colorScheme.primary else Color.Transparent,
+ MaterialTheme.shapes.medium,
+ )
+ .clip(MaterialTheme.shapes.medium)
+ .background(
+ when {
+ style != SearchBarStyle.Transparent -> MaterialTheme.colorScheme.inverseSurface
+ LocalDarkTheme.current != darkColors -> MaterialTheme.colorScheme.surfaceContainer
+ else -> MaterialTheme.colorScheme.inverseSurface
+ }
+ )
+ .height(IntrinsicSize.Min)
+ ) {
+ SearchBar(
+ modifier = Modifier
+ .padding(16.dp),
+ level = SearchBarLevel.Resting,
+ style = style,
+ value = "",
+ onValueChange = {},
+ readOnly = true,
+ darkColors = darkColors,
+ )
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .clickable {
+ onStyleChanged(style)
+ }
+ )
+ }
+ if (style == SearchBarStyle.Transparent) {
+ SingleChoiceSegmentedButtonRow(
+ modifier = Modifier.fillMaxWidth().padding(top = 16.dp),
+ ) {
+ SegmentedButton(
+ selected = colors == SearchBarColors.Auto,
+ onClick = {
+ onColorsChanged(SearchBarColors.Auto)
+ },
+ shape = SegmentedButtonDefaults.itemShape(
+ index = 0,
+ count = 3
+ ),
+ ) {
+ Icon(
+ imageVector = Icons.Rounded.AutoAwesome,
+ contentDescription = null,
+ modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
+ )
+ }
+ SegmentedButton(
+ selected = colors == SearchBarColors.Dark,
+ onClick = {
+ onColorsChanged(SearchBarColors.Dark)
+ },
+ shape = SegmentedButtonDefaults.itemShape(
+ index = 1,
+ count = 3
+ ),
+ ) {
+ Icon(
+ imageVector = Icons.Rounded.LightMode,
+ contentDescription = null,
+ modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
+ )
+ }
+ SegmentedButton(
+ selected = colors == SearchBarColors.Light,
+ onClick = {
+ onColorsChanged(SearchBarColors.Light)
+ },
+ shape = SegmentedButtonDefaults.itemShape(
+ index = 2,
+ count = 3
+ ),
+ ) {
+ Icon(
+ imageVector = Icons.Rounded.DarkMode,
+ contentDescription = null,
+ modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
+ )
+ }
+ }
+ }
+ }
+ }
+ }
}
}
-
- AlertDialog(
- onDismissRequest = { showDialog = false },
- confirmButton = {
- TextButton(onClick = {
- showDialog = false
- onValueChanged(styles[pagerState.currentPage])
- }) {
- Text(
- text = stringResource(android.R.string.ok),
- )
- }
- },
- dismissButton = {
- TextButton(onClick = { showDialog = false }) {
- Text(
- text = stringResource(android.R.string.cancel),
- )
- }
- },
-
- text = {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- HorizontalPager(
- state = pagerState,
- modifier = Modifier
- .height(150.dp)
- .padding(bottom = 16.dp)
- .background(MaterialTheme.colorScheme.secondary)
- ) {
- SearchBar(
- modifier = Modifier.padding(8.dp),
- level = level,
- style = styles[it],
- value = previewSearchValue,
- onValueChange = {}
- )
- }
- HorizontalPagerIndicator(pagerState = pagerState, pageCount = styles.size)
- }
- }
- )
}
}
\ No newline at end of file
diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml
index 4c424c6a..fc333f5e 100644
--- a/core/i18n/src/main/res/values/strings.xml
+++ b/core/i18n/src/main/res/values/strings.xml
@@ -653,6 +653,9 @@
More information about this build of this app
Style
Customize search bar appearance
+ Transparent
+ Solid
+ Hidden
Color
Open keyboard
Automatically show the keyboard when opening the app drawer