Add wide mode for tailwind and tailwind with speed data fields (#80)

This commit is contained in:
timklge 2025-03-27 21:08:35 +01:00 committed by GitHub
parent bcf47a9578
commit 5d7ba99f57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 99 additions and 48 deletions

View File

@ -157,7 +157,8 @@ class HeadwindDirectionDataType(
windDirection.roundToInt(),
config.textSize,
windSpeed?.toInt()?.toString() ?: "",
preview = config.preview
preview = config.preview,
wideMode = false
)
}

View File

@ -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)
@ -83,6 +89,38 @@ fun HeadwindDirection(
style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.6 * fontSize).sp, fontFamily = FontFamily.Monospace),
modifier = GlanceModifier.padding(1.dp)
)
} else {
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))
)
}
Text(
overlaySubText,
maxLines = 1,
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) {
@ -113,7 +151,7 @@ fun HeadwindDirection(
)
}
}
}
}
}
}

View File

@ -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<StreamData> {
private fun previewFlow(profileFlow: Flow<UserProfile>): Flow<de.timklge.karooheadwind.datatypes.TailwindDataType.StreamData> {
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,24 +117,20 @@ 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 ->
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
streamData.copy(isImperial = isImperial)
}
.combine(streamSpeedInMs()) { streamData, rideSpeedInMs ->
val rideSpeed = if (streamData.isImperial == true){
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.copy(rideSpeed = rideSpeed)
StreamData(headingResponse, absoluteWindDirection, windSpeed, settings, rideSpeed = rideSpeed, isImperial = isImperial, gustSpeed = gustSpeed)
}
}
@ -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,
)
}

View File

@ -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,
)
}