Fixes for responsive ui

squashed commit

closes: #24 and #34
This commit is contained in:
Sad Ellie 2023-03-30 12:17:33 +03:00
parent 6cf49812b7
commit 4c20c6c0b8
9 changed files with 243 additions and 201 deletions

View File

@ -27,11 +27,9 @@ 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.MaterialTheme
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@ -41,7 +39,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.dp
@Composable
fun BasicKeyboardButton(
@ -133,16 +130,14 @@ fun KeyboardButtonAdditional(
onClick: () -> Unit
) {
BasicKeyboardButton(
modifier = modifier
.minimumInteractiveComponentSize()
.heightIn(max = 48.dp),
modifier = modifier,
onClick = onClick,
onLongClick = onLongClick,
containerColor = Color.Transparent,
icon = icon,
iconColor = MaterialTheme.colorScheme.onSurfaceVariant,
allowVibration = allowVibration,
contentHeight = if (isPortrait()) 0.9f else 0.85f
contentHeight = if (isPortrait()) 0.8f else 0.85f
)
}

View File

@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
/**
* When Portrait mode will place [content1] and [content2] in a [Column].
@ -41,13 +42,19 @@ fun PortraitLandscape(
) {
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
ColumnWithConstraints(modifier) {
content1(Modifier.fillMaxHeight(0.34f).padding(horizontal = it.maxWidth * 0.03f))
content2(Modifier.fillMaxSize().padding(horizontal = it.maxWidth * 0.03f, vertical = it.maxHeight * 0.015f))
content1(Modifier.fillMaxHeight(0.38f).padding(horizontal = it.maxWidth * 0.03f))
content2(Modifier.fillMaxSize().padding(it.maxWidth * 0.03f, it.maxHeight * 0.015f))
}
} else {
RowWithConstraints(modifier) {
content1(Modifier.weight(1f).fillMaxHeight().padding(bottom = it.maxWidth * 0.015f, start = it.maxWidth * 0.015f, end = it.maxWidth * 0.015f))
content2(Modifier.weight(1f).fillMaxSize().padding(bottom = it.maxWidth * 0.015f, start = it.maxWidth * 0.015f, end = it.maxWidth * 0.015f))
val contentModifier = Modifier
.weight(1f)
.fillMaxSize()
.padding(
it.maxWidth * 0.015f, 0.dp,
it.maxHeight * 0.03f, it.maxHeight * 0.03f)
content1(contentModifier)
content2(contentModifier)
}
}
}

View File

@ -18,6 +18,8 @@
package com.sadellie.unitto.core.ui.common.textfield
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.text.BasicTextField
@ -30,10 +32,16 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
@ -42,6 +50,7 @@ import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.Paragraph
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.text.input.TextFieldValue
@ -66,19 +75,9 @@ fun InputTextField(
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
) {
val clipboardManager = LocalClipboardManager.current
fun copyCallback() {
clipboardManager.setText(
AnnotatedString(
Formatter.removeGrouping(
value.annotatedString.subSequence(value.selection).text
)
)
)
}
fun copyCallback() = clipboardManager.copyWithoutGrouping(value)
CompositionLocalProvider(
LocalTextInputService provides null,
LocalTextToolbar provides UnittoTextToolbar(
val textToolbar = UnittoTextToolbar(
view = LocalView.current,
copyCallback = ::copyCallback,
pasteCallback = {
@ -88,18 +87,27 @@ fun InputTextField(
)
)
},
cutCallback = { copyCallback(); cutCallback() }
cutCallback = {
copyCallback()
cutCallback()
onCursorChange(value.selection.end..value.selection.end)
}
)
CompositionLocalProvider(
LocalTextInputService provides null,
LocalTextToolbar provides textToolbar
) {
AutoSizableTextField(
modifier = modifier,
value = value,
textStyle = textStyle.copy(color = textColor),
minRatio = minRatio,
onValueChange = {
onCursorChange(it.selection.start..it.selection.end)
},
textStyle = textStyle,
minRatio = minRatio,
readOnly = false
showToolbar = textToolbar::showMenu,
hideToolbar = textToolbar::hide
)
}
}
@ -107,34 +115,54 @@ fun InputTextField(
@Composable
fun InputTextField(
modifier: Modifier = Modifier,
value: TextFieldValue,
value: String,
textStyle: TextStyle = NumbersTextStyleDisplayLarge,
minRatio: Float = 1f,
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
var textFieldValue by remember(value) {
mutableStateOf(TextFieldValue(value, selection = TextRange(value.length)))
}
val clipboardManager = LocalClipboardManager.current
fun copyCallback() {
clipboardManager.copyWithoutGrouping(textFieldValue)
textFieldValue = textFieldValue.copy(selection = TextRange(textFieldValue.selection.end))
}
CompositionLocalProvider(
LocalTextInputService provides null,
LocalTextToolbar provides UnittoTextToolbar(
view = LocalView.current,
copyCallback = ::copyCallback,
)
) {
AutoSizableTextField(
modifier = modifier,
value = value,
textStyle = textStyle,
value = textFieldValue,
onValueChange = { textFieldValue = it },
textStyle = textStyle.copy(color = textColor),
minRatio = minRatio,
readOnly = true
readOnly = true,
interactionSource = interactionSource
)
}
}
@Composable
private fun AutoSizableTextField(
modifier: Modifier = Modifier,
value: TextFieldValue,
onValueChange: (TextFieldValue) -> Unit = {},
textStyle: TextStyle = TextStyle(),
scaleFactor: Float = 0.95f,
minRatio: Float = 1f,
onValueChange: (TextFieldValue) -> Unit,
readOnly: Boolean = false,
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
cursorBrush: Brush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant)
showToolbar: (rect: Rect) -> Unit = {},
hideToolbar: () -> Unit = {},
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
// FIXME Acts strange when minRatio is set to 0 (still scales down).
val focusRequester = remember { FocusRequester() }
val density = LocalDensity.current
var nFontSize: TextUnit by remember { mutableStateOf(0.sp) }
@ -178,18 +206,30 @@ private fun AutoSizableTextField(
val nTextStyle = textStyle.copy(
// https://issuetracker.google.com/issues/266470454
// textAlign = TextAlign.End,
color = textColor,
fontSize = nFontSize
)
var offset = Offset.Zero
BasicTextField(
value = value,
singleLine = true,
onValueChange = onValueChange,
onValueChange = {
showToolbar(Rect(offset, 0f))
hideToolbar()
onValueChange(it)
},
modifier = Modifier
.widthIn(
max = with(density) { intrinsics.width.toDp() }
.focusRequester(focusRequester)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = {
hideToolbar()
focusRequester.requestFocus()
onValueChange(value.copy(selection = TextRange.Zero))
showToolbar(Rect(offset, 0f))
}
)
.widthIn(max = with(density) { intrinsics.width.toDp() })
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
// TextField size is changed with a delay (text jumps). Here we correct it.
@ -201,10 +241,27 @@ private fun AutoSizableTextField(
y = (placeable.height - intrinsics.height).roundToInt()
)
}
},
}
.onGloballyPositioned { layoutCoords -> offset = layoutCoords.positionInWindow() },
textStyle = nTextStyle,
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant),
singleLine = true,
readOnly = readOnly,
cursorBrush = cursorBrush
interactionSource = interactionSource
)
}
}
/**
* Copy value to clipboard without grouping symbols.
*
* Example:
* "123.456,789" will be copied as "123456,789"
*
* @param value Formatted value that has grouping symbols.
*/
fun ClipboardManager.copyWithoutGrouping(value: TextFieldValue) = this.setText(
AnnotatedString(
Formatter.removeGrouping(value.annotatedString.subSequence(value.selection).text)
)
)

View File

@ -45,10 +45,8 @@ class UnittoTextToolbar(
onSelectAllRequested: (() -> Unit)?
) {
textActionModeCallback.rect = rect
textActionModeCallback.onCopyRequested = { onCopyRequested?.invoke(); copyCallback.invoke() }
textActionModeCallback.onCutRequested = cutCallback?.let {
{ it.invoke(); onCutRequested?.invoke() }
}
textActionModeCallback.onCopyRequested = copyCallback
textActionModeCallback.onCutRequested = cutCallback
textActionModeCallback.onPasteRequested = pasteCallback
textActionModeCallback.onSelectAllRequested = onSelectAllRequested
if (actionMode == null) {

View File

@ -35,7 +35,6 @@ 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.foundation.text.selection.SelectionContainer
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.outlined.MoreVert
@ -47,7 +46,6 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -57,12 +55,8 @@ 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.LocalConfiguration
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -73,7 +67,6 @@ import com.sadellie.unitto.core.ui.Formatter
import com.sadellie.unitto.core.ui.common.MenuButton
import com.sadellie.unitto.core.ui.common.UnittoScreenWithTopBar
import com.sadellie.unitto.core.ui.common.textfield.InputTextField
import com.sadellie.unitto.core.ui.common.textfield.UnittoTextToolbar
import com.sadellie.unitto.data.model.HistoryItem
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard
import com.sadellie.unitto.feature.calculator.components.DragDownView
@ -90,26 +83,8 @@ internal fun CalculatorRoute(
navigateToSettings: () -> Unit,
viewModel: CalculatorViewModel = hiltViewModel()
) {
val clipboardManager = LocalClipboardManager.current
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
fun copyToClipboard() {
val clipboardText = clipboardManager.getText() ?: return
// This method is called immediately after copying formatted text, we replace it with the
// the unformatted version.
clipboardManager.setText(
AnnotatedString(
clipboardText.text.replace(Formatter.grouping, "")
)
)
}
CompositionLocalProvider(
LocalTextToolbar provides UnittoTextToolbar(
view = LocalView.current,
copyCallback = ::copyToClipboard
)
) {
CalculatorScreen(
uiState = uiState.value,
navigateToMenu = navigateToMenu,
@ -123,7 +98,6 @@ internal fun CalculatorRoute(
clearHistory = viewModel::clearHistory
)
}
}
@Composable
private fun CalculatorScreen(
@ -186,7 +160,6 @@ private fun CalculatorScreen(
.fillMaxSize(),
historyItems = uiState.history,
historyItemHeightCallback = { historyItemHeight = it },
onTextClick = addSymbol
)
},
textFields = { maxDragAmount ->
@ -243,18 +216,15 @@ private fun CalculatorScreen(
onCursorChange = onCursorChange
)
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
SelectionContainer(Modifier.weight(1f)) {
InputTextField(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.padding(horizontal = 8.dp),
value = TextFieldValue(
Formatter.fromSeparator(uiState.output, Separator.COMMA)
),
value = Formatter.format(uiState.output),
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f)
)
}
}
// Handle
Box(
Modifier

View File

@ -33,13 +33,13 @@ 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.ExpandLess
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
@ -164,13 +164,12 @@ private fun PortraitKeyboard(
val mainButtonModifier = Modifier
.fillMaxSize()
.weight(1f)
.padding(horizontalFraction(0.015f), verticalFraction(0.008f))
.padding(horizontalFraction(0.015f), verticalFraction(0.009f))
val additionalButtonModifier = Modifier
.minimumInteractiveComponentSize()
.weight(1f)
.height(verticalFraction(0.075f))
.height(verticalFraction(0.09f))
Spacer(modifier = Modifier.height(verticalFraction(0.015f)))
Spacer(modifier = Modifier.height(verticalFraction(0.025f)))
Row(
modifier = Modifier,
@ -201,7 +200,10 @@ private fun PortraitKeyboard(
}
}
Box(modifier = Modifier.height(verticalFraction(0.075f)), contentAlignment = Alignment.Center) {
Box(
modifier = Modifier.size(verticalFraction(0.09f)),
contentAlignment = Alignment.Center
) {
// Expand/Collapse
IconButton(
onClick = { showAdditional = !showAdditional },
@ -212,7 +214,7 @@ private fun PortraitKeyboard(
}
}
Spacer(modifier = Modifier.height(verticalFraction(0.015f)))
Spacer(modifier = Modifier.height(verticalFraction(0.025f)))
Row(weightModifier) {
KeyboardButtonFilled(mainButtonModifier, UnittoIcons.LeftBracket, allowVibration) { addSymbol(Token.leftBracket) }
@ -220,7 +222,6 @@ private fun PortraitKeyboard(
KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Percent, allowVibration) { addSymbol(Token.percent) }
KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Divide, allowVibration) { addSymbol(Token.divideDisplay) }
}
Row(weightModifier) {
KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration) { addSymbol(Token._7) }
KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration) { addSymbol(Token._8) }

View File

@ -19,10 +19,8 @@
package com.sadellie.unitto.feature.calculator.components
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@ -30,24 +28,35 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.History
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.derivedStateOf
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.layout.onPlaced
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalTextInputService
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
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 com.sadellie.unitto.core.ui.Formatter
import com.sadellie.unitto.core.ui.common.textfield.UnittoTextToolbar
import com.sadellie.unitto.core.ui.common.textfield.copyWithoutGrouping
import com.sadellie.unitto.core.ui.theme.NumbersTextStyleDisplayMedium
import com.sadellie.unitto.data.model.HistoryItem
import com.sadellie.unitto.feature.calculator.R
@ -59,7 +68,6 @@ internal fun HistoryList(
modifier: Modifier,
historyItems: List<HistoryItem>,
historyItemHeightCallback: (Int) -> Unit,
onTextClick: (String) -> Unit
) {
val verticalArrangement by remember(historyItems) {
derivedStateOf {
@ -95,15 +103,13 @@ internal fun HistoryList(
item {
HistoryListItem(
modifier = Modifier.onPlaced { historyItemHeightCallback(it.size.height) },
historyItem = historyItems.first(),
onTextClick = onTextClick
historyItem = historyItems.first()
)
}
items(historyItems.drop(1)) { historyItem ->
HistoryListItem(
modifier = Modifier,
historyItem = historyItem,
onTextClick = onTextClick
historyItem = historyItem
)
}
}
@ -114,43 +120,59 @@ internal fun HistoryList(
private fun HistoryListItem(
modifier: Modifier = Modifier,
historyItem: HistoryItem,
onTextClick: (String) -> Unit
) {
SelectionContainer {
val clipboardManager = LocalClipboardManager.current
val expr = Formatter.format(historyItem.expression)
var textFieldexpr by remember(expr) {
mutableStateOf(TextFieldValue(expr, selection = TextRange(expr.length)))
}
val res = Formatter.format(historyItem.expression)
var textFieldRes by remember(res) {
mutableStateOf(TextFieldValue(res, selection = TextRange(res.length)))
}
Column(modifier = modifier) {
Box(
Modifier.clickable { onTextClick(historyItem.expression) }
CompositionLocalProvider(
LocalTextInputService provides null,
LocalTextToolbar provides UnittoTextToolbar(
view = LocalView.current,
copyCallback = { clipboardManager.copyWithoutGrouping(textFieldexpr) }
)
) {
Text(
text = Formatter.format(historyItem.expression),
BasicTextField(
value = textFieldexpr,
onValueChange = { textFieldexpr = it },
maxLines = 1,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
style = NumbersTextStyleDisplayMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.End
textStyle = NumbersTextStyleDisplayMedium.copy(color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.End),
readOnly = true
)
}
Box(
Modifier.clickable { onTextClick(historyItem.result) }
CompositionLocalProvider(
LocalTextInputService provides null,
LocalTextToolbar provides UnittoTextToolbar(
view = LocalView.current,
copyCallback = { clipboardManager.copyWithoutGrouping(textFieldRes) }
)
) {
Text(
text = Formatter.format(historyItem.result),
BasicTextField(
value = textFieldRes,
onValueChange = { textFieldRes = it },
maxLines = 1,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
style = NumbersTextStyleDisplayMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f),
textAlign = TextAlign.End
textStyle = NumbersTextStyleDisplayMedium.copy(color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), textAlign = TextAlign.End),
readOnly = true
)
}
}
}
}
@Preview
@Composable
@ -178,8 +200,6 @@ private fun PreviewHistoryList() {
modifier = Modifier
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
.fillMaxSize(),
historyItems = historyItems,
historyItemHeightCallback = {},
onTextClick = {}
)
historyItems = historyItems
) {}
}

View File

@ -48,7 +48,6 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.R
@ -114,7 +113,7 @@ internal fun MyTextField(
) {
InputTextField(
modifier = Modifier.fillMaxWidth(),
value = TextFieldValue(it.take(1000)),
value = it.take(1000),
textStyle = NumbersTextStyleDisplayLarge.copy(textAlign = TextAlign.End)
)
}
@ -147,7 +146,7 @@ internal fun MyTextField(
) {
InputTextField(
modifier = Modifier.fillMaxWidth(),
value = TextFieldValue(it?.take(1000) ?: ""),
value = it?.take(1000) ?: "",
textStyle = NumbersTextStyleDisplayLarge.copy(
textAlign = TextAlign.End,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)

View File

@ -30,11 +30,10 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.with
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.SwapHoriz
import androidx.compose.material3.Icon
@ -51,11 +50,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.Formatter
import com.sadellie.unitto.core.ui.R
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
import com.sadellie.unitto.core.ui.common.textfield.InputTextField
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
@ -105,18 +103,15 @@ internal fun TopScreenPart(
)
val mContext = LocalContext.current
Column(
ColumnWithConstraints(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
InputTextField(
modifier = Modifier.weight(2f),
value = TextFieldValue(
when (converterMode) {
value = when (converterMode) {
ConverterMode.BASE -> inputValue.uppercase()
else -> Formatter.format(inputValue)
}
),
},
minRatio = 0.7f
)
AnimatedVisibility(
@ -126,8 +121,9 @@ internal fun TopScreenPart(
exit = shrinkVertically(clip = false)
) {
InputTextField(
value = TextFieldValue(calculatedValue?.let { Formatter.format(it) } ?: ""),
minRatio = 0.7f
value = calculatedValue?.let { value -> Formatter.format(value) } ?: "",
minRatio = 0.7f,
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
)
}
AnimatedContent(
@ -140,19 +136,17 @@ internal fun TopScreenPart(
with fadeOut())
.using(SizeTransform(clip = false))
}
) {
) { value ->
Text(
text = it,
text = value,
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
)
}
InputTextField(
modifier = Modifier
.weight(2f)
.clickable { onOutputTextFieldClick() },
value = TextFieldValue(
when {
.weight(2f),
value = when {
networkLoading -> stringResource(R.string.loading_label)
networkError -> stringResource(R.string.error_label)
converterMode == ConverterMode.BASE -> outputValue.uppercase()
@ -164,9 +158,8 @@ internal fun TopScreenPart(
)
}
else -> Formatter.format(outputValue)
}
),
minRatio = 0.7f
},
minRatio = 0.7f,
)
AnimatedContent(
modifier = Modifier.fillMaxWidth(),
@ -178,19 +171,21 @@ internal fun TopScreenPart(
with fadeOut())
.using(SizeTransform(clip = false))
}
) {
) { value ->
Text(
text = it,
text = value,
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
)
}
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
Row(verticalAlignment = Alignment.CenterVertically) {
UnitSelectionButton(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onClick = { unitFrom?.let { navigateToLeftScreen(it.unitId) } },
onClick = { unitFrom?.let { unit -> navigateToLeftScreen(unit.unitId) } },
label = unitFrom?.displayName ?: R.string.loading_label,
)
IconButton(