From f967d32d89dde913ea66aba4884cd9970bef53a5 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 20 Sep 2023 12:40:09 +0200 Subject: [wallet] simplify AmountInputField --- .../net/taler/wallet/compose/AmountInputField.kt | 70 ++++++++++------------ 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt b/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt index 9abc03d..0229ec5 100644 --- a/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt +++ b/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt @@ -16,8 +16,9 @@ package net.taler.wallet.compose -import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions @@ -25,17 +26,13 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text -import androidx.compose.material3.TextFieldColors -import androidx.compose.material3.TextFieldDefaults 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.graphics.Shape import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.OffsetMapping @@ -52,78 +49,64 @@ fun AmountInputField( value: String, onValueChange: (value: String) -> Unit, modifier: Modifier = Modifier, - enabled: Boolean = true, - readOnly: Boolean = false, - textStyle: TextStyle = LocalTextStyle.current, label: @Composable (() -> Unit)? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, supportingText: @Composable (() -> Unit)? = null, isError: Boolean = false, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - shape: Shape = TextFieldDefaults.outlinedShape, - colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors() ) { val decimalSeparator = DecimalFormat().decimalFormatSymbols.decimalSeparator - var tmpIn by remember { mutableStateOf(value) } + var amountInput by remember { mutableStateOf(value) } // React to external changes - val tmpOut = remember(tmpIn, value) { - transformOutput(tmpIn, decimalSeparator, '.').let { - if (value != it) value else tmpIn + val amountValue = remember(amountInput, value) { + transformOutput(amountInput, decimalSeparator, '.').let { + if (value != it) value else amountInput } } OutlinedTextField( - value = tmpOut, + value = amountValue, onValueChange = { input -> val filtered = transformOutput(input, decimalSeparator, '.') if (Amount.isValidAmountStr(filtered)) { - tmpIn = transformInput(input, decimalSeparator, '.') + amountInput = transformInput(input, decimalSeparator, '.') // tmpIn = input onValueChange(filtered) } }, modifier = modifier, - enabled = enabled, - readOnly = readOnly, - textStyle = textStyle.copy(fontFamily = FontFamily.Monospace), + textStyle = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace), label = label, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, supportingText = supportingText, isError = isError, visualTransformation = AmountInputVisualTransformation(decimalSeparator), - keyboardOptions = keyboardOptions.copy(keyboardType = KeyboardType.Decimal), + keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Decimal), keyboardActions = keyboardActions, singleLine = true, maxLines = 1, - interactionSource = interactionSource, - shape = shape, - colors = colors, ) } private class AmountInputVisualTransformation( private val decimalSeparator: Char, -): VisualTransformation { +) : VisualTransformation { override fun filter(text: AnnotatedString): TransformedText { val value = text.text val output = transformOutput(value, '.', decimalSeparator) val newText = AnnotatedString(output) - return TransformedText(newText, CursorOffsetMapping( - unmaskedText = text.toString(), - maskedText = newText.toString().replace(decimalSeparator, '.'), - )) + return TransformedText( + newText, CursorOffsetMapping( + unmaskedText = text.toString(), + maskedText = newText.toString().replace(decimalSeparator, '.'), + ) + ) } private class CursorOffsetMapping( private val unmaskedText: String, private val maskedText: String, - ): OffsetMapping { + ) : OffsetMapping { override fun originalToTransformed(offset: Int) = when { unmaskedText.startsWith('.') -> if (offset == 0) 0 else (offset + 1) // ".x" -> "0.x" else -> offset @@ -164,12 +147,23 @@ private fun transformOutput( fun AmountInputFieldPreview() { var value by remember { mutableStateOf("0") } TalerSurface { - Column { - Text(modifier = Modifier.padding(16.dp), text = value) + Column( + modifier = Modifier.fillMaxWidth().padding(16.dp), + verticalArrangement = spacedBy(16.dp), + ) { + AmountInputField( + value = value, + onValueChange = { value = it }, + label = { Text("Amount input:") }, + supportingText = { Text("This amount is nice.") }, + ) AmountInputField( value = value, onValueChange = { value = it }, + label = { Text("Error in amount input:") }, + supportingText = { Text("Amount is invalid.") }, + isError = true, ) } } -} \ No newline at end of file +} -- cgit v1.2.3