Implemented landscape support for MapScreen
This commit is contained in:
1 parent
5a0ff019e9
commit
609c83ed34
13 files changed
+87
-48
No files matched your search
@@ -113,7 +113,7 @@ private val darkScheme = darkColorScheme(
|
||||
// surfaceContainerHigh = Color(0xFF121212),
|
||||
surfaceContainerHighest = Color(0xFF242424), // filled card background
|
||||
surfaceContainerLow = Color(0xFF202020), // elevated card background
|
||||
// surfaceContainerLowest = Color(0xFF121212),
|
||||
surfaceContainerLowest = Color(0xCC121212),
|
||||
// surfaceDim = Color(0xFF121212),
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.rtbishop.look4sat.presentation.common
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.basicMarquee
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -117,7 +118,8 @@ fun NextPassRow(pass: OrbitalPass, modifier: Modifier = Modifier) {
|
||||
text = pass.name,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = 6.dp),
|
||||
.padding(end = 6.dp)
|
||||
.basicMarquee(),
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
|
||||
@@ -11,8 +11,12 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@@ -26,7 +30,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
@@ -99,7 +102,11 @@ private fun MapScreen(uiState: State<MapState>, mapView: MapView) {
|
||||
val rotateMod = Modifier.rotate(180f)
|
||||
val timeString = uiState.value.mapData?.aosTime ?: "00:00:00"
|
||||
val isTimeAos = uiState.value.mapData?.isTimeAos ?: true
|
||||
val osmInfo = "© OpenStreetMap contributors"
|
||||
LaunchedEffect(uiState.value.track) {
|
||||
val latitude = uiState.value.track?.get(0)?.get(0)?.latitude ?: 0.0
|
||||
val longitude = uiState.value.track?.get(0)?.get(0)?.longitude ?: 0.0
|
||||
mapView.controller.animateTo(GeoPoint(latitude, longitude))
|
||||
}
|
||||
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
if (isVerticalLayout()) {
|
||||
TopBar {
|
||||
@@ -118,50 +125,80 @@ private fun MapScreen(uiState: State<MapState>, mapView: MapView) {
|
||||
}
|
||||
ElevatedCard(modifier = Modifier.weight(1f)) {
|
||||
Box(contentAlignment = Alignment.BottomCenter) {
|
||||
LaunchedEffect(uiState.value.track) {
|
||||
val latitude = uiState.value.track?.get(0)?.get(0)?.latitude ?: 0.0
|
||||
val longitude = uiState.value.track?.get(0)?.get(0)?.longitude ?: 0.0
|
||||
mapView.controller.animateTo(GeoPoint(latitude, longitude))
|
||||
}
|
||||
AndroidView({ mapView }) { mapView ->
|
||||
uiState.value.stationPosition?.let { setStationPosition(it, mapView) }
|
||||
uiState.value.positions?.let { setPositions(it, mapView, onItemClick) }
|
||||
uiState.value.track?.let { setSatelliteTrack(it, mapView) }
|
||||
uiState.value.footprint?.let { setFootprint(it, mapView) }
|
||||
}
|
||||
Text(text = osmInfo, textAlign = TextAlign.Center, fontSize = 14.sp)
|
||||
}
|
||||
}
|
||||
uiState.value.mapData?.let { mapData ->
|
||||
ElevatedCard {
|
||||
MapDataCard(mapData)
|
||||
uiState.value.mapData?.let { mapData ->
|
||||
if (isVerticalLayout()) MapDataCard(mapData) else MapDataCards(mapData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MapDataCard(mapData: MapData) {
|
||||
Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_period, mapData.period), color = MaterialTheme.colorScheme.primary)
|
||||
Text(text = stringResource(R.string.map_phase, mapData.phase), color = MaterialTheme.colorScheme.primary)
|
||||
private fun MapDataCard(data: MapData) {
|
||||
val textColor = MaterialTheme.colorScheme.primary
|
||||
val cardColors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLowest)
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.SpaceBetween) {
|
||||
Text(text = "© OpenStreetMap contributors", fontSize = 14.sp)
|
||||
Card(colors = cardColors) {
|
||||
Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_azimuth, data.azimuth))
|
||||
Text(text = stringResource(R.string.map_elevation, data.elevation))
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_altitude, data.altitude), color = textColor)
|
||||
Text(text = stringResource(R.string.map_distance, data.range), color = textColor)
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_latitude, data.osmPos.latitude))
|
||||
Text(text = stringResource(R.string.map_longitude, data.osmPos.longitude))
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_qth, data.qthLoc), color = textColor)
|
||||
Text(text = stringResource(R.string.map_phase, data.phase), color = textColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_azimuth, mapData.azimuth))
|
||||
Text(text = stringResource(R.string.map_elevation, mapData.elevation))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MapDataCards(data: MapData) {
|
||||
val cardColors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLowest)
|
||||
val paddingMod = Modifier.padding(horizontal = 8.dp, vertical = 4.dp).width(160.dp)
|
||||
val osmText = "© OpenStreetMap contributors"
|
||||
val textColor = MaterialTheme.colorScheme.primary
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Card(colors = cardColors, modifier = Modifier.align(Alignment.TopStart)) {
|
||||
Column(horizontalAlignment = Alignment.Start, modifier = paddingMod) {
|
||||
Text(text = stringResource(R.string.map_azimuth, data.azimuth))
|
||||
Text(text = stringResource(R.string.map_elevation, data.elevation), color = textColor)
|
||||
}
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_altitude, mapData.altitude), color = MaterialTheme.colorScheme.primary)
|
||||
Text(text = stringResource(R.string.map_distance, mapData.range), color = MaterialTheme.colorScheme.primary)
|
||||
Card(colors = cardColors, modifier = Modifier.align(Alignment.TopEnd)) {
|
||||
Column(horizontalAlignment = Alignment.End, modifier = paddingMod) {
|
||||
Text(text = stringResource(R.string.map_altitude, data.altitude))
|
||||
Text(text = stringResource(R.string.map_distance, data.range), color = textColor)
|
||||
}
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_latitude, mapData.osmPos.latitude))
|
||||
Text(text = stringResource(R.string.map_longitude, mapData.osmPos.longitude))
|
||||
Card(colors = cardColors, modifier = Modifier.align(Alignment.BottomStart)) {
|
||||
Column(horizontalAlignment = Alignment.Start, modifier = paddingMod) {
|
||||
Text(text = stringResource(R.string.map_phase, data.phase))
|
||||
Text(text = stringResource(R.string.map_qth, data.qthLoc), color = textColor)
|
||||
}
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = stringResource(R.string.map_qth, mapData.qthLoc), color = MaterialTheme.colorScheme.primary)
|
||||
Text(text = stringResource(R.string.map_velocity, mapData.velocity), color = MaterialTheme.colorScheme.primary)
|
||||
Text(text = osmText, fontSize = 14.sp, modifier = Modifier.align(Alignment.BottomCenter))
|
||||
Card(colors = cardColors, modifier = Modifier.align(Alignment.BottomEnd)) {
|
||||
Column(horizontalAlignment = Alignment.End, modifier = paddingMod) {
|
||||
Text(text = stringResource(R.string.map_latitude, data.osmPos.latitude))
|
||||
Text(text = stringResource(R.string.map_longitude, data.osmPos.longitude), color = textColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,6 +343,8 @@ private fun getColorFilter(): ColorMatrixColorFilter {
|
||||
return ColorMatrixColorFilter(negative)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getMinZoom(screenHeight: Int): Double {
|
||||
if (!isVerticalLayout()) return 3.5
|
||||
return MapView.getTileSystem().getLatitudeZoom(maxLat, minLat, screenHeight)
|
||||
}
|
||||
@@ -148,7 +148,7 @@ fun RadiosDialog(modes: List<String>, cancel: () -> Unit, accept: (List<String>)
|
||||
val onAccept = { accept(selected.toList()).also { cancel() } }
|
||||
SharedDialog(title = "Radios", onCancel = cancel, onAccept = onAccept) {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(1),
|
||||
columns = GridCells.Adaptive(240.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxHeight(0.69f)
|
||||
.background(MaterialTheme.colorScheme.background),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.rtbishop.look4sat.presentation.passes
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.basicMarquee
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -201,7 +202,8 @@ private fun NearEarthPass(
|
||||
text = pass.name,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = 6.dp),
|
||||
.padding(end = 6.dp)
|
||||
.basicMarquee(),
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
|
||||
@@ -82,6 +82,7 @@ private fun RadarScreen(uiState: RadarState, navigateUp: () -> Unit) {
|
||||
}
|
||||
}
|
||||
val upcomingPass = uiState.currentPass ?: getDefaultPass()
|
||||
if (upcomingPass.losTime < System.currentTimeMillis()) navigateUp()
|
||||
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
if (isVerticalLayout()) {
|
||||
TopBar {
|
||||
|
||||
@@ -13,11 +13,9 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Checkbox
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
|
||||
@@ -117,7 +117,6 @@
|
||||
<string name="map_elevation">Элевация: %.1f°</string>
|
||||
<string name="map_latitude">Широта: %.1f°</string>
|
||||
<string name="map_longitude">Долгота: %.1f°</string>
|
||||
<string name="map_qth">QTH Локатор: %s</string>
|
||||
<string name="map_visible">Видимый</string>
|
||||
<string name="map_eclipsed">В тени</string>
|
||||
<string name="map_visibility">Видимость: %s</string>
|
||||
|
||||
@@ -117,7 +117,6 @@
|
||||
<string name="map_elevation">උත්තෝලනය: %.1f°</string>
|
||||
<string name="map_latitude">අක්ෂාංශ: %.1f°</string>
|
||||
<string name="map_longitude">දේශාංශ: %.1f°</string>
|
||||
<string name="map_qth">QTH Locator: %s</string>
|
||||
<string name="map_visible">දෘශ්ය</string>
|
||||
<string name="map_eclipsed">අදෘශ්ය</string>
|
||||
<string name="map_visibility">දෘශ්යතාව: %s</string>
|
||||
|
||||
@@ -117,7 +117,6 @@
|
||||
<string name="map_elevation">仰角:%.1f°</string>
|
||||
<string name="map_latitude">纬度:%.1f°</string>
|
||||
<string name="map_longitude">经度:%.1f°</string>
|
||||
<string name="map_qth">QTH 网格:%s</string>
|
||||
<string name="map_visible">日照中</string>
|
||||
<string name="map_eclipsed">地影中</string>
|
||||
<string name="map_visibility">能见度:%s</string>
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
<string name="map_elevation">Elevation: %.1f°</string>
|
||||
<string name="map_latitude">Latitude: %.1f°</string>
|
||||
<string name="map_longitude">Longitude: %.1f°</string>
|
||||
<string name="map_qth">QTH Locator: %s</string>
|
||||
<string name="map_qth" translatable="false">QTH: %s</string>
|
||||
<string name="map_visible">Visible</string>
|
||||
<string name="map_eclipsed">Eclipsed</string>
|
||||
<string name="map_visibility">Visibility: %s</string>
|
||||
|
||||
@@ -51,7 +51,8 @@ class SatelliteRepo(
|
||||
settingsRepo.selectedIds.collect { selectedIds ->
|
||||
_satellites.update { localStorage.getEntriesWithIds(selectedIds) }
|
||||
val (hoursAhead, minElevation, modes) = settingsRepo.passesSettings.value
|
||||
calculatePasses(System.currentTimeMillis(), hoursAhead, minElevation, modes)
|
||||
val timeNow = 1000 * ((System.currentTimeMillis() + 500) / 1000)
|
||||
calculatePasses(timeNow, hoursAhead, minElevation, modes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,10 +196,10 @@ class SatelliteRepo(
|
||||
}
|
||||
} while (satPos.elevation < 0.0)
|
||||
|
||||
// refine to 3 seconds
|
||||
// refine to 1 second
|
||||
calendarTimeMillis += -60L * 1000L
|
||||
do {
|
||||
calendarTimeMillis += 3L * 1000L
|
||||
calendarTimeMillis += 1L * 500L
|
||||
satPos = sat.getPosition(pos, calendarTimeMillis)
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) {
|
||||
@@ -207,7 +208,7 @@ class SatelliteRepo(
|
||||
}
|
||||
} while (satPos.elevation < 0.0)
|
||||
|
||||
val aos = satPos.time
|
||||
val aos = 1000 * ((satPos.time + 500) / 1000)
|
||||
val aosAz = satPos.azimuth.toDegrees().round(1)
|
||||
|
||||
// find when sat goes below
|
||||
@@ -221,10 +222,10 @@ class SatelliteRepo(
|
||||
}
|
||||
} while (satPos.elevation > 0.0)
|
||||
|
||||
// refine to 3 seconds
|
||||
// refine to 1 second
|
||||
calendarTimeMillis += -30L * 1000L
|
||||
do {
|
||||
calendarTimeMillis += 3L * 1000L
|
||||
calendarTimeMillis += 1L * 500L
|
||||
satPos = sat.getPosition(pos, calendarTimeMillis)
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) {
|
||||
@@ -233,7 +234,7 @@ class SatelliteRepo(
|
||||
}
|
||||
} while (satPos.elevation > 0.0)
|
||||
|
||||
val los = satPos.time // val tca = (aos + los) / 2
|
||||
val los = 1000 * ((satPos.time + 500) / 1000) // val tca = (aos + los) / 2
|
||||
val losAz = satPos.azimuth.toDegrees().round(1)
|
||||
val elev = maxElevation.toDegrees().round(1)
|
||||
return OrbitalPass(aos, aosAz, los, losAz, alt.toInt(), elev, sat)
|
||||
|
||||
Reference in new issue
Block a user