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,6 +157,7 @@ fun EditListPreference(
 | 
			
		|||
@Preview(showBackground = true)
 | 
			
		||||
@Composable
 | 
			
		||||
private fun EditListPreferencePreview() {
 | 
			
		||||
    Column {
 | 
			
		||||
        EditListPreference(
 | 
			
		||||
            title = "Ignore incoming",
 | 
			
		||||
            list = listOf(12345, 67890),
 | 
			
		||||
| 
						 | 
				
			
			@ -92,4 +166,19 @@ private fun EditListPreferencePreview() {
 | 
			
		|||
            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