mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 08:45:27 +02:00
parent
6cf49812b7
commit
4c20c6c0b8
@ -27,11 +27,9 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
|||||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.heightIn
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.minimumInteractiveComponentSize
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
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.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BasicKeyboardButton(
|
fun BasicKeyboardButton(
|
||||||
@ -133,16 +130,14 @@ fun KeyboardButtonAdditional(
|
|||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
BasicKeyboardButton(
|
BasicKeyboardButton(
|
||||||
modifier = modifier
|
modifier = modifier,
|
||||||
.minimumInteractiveComponentSize()
|
|
||||||
.heightIn(max = 48.dp),
|
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent,
|
||||||
icon = icon,
|
icon = icon,
|
||||||
iconColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
iconColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
allowVibration = allowVibration,
|
allowVibration = allowVibration,
|
||||||
contentHeight = if (isPortrait()) 0.9f else 0.85f
|
contentHeight = if (isPortrait()) 0.8f else 0.85f
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When Portrait mode will place [content1] and [content2] in a [Column].
|
* When Portrait mode will place [content1] and [content2] in a [Column].
|
||||||
@ -41,13 +42,19 @@ fun PortraitLandscape(
|
|||||||
) {
|
) {
|
||||||
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
ColumnWithConstraints(modifier) {
|
ColumnWithConstraints(modifier) {
|
||||||
content1(Modifier.fillMaxHeight(0.34f).padding(horizontal = it.maxWidth * 0.03f))
|
content1(Modifier.fillMaxHeight(0.38f).padding(horizontal = it.maxWidth * 0.03f))
|
||||||
content2(Modifier.fillMaxSize().padding(horizontal = it.maxWidth * 0.03f, vertical = it.maxHeight * 0.015f))
|
content2(Modifier.fillMaxSize().padding(it.maxWidth * 0.03f, it.maxHeight * 0.015f))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RowWithConstraints(modifier) {
|
RowWithConstraints(modifier) {
|
||||||
content1(Modifier.weight(1f).fillMaxHeight().padding(bottom = it.maxWidth * 0.015f, start = it.maxWidth * 0.015f, end = it.maxWidth * 0.015f))
|
val contentModifier = Modifier
|
||||||
content2(Modifier.weight(1f).fillMaxSize().padding(bottom = it.maxWidth * 0.015f, start = it.maxWidth * 0.015f, end = it.maxWidth * 0.015f))
|
.weight(1f)
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(
|
||||||
|
it.maxWidth * 0.015f, 0.dp,
|
||||||
|
it.maxHeight * 0.03f, it.maxHeight * 0.03f)
|
||||||
|
content1(contentModifier)
|
||||||
|
content2(contentModifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.core.ui.common.textfield
|
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.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
@ -30,10 +32,16 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.layout.layout
|
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.LocalClipboardManager
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
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.platform.LocalView
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.Paragraph
|
import androidx.compose.ui.text.Paragraph
|
||||||
|
import androidx.compose.ui.text.TextRange
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.createFontFamilyResolver
|
import androidx.compose.ui.text.font.createFontFamilyResolver
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
@ -66,19 +75,9 @@ fun InputTextField(
|
|||||||
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
) {
|
) {
|
||||||
val clipboardManager = LocalClipboardManager.current
|
val clipboardManager = LocalClipboardManager.current
|
||||||
fun copyCallback() {
|
fun copyCallback() = clipboardManager.copyWithoutGrouping(value)
|
||||||
clipboardManager.setText(
|
|
||||||
AnnotatedString(
|
|
||||||
Formatter.removeGrouping(
|
|
||||||
value.annotatedString.subSequence(value.selection).text
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
CompositionLocalProvider(
|
val textToolbar = UnittoTextToolbar(
|
||||||
LocalTextInputService provides null,
|
|
||||||
LocalTextToolbar provides UnittoTextToolbar(
|
|
||||||
view = LocalView.current,
|
view = LocalView.current,
|
||||||
copyCallback = ::copyCallback,
|
copyCallback = ::copyCallback,
|
||||||
pasteCallback = {
|
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(
|
AutoSizableTextField(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
value = value,
|
value = value,
|
||||||
|
textStyle = textStyle.copy(color = textColor),
|
||||||
|
minRatio = minRatio,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
onCursorChange(it.selection.start..it.selection.end)
|
onCursorChange(it.selection.start..it.selection.end)
|
||||||
},
|
},
|
||||||
textStyle = textStyle,
|
showToolbar = textToolbar::showMenu,
|
||||||
minRatio = minRatio,
|
hideToolbar = textToolbar::hide
|
||||||
readOnly = false
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,34 +115,54 @@ fun InputTextField(
|
|||||||
@Composable
|
@Composable
|
||||||
fun InputTextField(
|
fun InputTextField(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
value: TextFieldValue,
|
value: String,
|
||||||
textStyle: TextStyle = NumbersTextStyleDisplayLarge,
|
textStyle: TextStyle = NumbersTextStyleDisplayLarge,
|
||||||
minRatio: Float = 1f,
|
minRatio: Float = 1f,
|
||||||
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
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(
|
AutoSizableTextField(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
value = value,
|
value = textFieldValue,
|
||||||
textStyle = textStyle,
|
onValueChange = { textFieldValue = it },
|
||||||
|
textStyle = textStyle.copy(color = textColor),
|
||||||
minRatio = minRatio,
|
minRatio = minRatio,
|
||||||
readOnly = true
|
readOnly = true,
|
||||||
|
interactionSource = interactionSource
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AutoSizableTextField(
|
private fun AutoSizableTextField(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
value: TextFieldValue,
|
value: TextFieldValue,
|
||||||
onValueChange: (TextFieldValue) -> Unit = {},
|
|
||||||
textStyle: TextStyle = TextStyle(),
|
textStyle: TextStyle = TextStyle(),
|
||||||
scaleFactor: Float = 0.95f,
|
scaleFactor: Float = 0.95f,
|
||||||
minRatio: Float = 1f,
|
minRatio: Float = 1f,
|
||||||
|
onValueChange: (TextFieldValue) -> Unit,
|
||||||
readOnly: Boolean = false,
|
readOnly: Boolean = false,
|
||||||
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
showToolbar: (rect: Rect) -> Unit = {},
|
||||||
cursorBrush: Brush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant)
|
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
|
val density = LocalDensity.current
|
||||||
|
|
||||||
var nFontSize: TextUnit by remember { mutableStateOf(0.sp) }
|
var nFontSize: TextUnit by remember { mutableStateOf(0.sp) }
|
||||||
@ -178,18 +206,30 @@ private fun AutoSizableTextField(
|
|||||||
val nTextStyle = textStyle.copy(
|
val nTextStyle = textStyle.copy(
|
||||||
// https://issuetracker.google.com/issues/266470454
|
// https://issuetracker.google.com/issues/266470454
|
||||||
// textAlign = TextAlign.End,
|
// textAlign = TextAlign.End,
|
||||||
color = textColor,
|
|
||||||
fontSize = nFontSize
|
fontSize = nFontSize
|
||||||
)
|
)
|
||||||
|
var offset = Offset.Zero
|
||||||
|
|
||||||
BasicTextField(
|
BasicTextField(
|
||||||
value = value,
|
value = value,
|
||||||
singleLine = true,
|
onValueChange = {
|
||||||
onValueChange = onValueChange,
|
showToolbar(Rect(offset, 0f))
|
||||||
|
hideToolbar()
|
||||||
|
onValueChange(it)
|
||||||
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.widthIn(
|
.focusRequester(focusRequester)
|
||||||
max = with(density) { intrinsics.width.toDp() }
|
.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 ->
|
.layout { measurable, constraints ->
|
||||||
val placeable = measurable.measure(constraints)
|
val placeable = measurable.measure(constraints)
|
||||||
// TextField size is changed with a delay (text jumps). Here we correct it.
|
// 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()
|
y = (placeable.height - intrinsics.height).roundToInt()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
.onGloballyPositioned { layoutCoords -> offset = layoutCoords.positionInWindow() },
|
||||||
textStyle = nTextStyle,
|
textStyle = nTextStyle,
|
||||||
|
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant),
|
||||||
|
singleLine = true,
|
||||||
readOnly = readOnly,
|
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)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -45,10 +45,8 @@ class UnittoTextToolbar(
|
|||||||
onSelectAllRequested: (() -> Unit)?
|
onSelectAllRequested: (() -> Unit)?
|
||||||
) {
|
) {
|
||||||
textActionModeCallback.rect = rect
|
textActionModeCallback.rect = rect
|
||||||
textActionModeCallback.onCopyRequested = { onCopyRequested?.invoke(); copyCallback.invoke() }
|
textActionModeCallback.onCopyRequested = copyCallback
|
||||||
textActionModeCallback.onCutRequested = cutCallback?.let {
|
textActionModeCallback.onCutRequested = cutCallback
|
||||||
{ it.invoke(); onCutRequested?.invoke() }
|
|
||||||
}
|
|
||||||
textActionModeCallback.onPasteRequested = pasteCallback
|
textActionModeCallback.onPasteRequested = pasteCallback
|
||||||
textActionModeCallback.onSelectAllRequested = onSelectAllRequested
|
textActionModeCallback.onSelectAllRequested = onSelectAllRequested
|
||||||
if (actionMode == null) {
|
if (actionMode == null) {
|
||||||
|
@ -35,7 +35,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.sizeIn
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.outlined.MoreVert
|
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.TextButton
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -57,12 +55,8 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.onPlaced
|
import androidx.compose.ui.layout.onPlaced
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
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.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
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.MenuButton
|
||||||
import com.sadellie.unitto.core.ui.common.UnittoScreenWithTopBar
|
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.InputTextField
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.UnittoTextToolbar
|
|
||||||
import com.sadellie.unitto.data.model.HistoryItem
|
import com.sadellie.unitto.data.model.HistoryItem
|
||||||
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard
|
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard
|
||||||
import com.sadellie.unitto.feature.calculator.components.DragDownView
|
import com.sadellie.unitto.feature.calculator.components.DragDownView
|
||||||
@ -90,26 +83,8 @@ internal fun CalculatorRoute(
|
|||||||
navigateToSettings: () -> Unit,
|
navigateToSettings: () -> Unit,
|
||||||
viewModel: CalculatorViewModel = hiltViewModel()
|
viewModel: CalculatorViewModel = hiltViewModel()
|
||||||
) {
|
) {
|
||||||
val clipboardManager = LocalClipboardManager.current
|
|
||||||
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
|
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(
|
CalculatorScreen(
|
||||||
uiState = uiState.value,
|
uiState = uiState.value,
|
||||||
navigateToMenu = navigateToMenu,
|
navigateToMenu = navigateToMenu,
|
||||||
@ -122,7 +97,6 @@ internal fun CalculatorRoute(
|
|||||||
evaluate = viewModel::evaluate,
|
evaluate = viewModel::evaluate,
|
||||||
clearHistory = viewModel::clearHistory
|
clearHistory = viewModel::clearHistory
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -186,7 +160,6 @@ private fun CalculatorScreen(
|
|||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
historyItems = uiState.history,
|
historyItems = uiState.history,
|
||||||
historyItemHeightCallback = { historyItemHeight = it },
|
historyItemHeightCallback = { historyItemHeight = it },
|
||||||
onTextClick = addSymbol
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
textFields = { maxDragAmount ->
|
textFields = { maxDragAmount ->
|
||||||
@ -243,18 +216,15 @@ private fun CalculatorScreen(
|
|||||||
onCursorChange = onCursorChange
|
onCursorChange = onCursorChange
|
||||||
)
|
)
|
||||||
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
SelectionContainer(Modifier.weight(1f)) {
|
|
||||||
InputTextField(
|
InputTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp),
|
.padding(horizontal = 8.dp),
|
||||||
value = TextFieldValue(
|
value = Formatter.format(uiState.output),
|
||||||
Formatter.fromSeparator(uiState.output, Separator.COMMA)
|
|
||||||
),
|
|
||||||
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f)
|
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Handle
|
// Handle
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
|
@ -33,13 +33,13 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ExpandLess
|
import androidx.compose.material.icons.filled.ExpandLess
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.IconButtonDefaults
|
import androidx.compose.material3.IconButtonDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.minimumInteractiveComponentSize
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -164,13 +164,12 @@ private fun PortraitKeyboard(
|
|||||||
val mainButtonModifier = Modifier
|
val mainButtonModifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(horizontalFraction(0.015f), verticalFraction(0.008f))
|
.padding(horizontalFraction(0.015f), verticalFraction(0.009f))
|
||||||
val additionalButtonModifier = Modifier
|
val additionalButtonModifier = Modifier
|
||||||
.minimumInteractiveComponentSize()
|
|
||||||
.weight(1f)
|
.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(
|
Row(
|
||||||
modifier = Modifier,
|
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
|
// Expand/Collapse
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { showAdditional = !showAdditional },
|
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) {
|
Row(weightModifier) {
|
||||||
KeyboardButtonFilled(mainButtonModifier, UnittoIcons.LeftBracket, allowVibration) { addSymbol(Token.leftBracket) }
|
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.Percent, allowVibration) { addSymbol(Token.percent) }
|
||||||
KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Divide, allowVibration) { addSymbol(Token.divideDisplay) }
|
KeyboardButtonFilled(mainButtonModifier, UnittoIcons.Divide, allowVibration) { addSymbol(Token.divideDisplay) }
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(weightModifier) {
|
Row(weightModifier) {
|
||||||
KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration) { addSymbol(Token._7) }
|
KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key7, allowVibration) { addSymbol(Token._7) }
|
||||||
KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration) { addSymbol(Token._8) }
|
KeyboardButtonLight(mainButtonModifier, UnittoIcons.Key8, allowVibration) { addSymbol(Token._8) }
|
||||||
|
@ -19,10 +19,8 @@
|
|||||||
package com.sadellie.unitto.feature.calculator.components
|
package com.sadellie.unitto.feature.calculator.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.horizontalScroll
|
import androidx.compose.foundation.horizontalScroll
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
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.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
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.Icons
|
||||||
import androidx.compose.material.icons.filled.History
|
import androidx.compose.material.icons.filled.History
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.onPlaced
|
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.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.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.sadellie.unitto.core.ui.Formatter
|
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.core.ui.theme.NumbersTextStyleDisplayMedium
|
||||||
import com.sadellie.unitto.data.model.HistoryItem
|
import com.sadellie.unitto.data.model.HistoryItem
|
||||||
import com.sadellie.unitto.feature.calculator.R
|
import com.sadellie.unitto.feature.calculator.R
|
||||||
@ -59,7 +68,6 @@ internal fun HistoryList(
|
|||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
historyItems: List<HistoryItem>,
|
historyItems: List<HistoryItem>,
|
||||||
historyItemHeightCallback: (Int) -> Unit,
|
historyItemHeightCallback: (Int) -> Unit,
|
||||||
onTextClick: (String) -> Unit
|
|
||||||
) {
|
) {
|
||||||
val verticalArrangement by remember(historyItems) {
|
val verticalArrangement by remember(historyItems) {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
@ -95,15 +103,13 @@ internal fun HistoryList(
|
|||||||
item {
|
item {
|
||||||
HistoryListItem(
|
HistoryListItem(
|
||||||
modifier = Modifier.onPlaced { historyItemHeightCallback(it.size.height) },
|
modifier = Modifier.onPlaced { historyItemHeightCallback(it.size.height) },
|
||||||
historyItem = historyItems.first(),
|
historyItem = historyItems.first()
|
||||||
onTextClick = onTextClick
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
items(historyItems.drop(1)) { historyItem ->
|
items(historyItems.drop(1)) { historyItem ->
|
||||||
HistoryListItem(
|
HistoryListItem(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
historyItem = historyItem,
|
historyItem = historyItem
|
||||||
onTextClick = onTextClick
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,42 +120,58 @@ internal fun HistoryList(
|
|||||||
private fun HistoryListItem(
|
private fun HistoryListItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
historyItem: HistoryItem,
|
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) {
|
Column(modifier = modifier) {
|
||||||
Box(
|
CompositionLocalProvider(
|
||||||
Modifier.clickable { onTextClick(historyItem.expression) }
|
LocalTextInputService provides null,
|
||||||
|
LocalTextToolbar provides UnittoTextToolbar(
|
||||||
|
view = LocalView.current,
|
||||||
|
copyCallback = { clipboardManager.copyWithoutGrouping(textFieldexpr) }
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
Text(
|
BasicTextField(
|
||||||
text = Formatter.format(historyItem.expression),
|
value = textFieldexpr,
|
||||||
|
onValueChange = { textFieldexpr = it },
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
|
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
|
||||||
style = NumbersTextStyleDisplayMedium,
|
textStyle = NumbersTextStyleDisplayMedium.copy(color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.End),
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
readOnly = true
|
||||||
textAlign = TextAlign.End
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Box(
|
|
||||||
Modifier.clickable { onTextClick(historyItem.result) }
|
CompositionLocalProvider(
|
||||||
|
LocalTextInputService provides null,
|
||||||
|
LocalTextToolbar provides UnittoTextToolbar(
|
||||||
|
view = LocalView.current,
|
||||||
|
copyCallback = { clipboardManager.copyWithoutGrouping(textFieldRes) }
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
Text(
|
BasicTextField(
|
||||||
text = Formatter.format(historyItem.result),
|
value = textFieldRes,
|
||||||
|
onValueChange = { textFieldRes = it },
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
|
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
|
||||||
style = NumbersTextStyleDisplayMedium,
|
textStyle = NumbersTextStyleDisplayMedium.copy(color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), textAlign = TextAlign.End),
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f),
|
readOnly = true
|
||||||
textAlign = TextAlign.End
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@ -178,8 +200,6 @@ private fun PreviewHistoryList() {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
|
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
historyItems = historyItems,
|
historyItems = historyItems
|
||||||
historyItemHeightCallback = {},
|
) {}
|
||||||
onTextClick = {}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ import androidx.compose.ui.platform.LocalClipboardManager
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.sadellie.unitto.core.ui.R
|
import com.sadellie.unitto.core.ui.R
|
||||||
@ -114,7 +113,7 @@ internal fun MyTextField(
|
|||||||
) {
|
) {
|
||||||
InputTextField(
|
InputTextField(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
value = TextFieldValue(it.take(1000)),
|
value = it.take(1000),
|
||||||
textStyle = NumbersTextStyleDisplayLarge.copy(textAlign = TextAlign.End)
|
textStyle = NumbersTextStyleDisplayLarge.copy(textAlign = TextAlign.End)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -147,7 +146,7 @@ internal fun MyTextField(
|
|||||||
) {
|
) {
|
||||||
InputTextField(
|
InputTextField(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
value = TextFieldValue(it?.take(1000) ?: ""),
|
value = it?.take(1000) ?: "",
|
||||||
textStyle = NumbersTextStyleDisplayLarge.copy(
|
textStyle = NumbersTextStyleDisplayLarge.copy(
|
||||||
textAlign = TextAlign.End,
|
textAlign = TextAlign.End,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
|
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
|
||||||
|
@ -30,11 +30,10 @@ import androidx.compose.animation.fadeIn
|
|||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.animation.with
|
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.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@ -51,11 +50,10 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
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.Formatter
|
||||||
import com.sadellie.unitto.core.ui.R
|
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.core.ui.common.textfield.InputTextField
|
||||||
import com.sadellie.unitto.data.model.AbstractUnit
|
import com.sadellie.unitto.data.model.AbstractUnit
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
@ -105,18 +103,15 @@ internal fun TopScreenPart(
|
|||||||
)
|
)
|
||||||
val mContext = LocalContext.current
|
val mContext = LocalContext.current
|
||||||
|
|
||||||
Column(
|
ColumnWithConstraints(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
) {
|
||||||
InputTextField(
|
InputTextField(
|
||||||
modifier = Modifier.weight(2f),
|
modifier = Modifier.weight(2f),
|
||||||
value = TextFieldValue(
|
value = when (converterMode) {
|
||||||
when (converterMode) {
|
|
||||||
ConverterMode.BASE -> inputValue.uppercase()
|
ConverterMode.BASE -> inputValue.uppercase()
|
||||||
else -> Formatter.format(inputValue)
|
else -> Formatter.format(inputValue)
|
||||||
}
|
},
|
||||||
),
|
|
||||||
minRatio = 0.7f
|
minRatio = 0.7f
|
||||||
)
|
)
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
@ -126,8 +121,9 @@ internal fun TopScreenPart(
|
|||||||
exit = shrinkVertically(clip = false)
|
exit = shrinkVertically(clip = false)
|
||||||
) {
|
) {
|
||||||
InputTextField(
|
InputTextField(
|
||||||
value = TextFieldValue(calculatedValue?.let { Formatter.format(it) } ?: ""),
|
value = calculatedValue?.let { value -> Formatter.format(value) } ?: "",
|
||||||
minRatio = 0.7f
|
minRatio = 0.7f,
|
||||||
|
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
@ -140,19 +136,17 @@ internal fun TopScreenPart(
|
|||||||
with fadeOut())
|
with fadeOut())
|
||||||
.using(SizeTransform(clip = false))
|
.using(SizeTransform(clip = false))
|
||||||
}
|
}
|
||||||
) {
|
) { value ->
|
||||||
Text(
|
Text(
|
||||||
text = it,
|
text = value,
|
||||||
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
|
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
InputTextField(
|
InputTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(2f)
|
.weight(2f),
|
||||||
.clickable { onOutputTextFieldClick() },
|
value = when {
|
||||||
value = TextFieldValue(
|
|
||||||
when {
|
|
||||||
networkLoading -> stringResource(R.string.loading_label)
|
networkLoading -> stringResource(R.string.loading_label)
|
||||||
networkError -> stringResource(R.string.error_label)
|
networkError -> stringResource(R.string.error_label)
|
||||||
converterMode == ConverterMode.BASE -> outputValue.uppercase()
|
converterMode == ConverterMode.BASE -> outputValue.uppercase()
|
||||||
@ -164,9 +158,8 @@ internal fun TopScreenPart(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> Formatter.format(outputValue)
|
else -> Formatter.format(outputValue)
|
||||||
}
|
},
|
||||||
),
|
minRatio = 0.7f,
|
||||||
minRatio = 0.7f
|
|
||||||
)
|
)
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@ -178,19 +171,21 @@ internal fun TopScreenPart(
|
|||||||
with fadeOut())
|
with fadeOut())
|
||||||
.using(SizeTransform(clip = false))
|
.using(SizeTransform(clip = false))
|
||||||
}
|
}
|
||||||
) {
|
) { value ->
|
||||||
Text(
|
Text(
|
||||||
text = it,
|
text = value,
|
||||||
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
|
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
UnitSelectionButton(
|
UnitSelectionButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(1f),
|
.weight(1f),
|
||||||
onClick = { unitFrom?.let { navigateToLeftScreen(it.unitId) } },
|
onClick = { unitFrom?.let { unit -> navigateToLeftScreen(unit.unitId) } },
|
||||||
label = unitFrom?.displayName ?: R.string.loading_label,
|
label = unitFrom?.displayName ?: R.string.loading_label,
|
||||||
)
|
)
|
||||||
IconButton(
|
IconButton(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user