From 5364ead170ff66e0a13fc435117e1ea04f4eb273 Mon Sep 17 00:00:00 2001 From: sulai <6741822+sulai@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:49:58 +0100 Subject: [PATCH] Add GoogleMaps-like pinching (#12765) Co-authored-by: mrimvo <6030346+mrimvo@users.noreply.github.com> --- .../ui/components/ZoomGestureListener.kt | 27 +++++++++++-------- .../components/widgets/ZoomableScrollPane.kt | 9 ++++--- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/src/com/unciv/ui/components/ZoomGestureListener.kt b/core/src/com/unciv/ui/components/ZoomGestureListener.kt index ae0faadb3274f..3dde8e68bec65 100644 --- a/core/src/com/unciv/ui/components/ZoomGestureListener.kt +++ b/core/src/com/unciv/ui/components/ZoomGestureListener.kt @@ -9,8 +9,8 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent open class ZoomGestureListener( halfTapSquareSize: Float, tapCountInterval: Float, longPressDuration: Float, maxFlingDelay: Float ) : EventListener { - val detector: GestureDetector - var event: InputEvent? = null + + private val detector: GestureDetector constructor() : this(20f, 0.4f, 1.1f, Int.MAX_VALUE.toFloat()) @@ -22,22 +22,29 @@ open class ZoomGestureListener( maxFlingDelay, object : GestureDetector.GestureAdapter() { - override fun zoom(initialDistance: Float, distance: Float): Boolean { - this@ZoomGestureListener.zoom(initialDistance, distance) - return true - } - + private var pinchCenter: Vector2? = null + private var initialDistance = 0f + override fun pinch( stageInitialPointer1: Vector2, stageInitialPointer2: Vector2, stagePointer1: Vector2, stagePointer2: Vector2 ): Boolean { - this@ZoomGestureListener.pinch() + if (pinchCenter == null) { + pinchCenter = stageInitialPointer1.cpy().add(stageInitialPointer2).scl(.5f) + initialDistance = stageInitialPointer1.dst(stageInitialPointer2) + } + val currentCenter = stagePointer1.cpy().add(stagePointer2).scl(.5f) + val delta = currentCenter.cpy().sub(pinchCenter) + pinchCenter = currentCenter.cpy() + this@ZoomGestureListener.pinch(delta) + this@ZoomGestureListener.zoom(initialDistance, stagePointer1.dst(stagePointer2)) return true } override fun pinchStop() { + pinchCenter = null this@ZoomGestureListener.pinchStop() } }) @@ -61,12 +68,10 @@ open class ZoomGestureListener( detector.reset() return false } - this.event = event detector.touchUp(event.stageX, event.stageY, event.pointer, event.button) return true } InputEvent.Type.touchDragged -> { - this.event = event detector.touchDragged(event.stageX, event.stageY, event.pointer) return true } @@ -79,6 +84,6 @@ open class ZoomGestureListener( open fun scrolled(amountX: Float, amountY: Float): Boolean { return false } open fun zoom(initialDistance: Float, distance: Float) {} - open fun pinch() {} + open fun pinch(delta: Vector2) {} open fun pinchStop() {} } diff --git a/core/src/com/unciv/ui/components/widgets/ZoomableScrollPane.kt b/core/src/com/unciv/ui/components/widgets/ZoomableScrollPane.kt index 3853f884963cd..073fe79e040da 100644 --- a/core/src/com/unciv/ui/components/widgets/ZoomableScrollPane.kt +++ b/core/src/com/unciv/ui/components/widgets/ZoomableScrollPane.kt @@ -246,11 +246,16 @@ open class ZoomableScrollPane( } } - override fun pinch() { + override fun pinch(delta: Vector2) { if (!isZooming) { isZooming = true onZoomStartListener?.invoke() } + scrollTo( + scrollX - delta.x, + scrollY + delta.y, + true + ) } override fun pinchStop() { @@ -317,8 +322,6 @@ open class ZoomableScrollPane( //clamp() call is missing here but it doesn't seem to make any big difference in this case - if ((isScrollX && deltaX != 0f || isScrollY && deltaY != 0f)) - cancelTouchFocus() } override fun panStop(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {