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