mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added even more tweaks to Dialog Layouts and UI
This commit is contained in:
1 parent
5842239e26
commit
e3955239f3
6 files changed
+219
-260
No files matched your search
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() }
|
||||
//}
|
||||
@@ -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<Float>,
|
||||
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<String>, dismiss: () -> Unit, save: (List<String>) -> Unit) {
|
||||
val maxWidthModifier = Modifier.fillMaxWidth(1f)
|
||||
fun RadiosDialog(modes: List<String>, cancel: () -> Unit, accept: (List<String>) -> Unit) {
|
||||
val selected = remember { mutableStateListOf<String>().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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
+37
-54
@@ -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<String>, 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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user