sforkowany z mirror/meshtastic-android
feat: add RemoteHardwarePin config
rodzic
8bc628de9f
commit
1fe669fb73
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.Icon
|
||||
|
@ -20,21 +21,27 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.geeksville.mesh.ModuleConfigProtos.RemoteHardwarePin
|
||||
import com.geeksville.mesh.ModuleConfigProtos.RemoteHardwarePinType
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.copy
|
||||
import com.geeksville.mesh.remoteHardwarePin
|
||||
|
||||
@Composable
|
||||
fun EditListPreference(
|
||||
inline fun <reified T> EditListPreference(
|
||||
title: String,
|
||||
list: List<Int>,
|
||||
list: List<T>,
|
||||
maxCount: Int,
|
||||
enabled: Boolean,
|
||||
keyboardActions: KeyboardActions,
|
||||
onValuesChanged: (List<Int>) -> Unit,
|
||||
crossinline onValuesChanged: (List<T>) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val listState = remember(list) { mutableStateListOf<Int>().apply { addAll(list) } }
|
||||
val listState = remember(list) { mutableStateListOf<T>().apply { addAll(list) } }
|
||||
|
||||
Column(modifier = modifier) {
|
||||
Text(
|
||||
|
@ -44,13 +51,14 @@ fun EditListPreference(
|
|||
color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified,
|
||||
)
|
||||
listState.forEachIndexed { index, value ->
|
||||
EditTextPreference(
|
||||
// handle lora.ignoreIncoming: List<Int>
|
||||
if (value is Int) EditTextPreference(
|
||||
title = "${index + 1}/$maxCount",
|
||||
value = value,
|
||||
enabled = enabled,
|
||||
keyboardActions = keyboardActions,
|
||||
onValueChanged = {
|
||||
listState[index] = it
|
||||
listState[index] = it as T
|
||||
onValuesChanged(listState)
|
||||
},
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
|
@ -69,10 +77,75 @@ fun EditListPreference(
|
|||
}
|
||||
}
|
||||
)
|
||||
|
||||
// handle remoteHardware.availablePins: List<RemoteHardwarePin>
|
||||
if (value is RemoteHardwarePin) {
|
||||
EditTextPreference(
|
||||
title = "GPIO pin",
|
||||
value = value.gpioPin,
|
||||
enabled = enabled,
|
||||
keyboardActions = keyboardActions,
|
||||
onValueChanged = {
|
||||
if (it in 0..255) {
|
||||
listState[index] = value.copy { gpioPin = it } as T
|
||||
onValuesChanged(listState)
|
||||
}
|
||||
},
|
||||
)
|
||||
EditTextPreference(
|
||||
title = "Name",
|
||||
value = value.name,
|
||||
maxSize = 14, // name max_size:15
|
||||
enabled = enabled,
|
||||
isError = false,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
keyboardType = KeyboardType.Text, imeAction = ImeAction.Done
|
||||
),
|
||||
keyboardActions = keyboardActions,
|
||||
onValueChanged = {
|
||||
listState[index] = value.copy { name = it } as T
|
||||
onValuesChanged(listState)
|
||||
},
|
||||
trailingIcon = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
listState.removeAt(index)
|
||||
onValuesChanged(listState)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.TwoTone.Close,
|
||||
stringResource(R.string.delete),
|
||||
modifier = Modifier.wrapContentSize(),
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
DropDownPreference(
|
||||
title = "Type",
|
||||
enabled = enabled,
|
||||
items = RemoteHardwarePinType.values()
|
||||
.filter { it != RemoteHardwarePinType.UNRECOGNIZED }
|
||||
.map { it to it.name },
|
||||
selectedItem = value.type,
|
||||
onItemSelected = {
|
||||
listState[index] = value.copy { type = it } as T
|
||||
onValuesChanged(listState)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
OutlinedButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = { listState.add(listState.size, 0) },
|
||||
onClick = {
|
||||
// Add element based on the type T
|
||||
val newElement = when (T::class) {
|
||||
Int::class -> 0 as T
|
||||
RemoteHardwarePin::class -> remoteHardwarePin {} as T
|
||||
else -> throw IllegalArgumentException("Unsupported type: ${T::class}")
|
||||
}
|
||||
listState.add(listState.size, newElement)
|
||||
},
|
||||
enabled = maxCount > listState.size,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
disabledContentColor = MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled)
|
||||
|
@ -84,12 +157,28 @@ fun EditListPreference(
|
|||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun EditListPreferencePreview() {
|
||||
EditListPreference(
|
||||
title = "Ignore incoming",
|
||||
list = listOf(12345,67890),
|
||||
maxCount = 4,
|
||||
enabled = true,
|
||||
keyboardActions = KeyboardActions {},
|
||||
onValuesChanged = { },
|
||||
)
|
||||
Column {
|
||||
EditListPreference(
|
||||
title = "Ignore incoming",
|
||||
list = listOf(12345, 67890),
|
||||
maxCount = 4,
|
||||
enabled = true,
|
||||
keyboardActions = KeyboardActions {},
|
||||
onValuesChanged = {},
|
||||
)
|
||||
EditListPreference(
|
||||
title = "Available pins",
|
||||
list = listOf(
|
||||
remoteHardwarePin {
|
||||
gpioPin = 12
|
||||
name = "Front door"
|
||||
type = RemoteHardwarePinType.DIGITAL_READ
|
||||
},
|
||||
),
|
||||
maxCount = 4,
|
||||
enabled = true,
|
||||
keyboardActions = KeyboardActions {},
|
||||
onValuesChanged = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.geeksville.mesh.ui.components.config
|
|||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
@ -14,6 +15,7 @@ import androidx.compose.ui.platform.LocalFocusManager
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.RemoteHardwareConfig
|
||||
import com.geeksville.mesh.copy
|
||||
import com.geeksville.mesh.ui.components.EditListPreference
|
||||
import com.geeksville.mesh.ui.components.PreferenceCategory
|
||||
import com.geeksville.mesh.ui.components.PreferenceFooter
|
||||
import com.geeksville.mesh.ui.components.SwitchPreference
|
||||
|
@ -42,6 +44,30 @@ fun RemoteHardwareConfigItemList(
|
|||
}
|
||||
item { Divider() }
|
||||
|
||||
item {
|
||||
SwitchPreference(title = "Allow undefined pin access",
|
||||
checked = remoteHardwareInput.allowUndefinedPinAccess,
|
||||
enabled = enabled,
|
||||
onCheckedChange = {
|
||||
remoteHardwareInput = remoteHardwareInput.copy { allowUndefinedPinAccess = it }
|
||||
})
|
||||
}
|
||||
item { Divider() }
|
||||
|
||||
item {
|
||||
EditListPreference(title = "Available pins",
|
||||
list = remoteHardwareInput.availablePinsList,
|
||||
maxCount = 4, // available_pins max_count:4
|
||||
enabled = enabled,
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
|
||||
onValuesChanged = { list ->
|
||||
remoteHardwareInput = remoteHardwareInput.copy {
|
||||
availablePins.clear()
|
||||
availablePins.addAll(list)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
item {
|
||||
PreferenceFooter(
|
||||
enabled = remoteHardwareInput != remoteHardwareConfig,
|
||||
|
|
Ładowanie…
Reference in New Issue