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(),
|
||||
config.textSize,
|
||||
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.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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,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,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user