From 905995ab442425366c530cd994a8f4dede500a63 Mon Sep 17 00:00:00 2001 From: Lukas <77849373+qwqtoday@users.noreply.github.com> Date: Wed, 5 Aug 2026 00:08:44 +0800 Subject: [PATCH] Added configurable Radar offset to the sensors output (#230) --- .../core/data/repository/SettingsRepo.kt | 8 +++- .../look4sat/core/domain/model/Settings.kt | 4 +- .../src/main/res/values/strings.xml | 2 + .../look4sat/feature/radar/RadarScreen.kt | 1 + .../look4sat/feature/radar/RadarState.kt | 1 + .../look4sat/feature/radar/RadarView.kt | 5 ++- .../look4sat/feature/radar/RadarViewModel.kt | 10 ++++- .../feature/settings/SettingsScreen.kt | 37 ++++++++++++++++++- .../feature/settings/SettingsState.kt | 2 + .../feature/settings/SettingsViewModel.kt | 2 + gradle.properties | 3 ++ 11 files changed, 68 insertions(+), 7 deletions(-) diff --git a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt index fb8f863c..283142ac 100644 --- a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt +++ b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt @@ -86,6 +86,8 @@ class SettingsRepo( private val keySstvMode = "sstvMode" private val keyLowElevation = "lowElevation" private val keyHighElevation = "highElevation" + private val keyRadarCompassOffset = "radarCompassOffset" + private val keyRadarCompassOffsetElev = "radarCompassOffsetElev" private val keyUseCustomTle = "useCustomTle" private val keyUseCustomTransceivers = "useCustomTransceivers" private val keyTleUrl = "tleUrl" @@ -332,6 +334,8 @@ class SettingsRepo( putString(keySstvMode, new.sstvMode) putLong(keyLowElevation, new.lowElevation.toRawBits()) putLong(keyHighElevation, new.highElevation.toRawBits()) + putFloat(keyRadarCompassOffset, new.radarCompassOffset) + putFloat(keyRadarCompassOffsetElev, new.radarCompassOffsetElev) } new } @@ -348,7 +352,9 @@ class SettingsRepo( shouldSeeWhatsNew = preferences.getBoolean(keyShouldSeeWhatsNew, true), sstvMode = preferences.getString(keySstvMode, null) ?: "Auto", lowElevation = Double.fromBits(preferences.getLong(keyLowElevation, 15.0.toRawBits())), - highElevation = Double.fromBits(preferences.getLong(keyHighElevation, 45.0.toRawBits())) + highElevation = Double.fromBits(preferences.getLong(keyHighElevation, 45.0.toRawBits())), + radarCompassOffset = preferences.getFloat(keyRadarCompassOffset, 0f), + radarCompassOffsetElev = preferences.getFloat(keyRadarCompassOffsetElev, 0f) ) //endregion diff --git a/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt b/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt index 1647073b..281e0c86 100644 --- a/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt +++ b/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt @@ -61,7 +61,9 @@ data class OtherSettings( val shouldSeeWhatsNew: Boolean, val sstvMode: String = "Auto", val lowElevation: Double = 15.0, - val highElevation: Double = 45.0 + val highElevation: Double = 45.0, + val radarCompassOffset: Float = 0f, + val radarCompassOffsetElev: Float = 0f ) data class DataSourcesSettings( diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml index 492aaa2f..d571a14b 100644 --- a/core/presentation/src/main/res/values/strings.xml +++ b/core/presentation/src/main/res/values/strings.xml @@ -189,6 +189,8 @@ Radar sweep animation Use sensors for radar Red night filter + Radar compass offset + Radar compass offset (elev) Elevation highlight Low < %1$d° diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt index c3d753a2..aa164b32 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt @@ -225,6 +225,7 @@ private fun RadarCard(uiState: RadarState, modifier: Modifier = Modifier) { azimElev = uiState.orientationValues, shouldShowSweep = uiState.shouldShowSweep, shouldUseCompass = uiState.shouldUseCompass, + shouldFlipRadar = uiState.shouldFlipRadar, modifier = Modifier.align(Alignment.Center), sunPosition = uiState.sunPosition, moonPosition = uiState.moonPosition, diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarState.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarState.kt index bb5a0329..78aaadd9 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarState.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarState.kt @@ -58,6 +58,7 @@ data class RadarState( val satTrack: List = emptyList(), val shouldShowSweep: Boolean = false, val shouldUseCompass: Boolean = false, + val shouldFlipRadar: Boolean = false, val sunPosition: CelestialComputer.SunPosition? = null, val moonPosition: CelestialComputer.MoonPosition? = null, val transceivers: TransceiverSubState = TransceiverSubState(), diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt index bedf5a7d..07f4b0c1 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt @@ -74,6 +74,7 @@ fun RadarViewCompose( azimElev: Pair, shouldShowSweep: Boolean, shouldUseCompass: Boolean, + shouldFlipRadar: Boolean, modifier: Modifier = Modifier, sunPosition: CelestialComputer.SunPosition? = null, moonPosition: CelestialComputer.MoonPosition? = null, @@ -125,7 +126,9 @@ fun RadarViewCompose( cachedSweepBrush = makeSweepBrush(center, primaryColor) cachedSweepColor = primaryColor } - rotate(if (shouldUseCompass) -azimElev.first else 0f) { + val baseRotation = if (shouldUseCompass) -azimElev.first else 0f + val rotation = if (shouldFlipRadar) baseRotation + 180f else baseRotation + rotate(rotation) { if (shouldShowSweep) cachedSweepBrush?.let { drawSweep(center, sweepDegrees, radius, it) } drawRadar(radius, radarColor) drawElevationLabels(radius, primaryColor, measurer) diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt index c013022f..83d214fb 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt @@ -67,6 +67,8 @@ class RadarViewModel( private val stationPos = settingsRepo.stationPosition.value private val magDeclination = sensorsRepo.getMagDeclination(stationPos) + private var compassOffset = settingsRepo.otherSettings.value.radarCompassOffset + private var compassOffsetElev = settingsRepo.otherSettings.value.radarCompassOffsetElev private var transponders: List = emptyList() private var sstvDecoder: SstvDecoder? = null private var sstvRecordingJob: Job? = null @@ -99,7 +101,8 @@ class RadarViewModel( viewModelScope.launch { sensorsRepo.enableSensor() sensorsRepo.sensorData.collect { data -> - val orientationValues = (data.first + magDeclination) to data.second + val orientationValues = + (data.first + magDeclination + compassOffset) to (data.second + compassOffsetElev) _uiState.update { it.copy(orientationValues = orientationValues) } } } @@ -108,11 +111,14 @@ class RadarViewModel( private fun collectSettingsChanges() { viewModelScope.launch { settingsRepo.otherSettings.collectLatest { settings -> + compassOffset = settings.radarCompassOffset + compassOffsetElev = settings.radarCompassOffsetElev _uiState.update { it.copy( isUtc = settings.stateOfUtc, shouldShowSweep = settings.stateOfSweep, - shouldUseCompass = settings.stateOfSensors + shouldUseCompass = settings.stateOfSensors, + shouldFlipRadar = settings.radarCompassOffsetElev < 0f ) } } diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt index 9170aa04..a32393ac 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt @@ -38,6 +38,7 @@ import androidx.compose.material3.ElevatedCard import androidx.compose.material3.Icon import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Slider import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -487,7 +488,7 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni ElevatedCard( modifier = Modifier .fillMaxWidth() - .height(268.dp) + .height(404.dp) ) { Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)) { Text( @@ -506,6 +507,16 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni SwitchRow(R.string.prefs_other_switch_sensors, settings.stateOfSensors) { onAction(SettingsAction.ToggleSensor(it)) } + CompassOffsetRow( + labelResId = R.string.prefs_other_compass_offset, + value = settings.radarCompassOffset, + range = -180f..180f + ) { onAction(SettingsAction.SetRadarCompassOffset(it)) } + CompassOffsetRow( + labelResId = R.string.prefs_other_compass_offset_elev, + value = settings.radarCompassOffsetElev, + range = -90f..90f + ) { onAction(SettingsAction.SetRadarCompassOffsetElev(it)) } SwitchRow(R.string.prefs_other_switch_night_mode, settings.stateOfNightMode) { onAction(SettingsAction.ToggleNightMode(it)) } @@ -513,6 +524,28 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni } } +@Composable +private fun CompassOffsetRow( + labelResId: Int, + value: Float, + range: ClosedFloatingPointRange, + onValueChange: (Float) -> Unit +) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = stringResource(id = labelResId)) + Text(text = "${value.toInt()}°") + } + Slider( + value = value, + onValueChange = onValueChange, + valueRange = range + ) +} + @Composable private fun SwitchRow(labelResId: Int, checked: Boolean, onCheckedChange: (Boolean) -> Unit) { Row( @@ -559,7 +592,7 @@ private fun CardCredits(modifier: Modifier = Modifier) { ElevatedCard( modifier = modifier .fillMaxWidth() - .height(268.dp) + .height(404.dp) ) { Column( verticalArrangement = Arrangement.SpaceBetween, diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt index d5c66f5e..c0e0917b 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt @@ -65,6 +65,8 @@ sealed interface SettingsAction { data class ToggleSensor(val value: Boolean) : SettingsAction data class ToggleLightTheme(val value: Boolean) : SettingsAction data class ToggleNightMode(val value: Boolean) : SettingsAction + data class SetRadarCompassOffset(val value: Float) : SettingsAction + data class SetRadarCompassOffsetElev(val value: Float) : SettingsAction // Remote control data class UpdateRC(val settings: RCSettings) : SettingsAction diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt index 33a5a5b1..adcac2ad 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt @@ -123,6 +123,8 @@ class SettingsViewModel( is SettingsAction.ToggleSensor -> settingsRepo.updateOtherSettings { it.copy(stateOfSensors = action.value) } is SettingsAction.ToggleLightTheme -> settingsRepo.updateOtherSettings { it.copy(stateOfLightTheme = action.value) } is SettingsAction.ToggleNightMode -> settingsRepo.updateOtherSettings { it.copy(stateOfNightMode = action.value) } + is SettingsAction.SetRadarCompassOffset -> settingsRepo.updateOtherSettings { it.copy(radarCompassOffset = action.value) } + is SettingsAction.SetRadarCompassOffsetElev -> settingsRepo.updateOtherSettings { it.copy(radarCompassOffsetElev = action.value) } // Remote control & data sources is SettingsAction.UpdateRC -> settingsRepo.updateRCSettings(action.settings) is SettingsAction.UpdateRadioControl -> settingsRepo.updateRadioControlSettings(action.settings) diff --git a/gradle.properties b/gradle.properties index 6308f0e2..8ecdada7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,3 +3,6 @@ org.gradle.caching=true org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 org.gradle.parallel=true org.gradle.workers.max=4 + +# Enabled parallel sync for Gradle 9.4+ +org.gradle.tooling.parallel=true