From 1def59bca5af2501a24ae7bc84e19c4156d1425e Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Tue, 21 Nov 2023 17:34:02 +0300 Subject: [PATCH] Flex keyboards: - Switched to FlowRow - Calculating keypad button sizes only once - Improved responsive design - Overall decreased GPU usage by 10-20% - Returned a bug with wide delete button (very sad) closes: #131 --- .../sadellie/unitto/ConfigureKotlinAndroid.kt | 1 + .../unitto/core/ui/common/KeyboardButton.kt | 24 +- .../unitto/core/ui/common/KeypadFlow.kt | 63 ++ .../calculator/RPNCalculatorKeyboard.kt | 188 ++++-- .../components/CalculatorKeyboard.kt | 581 +++++++++--------- .../feature/converter/components/ChipsRow.kt | 2 - .../converter/components/ConverterKeyboard.kt | 181 +++--- .../addsubtract/AddSubtractPage.kt | 2 - .../{Keyboard.kt => AddSubtractKeyboard.kt} | 143 ++--- .../difference/DateDifferencePage.kt | 2 - 10 files changed, 654 insertions(+), 533 deletions(-) create mode 100644 core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeypadFlow.kt rename feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/{Keyboard.kt => AddSubtractKeyboard.kt} (54%) diff --git a/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt b/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt index c51737d9..29d03d3c 100644 --- a/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt +++ b/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt @@ -78,6 +78,7 @@ internal fun Project.configureKotlinAndroid( "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api", "-opt-in=androidx.compose.animation.ExperimentalAnimationApi", "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi", + "-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi", "-opt-in=androidx.compose.ui.unit.ExperimentalUnitApi", "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", ) diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeyboardButton.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeyboardButton.kt index 9af4232b..078c0218 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeyboardButton.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeyboardButton.kt @@ -33,7 +33,6 @@ import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalView -import com.sadellie.unitto.core.ui.isPortrait import kotlinx.coroutines.launch @Composable @@ -83,7 +82,7 @@ fun KeyboardButtonLight( modifier: Modifier, icon: ImageVector, allowVibration: Boolean, - contentHeight: Float = if (isPortrait()) 0.578f else 0.793f, + contentHeight: Float, onLongClick: (() -> Unit)? = null, onClick: () -> Unit, ) { @@ -104,7 +103,7 @@ fun KeyboardButtonFilled( modifier: Modifier, icon: ImageVector, allowVibration: Boolean, - contentHeight: Float = if (isPortrait()) 0.578f else 0.793f, + contentHeight: Float, onLongClick: (() -> Unit)? = null, onClick: () -> Unit, ) { @@ -125,7 +124,7 @@ fun KeyboardButtonAdditional( modifier: Modifier, icon: ImageVector, allowVibration: Boolean, - contentHeight: Float = 0.906f, + contentHeight: Float, onLongClick: (() -> Unit)? = null, onClick: () -> Unit, ) { @@ -146,7 +145,7 @@ fun KeyboardButtonTertiary( modifier: Modifier, icon: ImageVector, allowVibration: Boolean, - contentHeight: Float = if (isPortrait()) 0.578f else 0.793f, + contentHeight: Float, onLongClick: (() -> Unit)? = null, onClick: () -> Unit, ) { @@ -161,3 +160,18 @@ fun KeyboardButtonTertiary( allowVibration = allowVibration, ) } + +/** + * Mostly for main button in portrait mode. Changes icon size inside. + */ +const val KeyboardButtonContentHeightTall = 0.578f + +/** + * Mostly for main button in landscape mode. Changes icon size inside. + */ +const val KeyboardButtonContentHeightShort = 0.793f + +/** + * Mostly for additional buttons. Changes icon size inside. + */ +const val KeyboardButtonContentHeightWide = 0.906f diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeypadFlow.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeypadFlow.kt new file mode 100644 index 00000000..b77a9767 --- /dev/null +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/KeypadFlow.kt @@ -0,0 +1,63 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sadellie.unitto.core.ui.common + +import androidx.annotation.IntRange +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.FlowRowScope +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier + +/** + * Keypad layout for buttons. Uses [FlowRow]. + * + * @param modifier [Modifier] that will be applied to [FlowRow]. + * @param rows Amount of rows. Vertical size. + * @param columns Amount of columns. Horizontal size. + * @param verticalPadding Percentage. How much space of button height is gonna be a padding. + * @param horizontalPadding Percentage. How much space of button width is gonna be a padding. + * @param content Content, usually some buttons. Use `width` and `height` in [fillMaxWidth] + * and [fillMaxHeight] to build a [Modifier]. Passed [Composable]s are equally distributed, occupy + * entire height and width. + */ +@Composable +fun KeypadFlow( + modifier: Modifier, + rows: Int, + columns: Int, + @IntRange(0, 100) verticalPadding: Int = 10, + @IntRange(0, 100) horizontalPadding: Int = 10, + content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit +) { + val height: Float = remember { (1f - verticalPadding / 100f) / rows } + val width: Float = remember { (1f - horizontalPadding / 100f) / columns } + + FlowRow( + modifier = modifier, + maxItemsInEachRow = columns, + horizontalArrangement = Arrangement.SpaceAround, + verticalArrangement = Arrangement.SpaceAround + ) { + content(width, height) + } +} diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/RPNCalculatorKeyboard.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/RPNCalculatorKeyboard.kt index b517b75b..8e740587 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/RPNCalculatorKeyboard.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/RPNCalculatorKeyboard.kt @@ -18,21 +18,26 @@ package com.sadellie.unitto.feature.calculator -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.ExperimentalLayoutApi -import androidx.compose.foundation.layout.FlowRow +import android.content.res.Configuration +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.tooling.preview.Preview import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.KeyboardButtonAdditional +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightShort +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightTall +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightWide import com.sadellie.unitto.core.ui.common.KeyboardButtonFilled import com.sadellie.unitto.core.ui.common.KeyboardButtonLight import com.sadellie.unitto.core.ui.common.KeyboardButtonTertiary +import com.sadellie.unitto.core.ui.common.KeypadFlow import com.sadellie.unitto.core.ui.common.key.UnittoIcons import com.sadellie.unitto.core.ui.common.key.unittoicons.Backspace import com.sadellie.unitto.core.ui.common.key.unittoicons.Clear @@ -61,7 +66,6 @@ import com.sadellie.unitto.core.ui.common.key.unittoicons.Unary import com.sadellie.unitto.core.ui.common.key.unittoicons.Up import io.github.sadellie.evaluatto.RPNCalculation -@OptIn(ExperimentalLayoutApi::class) @Composable internal fun RPNCalculatorKeyboard( modifier: Modifier, @@ -73,69 +77,151 @@ internal fun RPNCalculatorKeyboard( ) { val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma } - val columns = 4 - val mainButtonRows = 5f - val additionalButtonRows = 1f - val additionalButtonRowFactor = 0.7f // How much smaller are the additional buttons than the main buttons - val additionalButtonIconHeight = 0.65f - val fillFactor = 0.92f + if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) { + RPNCalculatorKeyboardPortrait( + modifier = modifier, + fractionalIcon = fractionalIcon, + middleZero = middleZero, + allowVibration = allowVibration, + onCalculationClick = onCalculationClick, + onInputEditClick = onInputEditClick + ) + } else { + RPNCalculatorKeyboardLandscape( + modifier = modifier, + fractionalIcon = fractionalIcon, + middleZero = middleZero, + allowVibration = allowVibration, + onCalculationClick = onCalculationClick, + onInputEditClick = onInputEditClick + ) + } +} - val rows = remember { mainButtonRows + additionalButtonRows * additionalButtonRowFactor } - val height = remember { fillFactor / rows } - val width = remember { fillFactor / columns } - - FlowRow( - maxItemsInEachRow = columns, - modifier = modifier, - horizontalArrangement = Arrangement.SpaceAround, - verticalArrangement = Arrangement.SpaceAround +@Composable +private fun RPNCalculatorKeyboardPortrait( + modifier: Modifier, + fractionalIcon: ImageVector, + middleZero: Boolean, + allowVibration: Boolean, + onCalculationClick: (RPNCalculation) -> Unit, + onInputEditClick: (RPNInputEdit) -> Unit, +) { + Column( + modifier = modifier ) { - val aModifier = Modifier - .fillMaxHeight(height * additionalButtonRowFactor) - .fillMaxWidth(width) + KeypadFlow( + modifier = Modifier.fillMaxHeight(0.1f).fillMaxWidth(), + rows = 1, + columns = 4 + ) { width, height -> + val aModifier = Modifier + .fillMaxHeight(height) + .fillMaxWidth(width) + KeyboardButtonAdditional(aModifier, UnittoIcons.Swap, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.Swap) } + KeyboardButtonAdditional(aModifier, UnittoIcons.Up, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.RotateUp) } + KeyboardButtonAdditional(aModifier, UnittoIcons.Down, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.RotateDown) } + KeyboardButtonAdditional(aModifier, UnittoIcons.Pop, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.Pop) } + } + + KeypadFlow( + modifier = Modifier.weight(1f).fillMaxSize(), + rows = 5, + columns = 4 + ) { width, height -> + val bModifier = Modifier + .fillMaxHeight(height) + .fillMaxWidth(width) + + KeyboardButtonTertiary(bModifier, UnittoIcons.Clear, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Clear) } + KeyboardButtonFilled(bModifier, UnittoIcons.Unary, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Negate) } + KeyboardButtonFilled(bModifier, UnittoIcons.Percent, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Percent) } + KeyboardButtonFilled(bModifier, UnittoIcons.Divide, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Divide) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key7, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._7)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key8, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._8)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key9, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._9)) } + KeyboardButtonFilled(bModifier, UnittoIcons.Multiply, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Multiply) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key4, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._4)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key5, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._5)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key6, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._6)) } + KeyboardButtonFilled(bModifier, UnittoIcons.Minus, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Minus) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key1, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._1)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key2, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._2)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key3, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._3)) } + KeyboardButtonFilled(bModifier, UnittoIcons.Plus, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Plus) } + + if (middleZero) { + KeyboardButtonLight(bModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Dot) } + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._0)) } + } else { + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._0)) } + KeyboardButtonLight(bModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Dot) } + } + KeyboardButtonLight(bModifier, UnittoIcons.Backspace, allowVibration, KeyboardButtonContentHeightTall) { onInputEditClick(RPNInputEdit.Delete) } + KeyboardButtonFilled(bModifier, UnittoIcons.Enter, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Enter) } + } + } +} + +@Composable +private fun RPNCalculatorKeyboardLandscape( + modifier: Modifier, + fractionalIcon: ImageVector, + middleZero: Boolean, + allowVibration: Boolean, + onCalculationClick: (RPNCalculation) -> Unit, + onInputEditClick: (RPNInputEdit) -> Unit, +) { + KeypadFlow( + modifier = modifier, + rows = 4, + columns = 6 + ) { width, height -> val bModifier = Modifier .fillMaxHeight(height) .fillMaxWidth(width) - KeyboardButtonAdditional(modifier = aModifier, icon = UnittoIcons.Swap, allowVibration = allowVibration, contentHeight = additionalButtonIconHeight) { onCalculationClick(RPNCalculation.Swap) } - KeyboardButtonAdditional(modifier = aModifier, icon = UnittoIcons.Up, allowVibration = allowVibration, contentHeight = additionalButtonIconHeight) { onCalculationClick(RPNCalculation.RotateUp) } - KeyboardButtonAdditional(modifier = aModifier, icon = UnittoIcons.Down, allowVibration = allowVibration, contentHeight = additionalButtonIconHeight) { onCalculationClick(RPNCalculation.RotateDown) } - KeyboardButtonAdditional(modifier = aModifier, icon = UnittoIcons.Pop, allowVibration = allowVibration, contentHeight = additionalButtonIconHeight) { onCalculationClick(RPNCalculation.Pop) } + KeyboardButtonAdditional(bModifier, UnittoIcons.Swap, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.Swap) } + KeyboardButtonLight(bModifier, UnittoIcons.Key7, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._7)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key8, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._8)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key9, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._9)) } + KeyboardButtonTertiary(bModifier, UnittoIcons.Clear, allowVibration, KeyboardButtonContentHeightTall) { onCalculationClick(RPNCalculation.Clear) } + KeyboardButtonFilled(bModifier, UnittoIcons.Unary, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Negate) } - KeyboardButtonTertiary(modifier = bModifier, icon = UnittoIcons.Clear, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Clear) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Unary, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Negate) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Percent, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Percent) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Divide, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Divide) } + KeyboardButtonAdditional(bModifier, UnittoIcons.Up, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.RotateUp) } + KeyboardButtonLight(bModifier, UnittoIcons.Key4, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._4)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key5, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._5)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key6, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._6)) } + KeyboardButtonFilled(bModifier, UnittoIcons.Multiply, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Multiply) } + KeyboardButtonFilled(bModifier, UnittoIcons.Divide, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Divide) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key7, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._7)) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key8, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._8)) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key9, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._9)) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Multiply, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Multiply) } - - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key4, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._4)) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key5, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._5)) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key6, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._6)) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Minus, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Minus) } - - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key1, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._1)) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key2, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._2)) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key3, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._3)) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Plus, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Plus) } + KeyboardButtonAdditional(bModifier, UnittoIcons.Down, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.RotateDown) } + KeyboardButtonLight(bModifier, UnittoIcons.Key1, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._1)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key2, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._2)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key3, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._3)) } + KeyboardButtonFilled(bModifier, UnittoIcons.Plus, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Plus) } + KeyboardButtonFilled(bModifier, UnittoIcons.Minus, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Minus) } + KeyboardButtonAdditional(bModifier, UnittoIcons.Pop, allowVibration, KeyboardButtonContentHeightWide) { onCalculationClick(RPNCalculation.Pop) } if (middleZero) { - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key0, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._0)) } - KeyboardButtonLight(modifier = bModifier, icon = fractionalIcon, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Dot) } + KeyboardButtonLight(bModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Dot) } + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._0)) } } else { - KeyboardButtonLight(modifier = bModifier, icon = fractionalIcon, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Dot) } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Key0, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._0)) } + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Digit(Token.Digit._0)) } + KeyboardButtonLight(bModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Dot) } } - KeyboardButtonLight(modifier = bModifier, icon = UnittoIcons.Backspace, allowVibration = allowVibration) { onInputEditClick(RPNInputEdit.Delete) } - KeyboardButtonFilled(modifier = bModifier, icon = UnittoIcons.Enter, allowVibration = allowVibration) { onCalculationClick(RPNCalculation.Enter) } + KeyboardButtonLight(bModifier, UnittoIcons.Backspace, allowVibration, KeyboardButtonContentHeightShort) { onInputEditClick(RPNInputEdit.Delete) } + KeyboardButtonFilled(bModifier, UnittoIcons.Percent, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Percent) } + KeyboardButtonFilled(bModifier, UnittoIcons.Enter, allowVibration, KeyboardButtonContentHeightShort) { onCalculationClick(RPNCalculation.Enter) } } } -@Preview +@Preview(device = "spec:parent=pixel_5,orientation=portrait") +@Preview(device = "spec:parent=pixel_5,orientation=landscape") @Composable private fun PreviewKeyboard() { RPNCalculatorKeyboard( 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 533ec2dc..b47829aa 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 @@ -19,20 +19,23 @@ package com.sadellie.unitto.feature.calculator.components import android.content.res.Configuration -import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.AnimatedContent import androidx.compose.animation.Crossfade +import androidx.compose.animation.SizeTransform import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween +import androidx.compose.animation.expandVertically +import androidx.compose.animation.shrinkVertically +import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandMore @@ -41,7 +44,6 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -49,15 +51,20 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.ColumnWithConstraints import com.sadellie.unitto.core.ui.common.KeyboardButtonAdditional +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightShort +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightTall +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightWide import com.sadellie.unitto.core.ui.common.KeyboardButtonFilled import com.sadellie.unitto.core.ui.common.KeyboardButtonLight import com.sadellie.unitto.core.ui.common.KeyboardButtonTertiary -import com.sadellie.unitto.core.ui.common.RowWithConstraints +import com.sadellie.unitto.core.ui.common.KeypadFlow import com.sadellie.unitto.core.ui.common.key.UnittoIcons import com.sadellie.unitto.core.ui.common.key.unittoicons.AcTan import com.sadellie.unitto.core.ui.common.key.unittoicons.ArCos @@ -117,11 +124,15 @@ internal fun CalculatorKeyboard( toggleAngleMode: () -> Unit, evaluate: () -> Unit ) { + val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma } + val angleIcon = remember(radianMode) { if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg } + var invMode: Boolean by remember { mutableStateOf(false) } + if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) { PortraitKeyboard( modifier = modifier, - radianMode = radianMode, - fractional = fractional, + angleIcon = angleIcon, + fractionalIcon = fractionalIcon, allowVibration = allowVibration, middleZero = middleZero, addSymbol = addSymbol, @@ -131,12 +142,14 @@ internal fun CalculatorKeyboard( evaluate = evaluate, acButton = acButton, addBracket = addBracket, + invMode = invMode, + toggleInvMode = { invMode = !invMode }, ) } else { LandscapeKeyboard( modifier = modifier, - radianMode = radianMode, - fractional = fractional, + angleIcon = angleIcon, + fractionalIcon = fractionalIcon, allowVibration = allowVibration, middleZero = middleZero, addSymbol = addSymbol, @@ -146,6 +159,8 @@ internal fun CalculatorKeyboard( evaluate = evaluate, acButton = acButton, addBracket = addBracket, + invMode = invMode, + toggleInvMode = { invMode = !invMode }, ) } } @@ -153,8 +168,8 @@ internal fun CalculatorKeyboard( @Composable private fun PortraitKeyboard( modifier: Modifier, - radianMode: Boolean, - fractional: String, + angleIcon: ImageVector, + fractionalIcon: ImageVector, allowVibration: Boolean, middleZero: Boolean, addSymbol: (String) -> Unit, @@ -164,10 +179,10 @@ private fun PortraitKeyboard( evaluate: () -> Unit, acButton: Boolean, addBracket: () -> Unit, + invMode: Boolean, + toggleInvMode: () -> Unit, ) { - val fractionalIcon = remember { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma } var showAdditional: Boolean by remember { mutableStateOf(false) } - var invMode: Boolean by remember { mutableStateOf(false) } val expandRotation: Float by animateFloatAsState( targetValue = if (showAdditional) 180f else 0f, animationSpec = tween(easing = FastOutSlowInEasing), @@ -175,60 +190,67 @@ private fun PortraitKeyboard( ) ColumnWithConstraints( - modifier = modifier + modifier = modifier, ) { constraints -> - val mainButtonHorizontalPadding by remember(constraints.maxHeight) { - derivedStateOf { constraints.maxHeight * 0.007f } - } - - val additionalButtonHeight = remember { - constraints.maxHeight * 0.09f - } - - val spacerHeight = remember { - constraints.maxHeight * 0.025f - } - - val additionalRowSpacedBy = remember { - constraints.maxWidth * 0.03f - } - - val weightModifier = Modifier.weight(1f) - val mainButtonModifier = Modifier - .fillMaxSize() - .weight(1f) - .padding(mainButtonHorizontalPadding) - val additionalButtonModifier = Modifier - .weight(1f) - .height(additionalButtonHeight) + val spacerHeight = remember { constraints.maxHeight * 0.025f } + val additionalButtonHeight = remember { constraints.maxHeight * 0.09f } Spacer(modifier = Modifier.height(spacerHeight)) Row( - modifier = Modifier, - horizontalArrangement = Arrangement.spacedBy(additionalRowSpacedBy) + modifier = Modifier + .fillMaxWidth(), + horizontalArrangement = Arrangement.Start ) { - // Additional buttons - Crossfade(invMode, weightModifier, label = "Additional button") { - if (it) { - AdditionalButtonsPortraitInverse( - modifier = additionalButtonModifier, - allowVibration = allowVibration, - addSymbol = addSymbol, + Crossfade( + targetState = invMode, + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) { inverse -> + if (inverse) { + AdditionalPortrait( showAdditional = showAdditional, - radianMode = radianMode, - toggleAngleMode = toggleAngleMode, - toggleInvMode = { invMode = !invMode } + buttonHeight = additionalButtonHeight, + content1 = { buttonModifier -> + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Modulo, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.modulo) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Const.pi) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.PowerWide, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.factorial) } + }, + content2 = { buttonModifier -> + KeyboardButtonAdditional(buttonModifier, angleIcon, allowVibration, KeyboardButtonContentHeightWide) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArSin, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.arsinBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArCos, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.arcosBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.AcTan, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.actanBracket) } + + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration, KeyboardButtonContentHeightWide) { toggleInvMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ex, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.expBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Power10, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } + } ) } else { - AdditionalButtonsPortrait( - modifier = additionalButtonModifier, - allowVibration = allowVibration, - addSymbol = addSymbol, + AdditionalPortrait( showAdditional = showAdditional, - radianMode = radianMode, - toggleAngleMode = toggleAngleMode, - toggleInvMode = { invMode = !invMode } + buttonHeight = additionalButtonHeight, + content1 = { buttonModifier -> + KeyboardButtonAdditional(buttonModifier, UnittoIcons.RootWide, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.sqrt) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Const.pi) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.PowerWide, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.factorial) } + }, + content2 = { buttonModifier -> + KeyboardButtonAdditional(buttonModifier, angleIcon, allowVibration, KeyboardButtonContentHeightWide) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Sin, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.sinBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Cos, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.cosBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Tan, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.tanBracket) } + + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration, KeyboardButtonContentHeightWide) { toggleInvMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ln, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.lnBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Log, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.logBracket) } + } ) } } @@ -237,7 +259,6 @@ private fun PortraitKeyboard( modifier = Modifier.size(additionalButtonHeight), contentAlignment = Alignment.Center ) { - // Expand/Collapse IconButton( onClick = { showAdditional = !showAdditional }, colors = IconButtonDefaults.iconButtonColors(containerColor = MaterialTheme.colorScheme.inverseOnSurface) @@ -249,118 +270,116 @@ private fun PortraitKeyboard( Spacer(modifier = Modifier.height(spacerHeight)) - Row(weightModifier) { + KeypadFlow( + modifier = Modifier + .weight(1f) + .fillMaxSize(), + rows = 5, + columns = 4, + ) { width, height -> + val mainButtonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) + if (acButton) { - KeyboardButtonTertiary(mainButtonModifier, UnittoIcons.Clear, allowVibration) { clearSymbols() } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Brackets, allowVibration) { addBracket() } + KeyboardButtonTertiary(mainButtonModifier, UnittoIcons.Clear, allowVibration, KeyboardButtonContentHeightTall) { clearSymbols() } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Brackets, allowVibration, KeyboardButtonContentHeightTall) { addBracket() } } else { - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.LeftBracket, allowVibration) { addSymbol(Token.Operator.leftBracket) } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.RightBracket, allowVibration) { addSymbol(Token.Operator.rightBracket) } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.LeftBracket, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.leftBracket) } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.RightBracket, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.rightBracket) } } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Percent, allowVibration) { addSymbol(Token.Operator.percent) } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Divide, allowVibration) { addSymbol(Token.Operator.divide) } - } - Row(weightModifier) { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration) { addSymbol(Token.Digit._7) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration) { addSymbol(Token.Digit._8) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key9, allowVibration) { addSymbol(Token.Digit._9) } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Multiply, allowVibration) { addSymbol(Token.Operator.multiply) } - } - Row(weightModifier) { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key4, allowVibration) { addSymbol(Token.Digit._4) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key5, allowVibration) { addSymbol(Token.Digit._5) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key6, allowVibration) { addSymbol(Token.Digit._6) } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Minus, allowVibration) { addSymbol(Token.Operator.minus) } - } - Row(weightModifier) { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key1, allowVibration) { addSymbol(Token.Digit._1) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key2, allowVibration) { addSymbol(Token.Digit._2) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key3, allowVibration) { addSymbol(Token.Digit._3) } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Plus, allowVibration) { addSymbol(Token.Operator.plus) } - } - Row(weightModifier) { + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Percent, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.percent) } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Divide, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.divide) } + + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._7) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._8) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key9, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._9) } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Multiply, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.multiply) } + + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key4, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._4) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key5, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._5) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key6, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._6) } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Minus, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.minus) } + + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key1, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._1) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key2, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._2) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key3, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._3) } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Plus, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Operator.plus) } + if (middleZero) { - KeyboardButtonLight(mainButtonModifier, fractionalIcon, allowVibration) { addSymbol(Token.Digit.dot) } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key0, allowVibration) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(mainButtonModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._0) } } else { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key0, allowVibration) { addSymbol(Token.Digit._0) } - KeyboardButtonLight(mainButtonModifier, fractionalIcon, allowVibration) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(mainButtonModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit.dot) } } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Backspace, allowVibration, onLongClick = clearSymbols) { deleteSymbol() } - KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Equal, allowVibration) { evaluate() } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Backspace, allowVibration, KeyboardButtonContentHeightTall, clearSymbols) { deleteSymbol() } + KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Equal, allowVibration, KeyboardButtonContentHeightTall) { evaluate() } } Spacer(modifier = Modifier.height(spacerHeight)) } } +/** + * Additional buttons. + * + * Width: 4 buttons + * + * Height: 3 buttons + * + * @param showAdditional When `true` reveals [content2] with animation. + * @param buttonHeight Button height in [Dp]. + * @param content1 First row of buttons. + * @param content2 Second and third rows of buttons. + */ @Composable -private fun AdditionalButtonsPortrait( - modifier: Modifier, - allowVibration: Boolean, - addSymbol: (String) -> Unit, +private fun AdditionalPortrait( showAdditional: Boolean, - radianMode: Boolean, - toggleAngleMode: () -> Unit, - toggleInvMode: () -> Unit + buttonHeight: Dp, + content1: @Composable (buttonModifier: Modifier) -> Unit, + content2: @Composable (buttonModifier: Modifier) -> Unit ) { - Column { - Row { - KeyboardButtonAdditional(modifier, UnittoIcons.RootWide, allowVibration) { addSymbol(Token.Operator.sqrt) } - KeyboardButtonAdditional(modifier, UnittoIcons.Pi, allowVibration) { addSymbol(Token.Const.pi) } - KeyboardButtonAdditional(modifier, UnittoIcons.PowerWide, allowVibration) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(modifier, UnittoIcons.Factorial, allowVibration) { addSymbol(Token.Operator.factorial) } + AnimatedContent( + targetState = showAdditional, + modifier = Modifier, + transitionSpec = { + expandVertically(expandFrom = Alignment.Top) togetherWith + shrinkVertically(shrinkTowards = Alignment.Top) using (SizeTransform()) } - AnimatedVisibility(showAdditional) { - Column { - Row { - KeyboardButtonAdditional(modifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } - KeyboardButtonAdditional(modifier, UnittoIcons.Sin, allowVibration) { addSymbol(Token.Func.sinBracket) } - KeyboardButtonAdditional(modifier, UnittoIcons.Cos, allowVibration) { addSymbol(Token.Func.cosBracket) } - KeyboardButtonAdditional(modifier, UnittoIcons.Tan, allowVibration) { addSymbol(Token.Func.tanBracket) } - } - Row { - KeyboardButtonAdditional(modifier, UnittoIcons.Inv, allowVibration) { toggleInvMode() } - KeyboardButtonAdditional(modifier, UnittoIcons.E, allowVibration) { addSymbol(Token.Const.e) } - KeyboardButtonAdditional(modifier, UnittoIcons.Ln, allowVibration) { addSymbol(Token.Func.lnBracket) } - KeyboardButtonAdditional(modifier, UnittoIcons.Log, allowVibration) { addSymbol(Token.Func.logBracket) } - } - } - } - } -} + ) { show -> + if (show) { + KeypadFlow( + modifier = Modifier + .height(buttonHeight * 3) + .fillMaxWidth(), + rows = 3, + columns = 4, + verticalPadding = 0, + horizontalPadding = 0, + ) { width, height -> + val buttonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) -@Composable -private fun AdditionalButtonsPortraitInverse( - modifier: Modifier, - allowVibration: Boolean, - addSymbol: (String) -> Unit, - showAdditional: Boolean, - radianMode: Boolean, - toggleAngleMode: () -> Unit, - toggleInvMode: () -> Unit -) { - Column { - Row { - KeyboardButtonAdditional(modifier, UnittoIcons.Modulo, allowVibration) { addSymbol(Token.Operator.modulo) } - KeyboardButtonAdditional(modifier, UnittoIcons.Pi, allowVibration) { addSymbol(Token.Const.pi) } - KeyboardButtonAdditional(modifier, UnittoIcons.PowerWide, allowVibration) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(modifier, UnittoIcons.Factorial, allowVibration) { addSymbol(Token.Operator.factorial) } - } - AnimatedVisibility(showAdditional) { - Column { - Row { - KeyboardButtonAdditional(modifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } - KeyboardButtonAdditional(modifier, UnittoIcons.ArSin, allowVibration) { addSymbol(Token.Func.arsinBracket) } - KeyboardButtonAdditional(modifier, UnittoIcons.ArCos, allowVibration) { addSymbol(Token.Func.arcosBracket) } - KeyboardButtonAdditional(modifier, UnittoIcons.AcTan, allowVibration) { addSymbol(Token.Func.actanBracket) } - } - Row { - KeyboardButtonAdditional(modifier, UnittoIcons.Inv, allowVibration) { toggleInvMode() } - KeyboardButtonAdditional(modifier, UnittoIcons.E, allowVibration) { addSymbol(Token.Const.e) } - KeyboardButtonAdditional(modifier, UnittoIcons.Ex, allowVibration) { addSymbol(Token.Func.expBracket) } - KeyboardButtonAdditional(modifier, UnittoIcons.Power10, allowVibration) { addSymbol(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } - } + content1(buttonModifier) + content2(buttonModifier) + } + } else { + KeypadFlow( + modifier = Modifier + .height(buttonHeight * 1) + .fillMaxWidth(), + rows = 1, + columns = 4, + verticalPadding = 0, + horizontalPadding = 0, + ) { width, height -> + val buttonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) + + content1(buttonModifier) } } } @@ -369,8 +388,8 @@ private fun AdditionalButtonsPortraitInverse( @Composable private fun LandscapeKeyboard( modifier: Modifier, - radianMode: Boolean, - fractional: String, + angleIcon: ImageVector, + fractionalIcon: ImageVector, allowVibration: Boolean, middleZero: Boolean, addSymbol: (String) -> Unit, @@ -380,157 +399,131 @@ private fun LandscapeKeyboard( evaluate: () -> Unit, acButton: Boolean, addBracket: () -> Unit, + invMode: Boolean, + toggleInvMode: () -> Unit, ) { - val fractionalIcon = remember { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma } - var invMode: Boolean by remember { mutableStateOf(false) } + Crossfade( + targetState = invMode, + modifier = modifier + ) { inverse -> + if (inverse) { + KeypadFlow( + modifier = Modifier.fillMaxSize(), + rows = 4, + columns = 8 + ) { width, height -> + val buttonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) - RowWithConstraints(modifier) { constraints -> - val buttonModifier = Modifier - .fillMaxWidth() - .weight(1f) - .padding(constraints.maxWidth * 0.005f, constraints.maxHeight * 0.02f) - - Crossfade(invMode, Modifier.weight(3f), label = "Additional button") { - Row { - if (it) { - AdditionalButtonsLandscapeInverse( - modifier = Modifier.weight(1f), - buttonModifier = buttonModifier, - allowVibration = allowVibration, - radianMode = radianMode, - addSymbol = addSymbol, - toggleAngleMode = toggleAngleMode, - toggleInvMode = { invMode = !invMode } - ) + KeyboardButtonAdditional(buttonModifier, angleIcon, allowVibration, KeyboardButtonContentHeightShort) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Modulo, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Operator.modulo) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Const.pi) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key7, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._7) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key8, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._8) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key9, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._9) } + if (acButton) { + KeyboardButtonTertiary(buttonModifier, UnittoIcons.Clear, allowVibration, KeyboardButtonContentHeightShort) { clearSymbols() } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Brackets, allowVibration, KeyboardButtonContentHeightShort) { addBracket() } } else { - AdditionalButtonsLandscape( - modifier = Modifier.weight(1f), - buttonModifier = buttonModifier, - allowVibration = allowVibration, - radianMode = radianMode, - addSymbol = addSymbol, - toggleAngleMode = toggleAngleMode, - toggleInvMode = { invMode = !invMode } - ) + KeyboardButtonFilled(buttonModifier, UnittoIcons.LeftBracket, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.leftBracket) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.RightBracket, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.rightBracket) } } - } - } - Column(Modifier.weight(1f)) { - KeyboardButtonLight(buttonModifier, UnittoIcons.Key7, allowVibration) { addSymbol(Token.Digit._7) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Key4, allowVibration) { addSymbol(Token.Digit._4) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Key1, allowVibration) { addSymbol(Token.Digit._1) } - if (middleZero) { - KeyboardButtonLight(buttonModifier, fractionalIcon, allowVibration) { addSymbol(Token.Digit.dot) } - } else { - KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, allowVibration) { addSymbol(Token.Digit._0) } - } - } - Column(Modifier.weight(1f)) { - KeyboardButtonLight(buttonModifier, UnittoIcons.Key8, allowVibration) { addSymbol(Token.Digit._8) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Key5, allowVibration) { addSymbol(Token.Digit._5) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Key2, allowVibration) { addSymbol(Token.Digit._2) } - if (middleZero) { - KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, allowVibration) { addSymbol(Token.Digit._0) } - } else { - KeyboardButtonLight(buttonModifier, fractionalIcon, allowVibration) { addSymbol(Token.Digit.dot) } - } - } - Column(Modifier.weight(1f)) { - KeyboardButtonLight(buttonModifier, UnittoIcons.Key9, allowVibration) { addSymbol(Token.Digit._9) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Key6, allowVibration) { addSymbol(Token.Digit._6) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Key3, allowVibration) { addSymbol(Token.Digit._3) } - KeyboardButtonLight(buttonModifier, UnittoIcons.Backspace, allowVibration, onLongClick = clearSymbols) { deleteSymbol() } - } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration, KeyboardButtonContentHeightShort) { toggleInvMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.PowerWide, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.factorial) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key4, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._4) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key5, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._5) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key6, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._6) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Multiply, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.multiply) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Divide, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.divide) } - Column(Modifier.weight(1f)) { - if (acButton) { - KeyboardButtonTertiary(buttonModifier, UnittoIcons.Clear, allowVibration) { clearSymbols() } - } else { - KeyboardButtonFilled(buttonModifier, UnittoIcons.LeftBracket, allowVibration) { addSymbol(Token.Operator.leftBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArSin, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.arsinBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArCos, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.arcosBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.AcTan, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.actanBracket) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key1, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._1) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key2, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._2) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key3, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._3) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Minus, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.minus) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Percent, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.percent) } + + KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ex, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Func.expBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Power10, allowVibration, KeyboardButtonContentHeightWide) { addSymbol(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } + if (middleZero) { + KeyboardButtonLight(buttonModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } + } else { + KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(buttonModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } + } + KeyboardButtonLight(buttonModifier, UnittoIcons.Backspace, allowVibration, KeyboardButtonContentHeightShort, clearSymbols) { deleteSymbol() } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Plus, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.plus) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Equal, allowVibration, KeyboardButtonContentHeightShort) { evaluate() } } - KeyboardButtonFilled(buttonModifier, UnittoIcons.Multiply, allowVibration) { addSymbol(Token.Operator.multiply) } - KeyboardButtonFilled(buttonModifier, UnittoIcons.Minus, allowVibration) { addSymbol(Token.Operator.minus) } - KeyboardButtonFilled(buttonModifier, UnittoIcons.Plus, allowVibration) { addSymbol(Token.Operator.plus) } - } - Column(Modifier.weight(1f)) { - if (acButton) { - KeyboardButtonFilled(buttonModifier, UnittoIcons.Brackets, allowVibration) { addBracket() } - } else { - KeyboardButtonFilled(buttonModifier, UnittoIcons.RightBracket, allowVibration) { addSymbol(Token.Operator.rightBracket) } + } else { + KeypadFlow( + modifier = Modifier.fillMaxSize(), + rows = 4, + columns = 8 + ) { width, height -> + val buttonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) + + KeyboardButtonAdditional(buttonModifier, angleIcon, allowVibration, KeyboardButtonContentHeightShort) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.RootWide, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.sqrt) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Const.pi) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key7, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._7) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key8, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._8) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key9, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._9) } + if (acButton) { + KeyboardButtonTertiary(buttonModifier, UnittoIcons.Clear, allowVibration, KeyboardButtonContentHeightShort) { clearSymbols() } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Brackets, allowVibration, KeyboardButtonContentHeightShort) { addBracket() } + } else { + KeyboardButtonFilled(buttonModifier, UnittoIcons.LeftBracket, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.leftBracket) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.RightBracket, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.rightBracket) } + } + + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration, KeyboardButtonContentHeightShort) { toggleInvMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.PowerWide, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.power) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.factorial) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key4, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._4) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key5, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._5) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key6, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._6) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Multiply, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.multiply) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Divide, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.divide) } + + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Sin, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Func.sinBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Cos, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Func.cosBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Tan, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Func.tanBracket) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key1, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._1) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key2, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._2) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key3, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._3) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Minus, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.minus) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Percent, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.percent) } + + KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Const.e) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ln, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Func.lnBracket) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Log, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Func.logBracket) } + if (middleZero) { + KeyboardButtonLight(buttonModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } + } else { + KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit._0) } + KeyboardButtonLight(buttonModifier, fractionalIcon, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Digit.dot) } + } + KeyboardButtonLight(buttonModifier, UnittoIcons.Backspace, allowVibration, KeyboardButtonContentHeightShort, clearSymbols) { deleteSymbol() } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Plus, allowVibration, KeyboardButtonContentHeightShort) { addSymbol(Token.Operator.plus) } + KeyboardButtonFilled(buttonModifier, UnittoIcons.Equal, allowVibration, KeyboardButtonContentHeightShort) { evaluate() } } - KeyboardButtonFilled(buttonModifier, UnittoIcons.Divide, allowVibration) { addSymbol(Token.Operator.divide) } - KeyboardButtonFilled(buttonModifier, UnittoIcons.Percent, allowVibration) { addSymbol(Token.Operator.percent) } - KeyboardButtonFilled(buttonModifier, UnittoIcons.Equal, allowVibration) { evaluate() } } } } -@Composable -private fun AdditionalButtonsLandscape( - modifier: Modifier, - buttonModifier: Modifier, - allowVibration: Boolean, - radianMode: Boolean, - addSymbol: (String) -> Unit, - toggleAngleMode: () -> Unit, - toggleInvMode: () -> Unit -) { - Column(modifier) { - KeyboardButtonAdditional(buttonModifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration) { toggleInvMode() } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Sin, allowVibration) { addSymbol(Token.Func.sinBracket) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration) { addSymbol(Token.Const.e) } - } - - Column(modifier) { - KeyboardButtonAdditional(buttonModifier, UnittoIcons.RootWide, allowVibration) { addSymbol(Token.Operator.sqrt) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.PowerWide, allowVibration) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Cos, allowVibration) { addSymbol(Token.Func.cosBracket) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ln, allowVibration) { addSymbol(Token.Func.lnBracket) } - } - - Column(modifier) { - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi, allowVibration) { addSymbol(Token.Const.pi) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial, allowVibration) { addSymbol(Token.Operator.factorial) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Tan, allowVibration) { addSymbol(Token.Func.tanBracket) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Log, allowVibration) { addSymbol(Token.Func.logBracket) } - } -} - -@Composable -private fun AdditionalButtonsLandscapeInverse( - modifier: Modifier, - buttonModifier: Modifier, - allowVibration: Boolean, - radianMode: Boolean, - addSymbol: (String) -> Unit, - toggleAngleMode: () -> Unit, - toggleInvMode: () -> Unit -) { - Column(modifier) { - KeyboardButtonAdditional(buttonModifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration) { toggleInvMode() } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArSin, allowVibration) { addSymbol(Token.Func.arsinBracket) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration) { addSymbol(Token.Const.e) } - } - - Column(modifier) { - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Modulo, allowVibration) { addSymbol(Token.Operator.modulo) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.PowerWide, allowVibration) { addSymbol(Token.Operator.power) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArCos, allowVibration) { addSymbol(Token.Func.arcosBracket) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ex, allowVibration) { addSymbol(Token.Func.expBracket) } - } - - Column(modifier) { - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi, allowVibration) { addSymbol(Token.Const.pi) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial, allowVibration) { addSymbol(Token.Operator.factorial) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.AcTan, allowVibration) { addSymbol(Token.Func.actanBracket) } - KeyboardButtonAdditional(buttonModifier, UnittoIcons.Power10, allowVibration) { addSymbol(Token.Digit._1 + Token.Digit._0 + Token.Operator.power) } - } -} - -@Preview +@Preview(device = "spec:parent=pixel_5,orientation=portrait") +@Preview(device = "spec:parent=pixel_5,orientation=landscape") @Composable private fun PreviewCalculatorKeyboard() { CalculatorKeyboard( diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt index 2ad7411e..b716c3d1 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt @@ -23,7 +23,6 @@ import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.tween import androidx.compose.animation.core.updateTransition import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -112,7 +111,6 @@ internal fun ChipsRow( } } -@OptIn(ExperimentalLayoutApi::class) @Composable fun ChipsFlexRow( items: List = ALL_UNIT_GROUPS, diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt index b64df4f1..6150cce0 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt @@ -18,20 +18,20 @@ package com.sadellie.unitto.feature.converter.components -import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.sadellie.unitto.core.base.Token -import com.sadellie.unitto.core.ui.common.ColumnWithConstraints +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightShort +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightTall import com.sadellie.unitto.core.ui.common.KeyboardButtonFilled import com.sadellie.unitto.core.ui.common.KeyboardButtonLight import com.sadellie.unitto.core.ui.common.KeyboardButtonTertiary +import com.sadellie.unitto.core.ui.common.KeypadFlow import com.sadellie.unitto.core.ui.common.key.UnittoIcons import com.sadellie.unitto.core.ui.common.key.unittoicons.Backspace import com.sadellie.unitto.core.ui.common.key.unittoicons.Brackets @@ -63,6 +63,7 @@ import com.sadellie.unitto.core.ui.common.key.unittoicons.Power import com.sadellie.unitto.core.ui.common.key.unittoicons.RightBracket import com.sadellie.unitto.core.ui.common.key.unittoicons.Root import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.ui.isPortrait @Composable internal fun DefaultKeyboard( @@ -76,59 +77,50 @@ internal fun DefaultKeyboard( acButton: Boolean, addBracket: () -> Unit, ) { - ColumnWithConstraints(modifier) { - val fractionalIcon = remember { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma } - val mainButtonHorizontalPadding by remember(it.maxWidth) { - derivedStateOf { it.maxWidth * 0.01f } - } + val fractionalIcon = remember { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma } + val contentHeight: Float = if (isPortrait()) KeyboardButtonContentHeightTall else KeyboardButtonContentHeightShort - // Button modifier - val bModifier = Modifier - .fillMaxSize() - .weight(1f) - .padding(mainButtonHorizontalPadding) - // Column modifier - val cModifier = Modifier.weight(1f) - Row(cModifier) { - if (acButton) { - KeyboardButtonTertiary(bModifier, UnittoIcons.Clear, allowVibration) { clearInput() } - KeyboardButtonFilled(bModifier, UnittoIcons.Brackets, allowVibration) { addBracket() } - } else { - KeyboardButtonFilled(bModifier, UnittoIcons.LeftBracket, allowVibration) { addDigit(Token.Operator.leftBracket) } - KeyboardButtonFilled(bModifier, UnittoIcons.RightBracket, allowVibration) { addDigit(Token.Operator.rightBracket) } - } - KeyboardButtonFilled(bModifier, UnittoIcons.Power, allowVibration) { addDigit(Token.Operator.power) } - KeyboardButtonFilled(bModifier, UnittoIcons.Root, allowVibration) { addDigit(Token.Operator.sqrt) } + KeypadFlow( + modifier = modifier, + rows = 5, + columns = 4 + ) { width, height -> + val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height) + + if (acButton) { + KeyboardButtonTertiary(bModifier, UnittoIcons.Clear, allowVibration, contentHeight) { clearInput() } + KeyboardButtonFilled(bModifier, UnittoIcons.Brackets, allowVibration, contentHeight) { addBracket() } + } else { + KeyboardButtonFilled(bModifier, UnittoIcons.LeftBracket, allowVibration, contentHeight) { addDigit(Token.Operator.leftBracket) } + KeyboardButtonFilled(bModifier, UnittoIcons.RightBracket, allowVibration, contentHeight) { addDigit(Token.Operator.rightBracket) } } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key7, allowVibration) { addDigit(Token.Digit._7) } - KeyboardButtonLight(bModifier, UnittoIcons.Key8, allowVibration) { addDigit(Token.Digit._8) } - KeyboardButtonLight(bModifier, UnittoIcons.Key9, allowVibration) { addDigit(Token.Digit._9) } - KeyboardButtonFilled(bModifier, UnittoIcons.Divide, allowVibration) { addDigit(Token.Operator.divide) } - } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key4, allowVibration) { addDigit(Token.Digit._4) } - KeyboardButtonLight(bModifier, UnittoIcons.Key5, allowVibration) { addDigit(Token.Digit._5) } - KeyboardButtonLight(bModifier, UnittoIcons.Key6, allowVibration) { addDigit(Token.Digit._6) } - KeyboardButtonFilled(bModifier, UnittoIcons.Multiply, allowVibration) { addDigit(Token.Operator.multiply) } - } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key1, allowVibration) { addDigit(Token.Digit._1) } - KeyboardButtonLight(bModifier, UnittoIcons.Key2, allowVibration) { addDigit(Token.Digit._2) } - KeyboardButtonLight(bModifier, UnittoIcons.Key3, allowVibration) { addDigit(Token.Digit._3) } - KeyboardButtonFilled(bModifier, UnittoIcons.Minus, allowVibration) { addDigit(Token.Operator.minus) } - } - Row(cModifier) { - if (middleZero) { - KeyboardButtonLight(bModifier, fractionalIcon, allowVibration) { addDigit(Token.Digit.dot) } - KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration) { addDigit(Token.Digit._0) } - } else { - KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration) { addDigit(Token.Digit._0) } - KeyboardButtonLight(bModifier, fractionalIcon, allowVibration) { addDigit(Token.Digit.dot) } - } - KeyboardButtonLight(bModifier, UnittoIcons.Backspace, allowVibration, onLongClick = clearInput) { deleteDigit() } - KeyboardButtonFilled(bModifier, UnittoIcons.Plus, allowVibration) { addDigit(Token.Operator.plus) } + KeyboardButtonFilled(bModifier, UnittoIcons.Power, allowVibration, contentHeight) { addDigit(Token.Operator.power) } + KeyboardButtonFilled(bModifier, UnittoIcons.Root, allowVibration, contentHeight) { addDigit(Token.Operator.sqrt) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key7, allowVibration, contentHeight) { addDigit(Token.Digit._7) } + KeyboardButtonLight(bModifier, UnittoIcons.Key8, allowVibration, contentHeight) { addDigit(Token.Digit._8) } + KeyboardButtonLight(bModifier, UnittoIcons.Key9, allowVibration, contentHeight) { addDigit(Token.Digit._9) } + KeyboardButtonFilled(bModifier, UnittoIcons.Divide, allowVibration, contentHeight) { addDigit(Token.Operator.divide) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key4, allowVibration, contentHeight) { addDigit(Token.Digit._4) } + KeyboardButtonLight(bModifier, UnittoIcons.Key5, allowVibration, contentHeight) { addDigit(Token.Digit._5) } + KeyboardButtonLight(bModifier, UnittoIcons.Key6, allowVibration, contentHeight) { addDigit(Token.Digit._6) } + KeyboardButtonFilled(bModifier, UnittoIcons.Multiply, allowVibration, contentHeight) { addDigit(Token.Operator.multiply) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key1, allowVibration, contentHeight) { addDigit(Token.Digit._1) } + KeyboardButtonLight(bModifier, UnittoIcons.Key2, allowVibration, contentHeight) { addDigit(Token.Digit._2) } + KeyboardButtonLight(bModifier, UnittoIcons.Key3, allowVibration, contentHeight) { addDigit(Token.Digit._3) } + KeyboardButtonFilled(bModifier, UnittoIcons.Minus, allowVibration, contentHeight) { addDigit(Token.Operator.minus) } + + if (middleZero) { + KeyboardButtonLight(bModifier, fractionalIcon, allowVibration, contentHeight) { addDigit(Token.Digit.dot) } + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, contentHeight) { addDigit(Token.Digit._0) } + } else { + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, contentHeight) { addDigit(Token.Digit._0) } + KeyboardButtonLight(bModifier, fractionalIcon, allowVibration, contentHeight) { addDigit(Token.Digit.dot) } } + KeyboardButtonLight(bModifier, UnittoIcons.Backspace, allowVibration, contentHeight, onLongClick = clearInput) { deleteDigit() } + KeyboardButtonFilled(bModifier, UnittoIcons.Plus, allowVibration, contentHeight) { addDigit(Token.Operator.plus) } } } @@ -140,51 +132,38 @@ internal fun NumberBaseKeyboard( deleteDigit: () -> Unit, allowVibration: Boolean ) { - ColumnWithConstraints(modifier) { - val mainButtonHorizontalPadding by remember(it.maxWidth) { - derivedStateOf { it.maxWidth * 0.01f } - } + val contentHeight: Float = if (isPortrait()) KeyboardButtonContentHeightTall else KeyboardButtonContentHeightShort - // Button modifier - val bModifier = Modifier - .fillMaxSize() - .weight(1f) - .padding(mainButtonHorizontalPadding) - // Column modifier - val cModifier = Modifier.weight(1f) - Row(cModifier) { - KeyboardButtonFilled(bModifier, UnittoIcons.KeyA, allowVibration) { addDigit(Token.Letter._A) } - KeyboardButtonFilled(bModifier, UnittoIcons.KeyB, allowVibration) { addDigit(Token.Letter._B) } - KeyboardButtonFilled(bModifier, UnittoIcons.KeyC, allowVibration) { addDigit(Token.Letter._C) } - } - Row(cModifier) { - KeyboardButtonFilled(bModifier, UnittoIcons.KeyD, allowVibration) { addDigit(Token.Letter._D) } - KeyboardButtonFilled(bModifier, UnittoIcons.KeyE, allowVibration) { addDigit(Token.Letter._E) } - KeyboardButtonFilled(bModifier, UnittoIcons.KeyF, allowVibration) { addDigit(Token.Letter._F) } - } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key7, allowVibration) { addDigit(Token.Digit._7) } - KeyboardButtonLight(bModifier, UnittoIcons.Key8, allowVibration) { addDigit(Token.Digit._8) } - KeyboardButtonLight(bModifier, UnittoIcons.Key9, allowVibration) { addDigit(Token.Digit._9) } - } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key4, allowVibration) { addDigit(Token.Digit._4) } - KeyboardButtonLight(bModifier, UnittoIcons.Key5, allowVibration) { addDigit(Token.Digit._5) } - KeyboardButtonLight(bModifier, UnittoIcons.Key6, allowVibration) { addDigit(Token.Digit._6) } - } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key1, allowVibration) { addDigit(Token.Digit._1) } - KeyboardButtonLight(bModifier, UnittoIcons.Key2, allowVibration) { addDigit(Token.Digit._2) } - KeyboardButtonLight(bModifier, UnittoIcons.Key3, allowVibration) { addDigit(Token.Digit._3) } - } - Row(cModifier) { - KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration) { addDigit(Token.Digit._0) } - KeyboardButtonLight( - Modifier - .fillMaxSize() - .weight(2f) - .padding(mainButtonHorizontalPadding), UnittoIcons.Backspace, allowVibration, onLongClick = clearInput) { deleteDigit() } - } + KeypadFlow( + modifier = modifier, + rows = 6, + columns = 3 + ) { width, height -> + val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height) + + KeyboardButtonFilled(bModifier, UnittoIcons.KeyA, allowVibration, contentHeight) { addDigit(Token.Letter._A) } + KeyboardButtonFilled(bModifier, UnittoIcons.KeyB, allowVibration, contentHeight) { addDigit(Token.Letter._B) } + KeyboardButtonFilled(bModifier, UnittoIcons.KeyC, allowVibration, contentHeight) { addDigit(Token.Letter._C) } + + KeyboardButtonFilled(bModifier, UnittoIcons.KeyD, allowVibration, contentHeight) { addDigit(Token.Letter._D) } + KeyboardButtonFilled(bModifier, UnittoIcons.KeyE, allowVibration, contentHeight) { addDigit(Token.Letter._E) } + KeyboardButtonFilled(bModifier, UnittoIcons.KeyF, allowVibration, contentHeight) { addDigit(Token.Letter._F) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key7, allowVibration, contentHeight) { addDigit(Token.Digit._7) } + KeyboardButtonLight(bModifier, UnittoIcons.Key8, allowVibration, contentHeight) { addDigit(Token.Digit._8) } + KeyboardButtonLight(bModifier, UnittoIcons.Key9, allowVibration, contentHeight) { addDigit(Token.Digit._9) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key4, allowVibration, contentHeight) { addDigit(Token.Digit._4) } + KeyboardButtonLight(bModifier, UnittoIcons.Key5, allowVibration, contentHeight) { addDigit(Token.Digit._5) } + KeyboardButtonLight(bModifier, UnittoIcons.Key6, allowVibration, contentHeight) { addDigit(Token.Digit._6) } + + KeyboardButtonLight(bModifier, UnittoIcons.Key1, allowVibration, contentHeight) { addDigit(Token.Digit._1) } + KeyboardButtonLight(bModifier, UnittoIcons.Key2, allowVibration, contentHeight) { addDigit(Token.Digit._2) } + KeyboardButtonLight(bModifier, UnittoIcons.Key3, allowVibration, contentHeight) { addDigit(Token.Digit._3) } + + // TODO Should be a separate o use custom widthFillFactors and heightFillFactors + KeyboardButtonLight(bModifier, UnittoIcons.Key0, allowVibration, contentHeight) { addDigit(Token.Digit._0) } + KeyboardButtonLight(Modifier.fillMaxHeight(height).fillMaxWidth(width * 2), UnittoIcons.Backspace, allowVibration, contentHeight, clearInput) { deleteDigit() } } } @@ -192,7 +171,7 @@ internal fun NumberBaseKeyboard( @Composable private fun PreviewConverterKeyboard() { DefaultKeyboard( - modifier = Modifier, + modifier = Modifier.fillMaxSize(), addDigit = {}, clearInput = {}, deleteDigit = {}, @@ -208,7 +187,7 @@ private fun PreviewConverterKeyboard() { @Composable private fun PreviewConverterKeyboardNumberBase() { NumberBaseKeyboard( - modifier = Modifier, + modifier = Modifier.fillMaxSize(), addDigit = {}, clearInput = {}, deleteDigit = {}, diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractPage.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractPage.kt index 8ef1105b..82b91b44 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractPage.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractPage.kt @@ -33,7 +33,6 @@ import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxHeight @@ -109,7 +108,6 @@ internal fun AddSubtractPage( } @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -@OptIn(ExperimentalLayoutApi::class) @Composable private fun AddSubtractView( uiState: AddSubtractState, diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/Keyboard.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/AddSubtractKeyboard.kt similarity index 54% rename from feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/Keyboard.kt rename to feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/AddSubtractKeyboard.kt index f2e4502d..e74e960e 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/Keyboard.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/components/AddSubtractKeyboard.kt @@ -19,21 +19,23 @@ package com.sadellie.unitto.feature.datecalculator.components import androidx.compose.animation.Crossfade -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusDirection import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.unit.dp +import androidx.compose.ui.tooling.preview.Preview import com.sadellie.unitto.core.base.Token +import com.sadellie.unitto.core.ui.common.KeyboardButtonContentHeightTall import com.sadellie.unitto.core.ui.common.KeyboardButtonFilled import com.sadellie.unitto.core.ui.common.KeyboardButtonLight +import com.sadellie.unitto.core.ui.common.KeypadFlow import com.sadellie.unitto.core.ui.common.key.UnittoIcons import com.sadellie.unitto.core.ui.common.key.unittoicons.Backspace import com.sadellie.unitto.core.ui.common.key.unittoicons.Check @@ -60,90 +62,79 @@ internal fun AddSubtractKeyboard( imeAction: ImeAction, focusManager: FocusManager = LocalFocusManager.current ) { - Row(modifier) { - val weightModifier = Modifier.weight(1f) - val mainButtonModifier = Modifier - .fillMaxSize() - .weight(1f) - .padding(4.dp) - val actionIconHeight = if (isPortrait()) 0.396f else 0.68f + Row( + modifier = modifier + ) { + KeypadFlow( + modifier = Modifier + .fillMaxHeight() + .weight(3f), + rows = 4, + columns = 3 + ) { width, height -> + val mainButtonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) - fun keyboardAction() { - when (imeAction) { - ImeAction.Next -> focusManager.moveFocus(FocusDirection.Next) - else -> onConfirm() - } - } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._7) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._8) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key9, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._9) } - Column(weightModifier) { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration) { - addSymbol(Token.Digit._7) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key4, allowVibration) { - addSymbol(Token.Digit._4 - ) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key1, allowVibration) { - addSymbol(Token.Digit._1) - } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key4, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._4) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key5, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._5) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key6, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._6) } + + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key1, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._1) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key2, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._2) } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key3, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._3) } + + Spacer(mainButtonModifier) + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key0, allowVibration, KeyboardButtonContentHeightTall) { addSymbol(Token.Digit._0) } Spacer(mainButtonModifier) } - Column(weightModifier) { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration) { - addSymbol(Token.Digit._8) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key5, allowVibration) { - addSymbol(Token.Digit._5) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key2, allowVibration) { - addSymbol(Token.Digit._2) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key0, allowVibration) { - addSymbol(Token.Digit._0) - } - } + KeypadFlow( + modifier = Modifier + .fillMaxHeight() + .weight(1f), + rows = 2, + columns = 1, + // In digits keypad there are 4 rows with verticalPadding set to 10 + // In this keypad we have 2 times less rows, we use 2 times smaller verticalPadding -> 5 + verticalPadding = 5 + ) { width, height -> + val mainButtonModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) + val actionIconHeight = if (isPortrait()) 0.396f else 0.68f - Column(weightModifier) { - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key9, allowVibration) { - addSymbol(Token.Digit._9) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key6, allowVibration) { - addSymbol(Token.Digit._6) - } - KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key3, allowVibration) { - addSymbol(Token.Digit._3) - } - Spacer(mainButtonModifier) - } - - Column(weightModifier) { Crossfade( - targetState = imeAction, + targetState = imeAction == ImeAction.Next, modifier = mainButtonModifier, label = "Primary button animation" - ) { - when (it) { - ImeAction.Next -> KeyboardButtonFilled( - Modifier.fillMaxSize(), - UnittoIcons.Tab, - allowVibration, - actionIconHeight - ) { keyboardAction() } - else -> KeyboardButtonFilled( - Modifier.fillMaxSize(), - UnittoIcons.Check, - allowVibration, - actionIconHeight - ) { keyboardAction() } + ) { showNext -> + if (showNext) { + KeyboardButtonFilled(Modifier.fillMaxSize(), UnittoIcons.Tab, allowVibration, actionIconHeight) { focusManager.moveFocus(FocusDirection.Next) } + } else { + KeyboardButtonFilled(Modifier.fillMaxSize(), UnittoIcons.Check, allowVibration, actionIconHeight) { onConfirm() } } } - KeyboardButtonLight( - mainButtonModifier, - UnittoIcons.Backspace, - allowVibration, - actionIconHeight - ) { deleteSymbol() } + KeyboardButtonLight(mainButtonModifier, UnittoIcons.Backspace, allowVibration, actionIconHeight) { deleteSymbol() } } + } } + +@Preview +@Composable +fun PreviewAddSubtractKeyboardNew() { + AddSubtractKeyboard( + modifier = Modifier + .fillMaxSize(), + addSymbol = {}, + deleteSymbol = {}, + onConfirm = {}, + allowVibration = true, + imeAction = ImeAction.Next + ) +} diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt index f1075d17..398bbfd0 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt @@ -23,7 +23,6 @@ import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -61,7 +60,6 @@ internal fun DateDifferencePage( } @Composable -@OptIn(ExperimentalLayoutApi::class) private fun DateDifferenceView( uiState: DifferenceUIState, setStartDate: (ZonedDateTime) -> Unit,