Set location dialog prefab and proper ViewModel handling
This commit is contained in:
parent
8bdbe3dc69
commit
2937f17a69
3 changed files with 92 additions and 20 deletions
|
|
@ -3,18 +3,22 @@ package com.mirenkov.ktheightmap
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.offset
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Build
|
import androidx.compose.material.icons.filled.Build
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
|
|
@ -23,7 +27,10 @@ import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Slider
|
import androidx.compose.material3.Slider
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
|
@ -35,7 +42,8 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.platform.LocalContext
|
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.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
|
@ -79,8 +87,6 @@ class MainActivity : ComponentActivity() {
|
||||||
@Composable
|
@Composable
|
||||||
fun Main(vm: TileViewModel = viewModel()) {
|
fun Main(vm: TileViewModel = viewModel()) {
|
||||||
val sliderValue = rememberSaveable { mutableFloatStateOf(1F) }
|
val sliderValue = rememberSaveable { mutableFloatStateOf(1F) }
|
||||||
val canvasOffsetX = rememberSaveable { mutableFloatStateOf(-652.0647F) }
|
|
||||||
val canvasOffsetY = rememberSaveable { mutableFloatStateOf(-1145.693F) }
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val tileContainer = TileContainer(vm, coroutineScope)
|
val tileContainer = TileContainer(vm, coroutineScope)
|
||||||
KtHeightMapTheme {
|
KtHeightMapTheme {
|
||||||
|
|
@ -97,8 +103,6 @@ fun Main(vm: TileViewModel = viewModel()) {
|
||||||
backColor = colorScheme.background,
|
backColor = colorScheme.background,
|
||||||
scale = sliderValue,
|
scale = sliderValue,
|
||||||
tileContainer = tileContainer,
|
tileContainer = tileContainer,
|
||||||
offsetX = canvasOffsetX,
|
|
||||||
offsetY = canvasOffsetY,
|
|
||||||
modifier = Modifier.padding(innerPadding),
|
modifier = Modifier.padding(innerPadding),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +126,10 @@ fun Main(vm: TileViewModel = viewModel()) {
|
||||||
@Composable
|
@Composable
|
||||||
fun ToolButton(viewModel: TileViewModel) {
|
fun ToolButton(viewModel: TileViewModel) {
|
||||||
val context = LocalContext.current
|
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(
|
FloatingActionButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
expanded = !expanded
|
expanded = !expanded
|
||||||
|
|
@ -135,23 +142,79 @@ fun ToolButton(viewModel: TileViewModel) {
|
||||||
) {
|
) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text("Toggle debug") },
|
text = { Text("Toggle debug") },
|
||||||
onClick = { viewModel.debug = !viewModel.debug }
|
onClick = {
|
||||||
|
debug = !debug
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text("Log") },
|
text = { Text("Log") },
|
||||||
onClick = { viewModel.logRequested = true }
|
onClick = {
|
||||||
|
logRequested = true
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text("Set location") },
|
text = { Text("Set location") },
|
||||||
onClick = {}
|
onClick = {
|
||||||
|
expanded = false
|
||||||
|
dialogShown.value = true
|
||||||
|
}
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text("Settings") },
|
text = { Text("Settings") },
|
||||||
onClick = {
|
onClick = {
|
||||||
|
expanded = false
|
||||||
val intent = Intent(context, SettingsActivity::class.java)
|
val intent = Intent(context, SettingsActivity::class.java)
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
SetLocationDialog(viewModel, dialogShown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SetLocationDialog(vm: TileViewModel, dialogShown: MutableState<Boolean>) {
|
||||||
|
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())
|
||||||
|
} }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,15 +34,15 @@ fun MapCanvas(
|
||||||
backColor: Color,
|
backColor: Color,
|
||||||
gridColor: Color,
|
gridColor: Color,
|
||||||
scale: MutableFloatState,
|
scale: MutableFloatState,
|
||||||
offsetX: MutableFloatState,
|
|
||||||
offsetY: MutableFloatState,
|
|
||||||
tileContainer: TileContainer,
|
tileContainer: TileContainer,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
var offsetX by rememberSaveable { offsetX }
|
var offsetX by rememberSaveable { viewModel.mapOffsetX }
|
||||||
var offsetY by rememberSaveable { offsetY }
|
var offsetY by rememberSaveable { viewModel.mapOffsetY }
|
||||||
val scale by rememberSaveable { scale }
|
val scale by rememberSaveable { scale }
|
||||||
val textMeasurer = rememberTextMeasurer()
|
val textMeasurer = rememberTextMeasurer()
|
||||||
|
val debug by rememberSaveable { viewModel.debug }
|
||||||
|
var logRequested by rememberSaveable { viewModel.logRequested }
|
||||||
Canvas(
|
Canvas(
|
||||||
modifier = modifier.fillMaxSize()
|
modifier = modifier.fillMaxSize()
|
||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
|
|
@ -57,9 +57,9 @@ fun MapCanvas(
|
||||||
size = size
|
size = size
|
||||||
)
|
)
|
||||||
|
|
||||||
if (viewModel.logRequested) {
|
if (logRequested) {
|
||||||
Log.i(TAG, "Offset: %.6f, %.6f".format(offsetX, offsetY))
|
Log.i(TAG, "Offset: %.6f, %.6f".format(offsetX, offsetY))
|
||||||
viewModel.logRequested = false
|
logRequested = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val oldLevel = tileContainer.getLevel()
|
val oldLevel = tileContainer.getLevel()
|
||||||
|
|
@ -101,7 +101,7 @@ fun MapCanvas(
|
||||||
|
|
||||||
val crossRadius = 24F
|
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 latLonSize = Size(196F, 96F + additionalSize)
|
||||||
val latLonOffset = Offset(16F, 16F)
|
val latLonOffset = Offset(16F, 16F)
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ fun MapCanvas(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewModel.debug) {
|
if (debug) {
|
||||||
drawRect(
|
drawRect(
|
||||||
color = gridColor,
|
color = gridColor,
|
||||||
size = Size(TILE_SIZE, TILE_SIZE),
|
size = Size(TILE_SIZE, TILE_SIZE),
|
||||||
|
|
@ -175,7 +175,7 @@ fun MapCanvas(
|
||||||
val lon = SphereMercator.mercateX(centerTileX, level)
|
val lon = SphereMercator.mercateX(centerTileX, level)
|
||||||
val lat = SphereMercator.mercateY(centerTileY, level)
|
val lat = SphereMercator.mercateY(centerTileY, level)
|
||||||
append("%.6f\n%.6f".format(lon, lat))
|
append("%.6f\n%.6f".format(lon, lat))
|
||||||
if (viewModel.debug) {
|
if (debug) {
|
||||||
append("\n%.0f\n%.0f".format(offsetX, offsetY))
|
append("\n%.0f\n%.0f".format(offsetX, offsetY))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,22 @@
|
||||||
package com.mirenkov.ktheightmap
|
package com.mirenkov.ktheightmap
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
class TileViewModel(application: Application): ViewModel() {
|
class TileViewModel(application: Application): ViewModel() {
|
||||||
val repository: TileRepository
|
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 {
|
init {
|
||||||
val tileDb = TileDB.getInstance(application)
|
val tileDb = TileDB.getInstance(application)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue