From dea42ae4e5794a0d478e93f630ef1d71e04cf7f5 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Wed, 29 May 2024 14:31:14 +0200 Subject: [PATCH] Initial support of fling animation --- orion-viewer/build.gradle | 1 + .../viewer/selection/NewTouchProcessor.kt | 59 ++++++++++++++++++- .../orion/viewer/view/OrionDrawScene.kt | 3 + 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/orion-viewer/build.gradle b/orion-viewer/build.gradle index 4cc0d80e9..fdb15973e 100644 --- a/orion-viewer/build.gradle +++ b/orion-viewer/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation "androidx.multidex:multidex:2.0.1" implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7' implementation 'androidx.navigation:navigation-ui-ktx:2.7.7' + implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test:core:1.5.0' diff --git a/orion-viewer/src/main/java/universe/constellation/orion/viewer/selection/NewTouchProcessor.kt b/orion-viewer/src/main/java/universe/constellation/orion/viewer/selection/NewTouchProcessor.kt index a41f57324..2e4cd5503 100644 --- a/orion-viewer/src/main/java/universe/constellation/orion/viewer/selection/NewTouchProcessor.kt +++ b/orion-viewer/src/main/java/universe/constellation/orion/viewer/selection/NewTouchProcessor.kt @@ -1,10 +1,14 @@ package universe.constellation.orion.viewer.selection import android.graphics.Point -import androidx.core.view.GestureDetectorCompat import android.view.GestureDetector import android.view.MotionEvent -import universe.constellation.orion.viewer.* +import android.view.View +import androidx.core.view.GestureDetectorCompat +import androidx.dynamicanimation.animation.FlingAnimation +import androidx.dynamicanimation.animation.FloatPropertyCompat +import universe.constellation.orion.viewer.OrionViewerActivity +import universe.constellation.orion.viewer.log import universe.constellation.orion.viewer.view.OrionDrawScene enum class State { @@ -16,6 +20,29 @@ enum class State { open class NewTouchProcessor(val view: OrionDrawScene, val activity: OrionViewerActivity) : GestureDetector.SimpleOnGestureListener() { + val property = object : FloatPropertyCompat("doScroll") { + var prevValue = 0f + + override fun getValue(view2: View): Float { + return prevValue + } + + override fun setValue(view2: View, value: Float) { + val delta = prevValue - value + view.pageLayoutManager?.doScroll(0f, 0f, 0f, -delta) + prevValue = value + } + } + + private val flingAnim = + FlingAnimation( + view, + property + ) + .setMinValue(-20000f) + .setFriction(0.5f) + .setMaxValue(20000f) + private val detector = GestureDetectorCompat(activity, this) protected var state = State.UNDEFINED @@ -27,6 +54,8 @@ open class NewTouchProcessor(val view: OrionDrawScene, val activity: OrionViewer private val start0 = Point() private val last0 = Point() + private var isFlingActiveOnDown = false + init { detector.setIsLongpressEnabled(true) detector.setOnDoubleTapListener(this) @@ -74,10 +103,28 @@ open class NewTouchProcessor(val view: OrionDrawScene, val activity: OrionViewer } override fun onDown(e: MotionEvent): Boolean { + isFlingActiveOnDown = flingAnim.isRunning + if (isFlingActiveOnDown) { + flingAnim.cancel() + } + log("onDown") return true } + override fun onFling( + e1: MotionEvent?, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { + println("onFlingX $velocityY") + flingAnim.cancel() + flingAnim.setStartVelocity(velocityY) + flingAnim.start() + return true + } + override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { println("onScroll $enableTouchMove") if (!enableTouchMove) { @@ -89,6 +136,10 @@ open class NewTouchProcessor(val view: OrionDrawScene, val activity: OrionViewer } override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + if (isFlingActiveOnDown) { + return true + } + log("onSingleTapConfirmed") resetNextState() doAction(e.x.toInt(), e.y.toInt(), false) @@ -103,6 +154,10 @@ open class NewTouchProcessor(val view: OrionDrawScene, val activity: OrionViewer } override fun onLongPress(e: MotionEvent) { + if (isFlingActiveOnDown) { + return + } + log("onLongPress $state $nextState") if (state != State.UNDEFINED) return doAction(e.x.toInt(), e.y.toInt(), true) diff --git a/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/OrionDrawScene.kt b/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/OrionDrawScene.kt index 20ddfd13d..f34cc45ce 100644 --- a/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/OrionDrawScene.kt +++ b/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/OrionDrawScene.kt @@ -26,6 +26,7 @@ import android.graphics.PointF import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.View +import android.widget.Scroller import universe.constellation.orion.viewer.log import universe.constellation.orion.viewer.util.MoveUtil @@ -62,6 +63,8 @@ class OrionDrawScene : View { lateinit var stuff: ColorStuff + val scroller = Scroller(context) + constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet) : super(context, attrs)