From cb878fb171f98f1cfd6664d6948db427fcbae7a6 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Sun, 26 Feb 2023 18:58:23 +0400 Subject: [PATCH] Landscape mode support for calculator --- .../unitto/core/ui/common/KeyboardButton.kt | 17 +-- .../unitto/core/ui/common/UnittoButton.kt | 13 +- .../feature/calculator/CalculatorScreen.kt | 30 +++-- .../components/CalculatorKeyboard.kt | 124 ++++++++++++++++-- 4 files changed, 146 insertions(+), 38 deletions(-) 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 bb91385c..5d6c6aba 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 @@ -26,10 +26,11 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -46,7 +47,6 @@ fun BasicKeyboardButton( onClick: () -> Unit, onLongClick: (() -> Unit)?, containerColor: Color, - contentColor: Color, icon: ImageVector, iconColor: Color, allowVibration: Boolean @@ -65,7 +65,6 @@ fun BasicKeyboardButton( onLongClick = onLongClick, shape = RoundedCornerShape(cornerRadius), containerColor = containerColor, - contentColor = contentColor, contentPadding = PaddingValues(24.dp, 8.dp), interactionSource = interactionSource ) { @@ -90,7 +89,6 @@ fun KeyboardButtonLight( onClick = onClick, onLongClick = onLongClick, containerColor = MaterialTheme.colorScheme.inverseOnSurface, - contentColor = MaterialTheme.colorScheme.onSecondaryContainer, icon = icon, iconColor = MaterialTheme.colorScheme.onSurfaceVariant, allowVibration = allowVibration, @@ -110,7 +108,6 @@ fun KeyboardButtonFilled( onClick = onClick, onLongClick = onLongClick, containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onSecondaryContainer, icon = icon, iconColor = MaterialTheme.colorScheme.onSecondaryContainer, allowVibration = allowVibration @@ -123,15 +120,19 @@ fun KeyboardButtonAdditional( icon: ImageVector, onClick: () -> Unit ) { - IconButton( - onClick = onClick, + UnittoButton( modifier = modifier + .minimumInteractiveComponentSize() + .heightIn(max = 48.dp), + onClick = onClick, + containerColor = Color.Transparent, + contentPadding = PaddingValues(12.dp, 2.dp) ) { Icon( imageVector = icon, contentDescription = null, modifier = Modifier.fillMaxHeight(), - tint = MaterialTheme.colorScheme.onSecondaryContainer + tint = MaterialTheme.colorScheme.onSurfaceVariant ) } } diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoButton.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoButton.kt index c04526ee..76276f2f 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoButton.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoButton.kt @@ -27,14 +27,17 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle import androidx.compose.material3.Surface +import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -44,15 +47,15 @@ import androidx.compose.ui.semantics.Role @Composable fun UnittoButton( - onClick: () -> Unit, - onLongClick: (() -> Unit)?, modifier: Modifier = Modifier, - shape: Shape, + onClick: () -> Unit, + onLongClick: (() -> Unit)? = null, + shape: Shape = RoundedCornerShape(100), containerColor: Color, - contentColor: Color, + contentColor: Color = contentColorFor(containerColor), border: BorderStroke? = null, contentPadding: PaddingValues = ButtonDefaults.ContentPadding, - interactionSource: MutableInteractionSource, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, content: @Composable RowScope.() -> Unit ) { Surface( 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 ea985132..773cb58b 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 @@ -18,6 +18,7 @@ package com.sadellie.unitto.feature.calculator +import android.content.res.Configuration import androidx.compose.animation.Crossfade import androidx.compose.animation.core.Animatable import androidx.compose.animation.rememberSplineBasedDecay @@ -56,6 +57,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalTextToolbar import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource @@ -233,27 +235,29 @@ private fun CalculatorScreen( pasteCallback = addSymbol, cutCallback = deleteSymbol ) - SelectionContainer { - Text( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), - text = Formatter.format(uiState.output), - textAlign = TextAlign.End, - softWrap = false, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), - style = NumbersTextStyleDisplayMedium, - ) + if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) { + SelectionContainer { + Text( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp), + text = Formatter.format(uiState.output), + textAlign = TextAlign.End, + softWrap = false, + color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), + style = NumbersTextStyleDisplayMedium, + ) + } } // Handle Box( Modifier - .padding(16.dp) + .padding(8.dp) .background( MaterialTheme.colorScheme.onSurfaceVariant, RoundedCornerShape(100) ) - .sizeIn(36.dp, 4.dp) + .sizeIn(24.dp, 4.dp) ) } }, 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 27bd8664..1297334b 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 @@ -18,6 +18,7 @@ package com.sadellie.unitto.feature.calculator.components +import android.content.res.Configuration import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.animateFloatAsState @@ -26,6 +27,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandLess @@ -33,6 +35,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -40,6 +43,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate +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.KEY_0 @@ -119,6 +123,39 @@ internal fun CalculatorKeyboard( toggleAngleMode: () -> Unit, angleMode: AngleMode, evaluate: () -> Unit +) { + if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) { + PortraitKeyboard( + modifier = modifier, + addSymbol = addSymbol, + angleMode = angleMode, + toggleAngleMode = toggleAngleMode, + deleteSymbol = deleteSymbol, + clearSymbols = clearSymbols, + evaluate = evaluate + ) + } else { + LandscapeKeyboard( + modifier = modifier, + addSymbol = addSymbol, + angleMode = angleMode, + toggleAngleMode = toggleAngleMode, + deleteSymbol = deleteSymbol, + clearSymbols = clearSymbols, + evaluate = evaluate + ) + } +} + +@Composable +private fun PortraitKeyboard( + modifier: Modifier, + addSymbol: (String) -> Unit, + angleMode: AngleMode, + toggleAngleMode: () -> Unit, + deleteSymbol: () -> Unit, + clearSymbols: () -> Unit, + evaluate: () -> Unit ) { var showAdditional: Boolean by remember { mutableStateOf(false) } val expandRotation: Float by animateFloatAsState( @@ -134,6 +171,10 @@ internal fun CalculatorKeyboard( .fillMaxSize() .weight(1f) .padding(4.dp) + val additionalButtonModifier = Modifier + .minimumInteractiveComponentSize() + .weight(1f) + .heightIn(max = 48.dp) Row( modifier = Modifier.padding(vertical = 8.dp), @@ -142,24 +183,24 @@ internal fun CalculatorKeyboard( // Additional buttons Column(modifier = weightModifier) { Row(Modifier, horizontalArrangement = Arrangement.spacedBy(2.dp)) { - KeyboardButtonAdditional(weightModifier, UnittoIcons.SquareRoot) { addSymbol(KEY_SQRT) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Pi) { addSymbol(KEY_PI) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Exponent) { addSymbol(KEY_EXPONENT) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Factorial) { addSymbol(KEY_FACTORIAL) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.SquareRoot) { addSymbol(KEY_SQRT) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Pi) { addSymbol(KEY_PI) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Exponent) { addSymbol(KEY_EXPONENT) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Factorial) { addSymbol(KEY_FACTORIAL) } } AnimatedVisibility(visible = showAdditional) { Column { Row(Modifier, horizontalArrangement = Arrangement.spacedBy(2.dp)) { - KeyboardButtonAdditional(weightModifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad) { toggleAngleMode() } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Sin) { addSymbol(KEY_SIN) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Cos) { addSymbol(KEY_COS) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Tan) { addSymbol(KEY_TAN) } + KeyboardButtonAdditional(additionalButtonModifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad) { toggleAngleMode() } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Sin) { addSymbol(KEY_SIN) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Cos) { addSymbol(KEY_COS) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Tan) { addSymbol(KEY_TAN) } } Row(Modifier, horizontalArrangement = Arrangement.spacedBy(2.dp)) { - KeyboardButtonAdditional(weightModifier, UnittoIcons.Modulo) { addSymbol(KEY_MODULO) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.E) { addSymbol(KEY_E_SMALL) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Ln) { addSymbol(KEY_LN) } - KeyboardButtonAdditional(weightModifier, UnittoIcons.Log) { addSymbol(KEY_LOG) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Modulo) { addSymbol(KEY_MODULO) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.E) { addSymbol(KEY_E_SMALL) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Ln) { addSymbol(KEY_LN) } + KeyboardButtonAdditional(additionalButtonModifier, UnittoIcons.Log) { addSymbol(KEY_LOG) } } } } @@ -207,6 +248,65 @@ internal fun CalculatorKeyboard( } } +@Composable +private fun LandscapeKeyboard( + modifier: Modifier, + addSymbol: (String) -> Unit, + angleMode: AngleMode, + toggleAngleMode: () -> Unit, + deleteSymbol: () -> Unit, + clearSymbols: () -> Unit, + evaluate: () -> Unit +) { + Column(modifier = modifier) { + val buttonModifier = Modifier.weight(1f).padding(2.dp) + + Row(Modifier.weight(1f)) { + KeyboardButtonAdditional(buttonModifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.SquareRoot) { addSymbol(KEY_SQRT) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Pi) { addSymbol(KEY_PI) } + + KeyboardButtonLight(buttonModifier, UnittoIcons.Key7, { addSymbol(KEY_7) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Key8, { addSymbol(KEY_8) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Key9, { addSymbol(KEY_9) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.LeftBracket, { addSymbol(KEY_LEFT_BRACKET) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.RightBracket, { addSymbol(KEY_RIGHT_BRACKET) }) + } + Row(Modifier.weight(1f)) { + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Modulo) { addSymbol(KEY_MODULO) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Exponent) { addSymbol(KEY_EXPONENT) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Factorial) { addSymbol(KEY_FACTORIAL) } + + KeyboardButtonLight(buttonModifier, UnittoIcons.Key4, { addSymbol(KEY_4) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Key5, { addSymbol(KEY_5) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Key6, { addSymbol(KEY_6) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.Multiply, { addSymbol(KEY_MULTIPLY_DISPLAY) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.Divide, { addSymbol(KEY_DIVIDE_DISPLAY) }) + } + Row(Modifier.weight(1f)) { + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Sin) { addSymbol(KEY_SIN) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Cos) { addSymbol(KEY_COS) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Tan) { addSymbol(KEY_TAN) } + + KeyboardButtonLight(buttonModifier, UnittoIcons.Key1, { addSymbol(KEY_1) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Key2, { addSymbol(KEY_2) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Key3, { addSymbol(KEY_3) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.Minus, { addSymbol(KEY_MINUS_DISPLAY) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.Percent, { addSymbol(KEY_PERCENT) }) + } + Row(Modifier.weight(1f)) { + KeyboardButtonAdditional(buttonModifier, UnittoIcons.E) { addSymbol(KEY_E_SMALL) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Ln) { addSymbol(KEY_LN) } + KeyboardButtonAdditional(buttonModifier, UnittoIcons.Log) { addSymbol(KEY_LOG) } + KeyboardButtonLight(buttonModifier, UnittoIcons.Key0, { addSymbol(KEY_0) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Dot, { addSymbol(KEY_DOT) }) + KeyboardButtonLight(buttonModifier, UnittoIcons.Delete, { deleteSymbol() }, onLongClick = clearSymbols) + KeyboardButtonFilled(buttonModifier, UnittoIcons.Plus, { addSymbol(KEY_PLUS) }) + KeyboardButtonFilled(buttonModifier, UnittoIcons.Equal, { evaluate() }) + } + } +} + @Preview @Composable private fun PreviewCalculatorKeyboard() {