diff --git a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt index 0609ac4..ac2b6e2 100644 --- a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt +++ b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt @@ -157,7 +157,8 @@ class HeadwindDirectionDataType( windDirection.roundToInt(), config.textSize, windSpeed?.toInt()?.toString() ?: "", - preview = config.preview + preview = config.preview, + wideMode = false ) } diff --git a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionView.kt b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionView.kt index 32c3041..aeaf0f8 100644 --- a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionView.kt +++ b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionView.kt @@ -21,12 +21,17 @@ import androidx.glance.layout.Box import androidx.glance.layout.Column import androidx.glance.layout.ContentScale import androidx.glance.layout.Row +import androidx.glance.layout.Spacer +import androidx.glance.layout.fillMaxHeight import androidx.glance.layout.fillMaxSize import androidx.glance.layout.padding import androidx.glance.layout.size +import androidx.glance.layout.width +import androidx.glance.layout.wrapContentHeight import androidx.glance.text.FontFamily import androidx.glance.text.FontWeight import androidx.glance.text.Text +import androidx.glance.text.TextAlign import androidx.glance.text.TextStyle import de.timklge.karooheadwind.MainActivity import kotlin.math.roundToInt @@ -56,7 +61,8 @@ fun getArrowBitmapByBearing(baseBitmap: Bitmap, bearing: Int): Bitmap { fun HeadwindDirection( baseBitmap: Bitmap, bearing: Int, fontSize: Int, overlayText: String, overlaySubText: String? = null, - nightColor: Color = Color.Black, dayColor: Color = Color.White, preview: Boolean = false + nightColor: Color = Color.Black, dayColor: Color = Color.White, preview: Boolean = false, + wideMode: Boolean ) { val baseModifier = GlanceModifier.fillMaxSize().padding(5.dp).background(dayColor, nightColor).cornerRadius(10.dp) @@ -84,36 +90,68 @@ fun HeadwindDirection( modifier = GlanceModifier.padding(1.dp) ) } else { - Row(modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) { - Column(horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.CenterVertically) { - Column(modifier = GlanceModifier.size(40.dp)) { - Image( - provider = ImageProvider(getArrowBitmapByBearing(baseBitmap, bearing)), - contentDescription = "Relative wind direction indicator", - contentScale = ContentScale.Fit, - colorFilter = ColorFilter.tint(ColorProvider(Color.Black, Color.White)) - ) - } - } + if (wideMode){ + Row(modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically, horizontalAlignment = Alignment.CenterHorizontally) { + Column(modifier = GlanceModifier.defaultWeight(), horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.CenterVertically) { + Column(modifier = GlanceModifier.size(50.dp)) { + Image( + provider = ImageProvider(getArrowBitmapByBearing(baseBitmap, bearing)), + contentDescription = "Relative wind direction indicator", + contentScale = ContentScale.Fit, + colorFilter = ColorFilter.tint(ColorProvider(Color.Black, Color.White)) + ) + } - Column(modifier = GlanceModifier.defaultWeight(), horizontalAlignment = Alignment.Horizontal.CenterHorizontally) { - Text( - overlayText, - maxLines = 1, - style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.65 * fontSize).sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold), - modifier = GlanceModifier.padding(1.dp) - ) - - Row(){ Text( overlaySubText, maxLines = 1, - style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.4 * fontSize).sp, fontFamily = FontFamily.Monospace), + style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.35 * fontSize).sp, fontFamily = FontFamily.Monospace), modifier = GlanceModifier.padding(1.dp) ) } - } + // Spacer(modifier = GlanceModifier.width(10.dp)) + + Column(modifier = GlanceModifier.defaultWeight().fillMaxHeight(), verticalAlignment = Alignment.CenterVertically, horizontalAlignment = Alignment.CenterHorizontally) { + Text( + overlayText, + maxLines = 1, + modifier = GlanceModifier.padding(5.dp), + style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.75 * fontSize).sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold) + ) + } + } + } else { + Row(modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) { + Column(horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.CenterVertically) { + Column(modifier = GlanceModifier.size(40.dp)) { + Image( + provider = ImageProvider(getArrowBitmapByBearing(baseBitmap, bearing)), + contentDescription = "Relative wind direction indicator", + contentScale = ContentScale.Fit, + colorFilter = ColorFilter.tint(ColorProvider(Color.Black, Color.White)) + ) + } + } + + Column(modifier = GlanceModifier.defaultWeight(), horizontalAlignment = Alignment.Horizontal.CenterHorizontally) { + Text( + overlayText, + maxLines = 1, + style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.65 * fontSize).sp, fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold), + modifier = GlanceModifier.padding(1.dp) + ) + + Row(){ + Text( + overlaySubText, + maxLines = 1, + style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.4 * fontSize).sp, fontFamily = FontFamily.Monospace), + modifier = GlanceModifier.padding(1.dp) + ) + } + } + } } } } diff --git a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindAndRideSpeedDataType.kt b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindAndRideSpeedDataType.kt index 067daab..c7cc655 100644 --- a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindAndRideSpeedDataType.kt +++ b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindAndRideSpeedDataType.kt @@ -17,6 +17,7 @@ import de.timklge.karooheadwind.KarooHeadwindExtension import de.timklge.karooheadwind.R import de.timklge.karooheadwind.WindDirectionIndicatorSetting import de.timklge.karooheadwind.WindDirectionIndicatorTextSetting +import de.timklge.karooheadwind.datatypes.TailwindDataType.StreamData import de.timklge.karooheadwind.getRelativeHeadingFlow import de.timklge.karooheadwind.streamCurrentWeatherData import de.timklge.karooheadwind.streamDataFlow @@ -37,6 +38,7 @@ import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -78,14 +80,18 @@ class TailwindAndRideSpeedDataType( val rideSpeed: Double? = null, val isImperial: Boolean? = null) - private fun previewFlow(): Flow { + private fun previewFlow(profileFlow: Flow): Flow { return flow { + val profile = profileFlow.first() + while (true) { val bearing = (0..360).random().toDouble() val windSpeed = (0..20).random() val rideSpeed = (10..40).random().toDouble() + val gustSpeed = windSpeed * ((10..40).random().toDouble() / 10) + val isImperial = profile.preferredUnit.distance == UserProfile.PreferredUnit.UnitType.IMPERIAL - emit(StreamData(HeadingResponse.Value(bearing), bearing, windSpeed.toDouble(), HeadwindSettings(), rideSpeed)) + emit(StreamData(HeadingResponse.Value(bearing), bearing, windSpeed.toDouble(), HeadwindSettings(), rideSpeed, gustSpeed = gustSpeed, isImperial = isImperial)) delay(2_000) } @@ -111,25 +117,21 @@ class TailwindAndRideSpeedDataType( } val flow = if (config.preview) { - previewFlow() + previewFlow(karooSystem.streamUserProfile()) } else { - karooSystem.getRelativeHeadingFlow(context) - .combine(context.streamCurrentWeatherData()) { value, data -> value to data } - .combine(context.streamSettings(karooSystem)) { (value, data), settings -> - StreamData(value, data.firstOrNull()?.data?.current?.windDirection, data.firstOrNull()?.data?.current?.windSpeed, settings) - } - .combine(karooSystem.streamUserProfile()) { streamData, userProfile -> - val isImperial = userProfile.preferredUnit.distance == UserProfile.PreferredUnit.UnitType.IMPERIAL - streamData.copy(isImperial = isImperial) - } - .combine(streamSpeedInMs()) { streamData, rideSpeedInMs -> - val rideSpeed = if (streamData.isImperial == true){ - rideSpeedInMs * 2.23694 - } else { - rideSpeedInMs * 3.6 - } - streamData.copy(rideSpeed = rideSpeed) + combine(karooSystem.getRelativeHeadingFlow(context), context.streamCurrentWeatherData(), context.streamSettings(karooSystem), karooSystem.streamUserProfile(), streamSpeedInMs()) { headingResponse, weatherData, settings, userProfile, rideSpeedInMs -> + val isImperial = userProfile.preferredUnit.distance == UserProfile.PreferredUnit.UnitType.IMPERIAL + val absoluteWindDirection = weatherData.firstOrNull()?.data?.current?.windDirection + val windSpeed = weatherData.firstOrNull()?.data?.current?.windSpeed + val gustSpeed = weatherData.firstOrNull()?.data?.current?.windGusts + val rideSpeed = if (isImperial){ + rideSpeedInMs * 2.23694 + } else { + rideSpeedInMs * 3.6 } + + StreamData(headingResponse, absoluteWindDirection, windSpeed, settings, rideSpeed = rideSpeed, isImperial = isImperial, gustSpeed = gustSpeed) + } } val viewJob = CoroutineScope(Dispatchers.IO).launch { @@ -159,6 +161,13 @@ class TailwindAndRideSpeedDataType( val text = streamData.rideSpeed?.let { String.format(Locale.current.platformLocale, "%.1f", it) } ?: "" + val wideMode = config.gridSize.first == 60 + val gustSpeedAddon = if (wideMode) { + "-${streamData.gustSpeed?.roundToInt() ?: 0}" + } else { + "" + } + val subtextWithSign = when (streamData.settings.windDirectionIndicatorTextSetting) { WindDirectionIndicatorTextSetting.HEADWIND_SPEED -> { val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed @@ -167,9 +176,9 @@ class TailwindAndRideSpeedDataType( val sign = if (headwindSpeed < 0) "+" else { if (headwindSpeed > 0) "-" else "" } - "$sign${headwindSpeed.roundToInt().absoluteValue} ${windSpeed.roundToInt()}" + "$sign${headwindSpeed.roundToInt().absoluteValue} ${windSpeed.roundToInt()}${gustSpeedAddon}" } - WindDirectionIndicatorTextSetting.WIND_SPEED -> windSpeed.roundToInt().toString() + WindDirectionIndicatorTextSetting.WIND_SPEED -> "${windSpeed.roundToInt()}${gustSpeedAddon}" WindDirectionIndicatorTextSetting.NONE -> "" } @@ -196,7 +205,8 @@ class TailwindAndRideSpeedDataType( subtextWithSign, dayColor, nightColor, - preview = config.preview + preview = config.preview, + wideMode = wideMode, ) } diff --git a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindDataType.kt b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindDataType.kt index 566f264..48c78f6 100644 --- a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindDataType.kt +++ b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/TailwindDataType.kt @@ -160,7 +160,7 @@ class TailwindDataType( if (streamData.settings.windDirectionIndicatorSetting == WindDirectionIndicatorSetting.HEADWIND_DIRECTION) { val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed - val windSpeedInKmh = if (streamData.isImperial == true){ + val windSpeedInKmh = if (streamData.isImperial){ headwindSpeed / 2.23694 * 3.6 } else { headwindSpeed @@ -177,7 +177,9 @@ class TailwindDataType( mainText, subtext, dayColor, - nightColor + nightColor, + wideMode = config.gridSize.first == 60, + preview = config.preview, ) }