From f001cdb2a94813407d893a1c39c0aabc49ab5aa0 Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Sun, 13 Aug 2023 16:06:57 +0100 Subject: [PATCH] Added minor tweaks to Dialogs and layouts --- .../presentation/dialogs/FilterDialog.kt | 102 ++++++++++++------ .../presentation/dialogs/LocatorDialog.kt | 17 ++- .../presentation/dialogs/ModesDialog.kt | 52 ++++----- .../presentation/dialogs/PositionDialog.kt | 31 +++--- .../presentation/dialogs/TypesDialog.kt | 25 +++-- .../presentation/entries/EntriesScreen.kt | 2 +- app/src/main/res/drawable/ic_time.xml | 9 ++ app/src/main/res/values/strings.xml | 2 +- 8 files changed, 151 insertions(+), 89 deletions(-) create mode 100644 app/src/main/res/drawable/ic_time.xml diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt index 21f23650..2f01864f 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt @@ -21,60 +21,102 @@ 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.foundation.layout.size import androidx.compose.material3.ElevatedCard +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Slider +import androidx.compose.material3.SliderDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableDoubleStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.saveable.rememberSaveable 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.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.CardButton import com.rtbishop.look4sat.presentation.MainTheme @Preview(showBackground = true) @Composable private fun FilterDialogPreview() { - MainTheme { FilterDialog(8, 16.0, {}) { _, _ -> } } + MainTheme { FilterDialog(24, 16.0, {}) { _, _ -> } } } @Composable -fun FilterDialog(hours: Int, elevation: Double, toggle: () -> Unit, save: (Int, Double) -> Unit) { +fun FilterDialog(hours: Int, elevation: Double, dismiss: () -> Unit, save: (Int, Double) -> Unit) { val hoursValue = rememberSaveable { mutableIntStateOf(hours) } - val elevValue = rememberSaveable { mutableDoubleStateOf(elevation) } - Dialog(onDismissRequest = { toggle() }) { + val elevationValue = rememberSaveable { mutableIntStateOf(elevation.toInt()) } + val maxWidthModifier = Modifier.fillMaxWidth(1f) + Dialog(onDismissRequest = { dismiss() }) { ElevatedCard { - Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth(1f)) { - Text(text = "Filter passes", color = MaterialTheme.colorScheme.primary) - Text(text = "Show passes that occur within X hours") - OutlinedTextField(value = hoursValue.intValue.toString(), onValueChange = { newValue -> - val hoursAhead = try { - newValue.toInt() - } catch (exception: Exception) { - 12 - } - hoursValue.intValue = hoursAhead - }) - Text(text = "Show passes with max elevation above") - OutlinedTextField(value = elevValue.doubleValue.toString(), onValueChange = { newValue -> - val maxElevation = try { - newValue.toDouble() - } catch (exception: Exception) { - 16.0 - } - elevValue.doubleValue = maxElevation - }) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(6.dp), + modifier = maxWidthModifier.padding(12.dp) + ) { + Text(text = "Filter passes", fontSize = 20.sp, color = MaterialTheme.colorScheme.primary) + Row(horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.Bottom) { + Text(text = "Show passes within", fontSize = 18.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 = 20.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.primary + ) + } + Slider( + value = hoursValue.intValue.toFloat(), + onValueChange = { hoursValue.intValue = it.toInt() }, + valueRange = 1f..168f, + colors = SliderDefaults.colors(inactiveTrackColor = MaterialTheme.colorScheme.onSurfaceVariant) + ) + Row(horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.Bottom) { + Text(text = "Show passes above", fontSize = 18.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 = 20.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.primary + ) + } + Slider( + value = elevationValue.intValue.toFloat(), + onValueChange = { elevationValue.intValue = it.toInt() }, + valueRange = 0f..90f, + colors = SliderDefaults.colors(inactiveTrackColor = MaterialTheme.colorScheme.onSurfaceVariant) + ) Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) { - CardButton(onClick = { toggle() }, text = "Cancel") + CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) CardButton( onClick = { - save(hoursValue.intValue, elevValue.doubleValue) - toggle() - }, text = "Accept" + save(hoursValue.intValue, elevationValue.intValue.toDouble()) + dismiss() + }, text = stringResource(id = R.string.btn_accept) ) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/LocatorDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/LocatorDialog.kt index 4935d9a7..5c806cf8 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/LocatorDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/LocatorDialog.kt @@ -4,6 +4,7 @@ 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 @@ -15,6 +16,7 @@ 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.CardButton @@ -27,20 +29,25 @@ private fun LocatorDialogPreview() { } @Composable -fun LocatorDialog(qthLocator: String, hide: () -> Unit, save: (String) -> Unit) { +fun LocatorDialog(qthLocator: String, dismiss: () -> Unit, save: (String) -> Unit) { val locator = rememberSaveable { mutableStateOf(qthLocator) } - Dialog(onDismissRequest = { hide() }) { + val maxWidthModifier = Modifier.fillMaxWidth(1f) + Dialog(onDismissRequest = { dismiss() }) { ElevatedCard { - Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth(1f)) { + 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 = { hide() }, text = stringResource(id = R.string.btn_cancel)) + CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) CardButton( onClick = { save(locator.value) - hide() + dismiss() }, text = stringResource(id = R.string.btn_accept) ) } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/ModesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/ModesDialog.kt index 39a04347..5df47346 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/ModesDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/ModesDialog.kt @@ -5,11 +5,10 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth 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.items +import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.material3.Checkbox import androidx.compose.material3.ElevatedCard import androidx.compose.material3.MaterialTheme @@ -25,54 +24,49 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import com.rtbishop.look4sat.presentation.MainTheme -private val allModes = listOf( - "AFSK", "AFSK S-Net", "AFSK SALSAT", "AHRPT", "AM", "APT", "BPSK", "BPSK PMT-A3", - "CERTO", "CW", "DQPSK", "DSTAR", "DUV", "FFSK", "FM", "FMN", "FSK", "FSK AX.100 Mode 5", - "FSK AX.100 Mode 6", "FSK AX.25 G3RUH", "GFSK", "GFSK Rktr", "GMSK", "HRPT", "LoRa", - "LRPT", "LSB", "MFSK", "MSK", "MSK AX.100 Mode 5", "MSK AX.100 Mode 6", "OFDM", "OQPSK", - "PSK", "PSK31", "PSK63", "QPSK", "QPSK31", "QPSK63", "SSTV", "USB", "WSJT" -) - @Preview(showBackground = true) @Composable private fun ModesDialogPreview() { + val allModes = listOf( + "AFSK", "AFSK S-Net", "AFSK SALSAT", "AHRPT", "AM", "APT", "BPSK", "BPSK PMT-A3", + "CERTO", "CW", "DQPSK", "DSTAR", "DUV", "FFSK", "FM", "FMN", "FSK", "FSK AX.100 Mode 5", + "FSK AX.100 Mode 6", "FSK AX.25 G3RUH", "GFSK", "GFSK Rktr", "GMSK", "HRPT", "LoRa", + "LRPT", "LSB", "MFSK", "MSK", "MSK AX.100 Mode 5", "MSK AX.100 Mode 6", "OFDM", "OQPSK", + "PSK", "PSK31", "PSK63", "QPSK", "QPSK31", "QPSK63", "SSTV", "USB", "WSJT" + ) MainTheme { ModesDialog(allModes, listOf("AFSK", "AFSK S-Net"), {}) {} } } @Composable -fun ModesDialog(list: List, selected: List, toggle: () -> Unit, click: (String) -> Unit) { - Dialog(onDismissRequest = { toggle() }) { - ElevatedCard(modifier = Modifier.fillMaxHeight(0.9f)) { +fun ModesDialog(items: List, selected: List, dismiss: () -> Unit, select: (String) -> Unit) { + Dialog(onDismissRequest = { dismiss() }) { + ElevatedCard(modifier = Modifier.fillMaxHeight(0.75f)) { LazyVerticalGrid( - columns = GridCells.Fixed(1), + columns = GridCells.Adaptive(160.dp), modifier = Modifier.background(MaterialTheme.colorScheme.background), horizontalArrangement = Arrangement.spacedBy(1.dp), verticalArrangement = Arrangement.spacedBy(1.dp) ) { - items(list) { mode -> + itemsIndexed(items) { index, item -> Surface { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier .background(MaterialTheme.colorScheme.surface) - .fillMaxWidth() - .clickable { - click(mode) - toggle() - }) { + .clickable { select(item) }) { Text( - text = mode, - modifier = Modifier - .padding(start = 8.dp, end = 6.dp) - .weight(1f), + text = "$index).", + modifier = Modifier.padding(start = 12.dp, end = 6.dp), fontWeight = FontWeight.Normal, + color = MaterialTheme.colorScheme.secondary + ) + Text( + text = item, + modifier = Modifier.weight(1f), + fontWeight = FontWeight.Medium, maxLines = 1, overflow = TextOverflow.Ellipsis ) - Checkbox( - checked = selected.contains(mode), - onCheckedChange = null, - modifier = Modifier.padding(6.dp) - ) + Checkbox(checked = selected.contains(item), onCheckedChange = { select(item) }) } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/PositionDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/PositionDialog.kt index 8863b613..c0bc45e0 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/PositionDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/PositionDialog.kt @@ -4,6 +4,7 @@ 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 @@ -15,6 +16,7 @@ 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.CardButton @@ -27,12 +29,17 @@ private fun PositionDialogPreview() { } @Composable -fun PositionDialog(lat: Double, lon: Double, hide: () -> Unit, save: (Double, Double) -> Unit) { +fun PositionDialog(lat: Double, lon: Double, dismiss: () -> Unit, save: (Double, Double) -> Unit) { val latValue = rememberSaveable { mutableStateOf(lat.toString()) } val lonValue = rememberSaveable { mutableStateOf(lon.toString()) } - Dialog(onDismissRequest = { hide() }) { + val maxWidthModifier = Modifier.fillMaxWidth(1f) + Dialog(onDismissRequest = { dismiss() }) { ElevatedCard { - Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth(1f)) { + 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 ) @@ -41,9 +48,9 @@ fun PositionDialog(lat: Double, lon: Double, hide: () -> Unit, save: (Double, Do 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 = { hide() }, text = stringResource(id = R.string.btn_cancel)) + CardButton(onClick = { dismiss() }, text = stringResource(id = R.string.btn_cancel)) CardButton( - onClick = { saveValues(latValue.value, lonValue.value, hide, save) }, + onClick = { saveValues(latValue.value, lonValue.value, dismiss, save) }, text = stringResource(id = R.string.btn_accept) ) } @@ -52,11 +59,11 @@ fun PositionDialog(lat: Double, lon: Double, hide: () -> Unit, save: (Double, Do } } -private fun saveValues(lat: String, lon: String, hide: () -> Unit, save: (Double, Double) -> Unit) { - val latValue = lat.toDoubleOrNull() ?: 0.0 - val lonValue = lon.toDoubleOrNull() ?: 0.0 - val newLat = if (latValue > 90) 90.0 else if (latValue < -90) -90.0 else latValue - val newLon = if (lonValue > 180) 180.0 else if (lonValue < -180) -180.0 else lonValue - save(newLat, newLon) - hide() +private fun saveValues(latValue: String, lonValue: String, dismiss: () -> Unit, 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() } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/TypesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/TypesDialog.kt index 55ea0c05..c01d6bd1 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/TypesDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/TypesDialog.kt @@ -6,8 +6,9 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed +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.MaterialTheme import androidx.compose.material3.RadioButton @@ -31,23 +32,25 @@ private fun TypeDialogPreview() { } @Composable -fun TypesDialog(list: List, selected: String, toggle: () -> Unit, click: (String) -> Unit) { +fun TypesDialog(items: List, selected: String, dismiss: () -> Unit, select: (String) -> Unit) { val clickAction = { type: String -> - click(type) - toggle() + select(type) + dismiss() } - Dialog(onDismissRequest = { toggle() }) { + Dialog(onDismissRequest = { dismiss() }) { ElevatedCard(modifier = Modifier.fillMaxHeight(0.75f)) { - LazyColumn( + LazyVerticalGrid( + columns = GridCells.Adaptive(160.dp), modifier = Modifier.background(MaterialTheme.colorScheme.background), + horizontalArrangement = Arrangement.spacedBy(1.dp), verticalArrangement = Arrangement.spacedBy(1.dp) ) { - itemsIndexed(list) { index, type -> + itemsIndexed(items) { index, item -> Surface { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier .background(MaterialTheme.colorScheme.surface) - .clickable { clickAction(type) }) { + .clickable { clickAction(item) }) { Text( text = "$index).", modifier = Modifier.padding(start = 12.dp, end = 6.dp), @@ -55,13 +58,13 @@ fun TypesDialog(list: List, selected: String, toggle: () -> Unit, click: color = MaterialTheme.colorScheme.secondary ) Text( - text = type, + text = item, modifier = Modifier.weight(1f), fontWeight = FontWeight.Medium, maxLines = 1, overflow = TextOverflow.Ellipsis ) - RadioButton(selected = type == selected, onClick = { clickAction(type) }) + RadioButton(selected = item == selected, onClick = { clickAction(item) }) } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt index c6e9138f..e0ebc897 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt @@ -50,7 +50,7 @@ fun EntriesScreen(uiState: EntriesUiState, navToPasses: () -> Unit) { val showDialog = rememberSaveable { mutableStateOf(false) } val toggleDialog = { showDialog.value = showDialog.value.not() } if (showDialog.value) { - TypesDialog(list = uiState.typesList, selected = uiState.currentType, toggleDialog) { + TypesDialog(items = uiState.typesList, selected = uiState.currentType, toggleDialog) { uiState.takeAction(EntriesUiAction.SelectType(it)) } } diff --git a/app/src/main/res/drawable/ic_time.xml b/app/src/main/res/drawable/ic_time.xml new file mode 100644 index 00000000..33f9a689 --- /dev/null +++ b/app/src/main/res/drawable/ic_time.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3f734d64..f18a99a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,7 +50,7 @@ Show passes with max elevation above QTH locator settings - Set station\'s position using your locator + Set station\'s position using locator QTH Select modulation type