diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/common/SearchablePicker.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/common/SearchablePicker.kt index 3e626993c..f58befb58 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/common/SearchablePicker.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/common/SearchablePicker.kt @@ -1,16 +1,22 @@ package de.mm20.launcher2.ui.common import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material3.DockedSearchBar import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.SearchBarDefaults import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -18,6 +24,8 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow @@ -32,81 +40,122 @@ import de.mm20.launcher2.ui.ktx.toPixels @Composable fun SearchablePicker( + expanded: Boolean, value: SavableSearchable?, onValueChanged: (SavableSearchable?) -> Unit, onDismissRequest: () -> Unit, ) { - val viewModel: SearchablePickerVM = viewModel() + DismissableBottomSheet(expanded = expanded, onDismissRequest = onDismissRequest) { + val viewModel: SearchablePickerVM = viewModel() - DismissableBottomSheet(onDismissRequest = onDismissRequest) { - Column( + val colorSurface = MaterialTheme.colorScheme.surfaceContainerLow + + LazyColumn( modifier = Modifier - .fillMaxSize() - .padding(it) - ) { - OutlinedTextField( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - value = viewModel.searchQuery, - onValueChange = { viewModel.onSearchQueryChanged(it) }, - leadingIcon = { - Icon(painterResource(R.drawable.search_24px), null) - }, - placeholder = { - Text(stringResource(R.string.search_bar_placeholder)) - }, - singleLine = true, + .fillMaxSize(), + contentPadding = PaddingValues( + start = 16.dp, + end = 16.dp, + bottom = 16.dp + WindowInsets.navigationBars.asPaddingValues() + .calculateBottomPadding(), + top = 16.dp, ) - LazyColumn( - modifier = Modifier - .weight(1f) - .fillMaxWidth(), - ) { - items(viewModel.items) { - val iconSize = 32.dp.toPixels() - val icon by remember(it.key) { - viewModel.getIcon( - it, - iconSize.toInt() - ) - }.collectAsStateWithLifecycle(null) - val selected = it.key == value?.key - Surface( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - shape = MaterialTheme.shapes.small, - border = BorderStroke(1.dp, if (selected) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.outline), - color = if (selected) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.surface, - onClick = { onValueChanged(it) }) { - Row( - modifier = Modifier.padding(16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - ShapedLauncherIcon( - icon = { icon }, - size = 32.dp, - ) - Text( - text = it.label, - modifier = Modifier.weight(1f).padding(horizontal = 16.dp), - style = MaterialTheme.typography.labelMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - if (selected) { - Icon( - painterResource(R.drawable.check_circle_24px_filled), - contentDescription = null, - tint = MaterialTheme.colorScheme.secondary, + ) { + stickyHeader { + DockedSearchBar( + modifier = Modifier + .fillMaxWidth() + .drawBehind { + drawRect( + brush = Brush.verticalGradient( + 0.5f to colorSurface, + 0.5f to colorSurface.copy(alpha = 0f), ) - } + ) + } + .padding(bottom = 16.dp), + expanded = false, + onExpandedChange = {}, + inputField = { + SearchBarDefaults.InputField( + leadingIcon = { + Icon( + painterResource(R.drawable.search_24px), + contentDescription = null + ) + }, + trailingIcon = { + if (viewModel.searchQuery.isNotEmpty()) { + IconButton( + onClick = { + viewModel.onSearchQueryChanged("") + }) { + Icon(painterResource(R.drawable.close_24px), null) + } + } + }, + onSearch = {}, + expanded = false, + onExpandedChange = {}, + query = viewModel.searchQuery, + onQueryChange = { + viewModel.onSearchQueryChanged(it) + }, + placeholder = { + Text(stringResource(R.string.search_bar_placeholder)) + }, + ) + } + ) { + } + } + items(viewModel.items) { + val iconSize = 32.dp.toPixels() + val icon by remember(it.key) { + viewModel.getIcon( + it, + iconSize.toInt() + ) + }.collectAsStateWithLifecycle(null) + val selected = it.key == value?.key + Surface( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), + shape = MaterialTheme.shapes.small, + border = BorderStroke( + 1.dp, + if (selected) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.outline + ), + color = if (selected) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.surface, + onClick = { onValueChanged(it) }) { + Row( + modifier = Modifier.padding(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + ShapedLauncherIcon( + icon = { icon }, + size = 32.dp, + ) + Text( + text = it.label, + modifier = Modifier + .weight(1f) + .padding(horizontal = 16.dp), + style = MaterialTheme.typography.labelMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + if (selected) { + Icon( + painterResource(R.drawable.check_circle_24px_filled), + contentDescription = null, + tint = MaterialTheme.colorScheme.secondary, + ) } } } } } } - } \ No newline at end of file diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/component/DismissableBottomSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/component/DismissableBottomSheet.kt index 34b5acf94..67053c2ab 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/component/DismissableBottomSheet.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/component/DismissableBottomSheet.kt @@ -67,7 +67,7 @@ import kotlinx.coroutines.CancellationException fun DismissableBottomSheet( expanded: Boolean = true, onDismissRequest: () -> Unit, - content: @Composable (contentPadding: PaddingValues) -> Unit, + content: @Composable (contentPadding: PaddingValues) -> Unit, ) { DismissableBottomSheet( state = expanded, diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt index d66b7c379..348eed0b0 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt @@ -272,19 +272,18 @@ fun CustomizeSearchableSheet( } } } - if (pickIcon) { - DismissableBottomSheet( - onDismissRequest = { viewModel.closeIconPicker() }, - ) { - IconPicker( - searchable = searchable, - onSelect = { - viewModel.pickIcon(it) - viewModel.closeIconPicker() - }, - contentPadding = it, - ) - } + DismissableBottomSheet( + expanded = pickIcon, + onDismissRequest = { viewModel.closeIconPicker() }, + ) { + IconPicker( + searchable = searchable, + onSelect = { + viewModel.pickIcon(it) + viewModel.closeIconPicker() + }, + contentPadding = it, + ) } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt index 52662bf39..6bba88ce0 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/notes/NotesWidget.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight @@ -123,19 +124,18 @@ fun NotesWidget( } }, ) - if (showConflictResolveSheet) { - NoteWidgetConflictResolveSheet( - localContent = widget.config.storedText, - fileContent = text.text, - onResolve = { - viewModel.resolveFileContentConflict(context, it) - showConflictResolveSheet = false - }, - onDismissRequest = { - showConflictResolveSheet = false - } - ) - } + NoteWidgetConflictResolveSheet( + expanded = showConflictResolveSheet, + localContent = widget.config.storedText, + fileContent = text.text, + onResolve = { + viewModel.resolveFileContentConflict(context, it) + showConflictResolveSheet = false + }, + onDismissRequest = { + showConflictResolveSheet = false + } + ) return } Column { @@ -374,44 +374,44 @@ fun NotesWidget( } } - if (readWriteErrorSheetText != null) { - NoteReadWriteErrorSheet( - message = readWriteErrorSheetText!!, - onDismiss = { readWriteErrorSheetText = null }, - onRelink = { - linkFileLauncher.launch( - context.getString( - R.string.notes_widget_export_filename, - ZonedDateTime.now().format( - DateTimeFormatter.ISO_INSTANT - ) + NoteReadWriteErrorSheet( + message = readWriteErrorSheetText, + onDismiss = { readWriteErrorSheetText = null }, + onRelink = { + linkFileLauncher.launch( + context.getString( + R.string.notes_widget_export_filename, + ZonedDateTime.now().format( + DateTimeFormatter.ISO_INSTANT ) ) - }, - onUnlink = { - viewModel.unlinkFile(context) - } - ) - } + ) + }, + onUnlink = { + viewModel.unlinkFile(context) + } + ) } @Composable fun NoteWidgetConflictResolveSheet( + expanded: Boolean, localContent: String, fileContent: String, onResolve: (LinkedFileConflictStrategy) -> Unit, onDismissRequest: () -> Unit, ) { - var selectedStrategy by remember { mutableStateOf(null) } DismissableBottomSheet( + expanded = expanded, onDismissRequest = onDismissRequest, - ) { + var selectedStrategy by remember { mutableStateOf(null) } Column( modifier = Modifier .fillMaxWidth() .verticalScroll(rememberScrollState()) - .padding(it), + .padding(16.dp) + .navigationBarsPadding(), ) { Text( @@ -538,19 +538,24 @@ fun SelectableNoteContent( @Composable fun NoteReadWriteErrorSheet( - message: String, + message: String?, onDismiss: () -> Unit, onRelink: () -> Unit, onUnlink: () -> Unit, ) { DismissableBottomSheet( + state = message, + expanded = { it != null }, onDismissRequest = onDismiss, - ) { + ) { message -> + message ?: return@DismissableBottomSheet + Column( modifier = Modifier .fillMaxWidth() .verticalScroll(rememberScrollState()) - .padding(it) + .padding(16.dp) + .navigationBarsPadding() ) { Text( text = message, diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CorePaletteColorPreference.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CorePaletteColorPreference.kt index 89c554cda..3e6762ef7 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CorePaletteColorPreference.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CorePaletteColorPreference.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState @@ -51,7 +52,8 @@ fun CorePaletteColorPreference( var showDialog by remember { mutableStateOf(false) } Row( - modifier = modifier.fillMaxWidth() + modifier = modifier + .fillMaxWidth() .clip(MaterialTheme.shapes.extraSmall) .clickable( onClick = { showDialog = true }, @@ -62,7 +64,9 @@ fun CorePaletteColorPreference( ) { ColorSwatch( color = Color(value ?: defaultValue), - modifier = Modifier.padding(end = 20.dp).size(48.dp), + modifier = Modifier + .padding(end = 20.dp) + .size(48.dp), ) Text( @@ -74,78 +78,79 @@ fun CorePaletteColorPreference( ) } - if (showDialog) { - var currentValue by remember { mutableStateOf(value) } - DismissableBottomSheet(onDismissRequest = { + var currentValue by remember { mutableStateOf(value) } + DismissableBottomSheet( + expanded = showDialog, + onDismissRequest = { onValueChange(currentValue) showDialog = false }) { - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(it) - ) { - SwitchPreference( - icon = R.drawable.rule_settings_24px, - title = stringResource(R.string.theme_color_scheme_system_default), - value = currentValue == null, - onValueChanged = { - currentValue = if (it) null else defaultValue - }, - containerColor = Color.Transparent, + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(16.dp) + .navigationBarsPadding() + ) { + SwitchPreference( + icon = R.drawable.rule_settings_24px, + title = stringResource(R.string.theme_color_scheme_system_default), + value = currentValue == null, + onValueChanged = { + currentValue = if (it) null else defaultValue + }, + containerColor = Color.Transparent, + ) + AnimatedVisibility( + currentValue != null, + enter = expandVertically( + expandFrom = Alignment.Top, + ), + exit = shrinkVertically( + shrinkTowards = Alignment.Top, ) - AnimatedVisibility( - currentValue != null, - enter = expandVertically( - expandFrom = Alignment.Top, - ), - exit = shrinkVertically( - shrinkTowards = Alignment.Top, + ) { + Column { + HorizontalDivider( + modifier = Modifier.padding(bottom = 24.dp) ) - ) { - Column { + val colorPickerState = rememberHctColorPickerState( + initialColor = Color(value ?: defaultValue), + onColorChanged = { + currentValue = it.toArgb() + } + ) + HctColorPicker( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.CenterHorizontally), + state = colorPickerState, + ) + + if (autoGenerate != null) { HorizontalDivider( - modifier = Modifier.padding(bottom = 24.dp) + modifier = Modifier.padding(top = 16.dp) ) - val colorPickerState = rememberHctColorPickerState( - initialColor = Color(value ?: defaultValue), - onColorChanged = { - currentValue = it.toArgb() - } - ) - HctColorPicker( + + TextButton( modifier = Modifier - .fillMaxWidth() - .align(Alignment.CenterHorizontally), - state = colorPickerState, - ) - - if (autoGenerate != null) { - HorizontalDivider( - modifier = Modifier.padding(top = 16.dp) - ) - - TextButton( - modifier = Modifier - .padding(top = 8.dp) - .align(Alignment.End), - contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, - onClick = { - val autoGenerated = autoGenerate() - currentValue = autoGenerated - if (autoGenerated != null) { - colorPickerState.setColor(Color(autoGenerated)) - } + .padding(top = 8.dp) + .align(Alignment.End), + contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, + onClick = { + val autoGenerated = autoGenerate() + currentValue = autoGenerated + if (autoGenerated != null) { + colorPickerState.setColor(Color(autoGenerated)) } - ) { - Icon( - painterResource(R.drawable.wand_stars_20px), null, - modifier = Modifier - .padding(ButtonDefaults.IconSpacing) - .size(ButtonDefaults.IconSize) - ) - Text(stringResource(R.string.theme_color_scheme_autogenerate)) } + ) { + Icon( + painterResource(R.drawable.wand_stars_20px), null, + modifier = Modifier + .padding(ButtonDefaults.IconSpacing) + .size(ButtonDefaults.IconSize) + ) + Text(stringResource(R.string.theme_color_scheme_autogenerate)) } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ThemeColorPreference.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ThemeColorPreference.kt index 501ede1f8..f077be017 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ThemeColorPreference.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ThemeColorPreference.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -74,7 +75,8 @@ fun ThemeColorPreference( var showDialog by remember { mutableStateOf(false) } Row( - modifier = modifier.fillMaxWidth() + modifier = modifier + .fillMaxWidth() .clip(MaterialTheme.shapes.extraSmall) .clickable( onClick = { showDialog = true }, @@ -85,7 +87,9 @@ fun ThemeColorPreference( ) { ColorSwatch( color = Color((value ?: defaultValue).get(corePalette)), - modifier = Modifier.padding(end = 20.dp).size(48.dp), + modifier = Modifier + .padding(end = 20.dp) + .size(48.dp), ) Text( @@ -97,337 +101,338 @@ fun ThemeColorPreference( ) } - if (showDialog) { - var currentValue by remember { mutableStateOf(value) } + var currentValue by remember { mutableStateOf(value) } - val actualValue = currentValue ?: defaultValue - DismissableBottomSheet(onDismissRequest = { + DismissableBottomSheet( + expanded = showDialog, + onDismissRequest = { onValueChange(currentValue) showDialog = false }) { - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()) - .padding(it), + val actualValue = currentValue ?: defaultValue + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + .padding(16.dp) + .navigationBarsPadding(), + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween) ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween) + ToggleButton( + modifier = Modifier.weight(1f), + checked = actualValue is ColorRef, + onCheckedChange = { + if (actualValue is ColorRef) return@ToggleButton + currentValue = defaultValue + }, + shapes = ButtonGroupDefaults.connectedLeadingButtonShapes() ) { - ToggleButton( - modifier = Modifier.weight(1f), - checked = actualValue is ColorRef, - onCheckedChange = { - if (actualValue is ColorRef) return@ToggleButton - currentValue = defaultValue - }, - shapes = ButtonGroupDefaults.connectedLeadingButtonShapes() - ) { - Icon( - painterResource( - if (actualValue is ColorRef) R.drawable.check_20px else R.drawable.palette_20px - ), - null, - modifier = Modifier - .padding(end = ToggleButtonDefaults.IconSpacing) - .size(ToggleButtonDefaults.IconSize) - ) - Text(stringResource(R.string.theme_color_scheme_palette_color)) - } - ToggleButton( - modifier = Modifier.weight(1f), - checked = actualValue is StaticColor, - onCheckedChange = { - currentValue = StaticColor(actualValue.get(corePalette)) - }, - shapes = ButtonGroupDefaults.connectedTrailingButtonShapes() - ) { - Icon( - painterResource( - if (actualValue is StaticColor) R.drawable.check_20px else R.drawable.colorize_20px - ), - null, - modifier = Modifier - .padding(end = ToggleButtonDefaults.IconSpacing) - .size(ToggleButtonDefaults.IconSize) - ) - Text(stringResource(R.string.theme_color_scheme_custom_color)) - } + Icon( + painterResource( + if (actualValue is ColorRef) R.drawable.check_20px else R.drawable.palette_20px + ), + null, + modifier = Modifier + .padding(end = ToggleButtonDefaults.IconSpacing) + .size(ToggleButtonDefaults.IconSize) + ) + Text(stringResource(R.string.theme_color_scheme_palette_color)) } - AnimatedContent( - actualValue, - label = "AnimatedContent", - contentKey = { it is StaticColor } - ) { themeColor -> - Column { - if (themeColor is StaticColor) { - val colorPickerState = rememberHctColorPickerState( - initialColor = Color(themeColor.color), - onColorChanged = { - currentValue = StaticColor(it.toArgb()) - } - ) - HctColorPicker( - modifier = Modifier - .fillMaxWidth() - .padding(top = 24.dp) - .align(Alignment.CenterHorizontally), - state = colorPickerState - ) - } else if (themeColor is ColorRef) { - val hct = Hct.fromInt(corePalette.get(themeColor.color)) - val hue = hct.hue.toFloat() - val chroma = hct.chroma.toFloat() - var tone by remember(value == null) { mutableStateOf(themeColor.tone.toFloat()) } - Row( - modifier = Modifier.padding(top = 24.dp, bottom = 8.dp) - ) { - ColorSwatch( - color = Color( - corePalette - .get(CorePaletteColor.Primary) - .atTone(tone.toInt()) - ), - modifier = Modifier - .padding(8.dp) - .size(64.dp) - .clickable { - currentValue = ColorRef( - CorePaletteColor.Primary, - tone.roundToInt() - ) - }, - selected = themeColor.color == CorePaletteColor.Primary, - ) - Spacer(modifier = Modifier.weight(1f)) - ColorSwatch( - color = Color( - corePalette - .get(CorePaletteColor.Secondary) - .atTone(tone.toInt()) - ), - modifier = Modifier - .padding(8.dp) - .size(64.dp) - .clickable { - currentValue = ColorRef( - CorePaletteColor.Secondary, - tone.roundToInt() - ) - }, - selected = themeColor.color == CorePaletteColor.Secondary, - ) - Spacer(modifier = Modifier.weight(1f)) - ColorSwatch( - color = Color( - corePalette - .get(CorePaletteColor.Tertiary) - .atTone(tone.toInt()) - ), - modifier = Modifier - .padding(8.dp) - .size(64.dp) - .clickable { - currentValue = ColorRef( - CorePaletteColor.Tertiary, - tone.roundToInt() - ) - }, - selected = themeColor.color == CorePaletteColor.Tertiary, - ) + ToggleButton( + modifier = Modifier.weight(1f), + checked = actualValue is StaticColor, + onCheckedChange = { + currentValue = StaticColor(actualValue.get(corePalette)) + }, + shapes = ButtonGroupDefaults.connectedTrailingButtonShapes() + ) { + Icon( + painterResource( + if (actualValue is StaticColor) R.drawable.check_20px else R.drawable.colorize_20px + ), + null, + modifier = Modifier + .padding(end = ToggleButtonDefaults.IconSpacing) + .size(ToggleButtonDefaults.IconSize) + ) + Text(stringResource(R.string.theme_color_scheme_custom_color)) + } + } + AnimatedContent( + actualValue, + label = "AnimatedContent", + contentKey = { it is StaticColor } + ) { themeColor -> + Column { + if (themeColor is StaticColor) { + val colorPickerState = rememberHctColorPickerState( + initialColor = Color(themeColor.color), + onColorChanged = { + currentValue = StaticColor(it.toArgb()) } - Row( - modifier = Modifier.padding(bottom = 16.dp) - ) { - ColorSwatch( - color = Color( - corePalette - .get(CorePaletteColor.Neutral) - .atTone(tone.toInt()) - ), - modifier = Modifier - .padding(8.dp) - .size(64.dp) - .clickable { - currentValue = ColorRef( - CorePaletteColor.Neutral, - tone.roundToInt() - ) - }, - selected = themeColor.color == CorePaletteColor.Neutral, - ) - Spacer(modifier = Modifier.weight(1f)) - ColorSwatch( - color = Color( - corePalette - .get(CorePaletteColor.NeutralVariant) - .atTone(tone.toInt()) - ), - modifier = Modifier - .padding(8.dp) - .size(64.dp) - .clickable { - currentValue = ColorRef( - CorePaletteColor.NeutralVariant, - tone.roundToInt() - ) - }, - selected = themeColor.color == CorePaletteColor.NeutralVariant, - ) - Spacer(modifier = Modifier.weight(1f)) - ColorSwatch( - color = Color( - corePalette - .get(CorePaletteColor.Error) - .atTone(tone.toInt()) - ), - modifier = Modifier - .padding(8.dp) - .size(64.dp) - .clickable { - currentValue = ColorRef( - CorePaletteColor.Error, - tone.roundToInt() - ) - }, - selected = themeColor.color == CorePaletteColor.Error, - ) - } - Row( - verticalAlignment = Alignment.CenterVertically, + ) + HctColorPicker( + modifier = Modifier + .fillMaxWidth() + .padding(top = 24.dp) + .align(Alignment.CenterHorizontally), + state = colorPickerState + ) + } else if (themeColor is ColorRef) { + val hct = Hct.fromInt(corePalette.get(themeColor.color)) + val hue = hct.hue.toFloat() + val chroma = hct.chroma.toFloat() + var tone by remember(value == null) { mutableStateOf(themeColor.tone.toFloat()) } + Row( + modifier = Modifier.padding(top = 24.dp, bottom = 8.dp) + ) { + ColorSwatch( + color = Color( + corePalette + .get(CorePaletteColor.Primary) + .atTone(tone.toInt()) + ), modifier = Modifier - .fillMaxWidth() - .padding(top = 16.dp) - ) { - Text( - text = "T", - modifier = Modifier.width(32.dp), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center - ) - Slider( - modifier = Modifier.weight(1f), - value = tone, - valueRange = 0f..100f, - onValueChange = { - tone = it - currentValue = themeColor.copy(tone = it.roundToInt()) + .padding(8.dp) + .size(64.dp) + .clickable { + currentValue = ColorRef( + CorePaletteColor.Primary, + tone.roundToInt() + ) }, - track = { - Canvas( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - ) { - drawRoundRect( - brush = Brush.horizontalGradient( - colors = listOf( - Color.hct( - hue, - chroma, - 0f - ), - Color.hct( - hue, - chroma, - 10f - ), - Color.hct( - hue, - chroma, - 20f - ), - Color.hct( - hue, - chroma, - 30f - ), - Color.hct( - hue, - chroma, - 40f - ), - Color.hct( - hue, - chroma, - 50f - ), - Color.hct( - hue, - chroma, - 60f - ), - Color.hct( - hue, - chroma, - 70f - ), - Color.hct( - hue, - chroma, - 80f - ), - Color.hct( - hue, - chroma, - 90f - ), - Color.hct( - hue, - chroma, - 100f - ), - ) - ), - style = Fill, - cornerRadius = CornerRadius( - 10.dp.toPx(), - 10.dp.toPx() + selected = themeColor.color == CorePaletteColor.Primary, + ) + Spacer(modifier = Modifier.weight(1f)) + ColorSwatch( + color = Color( + corePalette + .get(CorePaletteColor.Secondary) + .atTone(tone.toInt()) + ), + modifier = Modifier + .padding(8.dp) + .size(64.dp) + .clickable { + currentValue = ColorRef( + CorePaletteColor.Secondary, + tone.roundToInt() + ) + }, + selected = themeColor.color == CorePaletteColor.Secondary, + ) + Spacer(modifier = Modifier.weight(1f)) + ColorSwatch( + color = Color( + corePalette + .get(CorePaletteColor.Tertiary) + .atTone(tone.toInt()) + ), + modifier = Modifier + .padding(8.dp) + .size(64.dp) + .clickable { + currentValue = ColorRef( + CorePaletteColor.Tertiary, + tone.roundToInt() + ) + }, + selected = themeColor.color == CorePaletteColor.Tertiary, + ) + } + Row( + modifier = Modifier.padding(bottom = 16.dp) + ) { + ColorSwatch( + color = Color( + corePalette + .get(CorePaletteColor.Neutral) + .atTone(tone.toInt()) + ), + modifier = Modifier + .padding(8.dp) + .size(64.dp) + .clickable { + currentValue = ColorRef( + CorePaletteColor.Neutral, + tone.roundToInt() + ) + }, + selected = themeColor.color == CorePaletteColor.Neutral, + ) + Spacer(modifier = Modifier.weight(1f)) + ColorSwatch( + color = Color( + corePalette + .get(CorePaletteColor.NeutralVariant) + .atTone(tone.toInt()) + ), + modifier = Modifier + .padding(8.dp) + .size(64.dp) + .clickable { + currentValue = ColorRef( + CorePaletteColor.NeutralVariant, + tone.roundToInt() + ) + }, + selected = themeColor.color == CorePaletteColor.NeutralVariant, + ) + Spacer(modifier = Modifier.weight(1f)) + ColorSwatch( + color = Color( + corePalette + .get(CorePaletteColor.Error) + .atTone(tone.toInt()) + ), + modifier = Modifier + .padding(8.dp) + .size(64.dp) + .clickable { + currentValue = ColorRef( + CorePaletteColor.Error, + tone.roundToInt() + ) + }, + selected = themeColor.color == CorePaletteColor.Error, + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(top = 16.dp) + ) { + Text( + text = "T", + modifier = Modifier.width(32.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center + ) + Slider( + modifier = Modifier.weight(1f), + value = tone, + valueRange = 0f..100f, + onValueChange = { + tone = it + currentValue = themeColor.copy(tone = it.roundToInt()) + }, + track = { + Canvas( + modifier = Modifier + .fillMaxWidth() + .height(20.dp) + ) { + drawRoundRect( + brush = Brush.horizontalGradient( + colors = listOf( + Color.hct( + hue, + chroma, + 0f + ), + Color.hct( + hue, + chroma, + 10f + ), + Color.hct( + hue, + chroma, + 20f + ), + Color.hct( + hue, + chroma, + 30f + ), + Color.hct( + hue, + chroma, + 40f + ), + Color.hct( + hue, + chroma, + 50f + ), + Color.hct( + hue, + chroma, + 60f + ), + Color.hct( + hue, + chroma, + 70f + ), + Color.hct( + hue, + chroma, + 80f + ), + Color.hct( + hue, + chroma, + 90f + ), + Color.hct( + hue, + chroma, + 100f + ), ) + ), + style = Fill, + cornerRadius = CornerRadius( + 10.dp.toPx(), + 10.dp.toPx() ) - } - }, - thumb = { - Box( - modifier = Modifier - .padding(vertical = 2.dp, horizontal = 8.dp) - .size(16.dp) - .shadow(1.dp, CircleShape) - .clip(CircleShape) - .background(Color.White) ) } - ) - Text( - text = tone.roundToInt().toString(), - modifier = Modifier.width(32.dp), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center, - ) - } - } - HorizontalDivider( - modifier = Modifier.padding(top = 16.dp) - ) - - TextButton( - modifier = Modifier - .padding(top = 8.dp) - .align(Alignment.End), - contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, - onClick = { currentValue = null } - ) { - Icon( - painterResource(R.drawable.restart_alt_20px), - null, - modifier = Modifier - .padding(ButtonDefaults.IconSpacing) - .size(ButtonDefaults.IconSize) + }, + thumb = { + Box( + modifier = Modifier + .padding(vertical = 2.dp, horizontal = 8.dp) + .size(16.dp) + .shadow(1.dp, CircleShape) + .clip(CircleShape) + .background(Color.White) + ) + } + ) + Text( + text = tone.roundToInt().toString(), + modifier = Modifier.width(32.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center, ) - Text(stringResource(R.string.preference_restore_default)) } } + HorizontalDivider( + modifier = Modifier.padding(top = 16.dp) + ) + + TextButton( + modifier = Modifier + .padding(top = 8.dp) + .align(Alignment.End), + contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, + onClick = { currentValue = null } + ) { + Icon( + painterResource(R.drawable.restart_alt_20px), + null, + modifier = Modifier + .padding(ButtonDefaults.IconSpacing) + .size(ButtonDefaults.IconSize) + ) + Text(stringResource(R.string.preference_restore_default)) + } } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt index f4df35539..bff5b5944 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt @@ -285,8 +285,9 @@ fun GesturePreference( } } - if (value is GestureAction.Launch && (showAppPicker || app == null)) { + if (value is GestureAction.Launch) { SearchablePicker( + expanded = (showAppPicker || app == null), onDismissRequest = { showAppPicker = false if (app == null) onValueChanged(GestureAction.NoAction) 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 14eb97ccf..ec318196e 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 @@ -13,6 +13,7 @@ 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.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -298,142 +299,141 @@ fun SearchBarStylePreference( ) { var showDialog by remember { mutableStateOf(false) } Preference(title = title, summary = summary, onClick = { showDialog = true }) - if (showDialog && value != null) { - val styles = remember { - SearchBarStyle.entries + + DismissableBottomSheet( + expanded = showDialog, + onDismissRequest = { + showDialog = false } + ) { + val styles = SearchBarStyle.entries val darkColors = LocalPreferDarkContentOverWallpaper.current && colors == SearchBarColors.Auto || colors == SearchBarColors.Dark - DismissableBottomSheet( - onDismissRequest = { - showDialog = false - } + Box( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(16.dp) + .navigationBarsPadding(), ) { - Box( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(it) + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), ) { - 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) + 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 } - ) { - Icon( - painterResource( - if (style == value) R.drawable.check_circle_24px_filled - else R.drawable.circle_24px - ), - contentDescription = null, - tint = if (style == value) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface, - ) + ), + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.secondary, + modifier = Modifier.weight(1f), + ) + IconButton( + onClick = { + onStyleChanged(style) } + ) { + Icon( + painterResource( + if (style == value) R.drawable.check_circle_24px_filled + else R.drawable.circle_24px + ), + 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 - .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) + .fillMaxSize() + .clickable { + onStyleChanged(style) + } + ) + } + if (style == SearchBarStyle.Transparent) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 16.dp), + horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween) ) { - 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) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 16.dp), - horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween) + ToggleButton( + modifier = Modifier.weight(1f), + checked = colors == SearchBarColors.Auto, + onCheckedChange = { + onColorsChanged(SearchBarColors.Auto) + }, + shapes = ButtonGroupDefaults.connectedLeadingButtonShapes(), ) { - ToggleButton( - modifier = Modifier.weight(1f), - checked = colors == SearchBarColors.Auto, - onCheckedChange = { - onColorsChanged(SearchBarColors.Auto) - }, - shapes = ButtonGroupDefaults.connectedLeadingButtonShapes(), - ) { - Icon( - painterResource(R.drawable.auto_awesome_20dp), - contentDescription = null, - ) - } - ToggleButton( - modifier = Modifier.weight(1f), - checked = colors == SearchBarColors.Light, - onCheckedChange = { - onColorsChanged(SearchBarColors.Light) - }, - shapes = ButtonGroupDefaults.connectedMiddleButtonShapes(), - ) { - Icon( - painterResource(R.drawable.light_mode_24px), - contentDescription = null, - ) - } - ToggleButton( - modifier = Modifier.weight(1f), - checked = colors == SearchBarColors.Dark, - onCheckedChange = { - onColorsChanged(SearchBarColors.Dark) - }, - shapes = ButtonGroupDefaults.connectedTrailingButtonShapes(), - ) { - Icon( - painterResource(R.drawable.dark_mode_24px), - contentDescription = null, - ) - } + Icon( + painterResource(R.drawable.auto_awesome_20dp), + contentDescription = null, + ) + } + ToggleButton( + modifier = Modifier.weight(1f), + checked = colors == SearchBarColors.Light, + onCheckedChange = { + onColorsChanged(SearchBarColors.Light) + }, + shapes = ButtonGroupDefaults.connectedMiddleButtonShapes(), + ) { + Icon( + painterResource(R.drawable.light_mode_24px), + contentDescription = null, + ) + } + ToggleButton( + modifier = Modifier.weight(1f), + checked = colors == SearchBarColors.Dark, + onCheckedChange = { + onColorsChanged(SearchBarColors.Dark) + }, + shapes = ButtonGroupDefaults.connectedTrailingButtonShapes(), + ) { + Icon( + painterResource(R.drawable.dark_mode_24px), + contentDescription = null, + ) } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt index 1f871dd21..a3bf86f1d 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt @@ -3,6 +3,7 @@ package de.mm20.launcher2.ui.settings.search import androidx.appcompat.app.AppCompatActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf @@ -397,27 +398,29 @@ fun SearchSettingsScreen() { } } - if (showFilterEditor) { + DismissableBottomSheet( + expanded = showFilterEditor, + onDismissRequest = { showFilterEditor = false }) { val filters by viewModel.searchFilters.collectAsStateWithLifecycle() - DismissableBottomSheet(onDismissRequest = { showFilterEditor = false }) { - Column( - modifier = Modifier.padding(it) - ) { - AnimatedVisibility(filters.allowNetwork) { - SmallMessage( - modifier = Modifier.padding(bottom = 16.dp), - icon = R.drawable.warning_24px, - text = stringResource(R.string.filter_settings_network_warning) - ) - } - SearchFilters( - filters = filters, - onFiltersChange = { - viewModel.setSearchFilters(it) - }, - settings = true, + Column( + modifier = Modifier + .padding(16.dp) + .navigationBarsPadding() + ) { + AnimatedVisibility(filters.allowNetwork) { + SmallMessage( + modifier = Modifier.padding(bottom = 16.dp), + icon = R.drawable.warning_24px, + text = stringResource(R.string.filter_settings_network_warning) ) } + SearchFilters( + filters = filters, + onFiltersChange = { + viewModel.setSearchFilters(it) + }, + settings = true, + ) } } } \ No newline at end of file diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/shapes/ShapeSchemeSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/shapes/ShapeSchemeSettingsScreen.kt index 6ed1a2b56..d9af08a19 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/shapes/ShapeSchemeSettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/shapes/ShapeSchemeSettingsScreen.kt @@ -77,7 +77,7 @@ import de.mm20.launcher2.themes.shapes.Shape as ThemeShape @Serializable data class ShapeSchemeSettingsRoute( @Serializable(with = UUIDSerializer::class) val id: UUID -): NavKey +) : NavKey @Composable fun ShapeSchemeSettingsScreen(themeId: UUID) { @@ -463,20 +463,38 @@ fun ShapePreference( ) } - if (showDialog) { - val maxRadius = (24 * factor).toInt() + val maxRadius = (24 * factor).toInt() - val baseTopStart = ((baseShape.radii?.get(0) ?: 12) * factor).toInt() - val baseTopEnd = ((baseShape.radii?.get(1) ?: 12) * factor).toInt() - val baseBottomEnd = ((baseShape.radii?.get(2) ?: 12) * factor).toInt() - val baseBottomStart = ((baseShape.radii?.get(3) ?: 12) * factor).toInt() + val baseTopStart = ((baseShape.radii?.get(0) ?: 12) * factor).toInt() + val baseTopEnd = ((baseShape.radii?.get(1) ?: 12) * factor).toInt() + val baseBottomEnd = ((baseShape.radii?.get(2) ?: 12) * factor).toInt() + val baseBottomStart = ((baseShape.radii?.get(3) ?: 12) * factor).toInt() - var currentCornerStyle by remember(shape) { mutableStateOf(shape?.corners) } - var currentTopStart by remember(shape) { mutableStateOf(shape?.radii?.get(0)) } - var currentTopEnd by remember(shape) { mutableStateOf(shape?.radii?.get(1)) } - var currentBottomEnd by remember(shape) { mutableStateOf(shape?.radii?.get(2)) } - var currentBottomStart by remember(shape) { mutableStateOf(shape?.radii?.get(3)) } + var currentCornerStyle by remember(shape) { mutableStateOf(shape?.corners) } + var currentTopStart by remember(shape) { mutableStateOf(shape?.radii?.get(0)) } + var currentTopEnd by remember(shape) { mutableStateOf(shape?.radii?.get(1)) } + var currentBottomEnd by remember(shape) { mutableStateOf(shape?.radii?.get(2)) } + var currentBottomStart by remember(shape) { mutableStateOf(shape?.radii?.get(3)) } + + DismissableBottomSheet( + expanded = showDialog, + onDismissRequest = { + showDialog = false + onValueChange( + ThemeShape( + corners = currentCornerStyle, + radii = if (currentTopStart != null || currentTopEnd != null || currentBottomEnd != null || currentBottomStart != null) { + intArrayOf( + currentTopStart ?: baseTopStart, + currentTopEnd ?: baseTopEnd, + currentBottomEnd ?: baseBottomEnd, + currentBottomStart ?: baseBottomStart, + ) + } else null + ) + ) + }) { val actualCornerStyle = currentCornerStyle ?: baseShape.corners ?: CornerStyle.Rounded val actualTopStart = currentTopStart ?: baseTopStart @@ -484,241 +502,222 @@ fun ShapePreference( val actualBottomEnd = currentBottomEnd ?: baseBottomEnd val actualBottomStart = currentBottomStart ?: baseBottomStart - DismissableBottomSheet( - onDismissRequest = { - showDialog = false - onValueChange( - ThemeShape( - corners = currentCornerStyle, - radii = if (currentTopStart != null || currentTopEnd != null || currentBottomEnd != null || currentBottomStart != null) { - intArrayOf( - currentTopStart ?: baseTopStart, - currentTopEnd ?: baseTopEnd, - currentBottomEnd ?: baseBottomEnd, - currentBottomStart ?: baseBottomStart, - ) - } else null - ) - ) - }) { - - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(it) - .padding(bottom = 8.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(it) + .padding(bottom = 8.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + val previewShape = if ((currentCornerStyle ?: baseShape.corners + ?: CornerStyle.Rounded) == CornerStyle.Rounded ) { - val previewShape = if ((currentCornerStyle ?: baseShape.corners - ?: CornerStyle.Rounded) == CornerStyle.Rounded - ) { - RoundedCornerShape( - topStart = (currentTopStart ?: baseTopStart).dp, - topEnd = (currentTopEnd ?: baseTopEnd).dp, - bottomEnd = (currentBottomEnd ?: baseBottomEnd).dp, - bottomStart = (currentBottomStart ?: baseBottomStart).dp + RoundedCornerShape( + topStart = (currentTopStart ?: baseTopStart).dp, + topEnd = (currentTopEnd ?: baseTopEnd).dp, + bottomEnd = (currentBottomEnd ?: baseBottomEnd).dp, + bottomStart = (currentBottomStart ?: baseBottomStart).dp + ) + } else { + CutCornerShape( + topStart = (currentTopStart ?: baseTopStart).dp, + topEnd = (currentTopEnd ?: baseTopEnd).dp, + bottomEnd = (currentBottomEnd ?: baseBottomEnd).dp, + bottomStart = (currentBottomStart ?: baseBottomStart).dp + ) + } + Box( + modifier = Modifier + .fillMaxWidth() + .height(max(96, maxRadius * 2).dp) + .background(MaterialTheme.colorScheme.surfaceContainer, previewShape) + .border( + 2.dp, + MaterialTheme.colorScheme.primary, + previewShape ) - } else { - CutCornerShape( - topStart = (currentTopStart ?: baseTopStart).dp, - topEnd = (currentTopEnd ?: baseTopEnd).dp, - bottomEnd = (currentBottomEnd ?: baseBottomEnd).dp, - bottomStart = (currentBottomStart ?: baseBottomStart).dp + ) + + Row( + modifier = Modifier + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween), + ) { + ToggleButton( + modifier = Modifier.weight(1f), + checked = actualCornerStyle == CornerStyle.Rounded, + onCheckedChange = { + currentCornerStyle = CornerStyle.Rounded + }, + shapes = ButtonGroupDefaults.connectedLeadingButtonShapes(), + ) { + Icon( + painterResource( + if (actualCornerStyle == CornerStyle.Rounded) R.drawable.check_20px else R.drawable.rounded_corner_alt_24px + ), + contentDescription = null, + modifier = Modifier + .padding(end = ToggleButtonDefaults.IconSpacing) + .size(ToggleButtonDefaults.IconSize) ) + Text(stringResource(R.string.preference_cards_shape_rounded)) } - Box( + ToggleButton( + modifier = Modifier.weight(1f), + checked = actualCornerStyle == CornerStyle.Cut, + onCheckedChange = { + currentCornerStyle = CornerStyle.Cut + }, + shapes = ButtonGroupDefaults.connectedTrailingButtonShapes(), + ) { + Icon( + painterResource( + if (actualCornerStyle == CornerStyle.Cut) R.drawable.check_20px else R.drawable.cut_corner_20px + ), + contentDescription = null, + modifier = Modifier + .padding(end = ToggleButtonDefaults.IconSpacing) + .size(ToggleButtonDefaults.IconSize) + ) + Text(stringResource(R.string.preference_cards_shape_cut)) + } + } + + + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painterResource(R.drawable.rounded_corner_24px), + null, modifier = Modifier - .fillMaxWidth() - .height(max(96, maxRadius * 2).dp) - .background(MaterialTheme.colorScheme.surfaceContainer, previewShape) - .border( - 2.dp, - MaterialTheme.colorScheme.primary, - previewShape - ) + .padding(end = 8.dp) + .rotate(-90f) + ) + Slider( + modifier = Modifier + .weight(1f), + value = actualTopStart.toFloat(), + onValueChange = { + currentTopStart = it.toInt() + }, + valueRange = 0f..maxRadius.toFloat(), + steps = maxRadius + 1 + ) + Text( + text = actualTopStart.toString(), + modifier = Modifier.width(32.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center, + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painterResource(R.drawable.rounded_corner_24px), + null, + modifier = Modifier.padding(end = 8.dp) + ) + Slider( + modifier = Modifier + .weight(1f), + value = actualTopEnd.toFloat(), + onValueChange = { + currentTopEnd = it.toInt() + }, + valueRange = 0f..maxRadius.toFloat(), + steps = maxRadius + 1, + ) + Text( + text = actualTopEnd.toString(), + modifier = Modifier.width(32.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center, + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painterResource(R.drawable.rounded_corner_24px), + null, + modifier = Modifier + .padding(end = 8.dp) + .rotate(90f) + ) + Slider( + modifier = Modifier + .weight(1f), + value = actualBottomEnd.toFloat(), + onValueChange = { + currentBottomEnd = it.toInt() + }, + valueRange = 0f..maxRadius.toFloat(), + steps = maxRadius + 1, + ) + Text( + text = actualBottomEnd.toString(), + modifier = Modifier.width(32.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center, + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painterResource(R.drawable.rounded_corner_24px), + null, + modifier = Modifier + .padding(end = 8.dp) + .rotate(180f) + ) + Slider( + modifier = Modifier + .weight(1f), + value = actualBottomStart.toFloat(), + onValueChange = { + currentBottomStart = it.toInt() + }, + valueRange = 0f..maxRadius.toFloat(), + steps = maxRadius + 1, + ) + Text( + text = actualBottomStart.toString(), + modifier = Modifier.width(32.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center, ) - Row( + } + + HorizontalDivider( + modifier = Modifier.padding(top = 16.dp) + ) + + TextButton( + modifier = Modifier + .padding(top = 8.dp) + .align(Alignment.End), + contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, + onClick = { + currentTopStart = null + currentTopEnd = null + currentBottomEnd = null + currentBottomStart = null + currentCornerStyle = null + onValueChange(null) + } + ) { + Icon( + painterResource(R.drawable.restart_alt_20px), null, modifier = Modifier - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(ButtonGroupDefaults.ConnectedSpaceBetween), - ) { - ToggleButton( - modifier = Modifier.weight(1f), - checked = actualCornerStyle == CornerStyle.Rounded, - onCheckedChange = { - currentCornerStyle = CornerStyle.Rounded - }, - shapes = ButtonGroupDefaults.connectedLeadingButtonShapes(), - ) { - Icon( - painterResource( - if (actualCornerStyle == CornerStyle.Rounded) R.drawable.check_20px else R.drawable.rounded_corner_alt_24px - ), - contentDescription = null, - modifier = Modifier - .padding(end = ToggleButtonDefaults.IconSpacing) - .size(ToggleButtonDefaults.IconSize) - ) - Text(stringResource(R.string.preference_cards_shape_rounded)) - } - ToggleButton( - modifier = Modifier.weight(1f), - checked = actualCornerStyle == CornerStyle.Cut, - onCheckedChange = { - currentCornerStyle = CornerStyle.Cut - }, - shapes = ButtonGroupDefaults.connectedTrailingButtonShapes(), - ) { - Icon( - painterResource( - if (actualCornerStyle == CornerStyle.Cut) R.drawable.check_20px else R.drawable.cut_corner_20px - ), - contentDescription = null, - modifier = Modifier - .padding(end = ToggleButtonDefaults.IconSpacing) - .size(ToggleButtonDefaults.IconSize) - ) - Text(stringResource(R.string.preference_cards_shape_cut)) - } - } - - - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - painterResource(R.drawable.rounded_corner_24px), - null, - modifier = Modifier - .padding(end = 8.dp) - .rotate(-90f) - ) - Slider( - modifier = Modifier - .weight(1f), - value = actualTopStart.toFloat(), - onValueChange = { - currentTopStart = it.toInt() - }, - valueRange = 0f..maxRadius.toFloat(), - steps = maxRadius + 1 - ) - Text( - text = actualTopStart.toString(), - modifier = Modifier.width(32.dp), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center, - ) - } - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - painterResource(R.drawable.rounded_corner_24px), - null, - modifier = Modifier.padding(end = 8.dp) - ) - Slider( - modifier = Modifier - .weight(1f), - value = actualTopEnd.toFloat(), - onValueChange = { - currentTopEnd = it.toInt() - }, - valueRange = 0f..maxRadius.toFloat(), - steps = maxRadius + 1, - ) - Text( - text = actualTopEnd.toString(), - modifier = Modifier.width(32.dp), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center, - ) - } - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - painterResource(R.drawable.rounded_corner_24px), - null, - modifier = Modifier - .padding(end = 8.dp) - .rotate(90f) - ) - Slider( - modifier = Modifier - .weight(1f), - value = actualBottomEnd.toFloat(), - onValueChange = { - currentBottomEnd = it.toInt() - }, - valueRange = 0f..maxRadius.toFloat(), - steps = maxRadius + 1, - ) - Text( - text = actualBottomEnd.toString(), - modifier = Modifier.width(32.dp), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center, - ) - } - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - painterResource(R.drawable.rounded_corner_24px), - null, - modifier = Modifier - .padding(end = 8.dp) - .rotate(180f) - ) - Slider( - modifier = Modifier - .weight(1f), - value = actualBottomStart.toFloat(), - onValueChange = { - currentBottomStart = it.toInt() - }, - valueRange = 0f..maxRadius.toFloat(), - steps = maxRadius + 1, - ) - Text( - text = actualBottomStart.toString(), - modifier = Modifier.width(32.dp), - style = MaterialTheme.typography.labelMedium, - textAlign = TextAlign.Center, - ) - - } - - HorizontalDivider( - modifier = Modifier.padding(top = 16.dp) + .padding(ButtonDefaults.IconSpacing) + .size(ButtonDefaults.IconSize) ) - - TextButton( - modifier = Modifier - .padding(top = 8.dp) - .align(Alignment.End), - contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, - onClick = { - currentTopStart = null - currentTopEnd = null - currentBottomEnd = null - currentBottomStart = null - currentCornerStyle = null - onValueChange(null) - } - ) { - Icon( - painterResource(R.drawable.restart_alt_20px), null, - modifier = Modifier - .padding(ButtonDefaults.IconSpacing) - .size(ButtonDefaults.IconSize) - ) - Text(stringResource(R.string.preference_restore_default)) - } + Text(stringResource(R.string.preference_restore_default)) } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/typography/TypographySettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/typography/TypographySettingsScreen.kt index 51306af5e..cb3292870 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/typography/TypographySettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/typography/TypographySettingsScreen.kt @@ -8,14 +8,20 @@ import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults @@ -758,47 +764,54 @@ private fun FontPreference( onClick = { showDialog = true }, ) - if (showDialog) { + DismissableBottomSheet( + expanded = showDialog, + onDismissRequest = { showDialog = false }, + ) { val fonts = remember { fontManager.getInstalledFonts() } - DismissableBottomSheet( - onDismissRequest = { showDialog = false }, + LazyColumn( + contentPadding = PaddingValues( + start = 16.dp, + top = 16.dp, + end = 16.dp, + bottom = 16.dp + WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding(), + ), + verticalArrangement = Arrangement.spacedBy(12.dp) ) { - LazyColumn(contentPadding = it, verticalArrangement = Arrangement.spacedBy(12.dp)) { - if (fonts.builtIn.isNotEmpty()) { - item { - FontPickerCategory( - preview.ExtraShort, - null, - fonts.builtIn, - onFontClick = { - onValueChange(it) - showDialog = false - }) - } + if (fonts.builtIn.isNotEmpty()) { + item { + FontPickerCategory( + preview.ExtraShort, + null, + fonts.builtIn, + onFontClick = { + onValueChange(it) + showDialog = false + }) } - if (fonts.deviceDefault.isNotEmpty()) { - item { - FontPickerCategory( - preview.ExtraShort, - stringResource(R.string.font_category_device_default), - fonts.deviceDefault, - onFontClick = { - onValueChange(it) - showDialog = false - }) - } + } + if (fonts.deviceDefault.isNotEmpty()) { + item { + FontPickerCategory( + preview.ExtraShort, + stringResource(R.string.font_category_device_default), + fonts.deviceDefault, + onFontClick = { + onValueChange(it) + showDialog = false + }) } - if (fonts.generic.isNotEmpty()) { - item { - FontPickerCategory( - preview.ExtraShort, - stringResource(R.string.font_category_generic), - fonts.generic, - onFontClick = { - onValueChange(it) - showDialog = false - }) - } + } + if (fonts.generic.isNotEmpty()) { + item { + FontPickerCategory( + preview.ExtraShort, + stringResource(R.string.font_category_generic), + fonts.generic, + onFontClick = { + onValueChange(it) + showDialog = false + }) } } } @@ -951,209 +964,210 @@ private fun TextStylePreference( }, onClick = { showDialog = true }, ) - if (showDialog) { - var fontFamily by remember(value) { - mutableStateOf(value?.fontFamily) - } - var fontSize by remember(value) { - mutableStateOf(value?.fontSize) - } - var lineHeight by remember(value) { - mutableStateOf(value?.lineHeight) - } - var weight by remember(value) { - mutableStateOf((value?.fontWeight as? ThemeFontWeight.Absolute)?.weight) - } - var letterSpacing by remember(value) { - mutableStateOf(value?.letterSpacing) - } + var fontFamily by remember(value) { + mutableStateOf(value?.fontFamily) + } + var fontSize by remember(value) { + mutableStateOf(value?.fontSize) + } + var lineHeight by remember(value) { + mutableStateOf(value?.lineHeight) + } + var weight by remember(value) { + mutableStateOf((value?.fontWeight as? ThemeFontWeight.Absolute)?.weight) + } + var letterSpacing by remember(value) { + mutableStateOf(value?.letterSpacing) + } - DismissableBottomSheet( - onDismissRequest = { - onValueChange( - ThemeTextStyle( - fontFamily = fontFamily, - fontSize = fontSize, - lineHeight = lineHeight, - fontWeight = weight?.let { ThemeFontWeight.Absolute(it) }, - letterSpacing = letterSpacing - ) + DismissableBottomSheet( + expanded = showDialog, + onDismissRequest = { + onValueChange( + ThemeTextStyle( + fontFamily = fontFamily, + fontSize = fontSize, + lineHeight = lineHeight, + fontWeight = weight?.let { ThemeFontWeight.Absolute(it) }, + letterSpacing = letterSpacing ) - showDialog = false - }, - ) { + ) + showDialog = false + }, + ) { - val actualFontFamily = fontFamily - ?: parentValue?.fontFamily - ?: defaultValue?.fontFamily - ?: defaultValueParent?.fontFamily!! - val actualFontSize = fontSize - ?: parentValue?.fontSize - ?: defaultValue?.fontSize - ?: defaultValueParent?.fontSize!! - val actualLineHeight = lineHeight - ?: parentValue?.lineHeight - ?: defaultValue?.lineHeight - ?: defaultValueParent?.lineHeight!! - val actualWeight = when { - weight != null -> FontWeight(weight!!) - parentValue?.fontWeight != null -> FontWeight(parentValue.fontWeight!!.weight) - defaultValue?.fontWeight is ThemeFontWeight.Absolute -> FontWeight((defaultValue.fontWeight as ThemeFontWeight.Absolute).weight) - defaultValue?.fontWeight is ThemeFontWeight.Relative && - defaultValueParent?.fontWeight is ThemeFontWeight.Absolute -> { - FontWeight( - (defaultValueParent.fontWeight as ThemeFontWeight.Absolute).weight + - (defaultValue.fontWeight as ThemeFontWeight.Relative).relativeWeight - ) - } - - else -> FontWeight.Normal + val actualFontFamily = fontFamily + ?: parentValue?.fontFamily + ?: defaultValue?.fontFamily + ?: defaultValueParent?.fontFamily!! + val actualFontSize = fontSize + ?: parentValue?.fontSize + ?: defaultValue?.fontSize + ?: defaultValueParent?.fontSize!! + val actualLineHeight = lineHeight + ?: parentValue?.lineHeight + ?: defaultValue?.lineHeight + ?: defaultValueParent?.lineHeight!! + val actualWeight = when { + weight != null -> FontWeight(weight!!) + parentValue?.fontWeight != null -> FontWeight(parentValue.fontWeight!!.weight) + defaultValue?.fontWeight is ThemeFontWeight.Absolute -> FontWeight((defaultValue.fontWeight as ThemeFontWeight.Absolute).weight) + defaultValue?.fontWeight is ThemeFontWeight.Relative && + defaultValueParent?.fontWeight is ThemeFontWeight.Absolute -> { + FontWeight( + (defaultValueParent.fontWeight as ThemeFontWeight.Absolute).weight + + (defaultValue.fontWeight as ThemeFontWeight.Relative).relativeWeight + ) } - val actualLetterSpacing = letterSpacing - ?: parentValue?.letterSpacing - ?: defaultValue?.letterSpacing - ?: defaultValueParent?.letterSpacing!! - Column( - modifier = Modifier.padding(it), + else -> FontWeight.Normal + } + val actualLetterSpacing = letterSpacing + ?: parentValue?.letterSpacing + ?: defaultValue?.letterSpacing + ?: defaultValueParent?.letterSpacing!! + + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(16.dp) + .navigationBarsPadding(), + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .heightIn(min = 200.dp), + contentAlignment = Alignment.Center, ) { - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 200.dp), - contentAlignment = Alignment.Center, - ) { - Text( - modifier = Modifier.fillMaxWidth(), - text = previewTexts.TwoLines, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.primary, - fontFamily = fontFamilyOf(context, fonts[actualFontFamily]), - fontSize = actualFontSize.sp, - lineHeight = actualLineHeight.em, - fontWeight = actualWeight, - letterSpacing = actualLetterSpacing.em, - ) - } - Row( - modifier = Modifier - .padding(vertical = 16.dp) - .fillMaxWidth() - .horizontalScroll(rememberScrollState()), - horizontalArrangement = Arrangement.spacedBy(16.dp), - ) { - for ((name, font) in fonts) { - val f = remember(font) { fontFamilyOf(context, font) } - Column( - modifier = Modifier - .width(56.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { + Text( + modifier = Modifier.fillMaxWidth(), + text = previewTexts.TwoLines, + textAlign = TextAlign.Center, + color = MaterialTheme.colorScheme.primary, + fontFamily = fontFamilyOf(context, fonts[actualFontFamily]), + fontSize = actualFontSize.sp, + lineHeight = actualLineHeight.em, + fontWeight = actualWeight, + letterSpacing = actualLetterSpacing.em, + ) + } + Row( + modifier = Modifier + .padding(vertical = 16.dp) + .fillMaxWidth() + .horizontalScroll(rememberScrollState()), + horizontalArrangement = Arrangement.spacedBy(16.dp), + ) { + for ((name, font) in fonts) { + val f = remember(font) { fontFamilyOf(context, font) } + Column( + modifier = Modifier + .width(56.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { - OutlinedIconToggleButton( - modifier = Modifier.size(56.dp), - checked = name == actualFontFamily, - onCheckedChange = { - if (it) fontFamily = name - }, - ) { - Text( - text = previewTexts.ExtraShort, - fontFamily = f, - style = MaterialTheme.typography.headlineSmall, - textAlign = TextAlign.Center, - ) - } + OutlinedIconToggleButton( + modifier = Modifier.size(56.dp), + checked = name == actualFontFamily, + onCheckedChange = { + if (it) fontFamily = name + }, + ) { Text( - text = name.capitalize(LocaleList.current), + text = previewTexts.ExtraShort, fontFamily = f, - style = MaterialTheme.typography.bodySmall, + style = MaterialTheme.typography.headlineSmall, textAlign = TextAlign.Center, - modifier = Modifier.width(56.dp), - maxLines = 1, - overflow = TextOverflow.MiddleEllipsis, ) } + Text( + text = name.capitalize(LocaleList.current), + fontFamily = f, + style = MaterialTheme.typography.bodySmall, + textAlign = TextAlign.Center, + modifier = Modifier.width(56.dp), + maxLines = 1, + overflow = TextOverflow.MiddleEllipsis, + ) } } - - SliderRow( - icon = R.drawable.format_bold_24px, - min = 100f, - max = 900f, - step = 100f, - value = actualWeight.weight.toFloat(), - onValueChange = { weight = it.toInt() }, - formatValue = { - it.roundToInt().toString() - } - ) - SliderRow( - icon = R.drawable.format_size_24px, - min = floor((defaultValue?.fontSize ?: defaultValueParent?.fontSize)!! / 2f), - max = ceil((defaultValue?.fontSize ?: defaultValueParent?.fontSize)!! * 2f), - value = actualFontSize.toFloat(), - onValueChange = { - fontSize = it.roundToInt() - }, - formatValue = { - it.roundToInt().toString() - } - ) - SliderRow( - icon = R.drawable.format_line_spacing_24px, - min = 0.5f, - max = 2f, - step = 0.05f, - value = actualLineHeight, - onValueChange = { lineHeight = it }, - formatValue = { - (it * 100).roundToInt().toString() + "%" - } - ) - SliderRow( - icon = R.drawable.format_letter_spacing_24px, - min = -0.25f, - max = 1f, - step = 0.01f, - value = actualLetterSpacing, - onValueChange = { letterSpacing = (it * 100f).roundToInt() / 100f }, - formatValue = { - (it * 100).roundToInt().toString() + "%" - } - ) - - HorizontalDivider( - modifier = Modifier.padding(top = 16.dp) - ) - - TextButton( - modifier = Modifier - .padding(top = 8.dp) - .align(Alignment.End), - contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, - onClick = { - fontFamily = null - fontSize = null - lineHeight = null - weight = null - letterSpacing = null - onValueChange(null) - } - ) { - Icon( - painterResource(R.drawable.restart_alt_20px), null, - modifier = Modifier - .padding(ButtonDefaults.IconSpacing) - .size(ButtonDefaults.IconSize) - ) - Text(stringResource(R.string.preference_restore_default)) - } } - } + SliderRow( + icon = R.drawable.format_bold_24px, + min = 100f, + max = 900f, + step = 100f, + value = actualWeight.weight.toFloat(), + onValueChange = { weight = it.toInt() }, + formatValue = { + it.roundToInt().toString() + } + ) + SliderRow( + icon = R.drawable.format_size_24px, + min = floor((defaultValue?.fontSize ?: defaultValueParent?.fontSize)!! / 2f), + max = ceil((defaultValue?.fontSize ?: defaultValueParent?.fontSize)!! * 2f), + value = actualFontSize.toFloat(), + onValueChange = { + fontSize = it.roundToInt() + }, + formatValue = { + it.roundToInt().toString() + } + ) + SliderRow( + icon = R.drawable.format_line_spacing_24px, + min = 0.5f, + max = 2f, + step = 0.05f, + value = actualLineHeight, + onValueChange = { lineHeight = it }, + formatValue = { + (it * 100).roundToInt().toString() + "%" + } + ) + SliderRow( + icon = R.drawable.format_letter_spacing_24px, + min = -0.25f, + max = 1f, + step = 0.01f, + value = actualLetterSpacing, + onValueChange = { letterSpacing = (it * 100f).roundToInt() / 100f }, + formatValue = { + (it * 100).roundToInt().toString() + "%" + } + ) + + HorizontalDivider( + modifier = Modifier.padding(top = 16.dp) + ) + + TextButton( + modifier = Modifier + .padding(top = 8.dp) + .align(Alignment.End), + contentPadding = ButtonDefaults.TextButtonWithIconContentPadding, + onClick = { + fontFamily = null + fontSize = null + lineHeight = null + weight = null + letterSpacing = null + onValueChange(null) + } + ) { + Icon( + painterResource(R.drawable.restart_alt_20px), null, + modifier = Modifier + .padding(ButtonDefaults.IconSpacing) + .size(ButtonDefaults.IconSize) + ) + Text(stringResource(R.string.preference_restore_default)) + } + } } }