Add wide mode for tailwind and tailwind with speed data fields (#80)
This commit is contained in:
parent
bcf47a9578
commit
5d7ba99f57
@ -157,7 +157,8 @@ class HeadwindDirectionDataType(
|
|||||||
windDirection.roundToInt(),
|
windDirection.roundToInt(),
|
||||||
config.textSize,
|
config.textSize,
|
||||||
windSpeed?.toInt()?.toString() ?: "",
|
windSpeed?.toInt()?.toString() ?: "",
|
||||||
preview = config.preview
|
preview = config.preview,
|
||||||
|
wideMode = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,12 +21,17 @@ import androidx.glance.layout.Box
|
|||||||
import androidx.glance.layout.Column
|
import androidx.glance.layout.Column
|
||||||
import androidx.glance.layout.ContentScale
|
import androidx.glance.layout.ContentScale
|
||||||
import androidx.glance.layout.Row
|
import androidx.glance.layout.Row
|
||||||
|
import androidx.glance.layout.Spacer
|
||||||
|
import androidx.glance.layout.fillMaxHeight
|
||||||
import androidx.glance.layout.fillMaxSize
|
import androidx.glance.layout.fillMaxSize
|
||||||
import androidx.glance.layout.padding
|
import androidx.glance.layout.padding
|
||||||
import androidx.glance.layout.size
|
import androidx.glance.layout.size
|
||||||
|
import androidx.glance.layout.width
|
||||||
|
import androidx.glance.layout.wrapContentHeight
|
||||||
import androidx.glance.text.FontFamily
|
import androidx.glance.text.FontFamily
|
||||||
import androidx.glance.text.FontWeight
|
import androidx.glance.text.FontWeight
|
||||||
import androidx.glance.text.Text
|
import androidx.glance.text.Text
|
||||||
|
import androidx.glance.text.TextAlign
|
||||||
import androidx.glance.text.TextStyle
|
import androidx.glance.text.TextStyle
|
||||||
import de.timklge.karooheadwind.MainActivity
|
import de.timklge.karooheadwind.MainActivity
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -56,7 +61,8 @@ fun getArrowBitmapByBearing(baseBitmap: Bitmap, bearing: Int): Bitmap {
|
|||||||
fun HeadwindDirection(
|
fun HeadwindDirection(
|
||||||
baseBitmap: Bitmap, bearing: Int, fontSize: Int,
|
baseBitmap: Bitmap, bearing: Int, fontSize: Int,
|
||||||
overlayText: String, overlaySubText: String? = null,
|
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)
|
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),
|
style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontSize = (0.6 * fontSize).sp, fontFamily = FontFamily.Monospace),
|
||||||
modifier = GlanceModifier.padding(1.dp)
|
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 {
|
} else {
|
||||||
Row(modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
|
Row(modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.CenterVertically) {
|
Column(horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.CenterVertically) {
|
||||||
@ -113,7 +151,7 @@ fun HeadwindDirection(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import de.timklge.karooheadwind.KarooHeadwindExtension
|
|||||||
import de.timklge.karooheadwind.R
|
import de.timklge.karooheadwind.R
|
||||||
import de.timklge.karooheadwind.WindDirectionIndicatorSetting
|
import de.timklge.karooheadwind.WindDirectionIndicatorSetting
|
||||||
import de.timklge.karooheadwind.WindDirectionIndicatorTextSetting
|
import de.timklge.karooheadwind.WindDirectionIndicatorTextSetting
|
||||||
|
import de.timklge.karooheadwind.datatypes.TailwindDataType.StreamData
|
||||||
import de.timklge.karooheadwind.getRelativeHeadingFlow
|
import de.timklge.karooheadwind.getRelativeHeadingFlow
|
||||||
import de.timklge.karooheadwind.streamCurrentWeatherData
|
import de.timklge.karooheadwind.streamCurrentWeatherData
|
||||||
import de.timklge.karooheadwind.streamDataFlow
|
import de.timklge.karooheadwind.streamDataFlow
|
||||||
@ -37,6 +38,7 @@ import kotlinx.coroutines.awaitCancellation
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -78,14 +80,18 @@ class TailwindAndRideSpeedDataType(
|
|||||||
val rideSpeed: Double? = null,
|
val rideSpeed: Double? = null,
|
||||||
val isImperial: Boolean? = 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 {
|
return flow {
|
||||||
|
val profile = profileFlow.first()
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
val bearing = (0..360).random().toDouble()
|
val bearing = (0..360).random().toDouble()
|
||||||
val windSpeed = (0..20).random()
|
val windSpeed = (0..20).random()
|
||||||
val rideSpeed = (10..40).random().toDouble()
|
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)
|
delay(2_000)
|
||||||
}
|
}
|
||||||
@ -111,24 +117,20 @@ class TailwindAndRideSpeedDataType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val flow = if (config.preview) {
|
val flow = if (config.preview) {
|
||||||
previewFlow()
|
previewFlow(karooSystem.streamUserProfile())
|
||||||
} else {
|
} else {
|
||||||
karooSystem.getRelativeHeadingFlow(context)
|
combine(karooSystem.getRelativeHeadingFlow(context), context.streamCurrentWeatherData(), context.streamSettings(karooSystem), karooSystem.streamUserProfile(), streamSpeedInMs()) { headingResponse, weatherData, settings, userProfile, rideSpeedInMs ->
|
||||||
.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
|
val isImperial = userProfile.preferredUnit.distance == UserProfile.PreferredUnit.UnitType.IMPERIAL
|
||||||
streamData.copy(isImperial = isImperial)
|
val absoluteWindDirection = weatherData.firstOrNull()?.data?.current?.windDirection
|
||||||
}
|
val windSpeed = weatherData.firstOrNull()?.data?.current?.windSpeed
|
||||||
.combine(streamSpeedInMs()) { streamData, rideSpeedInMs ->
|
val gustSpeed = weatherData.firstOrNull()?.data?.current?.windGusts
|
||||||
val rideSpeed = if (streamData.isImperial == true){
|
val rideSpeed = if (isImperial){
|
||||||
rideSpeedInMs * 2.23694
|
rideSpeedInMs * 2.23694
|
||||||
} else {
|
} else {
|
||||||
rideSpeedInMs * 3.6
|
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 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) {
|
val subtextWithSign = when (streamData.settings.windDirectionIndicatorTextSetting) {
|
||||||
WindDirectionIndicatorTextSetting.HEADWIND_SPEED -> {
|
WindDirectionIndicatorTextSetting.HEADWIND_SPEED -> {
|
||||||
val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed
|
val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed
|
||||||
@ -167,9 +176,9 @@ class TailwindAndRideSpeedDataType(
|
|||||||
val sign = if (headwindSpeed < 0) "+" else {
|
val sign = if (headwindSpeed < 0) "+" else {
|
||||||
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 -> ""
|
WindDirectionIndicatorTextSetting.NONE -> ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +205,8 @@ class TailwindAndRideSpeedDataType(
|
|||||||
subtextWithSign,
|
subtextWithSign,
|
||||||
dayColor,
|
dayColor,
|
||||||
nightColor,
|
nightColor,
|
||||||
preview = config.preview
|
preview = config.preview,
|
||||||
|
wideMode = wideMode,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -160,7 +160,7 @@ class TailwindDataType(
|
|||||||
|
|
||||||
if (streamData.settings.windDirectionIndicatorSetting == WindDirectionIndicatorSetting.HEADWIND_DIRECTION) {
|
if (streamData.settings.windDirectionIndicatorSetting == WindDirectionIndicatorSetting.HEADWIND_DIRECTION) {
|
||||||
val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed
|
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
|
headwindSpeed / 2.23694 * 3.6
|
||||||
} else {
|
} else {
|
||||||
headwindSpeed
|
headwindSpeed
|
||||||
@ -177,7 +177,9 @@ class TailwindDataType(
|
|||||||
mainText,
|
mainText,
|
||||||
subtext,
|
subtext,
|
||||||
dayColor,
|
dayColor,
|
||||||
nightColor
|
nightColor,
|
||||||
|
wideMode = config.gridSize.first == 60,
|
||||||
|
preview = config.preview,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user