diff --git a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/CameraManager.kt b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/CameraManager.kt index 99468c0c31..b21d622cb4 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/CameraManager.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/CameraManager.kt @@ -21,6 +21,7 @@ import de.westnordost.streetcomplete.data.osm.mapdata.LatLon import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds import de.westnordost.streetcomplete.util.ktx.runImmediate import kotlin.math.PI +import kotlin.math.min /** * Controls the camera of a Tangram MapController. Use in place of the @@ -68,6 +69,8 @@ class CameraManager(private val c: MapController, private val contentResolver: C val isAnimating: Boolean get() = lastAnimator != null + var maximumTilt: Float = PI.toFloat() / 6f // 60° + interface AnimationsListener { @UiThread fun onAnimationsStarted() @UiThread fun onAnimating() @@ -115,7 +118,7 @@ class CameraManager(private val c: MapController, private val contentResolver: C _tangramCamera.longitude = it.longitude } update.rotation?.let { _tangramCamera.rotation = it } - update.tilt?.let { _tangramCamera.tilt = it } + update.tilt?.let { _tangramCamera.tilt = min(it, maximumTilt) } update.zoom?.let { _tangramCamera.zoom = it } pushCameraPositionToController() } @@ -133,7 +136,8 @@ class CameraManager(private val c: MapController, private val contentResolver: C assignAnimation("rotation", animator) } update.tilt?.let { - propValues.add(PropertyValuesHolder.ofFloat(TangramTiltProperty, it)) + val tilt = min(it, maximumTilt) + propValues.add(PropertyValuesHolder.ofFloat(TangramTiltProperty, tilt)) assignAnimation("tilt", animator) } update.zoom?.let { diff --git a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/KtMapController.kt b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/KtMapController.kt index 4e8211e7b8..90cc13e0f0 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/KtMapController.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/KtMapController.kt @@ -40,6 +40,7 @@ import java.util.concurrent.ConcurrentLinkedQueue import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException +import kotlin.math.PI import kotlin.math.log10 import kotlin.math.max import kotlin.math.min @@ -207,6 +208,12 @@ class KtMapController(private val c: MapController, contentResolver: ContentReso set(value) { c.maximumZoomLevel = value } get() = c.maximumZoomLevel + var maximumTilt: Float + set(value) { + cameraManager.maximumTilt = value + } + get() = cameraManager.maximumTilt + fun screenPositionToLatLon(screenPosition: PointF): LatLon? = c.screenPositionToLngLat(screenPosition)?.toLatLon() fun latLonToScreenPosition(latLon: LatLon): PointF = c.lngLatToScreenPosition(latLon.toLngLat()) fun latLonToScreenPosition(latLon: LatLon, screenPositionOut: PointF, clipToViewport: Boolean) = @@ -329,7 +336,18 @@ class KtMapController(private val c: MapController, contentResolver: ContentReso /* -------------------------------------- Touch input --------------------------------------- */ - fun setShoveResponder(responder: TouchInput.ShoveResponder?) { gestureManager.setShoveResponder(responder) } + fun setShoveResponder(responder: TouchInput.ShoveResponder?) { + // enforce maximum tilt + gestureManager.setShoveResponder(object : TouchInput.ShoveResponder { + override fun onShoveBegin() = responder?.onShoveBegin() ?: false + override fun onShoveEnd() = responder?.onShoveEnd() ?: false + + override fun onShove(distance: Float): Boolean { + if (cameraPosition.tilt >= maximumTilt && distance < 0) return true + return responder?.onShove(distance) ?: false + } + }) + } fun setScaleResponder(responder: TouchInput.ScaleResponder?) { gestureManager.setScaleResponder(responder) } fun setRotateResponder(responder: TouchInput.RotateResponder?) { gestureManager.setRotateResponder(responder) } fun setPanResponder(responder: TouchInput.PanResponder?) { gestureManager.setPanResponder(responder) }