mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
config clean up and updates (#522)
This commit is contained in:
parent
e328b5b5d9
commit
9442c1d510
11 changed files with 436 additions and 346 deletions
|
|
@ -0,0 +1,128 @@
|
|||
package com.geeksville.mesh.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Checkbox
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.twotone.KeyboardArrowDown
|
||||
import androidx.compose.material.icons.twotone.KeyboardArrowUp
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.geeksville.mesh.R
|
||||
|
||||
@Composable
|
||||
fun BitwisePreference(
|
||||
title: String,
|
||||
value: Int,
|
||||
enabled: Boolean,
|
||||
items: List<Pair<Int, String>>,
|
||||
onItemSelected: (Int) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var dropDownExpanded by remember { mutableStateOf(value = false) }
|
||||
|
||||
RegularPreference(
|
||||
title = title,
|
||||
subtitle = value.toString(),
|
||||
onClick = { dropDownExpanded = !dropDownExpanded },
|
||||
enabled = enabled,
|
||||
trailingIcon = if (dropDownExpanded) Icons.TwoTone.KeyboardArrowDown
|
||||
else Icons.TwoTone.KeyboardArrowUp,
|
||||
)
|
||||
|
||||
Box {
|
||||
DropdownMenu(
|
||||
expanded = dropDownExpanded,
|
||||
onDismissRequest = { dropDownExpanded = !dropDownExpanded },
|
||||
) {
|
||||
items.forEach { item ->
|
||||
DropdownMenuItem(
|
||||
onClick = { onItemSelected(value xor item.first) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
content = {
|
||||
Text(
|
||||
text = item.second,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Checkbox(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentWidth(Alignment.End),
|
||||
checked = value and item.first != 0,
|
||||
onCheckedChange = { onItemSelected(value xor item.first) },
|
||||
enabled = enabled,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.End
|
||||
) {
|
||||
Button(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
enabled = enabled,
|
||||
onClick = { onItemSelected(0) },
|
||||
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Red)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.clear_last_messages),
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = Color.Unspecified,
|
||||
)
|
||||
}
|
||||
Button(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
enabled = enabled,
|
||||
onClick = { dropDownExpanded = false },
|
||||
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Green)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.close),
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = Color.DarkGray,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun BitwisePreferencePreview() {
|
||||
BitwisePreference(
|
||||
title = "Settings",
|
||||
value = 3,
|
||||
enabled = true,
|
||||
items = listOf(1 to "TEST1", 2 to "TEST2"),
|
||||
onItemSelected = {}
|
||||
)
|
||||
}
|
||||
|
|
@ -6,6 +6,9 @@ import androidx.compose.material.DropdownMenu
|
|||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.twotone.KeyboardArrowDown
|
||||
import androidx.compose.material.icons.twotone.KeyboardArrowUp
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -33,15 +36,10 @@ fun <T> DropDownPreference(
|
|||
onClick = {
|
||||
dropDownExpanded = true
|
||||
},
|
||||
modifier = modifier
|
||||
.background(
|
||||
color = if (dropDownExpanded)
|
||||
MaterialTheme.colors.primary.copy(alpha = 0.2f)
|
||||
else
|
||||
Color.Unspecified
|
||||
),
|
||||
enabled = enabled,
|
||||
)
|
||||
trailingIcon = if (dropDownExpanded) Icons.TwoTone.KeyboardArrowDown
|
||||
else Icons.TwoTone.KeyboardArrowUp,
|
||||
)
|
||||
|
||||
Box {
|
||||
DropdownMenu(
|
||||
|
|
|
|||
|
|
@ -3,32 +3,111 @@ package com.geeksville.mesh.ui.components
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.twotone.Info
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
||||
@Composable // Default keyboardOptions: KeyboardType.Number, ImeAction.Send
|
||||
@Composable
|
||||
fun EditTextPreference(
|
||||
title: String,
|
||||
value: String,
|
||||
value: Int,
|
||||
enabled: Boolean,
|
||||
keyboardActions: KeyboardActions,
|
||||
onValueChanged: (String) -> Unit,
|
||||
onValueChanged: (Int) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var valueState by remember(value) { mutableStateOf(value.toUInt().toString()) }
|
||||
|
||||
EditTextPreference(
|
||||
title = title,
|
||||
value = value,
|
||||
value = valueState,
|
||||
enabled = enabled,
|
||||
isError = value.toUInt().toString() != valueState,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
keyboardType = KeyboardType.Number, imeAction = ImeAction.Send
|
||||
keyboardType = KeyboardType.Number, imeAction = ImeAction.Done
|
||||
),
|
||||
keyboardActions = keyboardActions,
|
||||
onValueChanged = onValueChanged,
|
||||
onValueChanged = {
|
||||
if (it.isEmpty()) valueState = it
|
||||
else it.toUIntOrNull()?.toInt()?.let { int ->
|
||||
valueState = it
|
||||
onValueChanged(int)
|
||||
}
|
||||
},
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditTextPreference(
|
||||
title: String,
|
||||
value: Float,
|
||||
enabled: Boolean,
|
||||
keyboardActions: KeyboardActions,
|
||||
onValueChanged: (Float) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var valueState by remember(value) { mutableStateOf(value.toString()) }
|
||||
|
||||
EditTextPreference(
|
||||
title = title,
|
||||
value = valueState,
|
||||
enabled = enabled,
|
||||
isError = value.toString() != valueState,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
keyboardType = KeyboardType.Number, imeAction = ImeAction.Done
|
||||
),
|
||||
keyboardActions = keyboardActions,
|
||||
onValueChanged = {
|
||||
if (it.isEmpty()) valueState = it
|
||||
else it.toFloatOrNull()?.let { float ->
|
||||
valueState = it
|
||||
onValueChanged(float)
|
||||
}
|
||||
},
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditTextPreference(
|
||||
title: String,
|
||||
value: Double,
|
||||
enabled: Boolean,
|
||||
keyboardActions: KeyboardActions,
|
||||
onValueChanged: (Double) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var valueState by remember(value) { mutableStateOf(value.toString()) }
|
||||
|
||||
EditTextPreference(
|
||||
title = title,
|
||||
value = valueState,
|
||||
enabled = enabled,
|
||||
isError = value.toString() != valueState,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
keyboardType = KeyboardType.Number, imeAction = ImeAction.Done
|
||||
),
|
||||
keyboardActions = keyboardActions,
|
||||
onValueChanged = {
|
||||
if (it.isEmpty()) valueState = it
|
||||
else it.toDoubleOrNull()?.let { double ->
|
||||
valueState = it
|
||||
onValueChanged(double)
|
||||
}
|
||||
},
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
|
@ -38,6 +117,7 @@ fun EditTextPreference(
|
|||
title: String,
|
||||
value: String,
|
||||
enabled: Boolean,
|
||||
isError: Boolean,
|
||||
keyboardOptions: KeyboardOptions,
|
||||
keyboardActions: KeyboardActions,
|
||||
onValueChanged: (String) -> Unit,
|
||||
|
|
@ -48,10 +128,14 @@ fun EditTextPreference(
|
|||
singleLine = true,
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
enabled = enabled,
|
||||
isError = isError,
|
||||
onValueChange = onValueChanged,
|
||||
label = { Text(title) },
|
||||
keyboardOptions = keyboardOptions,
|
||||
keyboardActions = keyboardActions,
|
||||
trailingIcon = {
|
||||
if (isError) Icon(Icons.TwoTone.Info, "Error", tint = MaterialTheme.colors.error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +144,7 @@ fun EditTextPreference(
|
|||
private fun EditTextPreferencePreview() {
|
||||
EditTextPreference(
|
||||
title = "Advanced Settings",
|
||||
value = "${UInt.MAX_VALUE}",
|
||||
value = UInt.MAX_VALUE.toInt(),
|
||||
enabled = true,
|
||||
keyboardActions = KeyboardActions {},
|
||||
onValueChanged = {}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,19 @@ package com.geeksville.mesh.ui.components
|
|||
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -21,13 +26,15 @@ fun RegularPreference(
|
|||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
trailingIcon: ImageVector? = null,
|
||||
) {
|
||||
RegularPreference(
|
||||
title = title,
|
||||
subtitle = AnnotatedString(text = subtitle),
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
enabled = enabled
|
||||
enabled = enabled,
|
||||
trailingIcon = trailingIcon,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -38,8 +45,9 @@ fun RegularPreference(
|
|||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
trailingIcon: ImageVector? = null,
|
||||
) {
|
||||
Column(
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
|
|
@ -47,17 +55,28 @@ fun RegularPreference(
|
|||
onClick = onClick,
|
||||
)
|
||||
.padding(all = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified,
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.medium),
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else MaterialTheme.colors.onSurface.copy(
|
||||
alpha = ContentAlpha.medium
|
||||
),
|
||||
)
|
||||
}
|
||||
if (trailingIcon != null) Icon(
|
||||
trailingIcon, "trailingIcon",
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentWidth(Alignment.End)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue