diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/TextFieldValueExtensions.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/TextFieldValueExtensions.kt index ae5248e6..0427cb8d 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/TextFieldValueExtensions.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/TextFieldValueExtensions.kt @@ -126,6 +126,8 @@ fun TextFieldValue.deleteTokens(): TextFieldValue { ) } +fun TextFieldValue.placeCursorAtTheEnd(): TextFieldValue = copy(selection = TextRange(text.length)) + /** * Tries to get a [TextFieldValue]. Places cursor at the end. * diff --git a/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt b/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt index 2c942273..a0e1dd50 100644 --- a/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt +++ b/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt @@ -38,30 +38,9 @@ class CalculatorScreenTest { val composeTestRule = createAndroidComposeRule() @Test - fun loading_showLoadingKeyboard(): Unit = with(composeTestRule) { + fun ready(): Unit = with(composeTestRule) { setContent { - CalculatorScreen( - uiState = CalculatorUIState.Loading, - openDrawer = {}, - addTokens = {}, - addBracket = {}, - clearInput = {}, - deleteTokens = {}, - onValueChange = {}, - toggleCalculatorMode = {}, - equal = {}, - clearHistory = {}, - onDelete = {}, - ) - } - - onNodeWithTag("loading").assertExists() - } - - @Test - fun ready_showRealKeyboard(): Unit = with(composeTestRule) { - setContent { - CalculatorScreen( + Ready( uiState = CalculatorUIState.Ready( input = TextFieldValue(), output = CalculationResult.Empty, @@ -75,16 +54,15 @@ class CalculatorScreenTest { partialHistoryView = true ), openDrawer = {}, - addTokens = {}, - addBracket = {}, - clearInput = {}, - deleteTokens = {}, - onValueChange = {}, - toggleCalculatorMode = {}, - equal = {}, - clearHistory = {}, - onDelete = {}, - ) + onInputChange = {}, + onAddTokenClick = {}, + onBracketsClick = {}, + onDeleteClick = {}, + onClearClick = {}, + onEqualClick = {}, + onAngleClick = {}, + onClearHistoryClick = {}, + ) {} } onNodeWithTag("loading").assertDoesNotExist() @@ -94,7 +72,7 @@ class CalculatorScreenTest { @Test fun ready_swipeForHistory(): Unit = with(composeTestRule) { setContent { - CalculatorScreen( + Ready( uiState = CalculatorUIState.Ready( input = TextFieldValue(), output = CalculationResult.Empty, @@ -108,16 +86,15 @@ class CalculatorScreenTest { partialHistoryView = true ), openDrawer = {}, - addTokens = {}, - addBracket = {}, - clearInput = {}, - deleteTokens = {}, - onValueChange = {}, - toggleCalculatorMode = {}, - equal = {}, - clearHistory = {}, - onDelete = {}, - ) + onInputChange = {}, + onAddTokenClick = {}, + onBracketsClick = {}, + onDeleteClick = {}, + onClearClick = {}, + onEqualClick = {}, + onAngleClick = {}, + onClearHistoryClick = {}, + ) {} } onNodeWithTag("inputBox") diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt index bcf5a105..46efaa8c 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt @@ -86,68 +86,37 @@ internal fun CalculatorRoute( openDrawer: () -> Unit, viewModel: CalculatorViewModel = hiltViewModel(), ) { - val uiState = viewModel.uiState.collectAsStateWithLifecycle() - - CalculatorScreen( - uiState = uiState.value, - openDrawer = openDrawer, - addTokens = viewModel::addTokens, - addBracket = viewModel::addBracket, - clearInput = viewModel::clearInput, - deleteTokens = viewModel::deleteTokens, - onValueChange = viewModel::updateInput, - toggleCalculatorMode = viewModel::updateRadianMode, - equal = viewModel::equal, - clearHistory = viewModel::clearHistory, - onDelete = viewModel::deleteHistoryItem, - ) -} - -@Composable -internal fun CalculatorScreen( - uiState: CalculatorUIState, - openDrawer: () -> Unit, - addTokens: (String) -> Unit, - addBracket: () -> Unit, - clearInput: () -> Unit, - deleteTokens: () -> Unit, - onValueChange: (TextFieldValue) -> Unit, - toggleCalculatorMode: (Boolean) -> Unit, - equal: () -> Unit, - clearHistory: () -> Unit, - onDelete: (HistoryItem) -> Unit, -) { - when (uiState) { - is CalculatorUIState.Loading -> EmptyScreen() + when (val uiState = viewModel.uiState.collectAsStateWithLifecycle().value) { + CalculatorUIState.Loading -> EmptyScreen() is CalculatorUIState.Ready -> Ready( uiState = uiState, openDrawer = openDrawer, - addSymbol = addTokens, - addBracket = addBracket, - clearSymbols = clearInput, - deleteSymbol = deleteTokens, - onValueChange = onValueChange, - toggleAngleMode = { toggleCalculatorMode(!uiState.radianMode) }, - equal = equal, - clearHistory = clearHistory, - onDelete = onDelete, + onInputChange = viewModel::updateInput, + onAddTokenClick = viewModel::addTokens, + onBracketsClick = viewModel::addBracket, + onDeleteClick = viewModel::deleteTokens, + onClearClick = viewModel::clearInput, + onEqualClick = viewModel::equal, + onAngleClick = viewModel::updateRadianMode, + onClearHistoryClick = viewModel::clearHistory, + onDeleteHistoryItemClick = viewModel::deleteHistoryItem, ) } } @Composable -private fun Ready( +internal fun Ready( uiState: CalculatorUIState.Ready, openDrawer: () -> Unit, - addSymbol: (String) -> Unit, - addBracket: () -> Unit, - clearSymbols: () -> Unit, - deleteSymbol: () -> Unit, - onValueChange: (TextFieldValue) -> Unit, - toggleAngleMode: () -> Unit, - equal: () -> Unit, - clearHistory: () -> Unit, - onDelete: (HistoryItem) -> Unit, + onInputChange: (TextFieldValue) -> Unit, + onAddTokenClick: (String) -> Unit, + onBracketsClick: () -> Unit, + onDeleteClick: () -> Unit, + onClearClick: () -> Unit, + onEqualClick: () -> Unit, + onAngleClick: (Boolean) -> Unit, + onClearHistoryClick: () -> Unit, + onDeleteHistoryItemClick: (HistoryItem) -> Unit, ) { val focusManager = LocalFocusManager.current var showClearHistoryDialog by rememberSaveable { mutableStateOf(false) } @@ -240,8 +209,8 @@ private fun Ready( .height(historyListHeight), historyItems = uiState.history, formatterSymbols = uiState.formatterSymbols, - addTokens = addSymbol, - onDelete = onDelete, + addTokens = onAddTokenClick, + onDelete = onDeleteHistoryItemClick, showDeleteButtons = isOpen ) @@ -256,7 +225,7 @@ private fun Ready( ), formatterSymbols = uiState.formatterSymbols, input = uiState.input, - onValueChange = onValueChange, + onValueChange = onInputChange, output = uiState.output ) @@ -274,16 +243,16 @@ private fun Ready( .height(keyboardHeight) .fillMaxWidth() .padding(horizontal = 8.dp, vertical = 4.dp), + onAddTokenClick = onAddTokenClick, + onBracketsClick = onBracketsClick, + onDeleteClick = onDeleteClick, + onClearClick = onClearClick, + onEqualClick = { focusManager.clearFocus(); onEqualClick() }, + onAngleClick = onAngleClick, radianMode = uiState.radianMode, - fractional = uiState.formatterSymbols.fractional, - addSymbol = addSymbol, - clearSymbols = clearSymbols, - deleteSymbol = deleteSymbol, - toggleAngleMode = toggleAngleMode, - equal = { focusManager.clearFocus(); equal() }, + showAcButton = uiState.acButton, middleZero = uiState.middleZero, - acButton = uiState.acButton, - addBracket = addBracket + fractional = uiState.formatterSymbols.fractional, ) } } @@ -302,7 +271,7 @@ private fun Ready( confirmButton = { TextButton( onClick = { - clearHistory() + onClearHistoryClick() showClearHistoryDialog = false } ) { @@ -349,7 +318,7 @@ private fun PreviewCalculatorScreen() { ) } - CalculatorScreen( + Ready( uiState = CalculatorUIState.Ready( input = TextFieldValue("1.2345"), output = CalculationResult.Default("1234"), @@ -363,14 +332,13 @@ private fun PreviewCalculatorScreen() { partialHistoryView = true ), openDrawer = {}, - addTokens = {}, - addBracket = {}, - clearInput = {}, - deleteTokens = {}, - onValueChange = {}, - toggleCalculatorMode = {}, - equal = {}, - clearHistory = {}, - onDelete = {}, - ) + onInputChange = {}, + onAddTokenClick = {}, + onBracketsClick = {}, + onDeleteClick = {}, + onClearClick = {}, + onEqualClick = {}, + onAngleClick = {}, + onClearHistoryClick = {}, + ) {} } \ No newline at end of file diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt index 670221b5..3a2b844a 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt @@ -18,10 +18,8 @@ package com.sadellie.unitto.feature.calculator -import androidx.annotation.StringRes import androidx.compose.ui.text.input.TextFieldValue import com.sadellie.unitto.core.base.FormatterSymbols -import com.sadellie.unitto.core.base.R import com.sadellie.unitto.data.model.HistoryItem internal sealed class CalculatorUIState { @@ -48,13 +46,7 @@ sealed class CalculationResult { data object Empty : CalculationResult() - data object DivideByZeroError : CalculationResult() { - @StringRes - val label: Int = R.string.calculator_divide_by_zero_error - } + data object DivideByZeroError : CalculationResult() - data object Error : CalculationResult() { - @StringRes - val label: Int = R.string.error_label - } + data object Error : CalculationResult() } diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt index c3672bab..98b6714f 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt @@ -28,6 +28,7 @@ import com.sadellie.unitto.core.ui.common.textfield.addBracket import com.sadellie.unitto.core.ui.common.textfield.addTokens import com.sadellie.unitto.core.ui.common.textfield.deleteTokens import com.sadellie.unitto.core.ui.common.textfield.getTextField +import com.sadellie.unitto.core.ui.common.textfield.placeCursorAtTheEnd import com.sadellie.unitto.data.common.format import com.sadellie.unitto.data.common.isExpression import com.sadellie.unitto.data.common.stateIn @@ -114,62 +115,43 @@ internal class CalculatorViewModel @Inject constructor( } .stateIn(viewModelScope, CalculatorUIState.Loading) - fun addTokens(tokens: String) = _input.update { + fun addTokens(tokens: String) { val isClearInputNeeded = _equalClicked.value and Token.Digit.allWithDot.contains(tokens) - - var newValue = when { + val newValue = when { // Clean input after clicking "=" and any token that is a Digit isClearInputNeeded -> TextFieldValue() - _equalClicked.value -> it.copy(selection = TextRange(it.text.length)) - else -> it - } - newValue = newValue.addTokens(tokens) - - _equalClicked.update { false } - _fractionJob?.cancel() - savedStateHandle[_inputKey] = newValue.text - newValue + _equalClicked.value -> _input.value.placeCursorAtTheEnd() + else -> _input.value + }.addTokens(tokens) + updateInput(newValue) } - fun addBracket() = _input.update { - var newValue = if (_equalClicked.value) { + fun addBracket() { + val newValue = if (_equalClicked.value) { // Cursor is set to 0 when equal is clicked - it.copy(selection = TextRange(it.text.length)) + _input.value.placeCursorAtTheEnd() } else { - it - } - newValue = newValue.addBracket() - - _equalClicked.update { false } - _fractionJob?.cancel() - savedStateHandle[_inputKey] = newValue.text - newValue + _input.value + }.addBracket() + updateInput(newValue) } - fun deleteTokens() = _input.update { + fun deleteTokens() { val newValue = if (_equalClicked.value) { TextFieldValue() } else { - it.deleteTokens() + _input.value.deleteTokens() } - _equalClicked.update { false } - _fractionJob?.cancel() - savedStateHandle[_inputKey] = newValue.text - newValue + updateInput(newValue) } - fun clearInput() = _input.update { - _equalClicked.update { false } - _fractionJob?.cancel() - savedStateHandle[_inputKey] = "" - TextFieldValue() - } + fun clearInput() = updateInput(TextFieldValue()) - fun updateInput(value: TextFieldValue) = _input.update { - // Without this line: will place token (even in the middle of the input) and place cursor at - // the end. This line also removes fractional output once user touches input text field + fun updateInput(value: TextFieldValue) { + _fractionJob?.cancel() _equalClicked.update { false } - value + _input.update { value } + savedStateHandle[_inputKey] = value.text } fun updateRadianMode(newValue: Boolean) = viewModelScope.launch { diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt index 4882c3c2..9e04c96f 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt @@ -114,50 +114,50 @@ import com.sadellie.unitto.core.ui.common.icons.iconpack.Tan @Composable internal fun CalculatorKeyboard( modifier: Modifier, + onAddTokenClick: (String) -> Unit, + onBracketsClick: () -> Unit, + onDeleteClick: () -> Unit, + onClearClick: () -> Unit, + onEqualClick: () -> Unit, + onAngleClick: (Boolean) -> Unit, radianMode: Boolean, - fractional: String, + showAcButton: Boolean, middleZero: Boolean, - acButton: Boolean, - addSymbol: (String) -> Unit, - addBracket: () -> Unit, - clearSymbols: () -> Unit, - deleteSymbol: () -> Unit, - toggleAngleMode: () -> Unit, - equal: () -> Unit + fractional: String, ) { - var invMode: Boolean by remember { mutableStateOf(false) } + var showInvButtons: Boolean by remember { mutableStateOf(false) } if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) { LandscapeKeyboard( modifier = modifier, + onAddTokenClick = onAddTokenClick, + onBracketsClick = onBracketsClick, + onDeleteClick = onDeleteClick, + onClearClick = onClearClick, + onEqualClick = onEqualClick, + onInvClick = { showInvButtons = !showInvButtons }, + onAngleClick = onAngleClick, + showInvButtons = showInvButtons, radianMode = radianMode, - fractional = fractional, + showAcButton = showAcButton, middleZero = middleZero, - addSymbol = addSymbol, - toggleAngleMode = toggleAngleMode, - deleteSymbol = deleteSymbol, - clearSymbols = clearSymbols, - equal = equal, - acButton = acButton, - addBracket = addBracket, - invMode = invMode, - toggleInvMode = { invMode = !invMode }, + fractional = fractional, ) } else { PortraitKeyboard( modifier = modifier, + onAddTokenClick = onAddTokenClick, + onBracketsClick = onBracketsClick, + onDeleteClick = onDeleteClick, + onClearClick = onClearClick, + onEqualClick = onEqualClick, + onInvClick = { showInvButtons = !showInvButtons }, + onAngleClick = onAngleClick, + showInvButtons = showInvButtons, radianMode = radianMode, - fractional = fractional, + showAcButton = showAcButton, middleZero = middleZero, - addSymbol = addSymbol, - toggleAngleMode = toggleAngleMode, - deleteSymbol = deleteSymbol, - clearSymbols = clearSymbols, - equal = equal, - acButton = acButton, - addBracket = addBracket, - invMode = invMode, - toggleInvMode = { invMode = !invMode }, + fractional = fractional, ) } } @@ -165,18 +165,18 @@ internal fun CalculatorKeyboard( @Composable private fun PortraitKeyboard( modifier: Modifier, + onAddTokenClick: (String) -> Unit, + onBracketsClick: () -> Unit, + onDeleteClick: () -> Unit, + onClearClick: () -> Unit, + onEqualClick: () -> Unit, + onInvClick: () -> Unit, + onAngleClick: (Boolean) -> Unit, + showInvButtons: Boolean, radianMode: Boolean, - fractional: String, + showAcButton: Boolean, middleZero: Boolean, - addSymbol: (String) -> Unit, - toggleAngleMode: () -> Unit, - deleteSymbol: () -> Unit, - clearSymbols: () -> Unit, - equal: () -> Unit, - acButton: Boolean, - addBracket: () -> Unit, - invMode: Boolean, - toggleInvMode: () -> Unit, + fractional: String, ) { val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg } val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree } @@ -205,7 +205,7 @@ private fun PortraitKeyboard( horizontalArrangement = Arrangement.Start ) { Crossfade( - targetState = invMode, + targetState = showInvButtons, label = "Inverse switch", modifier = Modifier .fillMaxWidth() @@ -217,21 +217,21 @@ private fun PortraitKeyboard( showAdditional = showAdditional, buttonHeight = additionalButtonHeight, content1 = { buttonModifier -> - KeyboardButtonAdditional(buttonModifier, IconPack.Modulo, stringResource(R.string.keyboard_modulo), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Operator.modulo) } - KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Const.pi) } - KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Operator.factorial) } + KeyboardButtonAdditional(buttonModifier, IconPack.Modulo, stringResource(R.string.keyboard_modulo), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Operator.modulo) } + KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Const.pi) } + KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Operator.factorial) } }, content2 = { buttonModifier -> - KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightTallAdditional) { toggleAngleMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.ArSin, stringResource(R.string.keyboard_arsin), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.arsinBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.ArCos, stringResource(R.string.keyboard_arcos), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.arcosBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.AcTan, stringResource(R.string.keyboard_actan), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.actanBracket) } + KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightTallAdditional) { onAngleClick(!radianMode) } + KeyboardButtonAdditional(buttonModifier, IconPack.ArSin, stringResource(R.string.keyboard_arsin), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.arsinBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.ArCos, stringResource(R.string.keyboard_arcos), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.arcosBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.AcTan, stringResource(R.string.keyboard_actan), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.actanBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightTallAdditional) { toggleInvMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_euler), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Const.e) } - KeyboardButtonAdditional(buttonModifier, IconPack.Ex, stringResource(R.string.keyboard_exp), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.expBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Power10, stringResource(R.string.keyboard_power_10), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightTallAdditional) { onInvClick() } + KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_euler), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, IconPack.Ex, stringResource(R.string.keyboard_exp), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.expBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Power10, stringResource(R.string.keyboard_power_10), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } } ) } else { @@ -240,21 +240,21 @@ private fun PortraitKeyboard( showAdditional = showAdditional, buttonHeight = additionalButtonHeight, content1 = { buttonModifier -> - KeyboardButtonAdditional(buttonModifier, IconPack.Root, stringResource(R.string.keyboard_root), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Operator.sqrt) } - KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Const.pi) } - KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Operator.factorial) } + KeyboardButtonAdditional(buttonModifier, IconPack.Root, stringResource(R.string.keyboard_root), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Operator.sqrt) } + KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Const.pi) } + KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Operator.factorial) } }, content2 = { buttonModifier -> - KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightTallAdditional) { toggleAngleMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Sin, stringResource(R.string.keyboard_sin), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.sinBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Cos, stringResource(R.string.keyboard_cos), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.cosBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Tan, stringResource(R.string.keyboard_tan), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.tanBracket) } + KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightTallAdditional) { onAngleClick(!radianMode) } + KeyboardButtonAdditional(buttonModifier, IconPack.Sin, stringResource(R.string.keyboard_sin), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.sinBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Cos, stringResource(R.string.keyboard_cos), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.cosBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Tan, stringResource(R.string.keyboard_tan), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.tanBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightTallAdditional) { toggleInvMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_exp), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Const.e) } - KeyboardButtonAdditional(buttonModifier, IconPack.Ln, stringResource(R.string.keyboard_ln), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.lnBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Log, stringResource(R.string.keyboard_log), KeyboardButtonContentHeightTallAdditional) { addSymbol(Token.Func.logBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightTallAdditional) { onInvClick() } + KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_exp), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, IconPack.Ln, stringResource(R.string.keyboard_ln), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.lnBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Log, stringResource(R.string.keyboard_log), KeyboardButtonContentHeightTallAdditional) { onAddTokenClick(Token.Func.logBracket) } } ) } @@ -286,40 +286,40 @@ private fun PortraitKeyboard( .fillMaxWidth(width) .fillMaxHeight(height) - if (acButton) { - KeyboardButtonTertiary(mainButtonModifier, IconPack.Clear, stringResource(R.string.clear_label), KeyboardButtonContentHeightTall) { clearSymbols() } - KeyboardButtonFilled(mainButtonModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), KeyboardButtonContentHeightTall) { addBracket() } + if (showAcButton) { + KeyboardButtonTertiary(mainButtonModifier, IconPack.Clear, stringResource(R.string.clear_label), KeyboardButtonContentHeightTall) { onClearClick() } + KeyboardButtonFilled(mainButtonModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), KeyboardButtonContentHeightTall) { onBracketsClick() } } else { - KeyboardButtonFilled(mainButtonModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.leftBracket) } - KeyboardButtonFilled(mainButtonModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.rightBracket) } + KeyboardButtonFilled(mainButtonModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.leftBracket) } + KeyboardButtonFilled(mainButtonModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.rightBracket) } } - KeyboardButtonFilled(mainButtonModifier, IconPack.Percent, stringResource(R.string.keyboard_percent), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.percent) } - KeyboardButtonFilled(mainButtonModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.divide) } + KeyboardButtonFilled(mainButtonModifier, IconPack.Percent, stringResource(R.string.keyboard_percent), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.percent) } + KeyboardButtonFilled(mainButtonModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.divide) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key7, Token.Digit._7, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._7) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key8, Token.Digit._8, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._8) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key9, Token.Digit._9, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._9) } - KeyboardButtonFilled(mainButtonModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.multiply) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key7, Token.Digit._7, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._7) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key8, Token.Digit._8, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._8) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key9, Token.Digit._9, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._9) } + KeyboardButtonFilled(mainButtonModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.multiply) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key4, Token.Digit._4, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._4) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key5, Token.Digit._5, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._5) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key6, Token.Digit._6, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._6) } - KeyboardButtonFilled(mainButtonModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.minus) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key4, Token.Digit._4, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._4) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key5, Token.Digit._5, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._5) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key6, Token.Digit._6, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._6) } + KeyboardButtonFilled(mainButtonModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.minus) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key1, Token.Digit._1, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._1) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key2, Token.Digit._2, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._2) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key3, Token.Digit._3, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._3) } - KeyboardButtonFilled(mainButtonModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.plus) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key1, Token.Digit._1, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._1) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key2, Token.Digit._2, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._2) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key3, Token.Digit._3, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._3) } + KeyboardButtonFilled(mainButtonModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Operator.plus) } if (middleZero) { - KeyboardButtonLight(mainButtonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightTall) { addSymbol(Token.Digit.dot) } - KeyboardButtonLight(mainButtonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(mainButtonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit.dot) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._0) } } else { - KeyboardButtonLight(mainButtonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._0) } - KeyboardButtonLight(mainButtonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightTall) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(mainButtonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit._0) } + KeyboardButtonLight(mainButtonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightTall) { onAddTokenClick(Token.Digit.dot) } } - KeyboardButtonLight(mainButtonModifier, IconPack.Backspace, stringResource(R.string.delete_label), KeyboardButtonContentHeightTall, clearSymbols) { deleteSymbol() } - KeyboardButtonFilled(mainButtonModifier, IconPack.Equal, stringResource(R.string.keyboard_equal), KeyboardButtonContentHeightTall) { equal() } + KeyboardButtonLight(mainButtonModifier, IconPack.Backspace, stringResource(R.string.delete_label), KeyboardButtonContentHeightTall, onClearClick) { onDeleteClick() } + KeyboardButtonFilled(mainButtonModifier, IconPack.Equal, stringResource(R.string.keyboard_equal), KeyboardButtonContentHeightTall) { onEqualClick() } } Spacer(modifier = Modifier.height(spacerHeight)) @@ -397,18 +397,18 @@ private fun AdditionalPortrait( @Composable private fun LandscapeKeyboard( modifier: Modifier, + onAddTokenClick: (String) -> Unit, + onBracketsClick: () -> Unit, + onDeleteClick: () -> Unit, + onClearClick: () -> Unit, + onEqualClick: () -> Unit, + onInvClick: () -> Unit, + onAngleClick: (Boolean) -> Unit, + showInvButtons: Boolean, radianMode: Boolean, - fractional: String, + showAcButton: Boolean, middleZero: Boolean, - addSymbol: (String) -> Unit, - toggleAngleMode: () -> Unit, - deleteSymbol: () -> Unit, - clearSymbols: () -> Unit, - equal: () -> Unit, - acButton: Boolean, - addBracket: () -> Unit, - invMode: Boolean, - toggleInvMode: () -> Unit, + fractional: String, ) { val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg } val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree } @@ -417,7 +417,7 @@ private fun LandscapeKeyboard( val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma } Crossfade( - targetState = invMode, + targetState = showInvButtons, label = "Inverse switch", modifier = modifier ) { inverse -> @@ -431,51 +431,51 @@ private fun LandscapeKeyboard( .fillMaxWidth(width) .fillMaxHeight(height) - KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightShortAdditional) { toggleAngleMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Modulo, stringResource(R.string.keyboard_modulo), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Operator.modulo) } - KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Const.pi) } - KeyboardButtonLight(buttonModifier, IconPack.Key7, Token.Digit._7, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._7) } - KeyboardButtonLight(buttonModifier, IconPack.Key8, Token.Digit._8, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._8) } - KeyboardButtonLight(buttonModifier, IconPack.Key9, Token.Digit._9, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._9) } - if (acButton) { - KeyboardButtonTertiary(buttonModifier, IconPack.Clear, stringResource(R.string.clear_label), KeyboardButtonContentHeightShort) { clearSymbols() } - KeyboardButtonFilled(buttonModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), KeyboardButtonContentHeightShort) { addBracket() } + KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightShortAdditional) { onAngleClick(!radianMode) } + KeyboardButtonAdditional(buttonModifier, IconPack.Modulo, stringResource(R.string.keyboard_modulo), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Operator.modulo) } + KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Const.pi) } + KeyboardButtonLight(buttonModifier, IconPack.Key7, Token.Digit._7, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._7) } + KeyboardButtonLight(buttonModifier, IconPack.Key8, Token.Digit._8, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._8) } + KeyboardButtonLight(buttonModifier, IconPack.Key9, Token.Digit._9, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._9) } + if (showAcButton) { + KeyboardButtonTertiary(buttonModifier, IconPack.Clear, stringResource(R.string.clear_label), KeyboardButtonContentHeightShort) { onClearClick() } + KeyboardButtonFilled(buttonModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), KeyboardButtonContentHeightShort) { onBracketsClick() } } else { - KeyboardButtonFilled(buttonModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.leftBracket) } - KeyboardButtonFilled(buttonModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.rightBracket) } + KeyboardButtonFilled(buttonModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.leftBracket) } + KeyboardButtonFilled(buttonModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.rightBracket) } } - KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightShortAdditional) { toggleInvMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Operator.factorial) } - KeyboardButtonLight(buttonModifier, IconPack.Key4, Token.Digit._4, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._4) } - KeyboardButtonLight(buttonModifier, IconPack.Key5, Token.Digit._5, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._5) } - KeyboardButtonLight(buttonModifier, IconPack.Key6, Token.Digit._6, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._6) } - KeyboardButtonFilled(buttonModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.multiply) } - KeyboardButtonFilled(buttonModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.divide) } + KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightShortAdditional) { onInvClick() } + KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Operator.factorial) } + KeyboardButtonLight(buttonModifier, IconPack.Key4, Token.Digit._4, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._4) } + KeyboardButtonLight(buttonModifier, IconPack.Key5, Token.Digit._5, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._5) } + KeyboardButtonLight(buttonModifier, IconPack.Key6, Token.Digit._6, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._6) } + KeyboardButtonFilled(buttonModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.multiply) } + KeyboardButtonFilled(buttonModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.divide) } - KeyboardButtonAdditional(buttonModifier, IconPack.ArSin, stringResource(R.string.keyboard_arsin), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.arsinBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.ArCos, stringResource(R.string.keyboard_arcos), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.arcosBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.AcTan, stringResource(R.string.keyboard_actan), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.actanBracket) } - KeyboardButtonLight(buttonModifier, IconPack.Key1, Token.Digit._1, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._1) } - KeyboardButtonLight(buttonModifier, IconPack.Key2, Token.Digit._2, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._2) } - KeyboardButtonLight(buttonModifier, IconPack.Key3, Token.Digit._3, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._3) } - KeyboardButtonFilled(buttonModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.minus) } - KeyboardButtonFilled(buttonModifier, IconPack.Percent, stringResource(R.string.keyboard_percent), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.percent) } + KeyboardButtonAdditional(buttonModifier, IconPack.ArSin, stringResource(R.string.keyboard_arsin), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.arsinBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.ArCos, stringResource(R.string.keyboard_arcos), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.arcosBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.AcTan, stringResource(R.string.keyboard_actan), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.actanBracket) } + KeyboardButtonLight(buttonModifier, IconPack.Key1, Token.Digit._1, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._1) } + KeyboardButtonLight(buttonModifier, IconPack.Key2, Token.Digit._2, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._2) } + KeyboardButtonLight(buttonModifier, IconPack.Key3, Token.Digit._3, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._3) } + KeyboardButtonFilled(buttonModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.minus) } + KeyboardButtonFilled(buttonModifier, IconPack.Percent, stringResource(R.string.keyboard_percent), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.percent) } - KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_euler), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Const.e) } - KeyboardButtonAdditional(buttonModifier, IconPack.Ex, stringResource(R.string.keyboard_exp), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.expBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Power10, stringResource(R.string.keyboard_power_10), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_euler), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, IconPack.Ex, stringResource(R.string.keyboard_exp), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.expBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Power10, stringResource(R.string.keyboard_power_10), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } if (middleZero) { - KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } - KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit.dot) } + KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._0) } } else { - KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } - KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._0) } + KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit.dot) } } - KeyboardButtonLight(buttonModifier, IconPack.Backspace, stringResource(R.string.delete_label), KeyboardButtonContentHeightShort, clearSymbols) { deleteSymbol() } - KeyboardButtonFilled(buttonModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.plus) } - KeyboardButtonFilled(buttonModifier, IconPack.Equal, stringResource(R.string.keyboard_equal), KeyboardButtonContentHeightShort) { equal() } + KeyboardButtonLight(buttonModifier, IconPack.Backspace, stringResource(R.string.delete_label), KeyboardButtonContentHeightShort, onClearClick) { onDeleteClick() } + KeyboardButtonFilled(buttonModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.plus) } + KeyboardButtonFilled(buttonModifier, IconPack.Equal, stringResource(R.string.keyboard_equal), KeyboardButtonContentHeightShort) { onEqualClick() } } } else { KeypadFlow( @@ -487,51 +487,51 @@ private fun LandscapeKeyboard( .fillMaxWidth(width) .fillMaxHeight(height) - KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightShortAdditional) { toggleAngleMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Root, stringResource(R.string.keyboard_root), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Operator.sqrt) } - KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Const.pi) } - KeyboardButtonLight(buttonModifier, IconPack.Key7, Token.Digit._7, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._7) } - KeyboardButtonLight(buttonModifier, IconPack.Key8, Token.Digit._8, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._8) } - KeyboardButtonLight(buttonModifier, IconPack.Key9, Token.Digit._9, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._9) } - if (acButton) { - KeyboardButtonTertiary(buttonModifier, IconPack.Clear, stringResource(R.string.clear_label), KeyboardButtonContentHeightShort) { clearSymbols() } - KeyboardButtonFilled(buttonModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), KeyboardButtonContentHeightShort) { addBracket() } + KeyboardButtonAdditional(buttonModifier, angleIcon, stringResource(angleIconDescription), KeyboardButtonContentHeightShortAdditional) { onAngleClick(!radianMode) } + KeyboardButtonAdditional(buttonModifier, IconPack.Root, stringResource(R.string.keyboard_root), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Operator.sqrt) } + KeyboardButtonAdditional(buttonModifier, IconPack.Pi, stringResource(R.string.keyboard_pi), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Const.pi) } + KeyboardButtonLight(buttonModifier, IconPack.Key7, Token.Digit._7, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._7) } + KeyboardButtonLight(buttonModifier, IconPack.Key8, Token.Digit._8, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._8) } + KeyboardButtonLight(buttonModifier, IconPack.Key9, Token.Digit._9, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._9) } + if (showAcButton) { + KeyboardButtonTertiary(buttonModifier, IconPack.Clear, stringResource(R.string.clear_label), KeyboardButtonContentHeightShort) { onClearClick() } + KeyboardButtonFilled(buttonModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), KeyboardButtonContentHeightShort) { onBracketsClick() } } else { - KeyboardButtonFilled(buttonModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.leftBracket) } - KeyboardButtonFilled(buttonModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.rightBracket) } + KeyboardButtonFilled(buttonModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.leftBracket) } + KeyboardButtonFilled(buttonModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.rightBracket) } } - KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightShortAdditional) { toggleInvMode() } - KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Operator.factorial) } - KeyboardButtonLight(buttonModifier, IconPack.Key4, Token.Digit._4, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._4) } - KeyboardButtonLight(buttonModifier, IconPack.Key5, Token.Digit._5, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._5) } - KeyboardButtonLight(buttonModifier, IconPack.Key6, Token.Digit._6, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._6) } - KeyboardButtonFilled(buttonModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.multiply) } - KeyboardButtonFilled(buttonModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.divide) } + KeyboardButtonAdditional(buttonModifier, IconPack.Inv, stringResource(R.string.keyboard_inverse), KeyboardButtonContentHeightShortAdditional) { onInvClick() } + KeyboardButtonAdditional(buttonModifier, IconPack.Power, stringResource(R.string.keyboard_power), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, IconPack.Factorial, stringResource(R.string.keyboard_factorial), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Operator.factorial) } + KeyboardButtonLight(buttonModifier, IconPack.Key4, Token.Digit._4, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._4) } + KeyboardButtonLight(buttonModifier, IconPack.Key5, Token.Digit._5, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._5) } + KeyboardButtonLight(buttonModifier, IconPack.Key6, Token.Digit._6, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._6) } + KeyboardButtonFilled(buttonModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.multiply) } + KeyboardButtonFilled(buttonModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.divide) } - KeyboardButtonAdditional(buttonModifier, IconPack.Sin, stringResource(R.string.keyboard_sin), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.sinBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Cos, stringResource(R.string.keyboard_cos), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.cosBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Tan, stringResource(R.string.keyboard_tan), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.tanBracket) } - KeyboardButtonLight(buttonModifier, IconPack.Key1, Token.Digit._1, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._1) } - KeyboardButtonLight(buttonModifier, IconPack.Key2, Token.Digit._2, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._2) } - KeyboardButtonLight(buttonModifier, IconPack.Key3, Token.Digit._3, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._3) } - KeyboardButtonFilled(buttonModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.minus) } - KeyboardButtonFilled(buttonModifier, IconPack.Percent, stringResource(R.string.keyboard_percent), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.percent) } + KeyboardButtonAdditional(buttonModifier, IconPack.Sin, stringResource(R.string.keyboard_sin), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.sinBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Cos, stringResource(R.string.keyboard_cos), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.cosBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Tan, stringResource(R.string.keyboard_tan), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.tanBracket) } + KeyboardButtonLight(buttonModifier, IconPack.Key1, Token.Digit._1, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._1) } + KeyboardButtonLight(buttonModifier, IconPack.Key2, Token.Digit._2, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._2) } + KeyboardButtonLight(buttonModifier, IconPack.Key3, Token.Digit._3, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._3) } + KeyboardButtonFilled(buttonModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.minus) } + KeyboardButtonFilled(buttonModifier, IconPack.Percent, stringResource(R.string.keyboard_percent), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.percent) } - KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_euler), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Const.e) } - KeyboardButtonAdditional(buttonModifier, IconPack.Ln, stringResource(R.string.keyboard_ln), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.lnBracket) } - KeyboardButtonAdditional(buttonModifier, IconPack.Log, stringResource(R.string.keyboard_log), KeyboardButtonContentHeightShortAdditional) { addSymbol(Token.Func.logBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Euler, stringResource(R.string.keyboard_euler), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, IconPack.Ln, stringResource(R.string.keyboard_ln), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.lnBracket) } + KeyboardButtonAdditional(buttonModifier, IconPack.Log, stringResource(R.string.keyboard_log), KeyboardButtonContentHeightShortAdditional) { onAddTokenClick(Token.Func.logBracket) } if (middleZero) { - KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } - KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit.dot) } + KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._0) } } else { - KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } - KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(buttonModifier, IconPack.Key0, Token.Digit._0, KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit._0) } + KeyboardButtonLight(buttonModifier, fractionalIcon, stringResource(fractionalIconDescription), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Digit.dot) } } - KeyboardButtonLight(buttonModifier, IconPack.Backspace, stringResource(R.string.delete_label), KeyboardButtonContentHeightShort, clearSymbols) { deleteSymbol() } - KeyboardButtonFilled(buttonModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.plus) } - KeyboardButtonFilled(buttonModifier, IconPack.Equal, stringResource(R.string.keyboard_equal), KeyboardButtonContentHeightShort) { equal() } + KeyboardButtonLight(buttonModifier, IconPack.Backspace, stringResource(R.string.delete_label), KeyboardButtonContentHeightShort, onClearClick) { onDeleteClick() } + KeyboardButtonFilled(buttonModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), KeyboardButtonContentHeightShort) { onAddTokenClick(Token.Operator.plus) } + KeyboardButtonFilled(buttonModifier, IconPack.Equal, stringResource(R.string.keyboard_equal), KeyboardButtonContentHeightShort) { onEqualClick() } } } } @@ -542,18 +542,18 @@ private fun LandscapeKeyboard( private fun PreviewPortraitKeyboard() { PortraitKeyboard( modifier = Modifier.fillMaxHeight(), + onAddTokenClick = {}, + onBracketsClick = {}, + onDeleteClick = {}, + onClearClick = {}, + onEqualClick = {}, + onInvClick = {}, + onAngleClick = {}, + showInvButtons = false, radianMode = true, - fractional = Token.PERIOD, - addSymbol = {}, - clearSymbols = {}, - deleteSymbol = {}, - toggleAngleMode = {}, - equal = {}, + showAcButton = true, middleZero = false, - acButton = true, - addBracket = {}, - invMode = false, - toggleInvMode = {} + fractional = Token.PERIOD, ) } @@ -562,17 +562,17 @@ private fun PreviewPortraitKeyboard() { private fun PreviewLandscapeKeyboard() { LandscapeKeyboard( modifier = Modifier.fillMaxHeight(), + onAddTokenClick = {}, + onBracketsClick = {}, + onDeleteClick = {}, + onClearClick = {}, + onEqualClick = {}, + onInvClick = {}, + onAngleClick = {}, + showInvButtons = false, radianMode = true, - fractional = Token.PERIOD, - addSymbol = {}, - clearSymbols = {}, - deleteSymbol = {}, - toggleAngleMode = {}, - equal = {}, + showAcButton = true, middleZero = false, - acButton = true, - addBracket = {}, - invMode = false, - toggleInvMode = {} + fractional = Token.PERIOD, ) } diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt index 20f630bf..542f09d9 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.semantics.testTag import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import com.sadellie.unitto.core.base.FormatterSymbols +import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.ui.LocalWindowSize import com.sadellie.unitto.core.ui.WindowHeightSizeClass import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField @@ -78,26 +79,23 @@ fun TextBox( formatterSymbols = formatterSymbols ) if (LocalWindowSize.current.heightSizeClass > WindowHeightSizeClass.Compact) { + val calculationResultModifier = Modifier + .weight(2f) + .fillMaxWidth() + .padding(horizontal = 8.dp) + when (output) { is CalculationResult.Empty -> { Spacer( - modifier = Modifier - .weight(2f) - .fillMaxWidth() - .padding(horizontal = 8.dp) + modifier = calculationResultModifier ) } is CalculationResult.Default -> { - var outputTF by remember(output) { - mutableStateOf(TextFieldValue(output.text)) - } + var outputTF by remember(output) { mutableStateOf(TextFieldValue(output.text)) } ExpressionTextField( - modifier = Modifier - .weight(2f) - .fillMaxWidth() - .padding(horizontal = 8.dp), + modifier = calculationResultModifier, value = outputTF, minRatio = 0.8f, onValueChange = { outputTF = it }, @@ -108,17 +106,13 @@ fun TextBox( } is CalculationResult.Fraction -> { - var outputTF by remember(output) { - mutableStateOf(TextFieldValue(output.text)) - } + var outputTF by remember(output) { mutableStateOf(TextFieldValue(output.text)) } + ExpressionTextField( - modifier = Modifier - .weight(2f) - .fillMaxWidth() - .padding(horizontal = 8.dp), + modifier = calculationResultModifier, value = outputTF, minRatio = 0.8f, - onValueChange = { outputTF = it }, + onValueChange = { outputTF = outputTF.copy(selection = it.selection) }, textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f), formatterSymbols = formatterSymbols, readOnly = true, @@ -127,11 +121,8 @@ fun TextBox( is CalculationResult.DivideByZeroError -> { SimpleTextField( - modifier = Modifier - .weight(2f) - .fillMaxWidth() - .padding(horizontal = 8.dp), - value = TextFieldValue(stringResource(output.label)), + modifier = calculationResultModifier, + value = TextFieldValue(stringResource(R.string.calculator_divide_by_zero_error)), minRatio = 0.8f, onValueChange = {}, textColor = MaterialTheme.colorScheme.error, @@ -145,7 +136,7 @@ fun TextBox( .weight(2f) .fillMaxWidth() .padding(horizontal = 8.dp), - value = TextFieldValue(stringResource(output.label)), + value = TextFieldValue(stringResource(R.string.error_label)), minRatio = 0.8f, onValueChange = {}, textColor = MaterialTheme.colorScheme.error,