From 106739720573a348750ca87bb5c4517fd8cf9344 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 12 Dec 2021 22:05:36 +0100 Subject: [PATCH] Add unit converter for units of temperature --- .../launcher2/search/data/UnitConverter.kt | 3 +- .../converters/SimpleFactorConverter.kt | 7 +- .../converters/TemperatureConverter.kt | 112 +++++++++++++++++- 3 files changed, 116 insertions(+), 6 deletions(-) diff --git a/unitconverter/src/main/java/de/mm20/launcher2/search/data/UnitConverter.kt b/unitconverter/src/main/java/de/mm20/launcher2/search/data/UnitConverter.kt index 8eee3144..972d6065 100644 --- a/unitconverter/src/main/java/de/mm20/launcher2/search/data/UnitConverter.kt +++ b/unitconverter/src/main/java/de/mm20/launcher2/search/data/UnitConverter.kt @@ -35,7 +35,8 @@ open class UnitConverter( lazy { DataConverter(context) }, lazy { TimeConverter(context) }, lazy { VelocityConverter(context) }, - lazy { AreaConverter(context) } + lazy { AreaConverter(context) }, + lazy { TemperatureConverter(context) } ) for (conv in converters) { val converter = conv.value diff --git a/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/SimpleFactorConverter.kt b/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/SimpleFactorConverter.kt index a17d7490..ce47bd8a 100644 --- a/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/SimpleFactorConverter.kt +++ b/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/SimpleFactorConverter.kt @@ -3,6 +3,7 @@ package de.mm20.launcher2.unitconverter.converters import android.content.Context import de.mm20.launcher2.search.data.UnitConverter import de.mm20.launcher2.unitconverter.ConverterUtils +import de.mm20.launcher2.unitconverter.MeasureUnit import de.mm20.launcher2.unitconverter.UnitValue /** @@ -40,6 +41,6 @@ abstract class SimpleFactorConverter: Converter { data class MeasureUnitWithFactor( val factor: Double, - val symbol: String, - val nameResource: Int -) \ No newline at end of file + override val symbol: String, + override val nameResource: Int +): MeasureUnit \ No newline at end of file diff --git a/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/TemperatureConverter.kt b/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/TemperatureConverter.kt index a3bfa78e..00eca44b 100644 --- a/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/TemperatureConverter.kt +++ b/unitconverter/src/main/java/de/mm20/launcher2/unitconverter/converters/TemperatureConverter.kt @@ -1,8 +1,116 @@ package de.mm20.launcher2.unitconverter.converters import android.content.Context -import de.mm20.launcher2.unitconverter.Dimension +import de.mm20.launcher2.search.data.UnitConverter +import de.mm20.launcher2.unitconverter.* -class TemperatureConverter(context: Context): SimpleFactorConverter() { +class TemperatureConverter(context: Context) : Converter { override val dimension = Dimension.Temperature + + private val units = listOf( + TemperatureMeasureUnit( + context.getString(R.string.unit_degree_celsius_symbol), + R.plurals.unit_degree_celsius, + TemperatureUnit.DegreeCelsius + ), + TemperatureMeasureUnit( + context.getString(R.string.unit_degree_fahrenheit_symbol), + R.plurals.unit_degree_fahrenheit, + TemperatureUnit.DegreeFahrenheit + ), + TemperatureMeasureUnit( + context.getString(R.string.unit_kelvin_symbol), + R.plurals.unit_kelvin, + TemperatureUnit.Kelvin + ), + ) + + override suspend fun isValidUnit(symbol: String): Boolean { + return units.any { it.symbol == symbol } + } + + override suspend fun convert( + context: Context, + fromUnit: String, + value: Double, + toUnit: String? + ): UnitConverter { + val from = units.first { it.symbol == fromUnit } + val to = toUnit?.let { unit -> units.first { it.symbol == unit } } + + val values = mutableListOf() + + if (to != null) { + val toValue = convertTemperature(value, from.unit, to.unit) + + values += UnitValue( + value = value, + symbol = toUnit, + formattedName = ConverterUtils.formatName(context, to, toValue), + formattedValue = ConverterUtils.formatValue(context, to, toValue), + ) + } else { + for (to in units) { + if (to.symbol == from.symbol) continue + val v = convertTemperature(value, from.unit, to.unit) + values += UnitValue( + v, + to.symbol, + ConverterUtils.formatName(context, to, v), + ConverterUtils.formatValue(context, to, v) + ) + } + } + return UnitConverter( + dimension = Dimension.Temperature, + inputValue = UnitValue( + value = value, + symbol = fromUnit, + formattedName = ConverterUtils.formatName(context, from, value), + formattedValue = ConverterUtils.formatValue(context, from, value), + ), + values = values + ) + } + + private fun convertTemperature( + value: Double, + from: TemperatureUnit, + to: TemperatureUnit + ): Double { + if (from == to) return value + if (from == TemperatureUnit.Kelvin && to == TemperatureUnit.DegreeCelsius) { + return value - 273.15 + } + if (from == TemperatureUnit.DegreeCelsius && to == TemperatureUnit.Kelvin) { + return value + 273.15 + } + if (from === TemperatureUnit.DegreeCelsius && to == TemperatureUnit.DegreeFahrenheit) { + return value * (9.0 / 5.0) + 32.0 + } + if (from === TemperatureUnit.DegreeFahrenheit && to == TemperatureUnit.DegreeCelsius) { + return (value - 32.0) * (5.0 / 9.0) + } + + if (from === TemperatureUnit.Kelvin && to == TemperatureUnit.DegreeFahrenheit) { + return (value - 273.15) * (9.0 / 5.0) + 32.0 + } + if (from === TemperatureUnit.DegreeFahrenheit && to == TemperatureUnit.Kelvin) { + return (value - 32.0) * (5.0 / 9.0) + 273.15 + } + throw IllegalArgumentException() + } +} + +private data class TemperatureMeasureUnit( + override val symbol: String, + override val nameResource: Int, + val unit: TemperatureUnit +) : + MeasureUnit + +private enum class TemperatureUnit { + DegreeCelsius, + DegreeFahrenheit, + Kelvin, } \ No newline at end of file