mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-18 16:25:27 +02:00
parent
224ddd8bad
commit
263a1139dc
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Unitto is a calculator for Android
|
* Unitto is a calculator for Android
|
||||||
* Copyright (c) 2022-2024 Elshan Agaev
|
* Copyright (c) 2024 Elshan Agaev
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,10 +19,12 @@
|
|||||||
package com.sadellie.unitto.core.base
|
package com.sadellie.unitto.core.base
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Separators mean symbols that separate fractional part
|
* Formatter symbols. Always use [Token].
|
||||||
|
*
|
||||||
|
* @property grouping Symbol fpr thousands separator.
|
||||||
|
* @property fractional Symbol decimal separator.
|
||||||
*/
|
*/
|
||||||
object Separator {
|
data class FormatterSymbols(
|
||||||
const val SPACE = 0
|
val grouping: String,
|
||||||
const val PERIOD = 1
|
val fractional: String,
|
||||||
const val COMMA = 2
|
)
|
||||||
}
|
|
@ -20,6 +20,10 @@ package com.sadellie.unitto.core.base
|
|||||||
|
|
||||||
@Suppress("ObjectPropertyName")
|
@Suppress("ObjectPropertyName")
|
||||||
object Token {
|
object Token {
|
||||||
|
const val SPACE = " "
|
||||||
|
const val PERIOD = "."
|
||||||
|
const val COMMA = ","
|
||||||
|
|
||||||
object Digit {
|
object Digit {
|
||||||
const val _1 = "1"
|
const val _1 = "1"
|
||||||
const val _2 = "2"
|
const val _2 = "2"
|
||||||
|
@ -245,6 +245,7 @@ Alternatively you can use "Export" -->
|
|||||||
<string name="settings_currency_rates_note_text">Currency rates are updated daily. There\'s no real-time market monitoring in the app</string>
|
<string name="settings_currency_rates_note_text">Currency rates are updated daily. There\'s no real-time market monitoring in the app</string>
|
||||||
<string name="settings_currency_rates_note_title">Wrong currency rates?</string>
|
<string name="settings_currency_rates_note_title">Wrong currency rates?</string>
|
||||||
<string name="settings_dark_mode">Dark</string>
|
<string name="settings_dark_mode">Dark</string>
|
||||||
|
<string name="settings_decimal_separator">Decimal separator</string>
|
||||||
<string name="settings_disable_unit_group_description">Disable unit group</string>
|
<string name="settings_disable_unit_group_description">Disable unit group</string>
|
||||||
<string name="settings_display">Display</string>
|
<string name="settings_display">Display</string>
|
||||||
<string name="settings_display_support">App look and feel</string>
|
<string name="settings_display_support">App look and feel</string>
|
||||||
@ -301,6 +302,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
|||||||
<string name="settings_system_font_support">Use system font for texts in app</string>
|
<string name="settings_system_font_support">Use system font for texts in app</string>
|
||||||
<string name="settings_terms_and_conditions">Terms and Conditions</string>
|
<string name="settings_terms_and_conditions">Terms and Conditions</string>
|
||||||
<string name="settings_third_party_licenses">Third party licenses</string>
|
<string name="settings_third_party_licenses">Third party licenses</string>
|
||||||
|
<string name="settings_thousands_separator">Thousands separator</string>
|
||||||
<string name="settings_title">Settings</string>
|
<string name="settings_title">Settings</string>
|
||||||
<string name="settings_translate_app">Translate this app</string>
|
<string name="settings_translate_app">Translate this app</string>
|
||||||
<string name="settings_translate_app_support">Join POEditor project to help</string>
|
<string name="settings_translate_app_support">Join POEditor project to help</string>
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Unitto is a calculator for Android
|
|
||||||
* Copyright (c) 2023-2024 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.core.base
|
|
||||||
|
|
||||||
import org.junit.Assert
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
class SeparatorTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testExists() {
|
|
||||||
Assert.assertNotNull(Separator)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testSeparatorSpace() {
|
|
||||||
Assert.assertEquals(0, Separator.SPACE)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testSeparatorPeriod() {
|
|
||||||
Assert.assertEquals(1, Separator.PERIOD)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testSeparatorComma() {
|
|
||||||
Assert.assertEquals(2, Separator.COMMA)
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,14 @@ import org.junit.Assert
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class TokenTest {
|
class TokenTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFormatterSymbols() {
|
||||||
|
Assert.assertEquals(" ", Token.SPACE)
|
||||||
|
Assert.assertEquals(".", Token.PERIOD)
|
||||||
|
Assert.assertEquals(",", Token.COMMA)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDigit() {
|
fun testDigit() {
|
||||||
Assert.assertEquals("1234567890", Token.Digit.all.joinToString(""))
|
Assert.assertEquals("1234567890", Token.Digit.all.joinToString(""))
|
||||||
@ -126,7 +134,7 @@ class TokenTest {
|
|||||||
"e",
|
"e",
|
||||||
).joinToString("")
|
).joinToString("")
|
||||||
|
|
||||||
Assert.assertEquals("1234567890.$operator$func$consts", Token.expressionTokens.joinToString(""))
|
Assert.assertEquals("1234567890.$operator$func${consts}E", Token.expressionTokens.joinToString(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -21,6 +21,7 @@ package com.sadellie.unitto.core.ui.common.textfield
|
|||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import androidx.compose.ui.platform.ClipboardManager
|
import androidx.compose.ui.platform.ClipboardManager
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +22,7 @@ import androidx.compose.ui.text.AnnotatedString
|
|||||||
import androidx.compose.ui.text.input.OffsetMapping
|
import androidx.compose.ui.text.input.OffsetMapping
|
||||||
import androidx.compose.ui.text.input.TransformedText
|
import androidx.compose.ui.text.input.TransformedText
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
|
||||||
class ExpressionTransformer(private val formatterSymbols: FormatterSymbols) : VisualTransformation {
|
class ExpressionTransformer(private val formatterSymbols: FormatterSymbols) : VisualTransformation {
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import androidx.compose.ui.platform.LocalClipboardManager
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
|
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.core.ui.common.textfield
|
package com.sadellie.unitto.core.ui.common.textfield
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
|
|
||||||
private val numbersRegex by lazy { Regex("[\\d.]+") }
|
private val numbersRegex by lazy { Regex("[\\d.]+") }
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Unitto is a calculator for Android
|
|
||||||
* Copyright (c) 2023-2024 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.core.ui.common.textfield
|
|
||||||
|
|
||||||
import com.sadellie.unitto.core.base.Separator
|
|
||||||
|
|
||||||
sealed class FormatterSymbols(val grouping: String, val fractional: String) {
|
|
||||||
data object Spaces : FormatterSymbols(" ", ".")
|
|
||||||
data object Period : FormatterSymbols(".", ",")
|
|
||||||
data object Comma : FormatterSymbols(",", ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
object AllFormatterSymbols {
|
|
||||||
private val allFormatterSymbols by lazy {
|
|
||||||
hashMapOf(
|
|
||||||
Separator.SPACE to FormatterSymbols.Spaces,
|
|
||||||
Separator.PERIOD to FormatterSymbols.Period,
|
|
||||||
Separator.COMMA to FormatterSymbols.Comma
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defaults to [FormatterSymbols.Spaces] if not found.
|
|
||||||
*
|
|
||||||
* @see Separator
|
|
||||||
*/
|
|
||||||
fun getById(separator: Int): FormatterSymbols {
|
|
||||||
return allFormatterSymbols.getOrElse(separator) { FormatterSymbols.Spaces }
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,6 +44,7 @@ import androidx.compose.ui.text.input.TextFieldValue
|
|||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.TextUnit
|
import androidx.compose.ui.unit.TextUnit
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.ui.common.autosize.AutoSizeTextStyleBox
|
import com.sadellie.unitto.core.ui.common.autosize.AutoSizeTextStyleBox
|
||||||
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
|
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
|
||||||
|
|
||||||
|
@ -18,40 +18,44 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.core.ui
|
package com.sadellie.unitto.core.ui
|
||||||
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.clearAndFilterExpression
|
import com.sadellie.unitto.core.ui.common.textfield.clearAndFilterExpression
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class CleanAndFilterExpression {
|
class CleanAndFilterExpression {
|
||||||
|
|
||||||
|
private val formatterSymbols = FormatterSymbols(Token.COMMA, Token.PERIOD)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun noAdditionalSymbols() {
|
fun noAdditionalSymbols() {
|
||||||
assertEquals("123", "123".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123", "123".clearAndFilterExpression(formatterSymbols))
|
||||||
assertEquals("123.456", "123.456".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123.456", "123.456".clearAndFilterExpression(formatterSymbols))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun hasFormatterSymbol() {
|
fun hasFormatterSymbol() {
|
||||||
assertEquals("123456", "123,456".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123456", "123,456".clearAndFilterExpression(formatterSymbols))
|
||||||
assertEquals("123456.789", "123,456.789".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123456.789", "123,456.789".clearAndFilterExpression(formatterSymbols))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun hasWrongFormatterSymbol() {
|
fun hasWrongFormatterSymbol() {
|
||||||
assertEquals("123456", "123 456".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123456", "123 456".clearAndFilterExpression(formatterSymbols))
|
||||||
assertEquals("123456.789", "123 456.789".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123456.789", "123 456.789".clearAndFilterExpression(formatterSymbols))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun fractionExpression() {
|
fun fractionExpression() {
|
||||||
assertEquals("1600+1234÷56789", "1,600 1234⁄56789".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("1600+1234÷56789", "1,600 1234⁄56789".clearAndFilterExpression(formatterSymbols))
|
||||||
assertEquals("123456.789+1234÷56789", "123,456.789 1234⁄56789".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("123456.789+1234÷56789", "123,456.789 1234⁄56789".clearAndFilterExpression(formatterSymbols))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun garbage() {
|
fun garbage() {
|
||||||
// 'e' is a known symbol
|
// 'e' is a known symbol
|
||||||
assertEquals("eeee−123", "pee pee poo poo -123".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("eeee−123", "pee pee poo poo -123".clearAndFilterExpression(formatterSymbols))
|
||||||
assertEquals("eeee−123.456", "pee pee poo poo -123.456".clearAndFilterExpression(FormatterSymbols.Comma))
|
assertEquals("eeee−123.456", "pee pee poo poo -123.456".clearAndFilterExpression(formatterSymbols))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,15 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.core.ui
|
package com.sadellie.unitto.core.ui
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
|
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class ExpressionTransformerTest {
|
class ExpressionTransformerTest {
|
||||||
|
|
||||||
private val expr = ExpressionTransformer(FormatterSymbols.Comma)
|
private val expr = ExpressionTransformer(FormatterSymbols(Token.COMMA, Token.PERIOD))
|
||||||
|
|
||||||
// Use "|" for cursor
|
// Use "|" for cursor
|
||||||
private fun origToTrans(orig: String, trans: String) {
|
private fun origToTrans(orig: String, trans: String) {
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.core.ui
|
package com.sadellie.unitto.core.ui
|
||||||
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -40,7 +41,7 @@ class FormatterExpressionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setSeparatorSpaces() {
|
fun setSeparatorSpaces() {
|
||||||
fun String.format(): String = formatExpression(FormatterSymbols.Spaces)
|
fun String.format(): String = formatExpression(FormatterSymbols(Token.SPACE, Token.PERIOD))
|
||||||
assertEquals("123E+21", ENG_VALUE.format())
|
assertEquals("123E+21", ENG_VALUE.format())
|
||||||
assertEquals("123.3E+21", ENG_VALUE_FRACTIONAL.format())
|
assertEquals("123.3E+21", ENG_VALUE_FRACTIONAL.format())
|
||||||
assertEquals("123E+21+(123 456.789)", ENG_VALUE_EXPRESSION.format())
|
assertEquals("123E+21+(123 456.789)", ENG_VALUE_EXPRESSION.format())
|
||||||
@ -57,7 +58,7 @@ class FormatterExpressionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setSeparatorComma() {
|
fun setSeparatorComma() {
|
||||||
fun String.format(): String = formatExpression(FormatterSymbols.Comma)
|
fun String.format(): String = formatExpression(FormatterSymbols(Token.COMMA, Token.PERIOD))
|
||||||
assertEquals("123E+21", ENG_VALUE.format())
|
assertEquals("123E+21", ENG_VALUE.format())
|
||||||
assertEquals("123.3E+21", ENG_VALUE_FRACTIONAL.format())
|
assertEquals("123.3E+21", ENG_VALUE_FRACTIONAL.format())
|
||||||
assertEquals("123E+21+(123,456.789)", ENG_VALUE_EXPRESSION.format())
|
assertEquals("123E+21+(123,456.789)", ENG_VALUE_EXPRESSION.format())
|
||||||
@ -74,7 +75,7 @@ class FormatterExpressionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setSeparatorPeriod() {
|
fun setSeparatorPeriod() {
|
||||||
fun String.format(): String = formatExpression(FormatterSymbols.Period)
|
fun String.format(): String = formatExpression(FormatterSymbols(Token.PERIOD, Token.COMMA))
|
||||||
assertEquals("123E+21", ENG_VALUE.format())
|
assertEquals("123E+21", ENG_VALUE.format())
|
||||||
assertEquals("123,3E+21", ENG_VALUE_FRACTIONAL.format())
|
assertEquals("123,3E+21", ENG_VALUE_FRACTIONAL.format())
|
||||||
assertEquals("123E+21+(123.456,789)", ENG_VALUE_EXPRESSION.format())
|
assertEquals("123E+21+(123.456,789)", ENG_VALUE_EXPRESSION.format())
|
||||||
|
@ -51,7 +51,7 @@ interface UserPreferencesRepository {
|
|||||||
|
|
||||||
suspend fun updateDigitsPrecision(precision: Int)
|
suspend fun updateDigitsPrecision(precision: Int)
|
||||||
|
|
||||||
suspend fun updateSeparator(separator: Int)
|
suspend fun updateFormatterSymbols(grouping: String, fractional: String)
|
||||||
|
|
||||||
suspend fun updateOutputFormat(outputFormat: Int)
|
suspend fun updateOutputFormat(outputFormat: Int)
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.data.model.userprefs
|
package com.sadellie.unitto.data.model.userprefs
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
|
||||||
interface AddSubtractPreferences{
|
interface AddSubtractPreferences{
|
||||||
val separator: Int
|
val formatterSymbols: FormatterSymbols
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.data.model.userprefs
|
package com.sadellie.unitto.data.model.userprefs
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
|
||||||
interface BodyMassPreferences{
|
interface BodyMassPreferences{
|
||||||
val separator: Int
|
val formatterSymbols: FormatterSymbols
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.data.model.userprefs
|
package com.sadellie.unitto.data.model.userprefs
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
|
||||||
interface CalculatorPreferences {
|
interface CalculatorPreferences {
|
||||||
val radianMode: Boolean
|
val radianMode: Boolean
|
||||||
val separator: Int
|
val formatterSymbols: FormatterSymbols
|
||||||
val middleZero: Boolean
|
val middleZero: Boolean
|
||||||
val acButton: Boolean
|
val acButton: Boolean
|
||||||
val partialHistoryView: Boolean
|
val partialHistoryView: Boolean
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.data.model.userprefs
|
package com.sadellie.unitto.data.model.userprefs
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||||
|
|
||||||
interface ConverterPreferences {
|
interface ConverterPreferences {
|
||||||
val separator: Int
|
val formatterSymbols: FormatterSymbols
|
||||||
val middleZero: Boolean
|
val middleZero: Boolean
|
||||||
val acButton: Boolean
|
val acButton: Boolean
|
||||||
val precision: Int
|
val precision: Int
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.data.model.userprefs
|
package com.sadellie.unitto.data.model.userprefs
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
|
||||||
interface FormattingPreferences{
|
interface FormattingPreferences{
|
||||||
val digitsPrecision: Int
|
val digitsPrecision: Int
|
||||||
val separator: Int
|
val formatterSymbols: FormatterSymbols
|
||||||
val outputFormat: Int
|
val outputFormat: Int
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
package com.sadellie.unitto.data.userprefs
|
package com.sadellie.unitto.data.userprefs
|
||||||
|
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.Separator
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||||
import com.sadellie.unitto.data.converter.UnitID
|
import com.sadellie.unitto.data.converter.UnitID
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
@ -76,8 +77,21 @@ internal fun Preferences.getRadianMode(): Boolean {
|
|||||||
return this[PrefsKeys.RADIAN_MODE] ?: true
|
return this[PrefsKeys.RADIAN_MODE] ?: true
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Preferences.getSeparator(): Int {
|
internal fun Preferences.getFormatterSymbols(): FormatterSymbols {
|
||||||
return this[PrefsKeys.SEPARATOR] ?: Separator.SPACE
|
val grouping = this[PrefsKeys.FORMATTER_GROUPING]
|
||||||
|
val fractional = this[PrefsKeys.FORMATTER_FRACTIONAL]
|
||||||
|
|
||||||
|
// Updating from older version or fresh install
|
||||||
|
// TODO Remove in the future
|
||||||
|
if ((grouping == null) or (fractional == null)) {
|
||||||
|
return when(this[PrefsKeys.SEPARATOR] ?: 0) {
|
||||||
|
0 -> FormatterSymbols(Token.SPACE, Token.PERIOD)
|
||||||
|
1 -> FormatterSymbols(Token.PERIOD, Token.COMMA)
|
||||||
|
else -> FormatterSymbols(Token.COMMA, Token.PERIOD)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FormatterSymbols(grouping ?: Token.SPACE, fractional ?: Token.PERIOD)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Preferences.getMiddleZero(): Boolean {
|
internal fun Preferences.getMiddleZero(): Boolean {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.data.userprefs
|
package com.sadellie.unitto.data.userprefs
|
||||||
|
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||||
import com.sadellie.unitto.data.model.userprefs.AboutPreferences
|
import com.sadellie.unitto.data.model.userprefs.AboutPreferences
|
||||||
@ -53,7 +54,7 @@ data class GeneralPreferencesImpl(
|
|||||||
|
|
||||||
data class CalculatorPreferencesImpl(
|
data class CalculatorPreferencesImpl(
|
||||||
override val radianMode: Boolean,
|
override val radianMode: Boolean,
|
||||||
override val separator: Int,
|
override val formatterSymbols: FormatterSymbols,
|
||||||
override val middleZero: Boolean,
|
override val middleZero: Boolean,
|
||||||
override val acButton: Boolean,
|
override val acButton: Boolean,
|
||||||
override val partialHistoryView: Boolean,
|
override val partialHistoryView: Boolean,
|
||||||
@ -62,7 +63,7 @@ data class CalculatorPreferencesImpl(
|
|||||||
) : CalculatorPreferences
|
) : CalculatorPreferences
|
||||||
|
|
||||||
data class ConverterPreferencesImpl(
|
data class ConverterPreferencesImpl(
|
||||||
override val separator: Int,
|
override val formatterSymbols: FormatterSymbols,
|
||||||
override val middleZero: Boolean,
|
override val middleZero: Boolean,
|
||||||
override val acButton: Boolean,
|
override val acButton: Boolean,
|
||||||
override val precision: Int,
|
override val precision: Int,
|
||||||
@ -84,7 +85,7 @@ data class DisplayPreferencesImpl(
|
|||||||
|
|
||||||
data class FormattingPreferencesImpl(
|
data class FormattingPreferencesImpl(
|
||||||
override val digitsPrecision: Int,
|
override val digitsPrecision: Int,
|
||||||
override val separator: Int,
|
override val formatterSymbols: FormatterSymbols,
|
||||||
override val outputFormat: Int,
|
override val outputFormat: Int,
|
||||||
) : FormattingPreferences
|
) : FormattingPreferences
|
||||||
|
|
||||||
@ -93,11 +94,11 @@ data class UnitGroupsPreferencesImpl(
|
|||||||
) : UnitGroupsPreferences
|
) : UnitGroupsPreferences
|
||||||
|
|
||||||
data class AddSubtractPreferencesImpl(
|
data class AddSubtractPreferencesImpl(
|
||||||
override val separator: Int,
|
override val formatterSymbols: FormatterSymbols,
|
||||||
) : AddSubtractPreferences
|
) : AddSubtractPreferences
|
||||||
|
|
||||||
data class BodyMassPreferencesImpl(
|
data class BodyMassPreferencesImpl(
|
||||||
override val separator: Int,
|
override val formatterSymbols: FormatterSymbols,
|
||||||
) : BodyMassPreferences
|
) : BodyMassPreferences
|
||||||
|
|
||||||
data class AboutPreferencesImpl(
|
data class AboutPreferencesImpl(
|
||||||
|
@ -42,6 +42,8 @@ object PrefsKeys {
|
|||||||
// FORMATTER
|
// FORMATTER
|
||||||
val DIGITS_PRECISION = intPreferencesKey("DIGITS_PRECISION_PREF_KEY")
|
val DIGITS_PRECISION = intPreferencesKey("DIGITS_PRECISION_PREF_KEY")
|
||||||
val SEPARATOR = intPreferencesKey("SEPARATOR_PREF_KEY")
|
val SEPARATOR = intPreferencesKey("SEPARATOR_PREF_KEY")
|
||||||
|
val FORMATTER_GROUPING = stringPreferencesKey("FORMATTER_GROUPING_PREF_KEY")
|
||||||
|
val FORMATTER_FRACTIONAL = stringPreferencesKey("FORMATTER_FRACTIONAL_PREF_KEY")
|
||||||
val OUTPUT_FORMAT = intPreferencesKey("OUTPUT_FORMAT_PREF_KEY")
|
val OUTPUT_FORMAT = intPreferencesKey("OUTPUT_FORMAT_PREF_KEY")
|
||||||
|
|
||||||
// CALCULATOR
|
// CALCULATOR
|
||||||
|
@ -78,7 +78,7 @@ class UserPreferencesRepositoryImpl @Inject constructor(
|
|||||||
.map { preferences ->
|
.map { preferences ->
|
||||||
CalculatorPreferencesImpl(
|
CalculatorPreferencesImpl(
|
||||||
radianMode = preferences.getRadianMode(),
|
radianMode = preferences.getRadianMode(),
|
||||||
separator = preferences.getSeparator(),
|
formatterSymbols = preferences.getFormatterSymbols(),
|
||||||
middleZero = preferences.getMiddleZero(),
|
middleZero = preferences.getMiddleZero(),
|
||||||
partialHistoryView = preferences.getPartialHistoryView(),
|
partialHistoryView = preferences.getPartialHistoryView(),
|
||||||
precision = preferences.getDigitsPrecision(),
|
precision = preferences.getDigitsPrecision(),
|
||||||
@ -90,7 +90,7 @@ class UserPreferencesRepositoryImpl @Inject constructor(
|
|||||||
override val converterPrefs: Flow<ConverterPreferences> = data
|
override val converterPrefs: Flow<ConverterPreferences> = data
|
||||||
.map { preferences ->
|
.map { preferences ->
|
||||||
ConverterPreferencesImpl(
|
ConverterPreferencesImpl(
|
||||||
separator = preferences.getSeparator(),
|
formatterSymbols = preferences.getFormatterSymbols(),
|
||||||
middleZero = preferences.getMiddleZero(),
|
middleZero = preferences.getMiddleZero(),
|
||||||
precision = preferences.getDigitsPrecision(),
|
precision = preferences.getDigitsPrecision(),
|
||||||
outputFormat = preferences.getOutputFormat(),
|
outputFormat = preferences.getOutputFormat(),
|
||||||
@ -118,7 +118,7 @@ class UserPreferencesRepositoryImpl @Inject constructor(
|
|||||||
.map { preferences ->
|
.map { preferences ->
|
||||||
FormattingPreferencesImpl(
|
FormattingPreferencesImpl(
|
||||||
digitsPrecision = preferences.getDigitsPrecision(),
|
digitsPrecision = preferences.getDigitsPrecision(),
|
||||||
separator = preferences.getSeparator(),
|
formatterSymbols = preferences.getFormatterSymbols(),
|
||||||
outputFormat = preferences.getOutputFormat(),
|
outputFormat = preferences.getOutputFormat(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -133,14 +133,14 @@ class UserPreferencesRepositoryImpl @Inject constructor(
|
|||||||
override val addSubtractPrefs: Flow<AddSubtractPreferences> = data
|
override val addSubtractPrefs: Flow<AddSubtractPreferences> = data
|
||||||
.map { preferences ->
|
.map { preferences ->
|
||||||
AddSubtractPreferencesImpl(
|
AddSubtractPreferencesImpl(
|
||||||
separator = preferences.getSeparator(),
|
formatterSymbols = preferences.getFormatterSymbols(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val bodyMassPrefs: Flow<BodyMassPreferences> = data
|
override val bodyMassPrefs: Flow<BodyMassPreferences> = data
|
||||||
.map { preferences ->
|
.map { preferences ->
|
||||||
BodyMassPreferencesImpl(
|
BodyMassPreferencesImpl(
|
||||||
separator = preferences.getSeparator(),
|
formatterSymbols = preferences.getFormatterSymbols(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +164,13 @@ class UserPreferencesRepositoryImpl @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateSeparator(separator: Int) {
|
override suspend fun updateFormatterSymbols(grouping: String, fractional: String) {
|
||||||
|
// Grouping and fractional symbols are always different
|
||||||
|
if (grouping == fractional) return
|
||||||
|
|
||||||
dataStore.edit { preferences ->
|
dataStore.edit { preferences ->
|
||||||
preferences[PrefsKeys.SEPARATOR] = separator
|
preferences[PrefsKeys.FORMATTER_GROUPING] = grouping
|
||||||
|
preferences[PrefsKeys.FORMATTER_FRACTIONAL] = fractional
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,14 +49,15 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.DrawerButton
|
import com.sadellie.unitto.core.ui.common.DrawerButton
|
||||||
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
||||||
import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar
|
import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar
|
||||||
import com.sadellie.unitto.core.ui.common.SegmentedButton
|
import com.sadellie.unitto.core.ui.common.SegmentedButton
|
||||||
import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow
|
import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
|
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.openLink
|
import com.sadellie.unitto.core.ui.openLink
|
||||||
import com.sadellie.unitto.data.common.isEqualTo
|
import com.sadellie.unitto.data.common.isEqualTo
|
||||||
import com.sadellie.unitto.feature.bodymass.components.BodyMassResult
|
import com.sadellie.unitto.feature.bodymass.components.BodyMassResult
|
||||||
@ -223,7 +224,7 @@ fun PreviewBodyMassScreen() {
|
|||||||
weight = TextFieldValue(),
|
weight = TextFieldValue(),
|
||||||
normalWeightRange = BigDecimal(30) to BigDecimal(50),
|
normalWeightRange = BigDecimal(30) to BigDecimal(50),
|
||||||
result = BigDecimal(18.5),
|
result = BigDecimal(18.5),
|
||||||
formatterSymbols = FormatterSymbols.Spaces
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD)
|
||||||
),
|
),
|
||||||
updateHeight1 = {},
|
updateHeight1 = {},
|
||||||
updateHeight2 = {},
|
updateHeight2 = {},
|
||||||
|
@ -24,7 +24,6 @@ import android.os.Build
|
|||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.common.combine
|
import com.sadellie.unitto.data.common.combine
|
||||||
import com.sadellie.unitto.data.common.stateIn
|
import com.sadellie.unitto.data.common.stateIn
|
||||||
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
||||||
@ -64,7 +63,7 @@ internal class BodyMassViewModel @Inject constructor(
|
|||||||
weight = weight,
|
weight = weight,
|
||||||
result = result,
|
result = result,
|
||||||
normalWeightRange = normalWeightRange,
|
normalWeightRange = normalWeightRange,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator)
|
formatterSymbols = userPrefs.formatterSymbols
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.mapLatest { ui ->
|
.mapLatest { ui ->
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package com.sadellie.unitto.feature.bodymass
|
package com.sadellie.unitto.feature.bodymass
|
||||||
|
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
internal sealed class UIState {
|
internal sealed class UIState {
|
||||||
|
@ -37,9 +37,10 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
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.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import com.sadellie.unitto.data.common.format
|
import com.sadellie.unitto.data.common.format
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
@ -171,6 +172,6 @@ fun PreviewBodyMassResult() {
|
|||||||
value = BigDecimal(18.5),
|
value = BigDecimal(18.5),
|
||||||
range = BigDecimal(50) to BigDecimal(80),
|
range = BigDecimal(50) to BigDecimal(80),
|
||||||
rangeSuffix = "kg",
|
rangeSuffix = "kg",
|
||||||
formatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,10 @@ import androidx.compose.ui.test.performClick
|
|||||||
import androidx.compose.ui.test.performTouchInput
|
import androidx.compose.ui.test.performTouchInput
|
||||||
import androidx.compose.ui.test.swipeDown
|
import androidx.compose.ui.test.swipeDown
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.Token
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ class CalculatorScreenTest {
|
|||||||
radianMode = false,
|
radianMode = false,
|
||||||
precision = 3,
|
precision = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
formatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
history = emptyList(),
|
history = emptyList(),
|
||||||
middleZero = false,
|
middleZero = false,
|
||||||
acButton = true,
|
acButton = true,
|
||||||
@ -100,7 +101,7 @@ class CalculatorScreenTest {
|
|||||||
radianMode = false,
|
radianMode = false,
|
||||||
precision = 3,
|
precision = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
formatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
history = emptyList(),
|
history = emptyList(),
|
||||||
middleZero = false,
|
middleZero = false,
|
||||||
acButton = true,
|
acButton = true,
|
||||||
|
@ -62,14 +62,15 @@ import androidx.compose.ui.unit.IntOffset
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.LocalWindowSize
|
import com.sadellie.unitto.core.ui.LocalWindowSize
|
||||||
import com.sadellie.unitto.core.ui.WindowHeightSizeClass
|
import com.sadellie.unitto.core.ui.WindowHeightSizeClass
|
||||||
import com.sadellie.unitto.core.ui.common.DrawerButton
|
import com.sadellie.unitto.core.ui.common.DrawerButton
|
||||||
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
||||||
import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar
|
import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
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.HistoryItemHeight
|
import com.sadellie.unitto.feature.calculator.components.HistoryItemHeight
|
||||||
@ -355,7 +356,7 @@ private fun PreviewCalculatorScreen() {
|
|||||||
radianMode = false,
|
radianMode = false,
|
||||||
precision = 3,
|
precision = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
formatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
history = historyItems,
|
history = historyItems,
|
||||||
middleZero = false,
|
middleZero = false,
|
||||||
acButton = true,
|
acButton = true,
|
||||||
|
@ -20,8 +20,8 @@ package com.sadellie.unitto.feature.calculator
|
|||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.model.HistoryItem
|
import com.sadellie.unitto.data.model.HistoryItem
|
||||||
|
|
||||||
internal sealed class CalculatorUIState {
|
internal sealed class CalculatorUIState {
|
||||||
|
@ -24,7 +24,6 @@ import androidx.lifecycle.SavedStateHandle
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.addBracket
|
import com.sadellie.unitto.core.ui.common.textfield.addBracket
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.addTokens
|
import com.sadellie.unitto.core.ui.common.textfield.addTokens
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.deleteTokens
|
import com.sadellie.unitto.core.ui.common.textfield.deleteTokens
|
||||||
@ -79,7 +78,7 @@ internal class CalculatorViewModel @Inject constructor(
|
|||||||
radianMode = prefs.radianMode,
|
radianMode = prefs.radianMode,
|
||||||
precision = prefs.precision,
|
precision = prefs.precision,
|
||||||
outputFormat = prefs.outputFormat,
|
outputFormat = prefs.outputFormat,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(prefs.separator),
|
formatterSymbols = prefs.formatterSymbols,
|
||||||
history = history,
|
history = history,
|
||||||
middleZero = prefs.middleZero,
|
middleZero = prefs.middleZero,
|
||||||
acButton = prefs.acButton,
|
acButton = prefs.acButton,
|
||||||
|
@ -110,7 +110,6 @@ import com.sadellie.unitto.core.ui.common.icons.iconpack.RightBracket
|
|||||||
import com.sadellie.unitto.core.ui.common.icons.iconpack.Root
|
import com.sadellie.unitto.core.ui.common.icons.iconpack.Root
|
||||||
import com.sadellie.unitto.core.ui.common.icons.iconpack.Sin
|
import com.sadellie.unitto.core.ui.common.icons.iconpack.Sin
|
||||||
import com.sadellie.unitto.core.ui.common.icons.iconpack.Tan
|
import com.sadellie.unitto.core.ui.common.icons.iconpack.Tan
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun CalculatorKeyboard(
|
internal fun CalculatorKeyboard(
|
||||||
@ -182,8 +181,8 @@ private fun PortraitKeyboard(
|
|||||||
val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg }
|
val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg }
|
||||||
val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree }
|
val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree }
|
||||||
|
|
||||||
val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) IconPack.Dot else IconPack.Comma }
|
val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma }
|
||||||
val fractionalIconDescription = remember(fractional) { if (fractional == Token.Digit.dot) R.string.keyboard_dot else R.string.comma }
|
val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma }
|
||||||
|
|
||||||
var showAdditional: Boolean by remember { mutableStateOf(false) }
|
var showAdditional: Boolean by remember { mutableStateOf(false) }
|
||||||
val expandRotation: Float by animateFloatAsState(
|
val expandRotation: Float by animateFloatAsState(
|
||||||
@ -414,8 +413,8 @@ private fun LandscapeKeyboard(
|
|||||||
val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg }
|
val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg }
|
||||||
val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree }
|
val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree }
|
||||||
|
|
||||||
val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) IconPack.Dot else IconPack.Comma }
|
val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma }
|
||||||
val fractionalIconDescription = remember(fractional) { if (fractional == Token.Digit.dot) R.string.keyboard_dot else R.string.comma }
|
val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma }
|
||||||
|
|
||||||
Crossfade(
|
Crossfade(
|
||||||
targetState = invMode,
|
targetState = invMode,
|
||||||
@ -544,7 +543,7 @@ private fun PreviewPortraitKeyboard() {
|
|||||||
PortraitKeyboard(
|
PortraitKeyboard(
|
||||||
modifier = Modifier.fillMaxHeight(),
|
modifier = Modifier.fillMaxHeight(),
|
||||||
radianMode = true,
|
radianMode = true,
|
||||||
fractional = FormatterSymbols.Comma.fractional,
|
fractional = Token.PERIOD,
|
||||||
addSymbol = {},
|
addSymbol = {},
|
||||||
clearSymbols = {},
|
clearSymbols = {},
|
||||||
deleteSymbol = {},
|
deleteSymbol = {},
|
||||||
@ -564,7 +563,7 @@ private fun PreviewLandscapeKeyboard() {
|
|||||||
LandscapeKeyboard(
|
LandscapeKeyboard(
|
||||||
modifier = Modifier.fillMaxHeight(),
|
modifier = Modifier.fillMaxHeight(),
|
||||||
radianMode = true,
|
radianMode = true,
|
||||||
fractional = FormatterSymbols.Comma.fractional,
|
fractional = Token.PERIOD,
|
||||||
addSymbol = {},
|
addSymbol = {},
|
||||||
clearSymbols = {},
|
clearSymbols = {},
|
||||||
deleteSymbol = {},
|
deleteSymbol = {},
|
||||||
|
@ -47,9 +47,10 @@ import androidx.compose.ui.platform.LocalFocusManager
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
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.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FixedExpressionInputTextField
|
import com.sadellie.unitto.core.ui.common.textfield.FixedExpressionInputTextField
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.model.HistoryItem
|
import com.sadellie.unitto.data.model.HistoryItem
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -225,7 +226,7 @@ private fun PreviewHistoryList() {
|
|||||||
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
|
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
historyItems = historyItems,
|
historyItems = historyItems,
|
||||||
formatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
addTokens = {},
|
addTokens = {},
|
||||||
onDelete = {},
|
onDelete = {},
|
||||||
showDeleteButtons = true,
|
showDeleteButtons = true,
|
||||||
|
@ -39,10 +39,10 @@ import androidx.compose.ui.semantics.semantics
|
|||||||
import androidx.compose.ui.semantics.testTag
|
import androidx.compose.ui.semantics.testTag
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.ui.LocalWindowSize
|
import com.sadellie.unitto.core.ui.LocalWindowSize
|
||||||
import com.sadellie.unitto.core.ui.WindowHeightSizeClass
|
import com.sadellie.unitto.core.ui.WindowHeightSizeClass
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
|
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.SimpleTextField
|
import com.sadellie.unitto.core.ui.common.textfield.SimpleTextField
|
||||||
import com.sadellie.unitto.feature.calculator.CalculationResult
|
import com.sadellie.unitto.feature.calculator.CalculationResult
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
@ -80,7 +81,6 @@ import com.sadellie.unitto.core.ui.common.EmptyScreen
|
|||||||
import com.sadellie.unitto.core.ui.common.PortraitLandscape
|
import com.sadellie.unitto.core.ui.common.PortraitLandscape
|
||||||
import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar
|
import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
|
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.NumberBaseTextField
|
import com.sadellie.unitto.core.ui.common.textfield.NumberBaseTextField
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.SimpleTextField
|
import com.sadellie.unitto.core.ui.common.textfield.SimpleTextField
|
||||||
import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear
|
import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear
|
||||||
@ -425,7 +425,7 @@ private fun ConverterResultTextField(
|
|||||||
result: ConverterResult,
|
result: ConverterResult,
|
||||||
scale: Int = 0,
|
scale: Int = 0,
|
||||||
outputFormat: Int = OutputFormat.PLAIN,
|
outputFormat: Int = OutputFormat.PLAIN,
|
||||||
formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols: FormatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
onErrorClick: () -> Unit = {},
|
onErrorClick: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val mContext = LocalContext.current
|
val mContext = LocalContext.current
|
||||||
|
@ -20,9 +20,9 @@ package com.sadellie.unitto.feature.converter
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import com.sadellie.unitto.data.common.format
|
import com.sadellie.unitto.data.common.format
|
||||||
import com.sadellie.unitto.data.common.isEqualTo
|
import com.sadellie.unitto.data.common.isEqualTo
|
||||||
|
@ -23,7 +23,6 @@ import androidx.lifecycle.SavedStateHandle
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.addBracket
|
import com.sadellie.unitto.core.ui.common.textfield.addBracket
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.addTokens
|
import com.sadellie.unitto.core.ui.common.textfield.addTokens
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.deleteTokens
|
import com.sadellie.unitto.core.ui.common.textfield.deleteTokens
|
||||||
@ -94,7 +93,7 @@ internal class ConverterViewModel @Inject constructor(
|
|||||||
unitFrom = unitFrom as DefaultUnit,
|
unitFrom = unitFrom as DefaultUnit,
|
||||||
unitTo = unitTo as DefaultUnit,
|
unitTo = unitTo as DefaultUnit,
|
||||||
middleZero = prefs.middleZero,
|
middleZero = prefs.middleZero,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(prefs.separator),
|
formatterSymbols = prefs.formatterSymbols,
|
||||||
scale = prefs.precision,
|
scale = prefs.precision,
|
||||||
outputFormat = prefs.outputFormat,
|
outputFormat = prefs.outputFormat,
|
||||||
formatTime = prefs.unitConverterFormatTime,
|
formatTime = prefs.unitConverterFormatTime,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package com.sadellie.unitto.feature.converter
|
package com.sadellie.unitto.feature.converter
|
||||||
|
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||||
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
||||||
|
@ -22,7 +22,6 @@ import androidx.compose.ui.text.input.TextFieldValue
|
|||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.common.stateIn
|
import com.sadellie.unitto.data.common.stateIn
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
import com.sadellie.unitto.data.model.repository.UnitsRepository
|
import com.sadellie.unitto.data.model.repository.UnitsRepository
|
||||||
@ -112,7 +111,7 @@ internal class UnitSelectorViewModel @Inject constructor(
|
|||||||
sorting = prefs.unitConverterSorting,
|
sorting = prefs.unitConverterSorting,
|
||||||
scale = prefs.precision,
|
scale = prefs.precision,
|
||||||
outputFormat = prefs.outputFormat,
|
outputFormat = prefs.outputFormat,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(prefs.separator),
|
formatterSymbols = prefs.formatterSymbols,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.mapLatest { ui ->
|
.mapLatest { ui ->
|
||||||
|
@ -28,11 +28,12 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
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.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
||||||
import com.sadellie.unitto.core.ui.common.SearchBar
|
import com.sadellie.unitto.core.ui.common.SearchBar
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import com.sadellie.unitto.data.common.format
|
import com.sadellie.unitto.data.common.format
|
||||||
import com.sadellie.unitto.data.converter.UnitID
|
import com.sadellie.unitto.data.converter.UnitID
|
||||||
@ -189,7 +190,7 @@ private fun UnitToSelectorPreview() {
|
|||||||
input = "100",
|
input = "100",
|
||||||
scale = 3,
|
scale = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
formatterSymbols = FormatterSymbols.Spaces,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
),
|
),
|
||||||
onQueryChange = {},
|
onQueryChange = {},
|
||||||
toggleFavoritesOnly = {},
|
toggleFavoritesOnly = {},
|
||||||
|
@ -66,7 +66,6 @@ import com.sadellie.unitto.core.ui.common.icons.iconpack.Plus
|
|||||||
import com.sadellie.unitto.core.ui.common.icons.iconpack.Power
|
import com.sadellie.unitto.core.ui.common.icons.iconpack.Power
|
||||||
import com.sadellie.unitto.core.ui.common.icons.iconpack.RightBracket
|
import com.sadellie.unitto.core.ui.common.icons.iconpack.RightBracket
|
||||||
import com.sadellie.unitto.core.ui.common.icons.iconpack.Root
|
import com.sadellie.unitto.core.ui.common.icons.iconpack.Root
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun DefaultKeyboard(
|
internal fun DefaultKeyboard(
|
||||||
@ -79,8 +78,8 @@ internal fun DefaultKeyboard(
|
|||||||
acButton: Boolean,
|
acButton: Boolean,
|
||||||
addBracket: () -> Unit,
|
addBracket: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) IconPack.Dot else IconPack.Comma }
|
val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma }
|
||||||
val fractionalIconDescription = remember(fractional) { if (fractional == Token.Digit.dot) R.string.keyboard_dot else R.string.comma }
|
val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma }
|
||||||
val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonContentHeightShort else KeyboardButtonContentHeightTall
|
val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonContentHeightShort else KeyboardButtonContentHeightTall
|
||||||
|
|
||||||
KeypadFlow(
|
KeypadFlow(
|
||||||
@ -178,7 +177,7 @@ private fun PreviewConverterKeyboard() {
|
|||||||
addDigit = {},
|
addDigit = {},
|
||||||
clearInput = {},
|
clearInput = {},
|
||||||
deleteDigit = {},
|
deleteDigit = {},
|
||||||
fractional = FormatterSymbols.Spaces.fractional,
|
fractional = Token.PERIOD,
|
||||||
middleZero = false,
|
middleZero = false,
|
||||||
acButton = true,
|
acButton = true,
|
||||||
addBracket = {}
|
addBracket = {}
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
package com.sadellie.unitto.feature.converter
|
package com.sadellie.unitto.feature.converter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@ -32,7 +33,7 @@ class ConverterUIStateKtTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun format() {
|
fun format() {
|
||||||
val formatterSymbols = FormatterSymbols.Spaces
|
val formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD)
|
||||||
var basicValue = BigDecimal("1")
|
var basicValue = BigDecimal("1")
|
||||||
val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
|
val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
package com.sadellie.unitto.feature.datecalculator.addsubtract
|
package com.sadellie.unitto.feature.datecalculator.addsubtract
|
||||||
|
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils
|
import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
@ -32,6 +33,6 @@ internal data class AddSubtractState(
|
|||||||
val hours: TextFieldValue = TextFieldValue(),
|
val hours: TextFieldValue = TextFieldValue(),
|
||||||
val minutes: TextFieldValue = TextFieldValue(),
|
val minutes: TextFieldValue = TextFieldValue(),
|
||||||
val addition: Boolean = true,
|
val addition: Boolean = true,
|
||||||
val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
|
val formatterSymbols: FormatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
val allowVibration: Boolean = false,
|
val allowVibration: Boolean = false,
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,6 @@ import androidx.compose.ui.text.TextRange
|
|||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -46,7 +45,7 @@ internal class AddSubtractViewModel @Inject constructor(
|
|||||||
val uiState: StateFlow<AddSubtractState> = _uiState
|
val uiState: StateFlow<AddSubtractState> = _uiState
|
||||||
.combine(userPreferencesRepository.addSubtractPrefs) { uiState, userPrefs ->
|
.combine(userPreferencesRepository.addSubtractPrefs) { uiState, userPrefs ->
|
||||||
return@combine uiState.copy(
|
return@combine uiState.copy(
|
||||||
formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator),
|
formatterSymbols = userPrefs.formatterSymbols,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.onEach { updateResult() }
|
.onEach { updateResult() }
|
||||||
|
@ -40,9 +40,10 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import com.sadellie.unitto.data.common.format
|
import com.sadellie.unitto.data.common.format
|
||||||
import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils
|
import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils
|
||||||
@ -185,7 +186,7 @@ fun DateDifferenceViewPreview() {
|
|||||||
),
|
),
|
||||||
precision = 3,
|
precision = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
formatterSymbols = FormatterSymbols.Spaces
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD)
|
||||||
),
|
),
|
||||||
setStartDate = {},
|
setStartDate = {},
|
||||||
setEndDate = {},
|
setEndDate = {},
|
||||||
|
@ -20,7 +20,6 @@ package com.sadellie.unitto.feature.datecalculator.difference
|
|||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.common.stateIn
|
import com.sadellie.unitto.data.common.stateIn
|
||||||
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
||||||
import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils
|
import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils
|
||||||
@ -55,7 +54,7 @@ internal class DateDifferenceViewModel @Inject constructor(
|
|||||||
result = result,
|
result = result,
|
||||||
precision = prefs.digitsPrecision,
|
precision = prefs.digitsPrecision,
|
||||||
outputFormat = prefs.outputFormat,
|
outputFormat = prefs.outputFormat,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(prefs.separator)
|
formatterSymbols = prefs.formatterSymbols
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.mapLatest { ui ->
|
.mapLatest { ui ->
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.feature.datecalculator.difference
|
package com.sadellie.unitto.feature.datecalculator.difference
|
||||||
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
internal sealed class DifferenceUIState {
|
internal sealed class DifferenceUIState {
|
||||||
|
@ -54,9 +54,8 @@ import androidx.glance.text.Text
|
|||||||
import androidx.glance.text.TextAlign
|
import androidx.glance.text.TextAlign
|
||||||
import androidx.glance.text.TextStyle
|
import androidx.glance.text.TextStyle
|
||||||
import androidx.glance.unit.ColorProvider
|
import androidx.glance.unit.ColorProvider
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.Token
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
||||||
import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences
|
import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences
|
||||||
@ -139,7 +138,7 @@ private fun ReadyUI(
|
|||||||
val input = glancePrefs[CalculatorWidget.inputPrefKey] ?: ""
|
val input = glancePrefs[CalculatorWidget.inputPrefKey] ?: ""
|
||||||
val output = glancePrefs[CalculatorWidget.outputPrefKey] ?: ""
|
val output = glancePrefs[CalculatorWidget.outputPrefKey] ?: ""
|
||||||
val equalClicked = glancePrefs[CalculatorWidget.equalClickedPrefKey] ?: false
|
val equalClicked = glancePrefs[CalculatorWidget.equalClickedPrefKey] ?: false
|
||||||
val formatterSymbols = AllFormatterSymbols.getById(appPrefs.separator)
|
val formatterSymbols = appPrefs.formatterSymbols
|
||||||
|
|
||||||
fun runCalculateAction(
|
fun runCalculateAction(
|
||||||
input: String,
|
input: String,
|
||||||
|
@ -28,9 +28,10 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.base.Separator
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
||||||
import com.sadellie.unitto.core.ui.common.ListItem
|
import com.sadellie.unitto.core.ui.common.ListItem
|
||||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||||
@ -83,7 +84,7 @@ private fun PreviewCalculatorSettingsScreenStandard() {
|
|||||||
CalculatorSettingsScreen(
|
CalculatorSettingsScreen(
|
||||||
prefs = CalculatorPreferencesImpl(
|
prefs = CalculatorPreferencesImpl(
|
||||||
radianMode = true,
|
radianMode = true,
|
||||||
separator = Separator.SPACE,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
middleZero = false,
|
middleZero = false,
|
||||||
acButton = false,
|
acButton = false,
|
||||||
partialHistoryView = false,
|
partialHistoryView = false,
|
||||||
|
@ -34,9 +34,10 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.base.Separator
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
||||||
import com.sadellie.unitto.core.ui.common.ListItem
|
import com.sadellie.unitto.core.ui.common.ListItem
|
||||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||||
@ -133,7 +134,7 @@ private fun ConverterSettingsScreen(
|
|||||||
private fun PreviewConverterSettingsScreen() {
|
private fun PreviewConverterSettingsScreen() {
|
||||||
ConverterSettingsScreen(
|
ConverterSettingsScreen(
|
||||||
prefs = ConverterPreferencesImpl(
|
prefs = ConverterPreferencesImpl(
|
||||||
separator = Separator.SPACE,
|
formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD),
|
||||||
middleZero = false,
|
middleZero = false,
|
||||||
precision = 3,
|
precision = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
|
@ -18,13 +18,18 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.feature.settings.formatting
|
package com.sadellie.unitto.feature.settings.formatting
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.expandVertically
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.shrinkVertically
|
||||||
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.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@ -38,6 +43,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -48,10 +54,11 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
import com.sadellie.unitto.core.base.MAX_PRECISION
|
import com.sadellie.unitto.core.base.MAX_PRECISION
|
||||||
import com.sadellie.unitto.core.base.OutputFormat
|
import com.sadellie.unitto.core.base.OutputFormat
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.base.Separator
|
import com.sadellie.unitto.core.base.Token
|
||||||
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
import com.sadellie.unitto.core.ui.common.EmptyScreen
|
||||||
import com.sadellie.unitto.core.ui.common.ListItem
|
import com.sadellie.unitto.core.ui.common.ListItem
|
||||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||||
@ -60,7 +67,6 @@ import com.sadellie.unitto.core.ui.common.ScaffoldWithLargeTopBar
|
|||||||
import com.sadellie.unitto.core.ui.common.SegmentedButton
|
import com.sadellie.unitto.core.ui.common.SegmentedButton
|
||||||
import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow
|
import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow
|
||||||
import com.sadellie.unitto.core.ui.common.Slider
|
import com.sadellie.unitto.core.ui.common.Slider
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||||
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
|
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
|
||||||
import com.sadellie.unitto.data.common.format
|
import com.sadellie.unitto.data.common.format
|
||||||
@ -79,7 +85,7 @@ fun FormattingRoute(
|
|||||||
navigateUpAction = navigateUpAction,
|
navigateUpAction = navigateUpAction,
|
||||||
uiState = uiState,
|
uiState = uiState,
|
||||||
onPrecisionChange = viewModel::updatePrecision,
|
onPrecisionChange = viewModel::updatePrecision,
|
||||||
onSeparatorChange = viewModel::updateSeparator,
|
updateFormatterSymbols = viewModel::updateFormatterSymbols,
|
||||||
onOutputFormatChange = viewModel::updateOutputFormat,
|
onOutputFormatChange = viewModel::updateOutputFormat,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -91,7 +97,7 @@ fun FormattingScreen(
|
|||||||
navigateUpAction: () -> Unit,
|
navigateUpAction: () -> Unit,
|
||||||
uiState: FormattingUIState,
|
uiState: FormattingUIState,
|
||||||
onPrecisionChange: (Int) -> Unit,
|
onPrecisionChange: (Int) -> Unit,
|
||||||
onSeparatorChange: (Int) -> Unit,
|
updateFormatterSymbols: (grouping: String, fractional: String) -> Unit,
|
||||||
onOutputFormatChange: (Int) -> Unit,
|
onOutputFormatChange: (Int) -> Unit,
|
||||||
precisions: ClosedFloatingPointRange<Float> = 0f..16f, // 16th is a MAX_PRECISION (1000)
|
precisions: ClosedFloatingPointRange<Float> = 0f..16f, // 16th is a MAX_PRECISION (1000)
|
||||||
) {
|
) {
|
||||||
@ -114,143 +120,162 @@ fun FormattingScreen(
|
|||||||
title = stringResource(R.string.settings_formatting),
|
title = stringResource(R.string.settings_formatting),
|
||||||
navigationIcon = { NavigateUpButton(navigateUpAction) },
|
navigationIcon = { NavigateUpButton(navigateUpAction) },
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
LazyColumn(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
) {
|
) {
|
||||||
item("preview") {
|
PagedIsland(
|
||||||
PagedIsland(
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
pagerState = rememberPagerState { 2 },
|
||||||
|
) { currentPage ->
|
||||||
|
val preview = when (currentPage) {
|
||||||
|
0 -> "123456.${"789123456".repeat(ceil(uiState.precision.toDouble() / 9.0).toInt())}"
|
||||||
|
1 -> "0.${"1".padStart(uiState.precision, '0')}"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
.toBigDecimalOrNull()
|
||||||
|
?.format(uiState.precision, uiState.outputFormat)
|
||||||
|
?.formatExpression(uiState.formatterSymbols)
|
||||||
|
?: ""
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = preview,
|
||||||
|
style = LocalNumberTypography.current.displayMedium,
|
||||||
|
maxLines = 1,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(16.dp),
|
.horizontalScroll(rememberScrollState()),
|
||||||
pagerState = rememberPagerState { 2 },
|
textAlign = TextAlign.End,
|
||||||
) { currentPage ->
|
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||||
val preview = when (currentPage) {
|
)
|
||||||
0 -> "123456.${"789123456".repeat(ceil(uiState.precision.toDouble() / 9.0).toInt())}"
|
}
|
||||||
1 -> "0.${"1".padStart(uiState.precision, '0')}"
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
.toBigDecimalOrNull()
|
|
||||||
?.format(uiState.precision, uiState.outputFormat)
|
|
||||||
?.formatExpression(uiState.formatterSymbols)
|
|
||||||
?: ""
|
|
||||||
|
|
||||||
Text(
|
ListItem(
|
||||||
text = preview,
|
leadingContent = {
|
||||||
style = LocalNumberTypography.current.displayMedium,
|
Icon(
|
||||||
maxLines = 1,
|
Icons.Default.Architecture,
|
||||||
modifier = Modifier
|
stringResource(R.string.settings_precision)
|
||||||
.fillMaxWidth()
|
)
|
||||||
.horizontalScroll(rememberScrollState()),
|
},
|
||||||
textAlign = TextAlign.End,
|
headlineContent = {
|
||||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.settings_precision))
|
||||||
|
Text(precisionText)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
supportingContent = {
|
||||||
|
Text(stringResource(R.string.settings_precision_support))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Slider(
|
||||||
|
modifier = Modifier.padding(start = 56.dp, end = 16.dp),
|
||||||
|
value = uiState.precision.toFloat(),
|
||||||
|
valueRange = precisions,
|
||||||
|
onValueChange = { onPrecisionChange(it.roundToInt()) },
|
||||||
|
)
|
||||||
|
|
||||||
|
ListItem(
|
||||||
|
leadingContent = {
|
||||||
|
Icon(Icons.Default._123, stringResource(R.string.settings_thousands_separator))
|
||||||
|
},
|
||||||
|
headlineContent = { Text(stringResource(R.string.settings_thousands_separator)) },
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
Modifier
|
||||||
|
.horizontalScroll(rememberScrollState())
|
||||||
|
.wrapContentWidth()
|
||||||
|
.padding(start = 56.dp)
|
||||||
|
) {
|
||||||
|
SegmentedButtonsRow {
|
||||||
|
SegmentedButton(
|
||||||
|
label = stringResource(R.string.settings_space),
|
||||||
|
onClick = { updateFormatterSymbols(Token.SPACE, uiState.formatterSymbols.fractional) },
|
||||||
|
selected = uiState.formatterSymbols.grouping == Token.SPACE
|
||||||
|
)
|
||||||
|
SegmentedButton(
|
||||||
|
label = stringResource(R.string.settings_period),
|
||||||
|
onClick = { updateFormatterSymbols(Token.PERIOD, Token.COMMA) },
|
||||||
|
selected = uiState.formatterSymbols.grouping == Token.PERIOD,
|
||||||
|
)
|
||||||
|
SegmentedButton(
|
||||||
|
label = stringResource(R.string.comma),
|
||||||
|
onClick = { updateFormatterSymbols(Token.COMMA, Token.PERIOD) },
|
||||||
|
selected = uiState.formatterSymbols.grouping == Token.COMMA,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item("precision_label") {
|
AnimatedVisibility(
|
||||||
ListItem(
|
visible = uiState.formatterSymbols.grouping == Token.SPACE,
|
||||||
leadingContent = {
|
enter = expandVertically() + fadeIn(),
|
||||||
Icon(
|
exit = shrinkVertically() + fadeOut()
|
||||||
Icons.Default.Architecture,
|
) {
|
||||||
stringResource(R.string.settings_precision)
|
Column(
|
||||||
)
|
modifier = Modifier.padding(start = 40.dp)
|
||||||
},
|
|
||||||
headlineContent = {
|
|
||||||
Row(
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.settings_precision))
|
|
||||||
Text(precisionText)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
supportingContent = {
|
|
||||||
Text(stringResource(R.string.settings_precision_support))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item("precision_slider") {
|
|
||||||
Slider(
|
|
||||||
modifier = Modifier.padding(start = 56.dp, end = 16.dp),
|
|
||||||
value = uiState.precision.toFloat(),
|
|
||||||
valueRange = precisions,
|
|
||||||
onValueChange = { onPrecisionChange(it.roundToInt()) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item("separator_label") {
|
|
||||||
ListItem(
|
|
||||||
leadingContent = {
|
|
||||||
Icon(Icons.Default._123, stringResource(R.string.settings_separator))
|
|
||||||
},
|
|
||||||
headlineContent = { Text(stringResource(R.string.settings_separator)) },
|
|
||||||
supportingContent = { Text(stringResource(R.string.settings_separator_support)) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item("separator") {
|
|
||||||
Row(
|
|
||||||
Modifier
|
|
||||||
.horizontalScroll(rememberScrollState())
|
|
||||||
.wrapContentWidth()
|
|
||||||
.padding(start = 56.dp)
|
|
||||||
) {
|
) {
|
||||||
SegmentedButtonsRow {
|
ListItem(
|
||||||
SegmentedButton(
|
modifier = Modifier,
|
||||||
label = stringResource(R.string.settings_space),
|
headlineContent = { Text(stringResource(R.string.settings_decimal_separator)) },
|
||||||
onClick = { onSeparatorChange(Separator.SPACE) },
|
)
|
||||||
selected = Separator.SPACE == uiState.separator
|
Row(
|
||||||
)
|
Modifier
|
||||||
SegmentedButton(
|
.horizontalScroll(rememberScrollState())
|
||||||
label = stringResource(R.string.settings_period),
|
.wrapContentWidth()
|
||||||
onClick = { onSeparatorChange(Separator.PERIOD) },
|
.padding(start = 16.dp)
|
||||||
selected = Separator.PERIOD == uiState.separator
|
) {
|
||||||
)
|
SegmentedButtonsRow {
|
||||||
SegmentedButton(
|
SegmentedButton(
|
||||||
label = stringResource(R.string.comma),
|
label = stringResource(R.string.settings_period),
|
||||||
onClick = { onSeparatorChange(Separator.COMMA) },
|
onClick = { updateFormatterSymbols(Token.SPACE, Token.PERIOD) },
|
||||||
selected = Separator.COMMA == uiState.separator
|
selected = uiState.formatterSymbols.fractional == Token.PERIOD,
|
||||||
)
|
)
|
||||||
|
SegmentedButton(
|
||||||
|
label = stringResource(R.string.comma),
|
||||||
|
onClick = { updateFormatterSymbols(Token.SPACE, Token.COMMA) },
|
||||||
|
selected = uiState.formatterSymbols.fractional == Token.COMMA,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item("output_format_label") {
|
ListItem(
|
||||||
ListItem(
|
leadingContent = {
|
||||||
leadingContent = {
|
Icon(Icons.Default.EMobiledata, stringResource(R.string.settings_precision))
|
||||||
Icon(Icons.Default.EMobiledata, stringResource(R.string.settings_precision))
|
},
|
||||||
},
|
headlineContent = { Text(stringResource(R.string.settings_exponential_notation)) },
|
||||||
headlineContent = { Text(stringResource(R.string.settings_exponential_notation)) },
|
supportingContent = { Text(stringResource(R.string.settings_exponential_notation_support)) }
|
||||||
supportingContent = { Text(stringResource(R.string.settings_exponential_notation_support)) }
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item("output_format") {
|
Row(
|
||||||
Row(
|
Modifier
|
||||||
Modifier
|
.horizontalScroll(rememberScrollState())
|
||||||
.horizontalScroll(rememberScrollState())
|
.wrapContentWidth()
|
||||||
.wrapContentWidth()
|
.padding(start = 56.dp)
|
||||||
.padding(start = 56.dp)
|
) {
|
||||||
) {
|
SegmentedButtonsRow {
|
||||||
SegmentedButtonsRow {
|
SegmentedButton(
|
||||||
SegmentedButton(
|
label = stringResource(R.string.settings_auto),
|
||||||
label = stringResource(R.string.settings_auto),
|
onClick = { onOutputFormatChange(OutputFormat.ALLOW_ENGINEERING) },
|
||||||
onClick = { onOutputFormatChange(OutputFormat.ALLOW_ENGINEERING) },
|
selected = OutputFormat.ALLOW_ENGINEERING == uiState.outputFormat
|
||||||
selected = OutputFormat.ALLOW_ENGINEERING == uiState.outputFormat
|
)
|
||||||
)
|
SegmentedButton(
|
||||||
SegmentedButton(
|
label = stringResource(R.string.enabled_label),
|
||||||
label = stringResource(R.string.enabled_label),
|
onClick = { onOutputFormatChange(OutputFormat.FORCE_ENGINEERING) },
|
||||||
onClick = { onOutputFormatChange(OutputFormat.FORCE_ENGINEERING) },
|
selected = OutputFormat.FORCE_ENGINEERING == uiState.outputFormat
|
||||||
selected = OutputFormat.FORCE_ENGINEERING == uiState.outputFormat
|
)
|
||||||
)
|
SegmentedButton(
|
||||||
SegmentedButton(
|
label = stringResource(R.string.disabled_label),
|
||||||
label = stringResource(R.string.disabled_label),
|
onClick = { onOutputFormatChange(OutputFormat.PLAIN) },
|
||||||
onClick = { onOutputFormatChange(OutputFormat.PLAIN) },
|
selected = OutputFormat.PLAIN == uiState.outputFormat
|
||||||
selected = OutputFormat.PLAIN == uiState.outputFormat
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,18 +286,19 @@ fun FormattingScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun PreviewFormattingScreen() {
|
private fun PreviewFormattingScreen() {
|
||||||
var currentPrecision by remember { mutableIntStateOf(6) }
|
var currentPrecision by remember { mutableIntStateOf(6) }
|
||||||
var currentSeparator by remember { mutableIntStateOf(Separator.COMMA) }
|
var currentFormatterSymbols by remember { mutableStateOf(FormatterSymbols(Token.SPACE, Token.PERIOD)) }
|
||||||
var currentOutputFormat by remember { mutableIntStateOf(OutputFormat.PLAIN) }
|
var currentOutputFormat by remember { mutableIntStateOf(OutputFormat.PLAIN) }
|
||||||
|
|
||||||
FormattingScreen(
|
FormattingScreen(
|
||||||
uiState = FormattingUIState(
|
uiState = FormattingUIState(
|
||||||
precision = 16,
|
precision = 16,
|
||||||
separator = Separator.SPACE,
|
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
formatterSymbols = FormatterSymbols.Spaces
|
formatterSymbols = currentFormatterSymbols
|
||||||
),
|
),
|
||||||
onPrecisionChange = { currentPrecision = it },
|
onPrecisionChange = { currentPrecision = it },
|
||||||
onSeparatorChange = { currentSeparator = it },
|
updateFormatterSymbols = updateFormatterSymbols@{ grouping, fractional ->
|
||||||
|
currentFormatterSymbols = FormatterSymbols(grouping, fractional)
|
||||||
|
},
|
||||||
onOutputFormatChange = { currentOutputFormat = it },
|
onOutputFormatChange = { currentOutputFormat = it },
|
||||||
navigateUpAction = {},
|
navigateUpAction = {},
|
||||||
)
|
)
|
||||||
|
@ -18,11 +18,10 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.feature.settings.formatting
|
package com.sadellie.unitto.feature.settings.formatting
|
||||||
|
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
import com.sadellie.unitto.core.base.FormatterSymbols
|
||||||
|
|
||||||
data class FormattingUIState(
|
data class FormattingUIState(
|
||||||
val precision: Int,
|
val precision: Int,
|
||||||
val separator: Int,
|
|
||||||
val outputFormat: Int,
|
val outputFormat: Int,
|
||||||
val formatterSymbols: FormatterSymbols,
|
val formatterSymbols: FormatterSymbols,
|
||||||
)
|
)
|
||||||
|
@ -21,7 +21,6 @@ package com.sadellie.unitto.feature.settings.formatting
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.core.base.MAX_PRECISION
|
import com.sadellie.unitto.core.base.MAX_PRECISION
|
||||||
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
|
|
||||||
import com.sadellie.unitto.data.common.stateIn
|
import com.sadellie.unitto.data.common.stateIn
|
||||||
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
@ -38,9 +37,8 @@ class FormattingViewModel @Inject constructor(
|
|||||||
val uiState = _prefs.map { mainPrefs ->
|
val uiState = _prefs.map { mainPrefs ->
|
||||||
FormattingUIState(
|
FormattingUIState(
|
||||||
precision = mainPrefs.digitsPrecision,
|
precision = mainPrefs.digitsPrecision,
|
||||||
separator = mainPrefs.separator,
|
|
||||||
outputFormat = mainPrefs.outputFormat,
|
outputFormat = mainPrefs.outputFormat,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(mainPrefs.separator)
|
formatterSymbols = mainPrefs.formatterSymbols
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.stateIn(viewModelScope, null)
|
.stateIn(viewModelScope, null)
|
||||||
@ -55,10 +53,10 @@ class FormattingViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see UserPreferencesRepository.updateSeparator
|
* @see UserPreferencesRepository.updateFormatterSymbols
|
||||||
*/
|
*/
|
||||||
fun updateSeparator(separator: Int) = viewModelScope.launch {
|
fun updateFormatterSymbols(grouping: String, fractional: String) = viewModelScope.launch {
|
||||||
userPreferencesRepository.updateSeparator(separator)
|
userPreferencesRepository.updateFormatterSymbols(grouping, fractional)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user