mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 08:45:27 +02:00
Refactor CalculatorScreen
This commit is contained in:
parent
e14cd51070
commit
c8b11a4b02
@ -19,12 +19,16 @@
|
||||
package com.sadellie.unitto.core.ui.common
|
||||
|
||||
import android.view.HapticFeedbackConstants
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
@ -52,12 +56,18 @@ fun BasicKeyboardButton(
|
||||
}
|
||||
}
|
||||
}
|
||||
UnittoButton(
|
||||
modifier = modifier,
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.squashable(
|
||||
onClick = { onClick(); vibrate() },
|
||||
onLongClick = if (onLongClick != null) { { onLongClick(); vibrate() } } else null,
|
||||
containerColor = containerColor,
|
||||
contentPadding = PaddingValues()
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
cornerRadiusRange = 30..50,
|
||||
)
|
||||
.background(containerColor)
|
||||
,
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
|
@ -20,10 +20,12 @@ package com.sadellie.unitto.feature.calculator
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.AnchoredDraggableState
|
||||
import androidx.compose.foundation.gestures.DraggableAnchors
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.anchoredDraggable
|
||||
import androidx.compose.foundation.gestures.snapTo
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
@ -49,7 +51,6 @@ import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@ -70,13 +71,13 @@ import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.ui.common.MenuButton
|
||||
import com.sadellie.unitto.core.ui.common.SettingsButton
|
||||
import com.sadellie.unitto.core.ui.common.UnittoScreenWithTopBar
|
||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
|
||||
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
|
||||
import com.sadellie.unitto.data.model.HistoryItem
|
||||
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard
|
||||
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboardLoading
|
||||
import com.sadellie.unitto.feature.calculator.components.HistoryItemHeight
|
||||
import com.sadellie.unitto.feature.calculator.components.HistoryList
|
||||
import kotlinx.coroutines.launch
|
||||
import com.sadellie.unitto.feature.calculator.components.TextBox
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@ -179,146 +180,89 @@ private fun Ready(
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
var historyItemHeight by remember { mutableStateOf(0.dp) }
|
||||
|
||||
val textBoxHeight = maxHeight * 0.25f
|
||||
var dragStateCurrentValue by rememberSaveable { mutableStateOf(DragState.CLOSED) }
|
||||
val corScope = rememberCoroutineScope()
|
||||
|
||||
val dragState = rememberDragState(
|
||||
historyItem = historyItemHeight,
|
||||
max = maxHeight - textBoxHeight,
|
||||
initialValue = dragStateCurrentValue,
|
||||
enablePartialView = uiState.partialHistoryView
|
||||
val dragState = remember {
|
||||
AnchoredDraggableState(
|
||||
initialValue = DragState.CLOSED,
|
||||
positionalThreshold = { distance -> distance * 0.5f },
|
||||
velocityThreshold = { with(density) { HistoryItemHeight.toPx() } },
|
||||
animationSpec = tween()
|
||||
)
|
||||
val dragDp by remember(dragState) {
|
||||
}
|
||||
|
||||
var historyListHeight by remember { mutableStateOf(0.dp) }
|
||||
val keyboardHeight by remember(historyListHeight) {
|
||||
derivedStateOf {
|
||||
focusManager.clearFocus(true)
|
||||
with(density) {
|
||||
try {
|
||||
dragState.requireOffset().toDp()
|
||||
} catch (e: IllegalStateException) {
|
||||
corScope.launch { dragState.snapTo(DragState.CLOSED) }
|
||||
0.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val keyboardHeight by remember(dragState) {
|
||||
derivedStateOf {
|
||||
if (dragDp > historyItemHeight) {
|
||||
maxHeight - textBoxHeight - historyItemHeight
|
||||
if (historyListHeight > HistoryItemHeight) {
|
||||
maxHeight - textBoxHeight - HistoryItemHeight
|
||||
} else {
|
||||
maxHeight - textBoxHeight - dragDp
|
||||
maxHeight - textBoxHeight - historyListHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(dragState.currentValue) {
|
||||
dragStateCurrentValue = dragState.currentValue
|
||||
LaunchedEffect(uiState.partialHistoryView) {
|
||||
val anchors: DraggableAnchors<DragState> = with(density) {
|
||||
if (uiState.partialHistoryView) {
|
||||
DraggableAnchors {
|
||||
DragState.CLOSED at 0f
|
||||
DragState.SMALL at HistoryItemHeight.toPx()
|
||||
DragState.OPEN at (maxHeight * 0.75f).toPx()
|
||||
}
|
||||
} else {
|
||||
DraggableAnchors {
|
||||
DragState.CLOSED at 0f
|
||||
DragState.OPEN at (maxHeight * 0.75f).toPx()
|
||||
}
|
||||
}
|
||||
}
|
||||
dragState.updateAnchors(anchors)
|
||||
}
|
||||
|
||||
LaunchedEffect(dragState.offset) {
|
||||
with(density) {
|
||||
if (!dragState.offset.isNaN()) {
|
||||
historyListHeight = dragState.requireOffset().toDp()
|
||||
}
|
||||
}
|
||||
|
||||
focusManager.clearFocus()
|
||||
showClearHistoryButton = dragState.currentValue == DragState.OPEN
|
||||
}
|
||||
|
||||
// History
|
||||
HistoryList(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
|
||||
.fillMaxWidth()
|
||||
.height(dragDp),
|
||||
.height(historyListHeight),
|
||||
historyItems = uiState.history,
|
||||
heightCallback = { historyItemHeight = it },
|
||||
formatterSymbols = uiState.formatterSymbols,
|
||||
addTokens = addSymbol,
|
||||
addTokens = addSymbol
|
||||
)
|
||||
|
||||
// Input
|
||||
Column(
|
||||
TextBox(
|
||||
modifier = Modifier
|
||||
.semantics { testTag = "inputBox" }
|
||||
.offset(y = dragDp)
|
||||
.offset(y = historyListHeight)
|
||||
.height(textBoxHeight)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceVariant,
|
||||
RoundedCornerShape(
|
||||
topStartPercent = 0, topEndPercent = 0,
|
||||
bottomStartPercent = 20, bottomEndPercent = 20
|
||||
)
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.anchoredDraggable(
|
||||
state = dragState,
|
||||
orientation = Orientation.Vertical
|
||||
)
|
||||
.padding(top = 12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
ExpressionTextField(
|
||||
modifier = Modifier
|
||||
.weight(2f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = uiState.input,
|
||||
minRatio = 0.5f,
|
||||
cutCallback = deleteSymbol,
|
||||
pasteCallback = addSymbol,
|
||||
onCursorChange = onCursorChange,
|
||||
formatterSymbols = uiState.formatterSymbols
|
||||
)
|
||||
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
when (uiState.output) {
|
||||
is CalculationResult.Default -> {
|
||||
var output by remember(uiState.output) {
|
||||
mutableStateOf(TextFieldValue(uiState.output.text))
|
||||
}
|
||||
|
||||
ExpressionTextField(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = output,
|
||||
minRatio = 1f,
|
||||
onCursorChange = { output = output.copy(selection = it) },
|
||||
,
|
||||
formatterSymbols = uiState.formatterSymbols,
|
||||
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f),
|
||||
readOnly = true,
|
||||
input = uiState.input,
|
||||
deleteSymbol = deleteSymbol,
|
||||
addSymbol = addSymbol,
|
||||
onCursorChange = onCursorChange,
|
||||
output = uiState.output
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
val label = uiState.output.label?.let { stringResource(it) } ?: ""
|
||||
|
||||
UnformattedTextField(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = TextFieldValue(label),
|
||||
minRatio = 1f,
|
||||
onCursorChange = {},
|
||||
textColor = MaterialTheme.colorScheme.error,
|
||||
readOnly = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Handle
|
||||
Box(
|
||||
Modifier
|
||||
.padding(8.dp)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
RoundedCornerShape(100)
|
||||
)
|
||||
.sizeIn(24.dp, 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
// Keyboard
|
||||
CalculatorKeyboard(
|
||||
modifier = Modifier
|
||||
.semantics { testTag = "ready" }
|
||||
.offset(y = dragDp + textBoxHeight)
|
||||
.offset(y = historyListHeight + textBoxHeight)
|
||||
.height(keyboardHeight)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
|
@ -18,45 +18,4 @@
|
||||
|
||||
package com.sadellie.unitto.feature.calculator
|
||||
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.gestures.AnchoredDraggableState
|
||||
import androidx.compose.foundation.gestures.DraggableAnchors
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
internal enum class DragState { CLOSED, SMALL, OPEN }
|
||||
|
||||
@Composable
|
||||
internal fun rememberDragState(
|
||||
initialValue: DragState = DragState.CLOSED,
|
||||
historyItem: Dp,
|
||||
max: Dp,
|
||||
enablePartialView: Boolean,
|
||||
): AnchoredDraggableState<DragState> {
|
||||
val historyItemHeight = with(LocalDensity.current) { historyItem.toPx() }
|
||||
val maxHeight = with(LocalDensity.current) { max.toPx() }
|
||||
val anchors: DraggableAnchors<DragState> = if (enablePartialView) {
|
||||
DraggableAnchors {
|
||||
DragState.CLOSED at 0f
|
||||
DragState.SMALL at historyItemHeight
|
||||
DragState.OPEN at maxHeight
|
||||
}
|
||||
} else {
|
||||
DraggableAnchors {
|
||||
DragState.CLOSED at 0f
|
||||
DragState.OPEN at maxHeight
|
||||
}
|
||||
}
|
||||
|
||||
return remember(historyItem, enablePartialView) {
|
||||
AnchoredDraggableState(
|
||||
initialValue = initialValue,
|
||||
anchors = anchors,
|
||||
positionalThreshold = { 0f },
|
||||
velocityThreshold = { 0f },
|
||||
animationSpec = tween()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@ -47,9 +48,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
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.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalTextInputService
|
||||
import androidx.compose.ui.platform.LocalTextToolbar
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
@ -58,7 +57,6 @@ import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
|
||||
@ -75,14 +73,12 @@ import java.util.Locale
|
||||
internal fun HistoryList(
|
||||
modifier: Modifier,
|
||||
historyItems: List<HistoryItem>,
|
||||
heightCallback: (Dp) -> Unit,
|
||||
formatterSymbols: FormatterSymbols,
|
||||
addTokens: (String) -> Unit,
|
||||
) {
|
||||
if (historyItems.isEmpty()) {
|
||||
HistoryListPlaceholder(
|
||||
modifier = modifier,
|
||||
heightCallback = heightCallback
|
||||
)
|
||||
} else {
|
||||
HistoryListContent(
|
||||
@ -90,7 +86,6 @@ internal fun HistoryList(
|
||||
historyItems = historyItems,
|
||||
addTokens = addTokens,
|
||||
formatterSymbols = formatterSymbols,
|
||||
heightCallback = heightCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -98,19 +93,14 @@ internal fun HistoryList(
|
||||
@Composable
|
||||
private fun HistoryListPlaceholder(
|
||||
modifier: Modifier,
|
||||
heightCallback: (Dp) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
||||
Column(
|
||||
modifier = modifier.wrapContentHeight(unbounded = true),
|
||||
verticalArrangement = Arrangement.Center
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.onPlaced { heightCallback(with(density) { it.size.height.toDp() }) }
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 32.dp),
|
||||
modifier = Modifier.height(HistoryItemHeight),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
@ -126,12 +116,8 @@ private fun HistoryListContent(
|
||||
historyItems: List<HistoryItem>,
|
||||
addTokens: (String) -> Unit,
|
||||
formatterSymbols: FormatterSymbols,
|
||||
heightCallback: (Dp) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val state = rememberLazyListState()
|
||||
val firstItem by remember(historyItems) { mutableStateOf(historyItems.first()) }
|
||||
val restOfTheItems by remember(firstItem) { mutableStateOf(historyItems.drop(1)) }
|
||||
|
||||
LaunchedEffect(historyItems) { state.scrollToItem(0) }
|
||||
|
||||
@ -141,19 +127,8 @@ private fun HistoryListContent(
|
||||
reverseLayout = true,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.Bottom)
|
||||
) {
|
||||
// We do this so that callback for items height is called only once
|
||||
item(firstItem.id) {
|
||||
items(historyItems, { it.id }) { historyItem ->
|
||||
HistoryListItem(
|
||||
modifier = Modifier.onPlaced { heightCallback(with(density) { it.size.height.toDp() }) },
|
||||
historyItem = historyItems.first(),
|
||||
formatterSymbols = formatterSymbols,
|
||||
addTokens = addTokens,
|
||||
)
|
||||
}
|
||||
|
||||
items(restOfTheItems, { it.id }) { historyItem ->
|
||||
HistoryListItem(
|
||||
modifier = Modifier,
|
||||
historyItem = historyItem,
|
||||
formatterSymbols = formatterSymbols,
|
||||
addTokens = addTokens,
|
||||
@ -193,7 +168,10 @@ private fun HistoryListItem(
|
||||
}
|
||||
}
|
||||
|
||||
Column(modifier = modifier) {
|
||||
Column(
|
||||
modifier = modifier.height(HistoryItemHeight),
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalTextInputService provides null,
|
||||
LocalTextToolbar provides UnittoTextToolbar(
|
||||
@ -246,6 +224,8 @@ private fun HistoryListItem(
|
||||
}
|
||||
}
|
||||
|
||||
internal val HistoryItemHeight = 92.dp
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewHistoryList() {
|
||||
@ -275,7 +255,6 @@ private fun PreviewHistoryList() {
|
||||
.fillMaxSize(),
|
||||
historyItems = historyItems,
|
||||
formatterSymbols = FormatterSymbols.Spaces,
|
||||
heightCallback = {},
|
||||
addTokens = {}
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sadellie.unitto.feature.calculator.components
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.testTag
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
|
||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
||||
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
|
||||
import com.sadellie.unitto.feature.calculator.CalculationResult
|
||||
|
||||
@Composable
|
||||
fun TextBox(
|
||||
modifier: Modifier,
|
||||
formatterSymbols: FormatterSymbols,
|
||||
input: TextFieldValue,
|
||||
deleteSymbol: () -> Unit,
|
||||
addSymbol: (String) -> Unit,
|
||||
onCursorChange: (TextRange) -> Unit,
|
||||
output: CalculationResult,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.semantics { testTag = "inputBox" }
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceVariant,
|
||||
RoundedCornerShape(
|
||||
topStartPercent = 0, topEndPercent = 0,
|
||||
bottomStartPercent = 20, bottomEndPercent = 20
|
||||
)
|
||||
)
|
||||
.padding(top = 12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
ExpressionTextField(
|
||||
modifier = Modifier
|
||||
.weight(2f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = input,
|
||||
minRatio = 0.5f,
|
||||
cutCallback = deleteSymbol,
|
||||
pasteCallback = addSymbol,
|
||||
onCursorChange = onCursorChange,
|
||||
formatterSymbols = formatterSymbols
|
||||
)
|
||||
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
when (output) {
|
||||
is CalculationResult.Default -> {
|
||||
var outputTF by remember(output) {
|
||||
mutableStateOf(TextFieldValue(output.text))
|
||||
}
|
||||
|
||||
ExpressionTextField(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = outputTF,
|
||||
minRatio = 1f,
|
||||
onCursorChange = { outputTF = outputTF.copy(selection = it) },
|
||||
formatterSymbols = formatterSymbols,
|
||||
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f),
|
||||
readOnly = true,
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
val label = output.label?.let { stringResource(it) } ?: ""
|
||||
|
||||
UnformattedTextField(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = TextFieldValue(label),
|
||||
minRatio = 1f,
|
||||
onCursorChange = {},
|
||||
textColor = MaterialTheme.colorScheme.error,
|
||||
readOnly = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Handle
|
||||
Box(
|
||||
Modifier
|
||||
.padding(8.dp)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
RoundedCornerShape(100)
|
||||
)
|
||||
.sizeIn(24.dp, 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user