From e3955239f3184aa75245956f59d517b035e1c38f Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Sun, 15 Dec 2024 13:26:35 +0000 Subject: [PATCH] Added even more tweaks to Dialog Layouts and UI --- .../look4sat/presentation/MainTheme.kt | 36 ++- .../presentation/components/Common.kt | 30 +++ .../presentation/passes/PassesDialog.kt | 245 ++++++++---------- .../presentation/passes/PassesScreen.kt | 4 +- .../satellites/SatellitesDialog.kt | 91 +++---- .../presentation/settings/SettingsDialog.kt | 73 +----- 6 files changed, 219 insertions(+), 260 deletions(-) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt index 45f82645..0caa88d5 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt @@ -9,7 +9,9 @@ import androidx.compose.material3.Typography import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.TextStyle @@ -19,19 +21,41 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.view.WindowCompat +val LocalSpacing = compositionLocalOf { Spacing } +//val MaterialTheme.spacing: Spacing +// @Composable @ReadOnlyComposable get() = Spacing + +data object SpacingDefaults { + internal const val EXTRA_SMALL = 4 + internal const val SMALL = 6 + internal const val MEDIUM = 8 + internal const val LARGE = 12 + internal const val EXTRA_LARGE = 16 +} + +data object Spacing { + val extraSmall = SpacingDefaults.EXTRA_SMALL.dp + val small = SpacingDefaults.SMALL.dp + val medium = SpacingDefaults.MEDIUM.dp + val large = SpacingDefaults.LARGE.dp + val extraLarge = SpacingDefaults.EXTRA_LARGE.dp +} + @Composable fun MainTheme(isDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { val view = LocalView.current if (view.isInEditMode) { MaterialTheme(darkScheme, shapes, typography, content) } else { - val colorScheme = if (isDarkTheme) darkScheme else lightScheme - SideEffect { - val window = (view.context as ComponentActivity).window - val insetsController = WindowCompat.getInsetsController(window, view) - insetsController.isAppearanceLightStatusBars = false + CompositionLocalProvider(LocalSpacing provides Spacing) { + val colorScheme = if (isDarkTheme) darkScheme else lightScheme + SideEffect { + val window = (view.context as ComponentActivity).window + val insetsController = WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = false + } + MaterialTheme(colorScheme, shapes, typography, content) } - MaterialTheme(colorScheme, shapes, typography, content) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt index 760da81a..3cb976da 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt @@ -38,10 +38,12 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.predict.NearEarthObject import com.rtbishop.look4sat.domain.predict.OrbitalData import com.rtbishop.look4sat.domain.predict.OrbitalPass +import com.rtbishop.look4sat.presentation.LocalSpacing import com.rtbishop.look4sat.presentation.MainTheme import java.text.SimpleDateFormat import java.util.Date @@ -253,6 +255,34 @@ fun getDefaultPass(): OrbitalPass { return OrbitalPass(0L, 0.0, 0L, 0.0, 0, 0.0, satellite, 0f) } +@Composable +fun SharedDialog( + title: String, onCancel: () -> Unit, onAccept: () -> Unit, content: @Composable () -> Unit +) { + val padding = LocalSpacing.current.extraLarge + Dialog(onDismissRequest = { onCancel() }) { + ElevatedCard { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(padding) + ) { + Text( + text = title, + fontSize = 18.sp, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(start = padding, top = padding, end = padding) + ) + content() + Row(modifier = Modifier.padding(start = padding, bottom = padding, end = padding)) { + CardButton(onClick = onCancel, text = stringResource(id = R.string.btn_cancel)) + Spacer(modifier = Modifier.weight(1f)) + CardButton(onClick = onAccept, text = stringResource(id = R.string.btn_accept)) + } + } + } + } +} + //fun Modifier.onClick(onClick: () -> Unit): Modifier = composed { // clickable(remember { MutableInteractionSource() }, null) { onClick() } //} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesDialog.kt index 960c4d70..31137168 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesDialog.kt @@ -22,16 +22,13 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column 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.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.material3.Checkbox -import androidx.compose.material3.ElevatedCard import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -39,22 +36,22 @@ import androidx.compose.material3.Slider import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableDoubleStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.Dialog import com.rtbishop.look4sat.R +import com.rtbishop.look4sat.presentation.LocalSpacing import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.components.CardButton +import com.rtbishop.look4sat.presentation.components.SharedDialog private val allModes = listOf( "AFSK", "AFSK S-Net", "AFSK SALSAT", "AHRPT", "AM", "APT", "BPSK", "BPSK PMT-A3", @@ -64,86 +61,75 @@ private val allModes = listOf( "PSK", "PSK31", "PSK63", "QPSK", "QPSK31", "QPSK63", "SSTV", "USB", "WSJT" ) -@Preview(showBackground = true) +@Preview @Composable private fun PassesDialogPreview() { MainTheme { PassesDialog(24, 16.0, {}) { _, _ -> } } } @Composable -fun PassesDialog(hours: Int, elev: Double, dismiss: () -> Unit, save: (Int, Double) -> Unit) { - val maxWidthModifier = Modifier.fillMaxWidth() +fun PassesDialog(hours: Int, elevation: Double, cancel: () -> Unit, accept: (Int, Double) -> Unit) { val hoursValue = remember { mutableIntStateOf(hours) } - val elevationValue = remember { mutableIntStateOf(elev.toInt()) } - Dialog(onDismissRequest = { dismiss() }) { - ElevatedCard { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(6.dp), - modifier = maxWidthModifier.padding(16.dp) - ) { - Text(text = "Passes", fontSize = 18.sp, color = MaterialTheme.colorScheme.primary) - Spacer(modifier = Modifier.height(8.dp)) - Row(horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.Bottom) { - Text(text = "Show passes above", fontSize = 16.sp, modifier = Modifier.weight(1f)) - Icon( - painter = painterResource(id = R.drawable.ic_elevation), - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier - .size(20.dp) - .padding(bottom = 4.dp) - ) - Text( - text = "${elevationValue.intValue}°", - fontSize = 18.sp, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.primary - ) - } - Slider( - value = elevationValue.intValue.toFloat(), - onValueChange = { elevationValue.intValue = it.toInt() }, - valueRange = 0f..60f - ) - Spacer(modifier = Modifier.height(8.dp)) - Row(horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.Bottom) { - Text(text = "Show passes within", fontSize = 16.sp, modifier = Modifier.weight(1f)) - Icon( - painter = painterResource(id = R.drawable.ic_time), - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier - .size(20.dp) - .padding(bottom = 4.dp) - ) - Text( - text = "${hoursValue.intValue}h", - fontSize = 18.sp, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.primary - ) - } - Slider( - value = hoursValue.intValue.toFloat(), - onValueChange = { hoursValue.intValue = it.toInt() }, - valueRange = 1f..240f - ) - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = maxWidthModifier - ) { - CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) - CardButton( - onClick = { - save(hoursValue.intValue, elevationValue.intValue.toDouble()) - dismiss() - }, text = stringResource(id = R.string.btn_accept) - ) - } - } + val elevationValueNew = remember { mutableDoubleStateOf(elevation) } + val onAccept = { + accept(hoursValue.intValue, elevationValueNew.doubleValue).also { cancel() } + } + SharedDialog(title = "Passes", onCancel = cancel, onAccept = onAccept) { + SliderRow( + title = "Show passes above", + value = elevationValueNew.doubleValue, + valuePostfix = "°", + valueResId = R.drawable.ic_elevation, + valueRange = 0f..60f + ) { elevationValueNew.doubleValue = it.toDouble() } + SliderRow( + title = "Show passes within", + value = hoursValue.intValue.toDouble(), + valuePostfix = "h", + valueResId = R.drawable.ic_time, + valueRange = 1f..240f + ) { hoursValue.intValue = it.toInt() } + } +} + +@Composable +private fun SliderRow( + title: String, + value: Double, + valuePostfix: String, + valueResId: Int, + valueRange: ClosedFloatingPointRange, + onChange: (Float) -> Unit +) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(LocalSpacing.current.medium), + modifier = Modifier.padding(horizontal = LocalSpacing.current.extraLarge) + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(LocalSpacing.current.medium), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = title, + fontSize = 16.sp, + modifier = Modifier.weight(1f), + color = MaterialTheme.colorScheme.onSurface + ) + Icon( + painter = painterResource(id = valueResId), + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(20.dp) + ) + Text( + text = "${value.toInt()}$valuePostfix", + fontSize = 18.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.primary + ) } + Slider(value = value.toFloat(), onValueChange = onChange, valueRange = valueRange) } } @@ -154,69 +140,52 @@ private fun RadiosDialogPreview() { } @Composable -fun RadiosDialog(modes: List, dismiss: () -> Unit, save: (List) -> Unit) { - val maxWidthModifier = Modifier.fillMaxWidth(1f) +fun RadiosDialog(modes: List, cancel: () -> Unit, accept: (List) -> Unit) { val selected = remember { mutableStateListOf().apply { addAll(modes) } } - val select = { mode: String -> if (selected.contains(mode)) selected.remove(mode) else selected.add(mode) } - Dialog(onDismissRequest = { dismiss() }) { - ElevatedCard { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(16.dp), - modifier = maxWidthModifier.padding(vertical = 16.dp) - ) { - Text(text = "Radios", fontSize = 18.sp, color = MaterialTheme.colorScheme.primary) - LazyVerticalGrid( - columns = GridCells.Fixed(1), - modifier = Modifier - .background(MaterialTheme.colorScheme.background) - .weight(1f), - horizontalArrangement = Arrangement.spacedBy(1.dp), - verticalArrangement = Arrangement.spacedBy(1.dp) - ) { - item { HorizontalDivider(thickness = 0.dp, color = MaterialTheme.colorScheme.surface) } - itemsIndexed(allModes) { index, item -> - Surface { - Row(verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .background(MaterialTheme.colorScheme.surface) - .clickable { select(item) }) { - Text( - text = "$index).", - modifier = Modifier.padding(start = 8.dp, end = 6.dp), - fontWeight = FontWeight.Normal, - color = MaterialTheme.colorScheme.primary - ) - Text( - text = item, - modifier = Modifier.weight(1f), - fontWeight = FontWeight.Medium, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Checkbox( - checked = selected.contains(item), - onCheckedChange = null, - modifier = Modifier.padding(8.dp) - ) - } - } + val select = { mode: String -> + if (selected.contains(mode)) selected.remove(mode) else selected.add(mode) + } + val onAccept = { accept(selected.toList()).also { cancel() } } + SharedDialog(title = "Radios", onCancel = cancel, onAccept = onAccept) { + LazyVerticalGrid( + columns = GridCells.Fixed(1), + modifier = Modifier + .fillMaxHeight(0.69f) + .background(MaterialTheme.colorScheme.background), + horizontalArrangement = Arrangement.spacedBy(1.dp), + verticalArrangement = Arrangement.spacedBy(1.dp) + ) { + item { HorizontalDivider(color = MaterialTheme.colorScheme.surface) } + itemsIndexed(allModes) { index, item -> + Surface { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .background(MaterialTheme.colorScheme.surface) + .clickable { select(item) } + ) { + Text( + text = "${index + 1}).", + modifier = Modifier.padding(start = 16.dp, end = 8.dp), + fontWeight = FontWeight.Normal, + color = MaterialTheme.colorScheme.primary + ) + Text( + text = item, + modifier = Modifier.weight(1f), + fontWeight = FontWeight.Medium, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Checkbox( + checked = selected.contains(item), + onCheckedChange = null, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) + ) } - item { HorizontalDivider(thickness = 24.dp, color = MaterialTheme.colorScheme.surface) } - } - Row( - horizontalArrangement = Arrangement.SpaceBetween, - modifier = maxWidthModifier.padding(horizontal = 16.dp) - ) { - CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) - CardButton( - onClick = { - save(selected.toList()) - dismiss() - }, text = stringResource(id = R.string.btn_accept) - ) } } + item { HorizontalDivider(color = MaterialTheme.colorScheme.surface) } } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt index 3caed898..c566564d 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt @@ -71,12 +71,12 @@ private fun PassesScreen(uiState: PassesState, navigateToRadar: (Int, Long) -> U val showPassesDialog = { uiState.takeAction(PassesAction.TogglePassesDialog) } val showRadiosDialog = { uiState.takeAction(PassesAction.ToggleRadiosDialog) } if (uiState.isPassesDialogShown) { - PassesDialog(hours = uiState.hours, elev = uiState.elevation, dismiss = showPassesDialog) { hours, elevation -> + PassesDialog(hours = uiState.hours, elevation = uiState.elevation, cancel = showPassesDialog) { hours, elevation -> uiState.takeAction(PassesAction.FilterPasses(hours, elevation)) } } if (uiState.isRadiosDialogShown) { - RadiosDialog(modes = uiState.modes, dismiss = showRadiosDialog) { modes -> + RadiosDialog(modes = uiState.modes, cancel = showRadiosDialog) { modes -> uiState.takeAction(PassesAction.FilterRadios(modes)) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt index 7a11c877..6d2dcbde 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt @@ -3,29 +3,25 @@ package com.rtbishop.look4sat.presentation.satellites import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.itemsIndexed -import androidx.compose.material3.ElevatedCard +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.Dialog import com.rtbishop.look4sat.presentation.MainTheme +import com.rtbishop.look4sat.presentation.components.SharedDialog @Preview(showBackground = true) @Composable @@ -38,55 +34,42 @@ private fun TypeDialogPreview() { fun TypesDialog( items: List, selected: String, dismiss: () -> Unit, select: (String) -> Unit ) { - val height = LocalConfiguration.current.screenHeightDp - Dialog(onDismissRequest = { dismiss() }) { - ElevatedCard { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.heightIn(max = height.times(0.80).dp) - ) { - Text( - text = "Select category", - fontSize = 18.sp, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(top = 8.dp, bottom = 4.dp) - ) - LazyVerticalGrid( - columns = GridCells.Adaptive(240.dp), - modifier = Modifier.background(MaterialTheme.colorScheme.background), - horizontalArrangement = Arrangement.spacedBy(1.dp), - verticalArrangement = Arrangement.spacedBy(1.dp) - ) { - itemsIndexed(items) { index, item -> - Row(verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .background(MaterialTheme.colorScheme.surface) - .clickable { select(item) }) { - Text( - text = "$index).", - modifier = Modifier.padding(start = 12.dp, end = 6.dp), - fontWeight = FontWeight.Normal, - color = MaterialTheme.colorScheme.primary - ) - Text( - text = item, - modifier = Modifier.weight(1f), - fontWeight = FontWeight.Medium, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - RadioButton( - selected = item == selected, - onClick = null, - modifier = Modifier.padding( - start = 8.dp, top = 8.dp, end = 12.dp, bottom = 8.dp - ) - ) - } - } + SharedDialog(title = "Select category", onCancel = dismiss, onAccept = {}) { + LazyVerticalGrid( + columns = GridCells.Adaptive(240.dp), + modifier = Modifier + .fillMaxHeight(0.69f) + .background(MaterialTheme.colorScheme.background), + horizontalArrangement = Arrangement.spacedBy(1.dp), + verticalArrangement = Arrangement.spacedBy(1.dp) + ) { + item { HorizontalDivider(color = MaterialTheme.colorScheme.surface) } + itemsIndexed(items) { index, item -> + Row(verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .background(MaterialTheme.colorScheme.surface) + .clickable { select(item) }) { + Text( + text = "${index + 1}).", + modifier = Modifier.padding(start = 16.dp, end = 8.dp), + fontWeight = FontWeight.Normal, + color = MaterialTheme.colorScheme.primary + ) + Text( + text = item, + modifier = Modifier.weight(1f), + fontWeight = FontWeight.Medium, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + RadioButton( + selected = item == selected, + onClick = null, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) + ) } } + item { HorizontalDivider(color = MaterialTheme.colorScheme.surface) } } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsDialog.kt index c1064f9e..51c46fb9 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsDialog.kt @@ -1,26 +1,15 @@ package com.rtbishop.look4sat.presentation.settings -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ElevatedCard -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog import com.rtbishop.look4sat.R import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.components.CardButton +import com.rtbishop.look4sat.presentation.components.SharedDialog @Preview(showBackground = true) @Composable @@ -32,40 +21,22 @@ private fun PositionDialogPreview() { fun PositionDialog(lat: Double, lon: Double, dismiss: () -> Unit, save: (Double, Double) -> Unit) { val latValue = rememberSaveable { mutableStateOf(lat.toString()) } val lonValue = rememberSaveable { mutableStateOf(lon.toString()) } - val maxWidthModifier = Modifier.fillMaxWidth(1f) - Dialog(onDismissRequest = { dismiss() }) { - ElevatedCard { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(12.dp), - modifier = maxWidthModifier.padding(12.dp) - ) { - Text( - text = stringResource(id = R.string.position_title), color = MaterialTheme.colorScheme.primary - ) - Text(text = stringResource(id = R.string.position_lat_text)) - OutlinedTextField(value = latValue.value, onValueChange = { latValue.value = it }) - Text(text = stringResource(id = R.string.position_lon_text)) - OutlinedTextField(value = lonValue.value, onValueChange = { lonValue.value = it }) - Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) { - CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) - CardButton( - onClick = { saveValues(latValue.value, lonValue.value, dismiss, save) }, - text = stringResource(id = R.string.btn_accept) - ) - } - } - } + val titleText = stringResource(id = R.string.position_title) + val onAccept = { saveValues(latValue.value, lonValue.value, save).also { dismiss() } } + SharedDialog(title = titleText, onCancel = dismiss, onAccept = onAccept) { + Text(text = stringResource(id = R.string.position_lat_text)) + OutlinedTextField(value = latValue.value, onValueChange = { latValue.value = it }) + Text(text = stringResource(id = R.string.position_lon_text)) + OutlinedTextField(value = lonValue.value, onValueChange = { lonValue.value = it }) } } -private fun saveValues(latValue: String, lonValue: String, dismiss: () -> Unit, save: (Double, Double) -> Unit) { +private fun saveValues(latValue: String, lonValue: String, save: (Double, Double) -> Unit) { val latitude = latValue.toDoubleOrNull() ?: 0.0 val longitude = lonValue.toDoubleOrNull() ?: 0.0 val newLatitude = if (latitude > 90) 90.0 else if (latitude < -90) -90.0 else latitude val newLongitude = if (longitude > 180) 180.0 else if (longitude < -180) -180.0 else longitude save(newLatitude, newLongitude) - dismiss() } @Preview(showBackground = true) @@ -77,27 +48,9 @@ private fun LocatorDialogPreview() { @Composable fun LocatorDialog(qthLocator: String, dismiss: () -> Unit, save: (String) -> Unit) { val locator = rememberSaveable { mutableStateOf(qthLocator) } - val maxWidthModifier = Modifier.fillMaxWidth(1f) - Dialog(onDismissRequest = { dismiss() }) { - ElevatedCard { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(12.dp), - modifier = maxWidthModifier.padding(12.dp) - ) { - Text(text = stringResource(id = R.string.locator_title), color = MaterialTheme.colorScheme.primary) - Text(text = stringResource(id = R.string.locator_text)) - OutlinedTextField(value = locator.value, onValueChange = { locator.value = it }) - Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) { - CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) - CardButton( - onClick = { - save(locator.value) - dismiss() - }, text = stringResource(id = R.string.btn_accept) - ) - } - } - } + val onAccept = { save(locator.value).also { dismiss() } } + SharedDialog(title = "Radios", onCancel = dismiss, onAccept = onAccept) { + Text(text = stringResource(id = R.string.locator_text)) + OutlinedTextField(value = locator.value, onValueChange = { locator.value = it }) } }