Feet and inches input and output

closes #145
This commit is contained in:
Sad Ellie 2024-01-04 18:42:39 +03:00
parent 839954ce85
commit 5b7169d396
3 changed files with 264 additions and 82 deletions

View File

@ -31,6 +31,8 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.togetherWith import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@ -46,6 +48,7 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
@ -57,6 +60,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -64,6 +68,7 @@ import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.OutputFormat
@ -81,6 +86,7 @@ import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear
import com.sadellie.unitto.data.common.format import com.sadellie.unitto.data.common.format
import com.sadellie.unitto.data.converter.MyUnitIDS
import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.feature.converter.components.DefaultKeyboard import com.sadellie.unitto.feature.converter.components.DefaultKeyboard
@ -109,6 +115,7 @@ internal fun ConverterRoute(
deleteDigit = viewModel::deleteTokens, deleteDigit = viewModel::deleteTokens,
clearInput = viewModel::clearInput, clearInput = viewModel::clearInput,
onCursorChange = viewModel::onCursorChange, onCursorChange = viewModel::onCursorChange,
onFocusOnInput2 = viewModel::updateFocused,
onErrorClick = viewModel::updateCurrencyRates, onErrorClick = viewModel::updateCurrencyRates,
addBracket = viewModel::addBracket addBracket = viewModel::addBracket
) )
@ -126,6 +133,7 @@ private fun ConverterScreen(
deleteDigit: () -> Unit, deleteDigit: () -> Unit,
clearInput: () -> Unit, clearInput: () -> Unit,
onCursorChange: (TextRange) -> Unit, onCursorChange: (TextRange) -> Unit,
onFocusOnInput2: (Boolean) -> Unit,
onErrorClick: (AbstractUnit) -> Unit, onErrorClick: (AbstractUnit) -> Unit,
addBracket: () -> Unit, addBracket: () -> Unit,
) { ) {
@ -160,6 +168,7 @@ private fun ConverterScreen(
modifier = Modifier.padding(it), modifier = Modifier.padding(it),
uiState = uiState, uiState = uiState,
onCursorChange = onCursorChange, onCursorChange = onCursorChange,
onFocusOnInput2 = onFocusOnInput2,
processInput = processInput, processInput = processInput,
deleteDigit = deleteDigit, deleteDigit = deleteDigit,
navigateToLeftScreen = navigateToLeftScreen, navigateToLeftScreen = navigateToLeftScreen,
@ -254,6 +263,7 @@ private fun Default(
modifier: Modifier, modifier: Modifier,
uiState: UnitConverterUIState.Default, uiState: UnitConverterUIState.Default,
onCursorChange: (TextRange) -> Unit, onCursorChange: (TextRange) -> Unit,
onFocusOnInput2: (Boolean) -> Unit,
processInput: (String) -> Unit, processInput: (String) -> Unit,
deleteDigit: () -> Unit, deleteDigit: () -> Unit,
navigateToLeftScreen: () -> Unit, navigateToLeftScreen: () -> Unit,
@ -288,7 +298,9 @@ private fun Default(
modifier = modifier.fillMaxSize(), modifier = modifier.fillMaxSize(),
content1 = { contentModifier -> content1 = { contentModifier ->
ColumnWithConstraints(modifier = contentModifier) { ColumnWithConstraints(modifier = contentModifier) {
val textFieldModifier = Modifier.fillMaxWidth().weight(2f) val textFieldModifier = Modifier
.fillMaxWidth()
.weight(2f)
AnimatedVisibility( AnimatedVisibility(
visible = lastUpdate != null, visible = lastUpdate != null,
@ -307,33 +319,79 @@ private fun Default(
) )
} }
ExpressionTextField( if (uiState.unitFrom.id == MyUnitIDS.foot) {
modifier = textFieldModifier, Row(
minRatio = 0.7f, modifier = textFieldModifier,
placeholder = Token.Digit._0, horizontalArrangement = Arrangement.spacedBy(8.dp)
value = uiState.input, ) {
onCursorChange = onCursorChange, Column(
pasteCallback = processInput, modifier = Modifier
cutCallback = deleteDigit, .fillMaxWidth()
formatterSymbols = uiState.formatterSymbols, .weight(1f)
) ) {
AnimatedVisibility( ExpressionTextField(
visible = calculation.text.isNotEmpty(), modifier = Modifier.fillMaxWidth().weight(1f),
modifier = Modifier.weight(1f), minRatio = 0.7f,
enter = expandVertically(clip = false), placeholder = Token.Digit._0,
exit = shrinkVertically(clip = false) value = uiState.input1,
) { onCursorChange = onCursorChange,
pasteCallback = processInput,
cutCallback = deleteDigit,
formatterSymbols = uiState.formatterSymbols,
)
AnimatedUnitShortName(stringResource(uiState.unitFrom.shortName))
}
VerticalDivider()
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
ExpressionTextField(
modifier = Modifier.fillMaxWidth().weight(1f)
.onFocusEvent { state -> onFocusOnInput2(state.hasFocus) },
minRatio = 0.7f,
placeholder = Token.Digit._0,
value = uiState.input2,
onCursorChange = onCursorChange,
pasteCallback = processInput,
cutCallback = deleteDigit,
formatterSymbols = uiState.formatterSymbols,
)
AnimatedUnitShortName(stringResource(R.string.unit_inch_short))
}
}
} else {
ExpressionTextField( ExpressionTextField(
modifier = Modifier, modifier = textFieldModifier,
value = calculation,
onCursorChange = { calculation = calculation.copy(selection = it) },
formatterSymbols = uiState.formatterSymbols,
minRatio = 0.7f, minRatio = 0.7f,
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), placeholder = Token.Digit._0,
readOnly = true value = uiState.input1,
onCursorChange = onCursorChange,
pasteCallback = processInput,
cutCallback = deleteDigit,
formatterSymbols = uiState.formatterSymbols,
) )
AnimatedVisibility(
visible = calculation.text.isNotEmpty(),
modifier = Modifier.weight(1f),
enter = expandVertically(clip = false),
exit = shrinkVertically(clip = false)
) {
ExpressionTextField(
modifier = Modifier,
value = calculation,
onCursorChange = { calculation = calculation.copy(selection = it) },
formatterSymbols = uiState.formatterSymbols,
minRatio = 0.7f,
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
readOnly = true
)
}
AnimatedUnitShortName(stringResource(uiState.unitFrom.shortName))
} }
AnimatedUnitShortName(stringResource(uiState.unitFrom.shortName))
ConverterResultTextField( ConverterResultTextField(
modifier = textFieldModifier, modifier = textFieldModifier,
@ -392,6 +450,7 @@ private fun ConverterResultTextField(
is ConverterResult.Default -> result.value.format(scale, outputFormat) is ConverterResult.Default -> result.value.format(scale, outputFormat)
is ConverterResult.NumberBase -> result.value.uppercase() is ConverterResult.NumberBase -> result.value.uppercase()
is ConverterResult.Time -> result.format(mContext, formatterSymbols) is ConverterResult.Time -> result.format(mContext, formatterSymbols)
is ConverterResult.FootInch -> result.format(mContext, scale, outputFormat, formatterSymbols)
else -> "" else -> ""
} }
mutableStateOf(TextFieldValue(value)) mutableStateOf(TextFieldValue(value))
@ -430,7 +489,9 @@ private fun ConverterResultTextField(
) )
} }
is ConverterResult.NumberBase, is ConverterResult.Time -> { is ConverterResult.NumberBase,
is ConverterResult.Time,
is ConverterResult.FootInch -> {
UnformattedTextField( UnformattedTextField(
modifier = modifier, modifier = modifier,
value = resultTextField, value = resultTextField,
@ -527,6 +588,7 @@ private fun PreviewConverterScreen() {
deleteDigit = {}, deleteDigit = {},
clearInput = {}, clearInput = {},
onCursorChange = {}, onCursorChange = {},
onFocusOnInput2 = {},
onErrorClick = {}, onErrorClick = {},
addBracket = {} addBracket = {}
) )

View File

@ -24,6 +24,7 @@ import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.formatExpression import com.sadellie.unitto.core.ui.common.textfield.formatExpression
import com.sadellie.unitto.data.common.format
import com.sadellie.unitto.data.common.isEqualTo import com.sadellie.unitto.data.common.isEqualTo
import com.sadellie.unitto.data.common.isGreaterThan import com.sadellie.unitto.data.common.isGreaterThan
import com.sadellie.unitto.data.common.isLessThan import com.sadellie.unitto.data.common.isLessThan
@ -37,7 +38,8 @@ internal sealed class UnitConverterUIState {
data object Loading : UnitConverterUIState() data object Loading : UnitConverterUIState()
data class Default( data class Default(
val input: TextFieldValue = TextFieldValue(), val input1: TextFieldValue,
val input2: TextFieldValue,
val calculation: BigDecimal?, val calculation: BigDecimal?,
val result: ConverterResult, val result: ConverterResult,
val unitFrom: DefaultUnit, val unitFrom: DefaultUnit,
@ -53,7 +55,7 @@ internal sealed class UnitConverterUIState {
) : UnitConverterUIState() ) : UnitConverterUIState()
data class NumberBase( data class NumberBase(
val input: TextFieldValue = TextFieldValue(), val input: TextFieldValue,
val result: ConverterResult, val result: ConverterResult,
val unitFrom: NumberBaseUnit, val unitFrom: NumberBaseUnit,
val unitTo: NumberBaseUnit, val unitTo: NumberBaseUnit,
@ -85,6 +87,11 @@ internal sealed class ConverterResult {
val attosecond: BigDecimal, val attosecond: BigDecimal,
) : ConverterResult() ) : ConverterResult()
data class FootInch(
val foot: BigDecimal,
val inch: BigDecimal,
) : ConverterResult()
data object Loading : ConverterResult() data object Loading : ConverterResult()
data object Error : ConverterResult() data object Error : ConverterResult()
@ -128,6 +135,25 @@ internal fun ConverterResult.Time.format(mContext: Context, formatterSymbols: Fo
return (if (negative) Token.Operator.minus else "") + result.joinToString(" ").ifEmpty { Token.Digit._0 } return (if (negative) Token.Operator.minus else "") + result.joinToString(" ").ifEmpty { Token.Digit._0 }
} }
internal fun ConverterResult.FootInch.format(
mContext: Context,
scale: Int,
outputFormat: Int,
formatterSymbols: FormatterSymbols
): String {
var result = ""
result += foot.format(scale, outputFormat).formatExpression(formatterSymbols)
if (inch.isGreaterThan(BigDecimal.ZERO)) {
result += mContext.getString(R.string.unit_foot_short)
result += " "
result += inch.format(scale, outputFormat).formatExpression(formatterSymbols)
result += mContext.getString(R.string.unit_inch_short)
}
return result
}
internal fun formatTime( internal fun formatTime(
input: BigDecimal, input: BigDecimal,
): ConverterResult.Time { ): ConverterResult.Time {
@ -202,6 +228,26 @@ internal fun formatTime(
) )
} }
/**
* Creates an object for displaying formatted foot and inch output. Units are passed as objects so
* that changes in basic units don't require modifying the method. Also this method can't access
* units repository directly.
*
* @param input Input in feet.
* @param footUnit Foot unit [DefaultUnit].
* @param inchUnit Inch unit [DefaultUnit].
* @return Result where decimal places are converter into inches.
*/
internal fun formatFootInch(
input: BigDecimal,
footUnit: DefaultUnit,
inchUnit: DefaultUnit
): ConverterResult.FootInch {
val (integral, fractional) = input.divideAndRemainder(BigDecimal.ONE)
return ConverterResult.FootInch(integral, footUnit.convert(inchUnit, fractional))
}
private val dayBasicUnit by lazy { BigDecimal("86400000000000000000000") } private val dayBasicUnit by lazy { BigDecimal("86400000000000000000000") }
private val hourBasicUnit by lazy { BigDecimal("3600000000000000000000") } private val hourBasicUnit by lazy { BigDecimal("3600000000000000000000") }
private val minuteBasicUnit by lazy { BigDecimal("60000000000000000000") } private val minuteBasicUnit by lazy { BigDecimal("60000000000000000000") }

View File

@ -65,8 +65,11 @@ internal class ConverterViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle private val savedStateHandle: SavedStateHandle
) : ViewModel() { ) : ViewModel() {
private val converterInputKey = "CONVERTER_INPUT" private val converterInputKey1 = "CONVERTER_INPUT_1"
private val _input = MutableStateFlow(savedStateHandle.getTextField(converterInputKey)) private val converterInputKey2 = "CONVERTER_INPUT_2"
private val _input1 = MutableStateFlow(savedStateHandle.getTextField(converterInputKey1))
private val _input2 = MutableStateFlow(savedStateHandle.getTextField(converterInputKey2))
private val _focusedOnInput2 = MutableStateFlow(false)
private val _calculation = MutableStateFlow<BigDecimal?>(null) private val _calculation = MutableStateFlow<BigDecimal?>(null)
private val _result = MutableStateFlow<ConverterResult>(ConverterResult.Loading) private val _result = MutableStateFlow<ConverterResult>(ConverterResult.Loading)
private val _unitFrom = MutableStateFlow<AbstractUnit?>(null) private val _unitFrom = MutableStateFlow<AbstractUnit?>(null)
@ -83,18 +86,20 @@ internal class ConverterViewModel @Inject constructor(
private var _loadCurrenciesJob: Job? = null private var _loadCurrenciesJob: Job? = null
val converterUiState: StateFlow<UnitConverterUIState> = combine( val converterUiState: StateFlow<UnitConverterUIState> = combine(
_input, _input1,
_input2,
_calculation, _calculation,
_result, _result,
_unitFrom, _unitFrom,
_unitTo, _unitTo,
userPrefsRepository.converterPrefs, userPrefsRepository.converterPrefs,
_currenciesState _currenciesState
) { input, calculation, result, unitFrom, unitTo, prefs, currenciesState -> ) { input1, input2, calculation, result, unitFrom, unitTo, prefs, currenciesState ->
return@combine when { return@combine when {
(unitFrom is DefaultUnit) and (unitTo is DefaultUnit) -> { (unitFrom is DefaultUnit) and (unitTo is DefaultUnit) -> {
UnitConverterUIState.Default( UnitConverterUIState.Default(
input = input, input1 = input1,
input2 = input2,
calculation = calculation, calculation = calculation,
result = result, result = result,
unitFrom = unitFrom as DefaultUnit, unitFrom = unitFrom as DefaultUnit,
@ -111,7 +116,7 @@ internal class ConverterViewModel @Inject constructor(
} }
(unitFrom is NumberBaseUnit) and (unitTo is NumberBaseUnit) -> { (unitFrom is NumberBaseUnit) and (unitTo is NumberBaseUnit) -> {
UnitConverterUIState.NumberBase( UnitConverterUIState.NumberBase(
input = input, input = input1,
result = result, result = result,
unitFrom = unitFrom as NumberBaseUnit, unitFrom = unitFrom as NumberBaseUnit,
unitTo = unitTo as NumberBaseUnit, unitTo = unitTo as NumberBaseUnit,
@ -134,24 +139,31 @@ internal class ConverterViewModel @Inject constructor(
is CurrencyRateUpdateState.Ready, is CurrencyRateUpdateState.Nothing -> {} is CurrencyRateUpdateState.Ready, is CurrencyRateUpdateState.Nothing -> {}
} }
when (ui) { try {
is UnitConverterUIState.Default -> { when (ui) {
convertDefault( is UnitConverterUIState.Default -> {
unitFrom = ui.unitFrom, convertDefault(
unitTo = ui.unitTo, unitFrom = ui.unitFrom,
input = ui.input, unitTo = ui.unitTo,
formatTime = ui.formatTime input1 = ui.input1,
) input2 = ui.input2,
formatTime = ui.formatTime
)
}
is UnitConverterUIState.NumberBase -> {
convertNumberBase(
unitFrom = ui.unitFrom,
unitTo = ui.unitTo,
input = ui.input
)
}
is UnitConverterUIState.Loading -> {}
} }
is UnitConverterUIState.NumberBase -> { } catch (e: Exception) {
convertNumberBase( _result.update { ConverterResult.Default(BigDecimal.ZERO) }
unitFrom = ui.unitFrom,
unitTo = ui.unitTo,
input = ui.input
)
}
is UnitConverterUIState.Loading -> {}
} }
ui ui
} }
.stateIn(viewModelScope, UnitConverterUIState.Loading) .stateIn(viewModelScope, UnitConverterUIState.Loading)
@ -194,7 +206,7 @@ internal class ConverterViewModel @Inject constructor(
val rightSideUIState = combine( val rightSideUIState = combine(
_unitFrom, _unitFrom,
_unitTo, _unitTo,
_input, _input1,
_calculation, _calculation,
_rightQuery, _rightQuery,
_rightUnits, _rightUnits,
@ -251,30 +263,73 @@ internal class ConverterViewModel @Inject constructor(
} }
} }
fun addTokens(tokens: String) = _input.update { /**
val newValue = it.addTokens(tokens) * Change currently focused text field. For feet and inches input
savedStateHandle[converterInputKey] = newValue.text *
newValue * @param focusOnInput2 `true` if focus is on inches input. `false`if focus on feet input.
*/
fun updateFocused(focusOnInput2: Boolean) = _focusedOnInput2.update { focusOnInput2 }
fun addTokens(tokens: String) {
if (_focusedOnInput2.value) {
_input2.update {
val newValue = it.addTokens(tokens)
savedStateHandle[converterInputKey2] = newValue.text
newValue
}
} else {
_input1.update {
val newValue = it.addTokens(tokens)
savedStateHandle[converterInputKey1] = newValue.text
newValue
}
}
} }
fun addBracket() = _input.update { fun addBracket() {
val newValue = it.addBracket() if (_focusedOnInput2.value) {
savedStateHandle[converterInputKey] = newValue.text _input2.update {
newValue val newValue = it.addBracket()
savedStateHandle[converterInputKey2] = newValue.text
newValue
}
} else {
_input1.update {
val newValue = it.addBracket()
savedStateHandle[converterInputKey1] = newValue.text
newValue
}
}
} }
fun deleteTokens() = _input.update { fun deleteTokens() {
val newValue = it.deleteTokens() if (_focusedOnInput2.value) {
savedStateHandle[converterInputKey] = newValue.text _input2.update {
newValue val newValue = it.deleteTokens()
savedStateHandle[converterInputKey2] = newValue.text
newValue
}
} else {
_input1.update {
val newValue = it.deleteTokens()
savedStateHandle[converterInputKey1] = newValue.text
newValue
}
}
} }
fun clearInput() = _input.update { fun clearInput() {
savedStateHandle[converterInputKey] = "" _input1.update {
TextFieldValue() savedStateHandle[converterInputKey1] = ""
TextFieldValue()
}
_input2.update {
savedStateHandle[converterInputKey2] = ""
TextFieldValue()
}
} }
fun onCursorChange(selection: TextRange) = _input.update { it.copy(selection = selection) } fun onCursorChange(selection: TextRange) = _input1.update { it.copy(selection = selection) }
fun updateCurrencyRates(unit: AbstractUnit) { fun updateCurrencyRates(unit: AbstractUnit) {
_loadCurrenciesJob = viewModelScope.launch(Dispatchers.IO) { _loadCurrenciesJob = viewModelScope.launch(Dispatchers.IO) {
@ -387,31 +442,50 @@ internal class ConverterViewModel @Inject constructor(
private fun convertDefault( private fun convertDefault(
unitFrom: DefaultUnit, unitFrom: DefaultUnit,
unitTo: DefaultUnit, unitTo: DefaultUnit,
input: TextFieldValue, input1: TextFieldValue,
input2: TextFieldValue,
formatTime: Boolean, formatTime: Boolean,
) = viewModelScope.launch(Dispatchers.Default) { ) = viewModelScope.launch(Dispatchers.Default) {
val calculated = try { val footInchInput = unitFrom.id == MyUnitIDS.foot
Expression(input.text.ifEmpty { Token.Digit._0 }).calculate()
if (footInchInput) { _calculation.update { null } }
// Calculate
val calculated1 = try {
Expression(input1.text.ifEmpty { Token.Digit._0 }).calculate()
} catch (e: ExpressionException.DivideByZero) { } catch (e: ExpressionException.DivideByZero) {
_calculation.update { null } _calculation.update { null }
return@launch return@launch
} catch (e: Exception) { } catch (e: Exception) {
return@launch return@launch
} }
_calculation.update { if (input.text.isExpression()) calculated else null } val calculated2 = try {
Expression(input2.text.ifEmpty { Token.Digit._0 }).calculate()
try { } catch (e: ExpressionException.DivideByZero) {
if ((unitFrom.group == UnitGroup.TIME) and (formatTime)) { _calculation.update { null }
_result.update { formatTime(calculated.multiply(unitFrom.basicUnit)) } return@launch
return@launch
}
val conversion = unitFrom.convert(unitTo, calculated)
_result.update { ConverterResult.Default(conversion) }
} catch (e: Exception) { } catch (e: Exception) {
_result.update { ConverterResult.Default(BigDecimal.ZERO) } return@launch
}
// Update calculation
_calculation.update { if (input1.text.isExpression()) calculated1 else null }
// Convert
var conversion = unitFrom.convert(unitTo, calculated1)
if (footInchInput) {
// Converted from second text field too
val inches = unitsRepo.getById(MyUnitIDS.inch) as DefaultUnit
conversion += inches.convert(unitTo, calculated2)
}
// Update result
_result.update {
when {
(unitFrom.group == UnitGroup.TIME) and (formatTime) -> formatTime(calculated1.multiply(unitFrom.basicUnit))
unitTo.id == MyUnitIDS.foot -> formatFootInch(conversion, unitTo, unitsRepo.getById(MyUnitIDS.inch) as DefaultUnit)
else -> ConverterResult.Default(conversion)
}
} }
} }