diff --git a/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt b/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt index d0c28b7..771fde4 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt @@ -3,18 +3,22 @@ package com.mirenkov.ktheightmap import android.app.Application import android.content.Intent import android.os.Bundle +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Build +import androidx.compose.material3.AlertDialog import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.FloatingActionButton @@ -23,7 +27,10 @@ import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Slider import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf @@ -35,7 +42,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.toUpperCase import androidx.compose.ui.unit.dp import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -79,8 +87,6 @@ class MainActivity : ComponentActivity() { @Composable fun Main(vm: TileViewModel = viewModel()) { val sliderValue = rememberSaveable { mutableFloatStateOf(1F) } - val canvasOffsetX = rememberSaveable { mutableFloatStateOf(-652.0647F) } - val canvasOffsetY = rememberSaveable { mutableFloatStateOf(-1145.693F) } val coroutineScope = rememberCoroutineScope() val tileContainer = TileContainer(vm, coroutineScope) KtHeightMapTheme { @@ -97,8 +103,6 @@ fun Main(vm: TileViewModel = viewModel()) { backColor = colorScheme.background, scale = sliderValue, tileContainer = tileContainer, - offsetX = canvasOffsetX, - offsetY = canvasOffsetY, modifier = Modifier.padding(innerPadding), ) } @@ -122,7 +126,10 @@ fun Main(vm: TileViewModel = viewModel()) { @Composable fun ToolButton(viewModel: TileViewModel) { val context = LocalContext.current - var expanded by remember{ mutableStateOf(false) } + var expanded by rememberSaveable{ mutableStateOf(false) } + var debug by rememberSaveable{ viewModel.debug } + var logRequested by remember{ viewModel.logRequested } + val dialogShown = rememberSaveable{ mutableStateOf(false) } FloatingActionButton( onClick = { expanded = !expanded @@ -135,23 +142,79 @@ fun ToolButton(viewModel: TileViewModel) { ) { DropdownMenuItem( text = { Text("Toggle debug") }, - onClick = { viewModel.debug = !viewModel.debug } + onClick = { + debug = !debug + expanded = false + } ) DropdownMenuItem( text = { Text("Log") }, - onClick = { viewModel.logRequested = true } + onClick = { + logRequested = true + expanded = false + } ) DropdownMenuItem( text = { Text("Set location") }, - onClick = {} + onClick = { + expanded = false + dialogShown.value = true + } ) DropdownMenuItem( text = { Text("Settings") }, onClick = { + expanded = false val intent = Intent(context, SettingsActivity::class.java) context.startActivity(intent) } ) + SetLocationDialog(viewModel, dialogShown) } } +} + +@Composable +fun SetLocationDialog(vm: TileViewModel, dialogShown: MutableState) { + var showLocationDialog by dialogShown + if (showLocationDialog) { + var latitudeText by remember { vm.latitudeText } + var longitudeText by remember { vm.longitudeText } + AlertDialog ( + onDismissRequest = { showLocationDialog = false }, + title = { Text("Input coordinates") }, + text = { + Column { + TextField( + value = latitudeText, + onValueChange = { newValue -> + latitudeText = newValue + }, + label = { Text("Latitude") }, + placeholder = { Text("60.086763") }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) + ) + TextField( + value = longitudeText, + onValueChange = { newValue -> + longitudeText = newValue + }, + label = { Text("Longitude") }, + placeholder = { Text("30.014658") }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) + ) + } + }, + confirmButton = { TextButton(onClick = { + Log.i(TAG, "Lat: %.6f, Lon: %.6f".format( + latitudeText.text.toDoubleOrNull() ?: 0.0, longitudeText.text.toDoubleOrNull() ?: 0.0 + )) + }) { + Text("Confirm".uppercase()) + } }, + dismissButton = { TextButton(onClick = { showLocationDialog = false }) { + Text("Cancel".uppercase()) + } } + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt b/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt index e24ca4c..1939d04 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt @@ -34,15 +34,15 @@ fun MapCanvas( backColor: Color, gridColor: Color, scale: MutableFloatState, - offsetX: MutableFloatState, - offsetY: MutableFloatState, tileContainer: TileContainer, modifier: Modifier = Modifier ) { - var offsetX by rememberSaveable { offsetX } - var offsetY by rememberSaveable { offsetY } + var offsetX by rememberSaveable { viewModel.mapOffsetX } + var offsetY by rememberSaveable { viewModel.mapOffsetY } val scale by rememberSaveable { scale } val textMeasurer = rememberTextMeasurer() + val debug by rememberSaveable { viewModel.debug } + var logRequested by rememberSaveable { viewModel.logRequested } Canvas( modifier = modifier.fillMaxSize() .pointerInput(Unit) { @@ -57,9 +57,9 @@ fun MapCanvas( size = size ) - if (viewModel.logRequested) { + if (logRequested) { Log.i(TAG, "Offset: %.6f, %.6f".format(offsetX, offsetY)) - viewModel.logRequested = false + logRequested = false } val oldLevel = tileContainer.getLevel() @@ -101,7 +101,7 @@ fun MapCanvas( val crossRadius = 24F - val additionalSize = if (viewModel.debug) 96F else 0F + val additionalSize = if (debug) 96F else 0F val latLonSize = Size(196F, 96F + additionalSize) val latLonOffset = Offset(16F, 16F) @@ -124,7 +124,7 @@ fun MapCanvas( ) } - if (viewModel.debug) { + if (debug) { drawRect( color = gridColor, size = Size(TILE_SIZE, TILE_SIZE), @@ -175,7 +175,7 @@ fun MapCanvas( val lon = SphereMercator.mercateX(centerTileX, level) val lat = SphereMercator.mercateY(centerTileY, level) append("%.6f\n%.6f".format(lon, lat)) - if (viewModel.debug) { + if (debug) { append("\n%.0f\n%.0f".format(offsetX, offsetY)) } } diff --git a/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt b/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt index 5059504..ceb1e3f 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt @@ -1,13 +1,22 @@ package com.mirenkov.ktheightmap import android.app.Application +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.ViewModel class TileViewModel(application: Application): ViewModel() { val repository: TileRepository - var debug = false - var logRequested = false + + var debug = mutableStateOf(false) + var logRequested = mutableStateOf(false) + + var latitudeText = mutableStateOf(TextFieldValue("")) + var longitudeText = mutableStateOf(TextFieldValue("")) + + val mapOffsetX = mutableFloatStateOf(-646.65625F) + val mapOffsetY = mutableFloatStateOf(-1157.2814F) init { val tileDb = TileDB.getInstance(application)