react-native-gesture-handler 2.32.0 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +27 -11
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +32 -33
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +144 -15
- package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +6 -3
- package/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt +23 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +4 -7
- package/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/react/Extensions.kt +3 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +2 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +9 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +8 -6
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt +2 -7
- package/apple/Handlers/RNFlingHandler.m +44 -4
- package/apple/Handlers/RNHoverHandler.m +24 -26
- package/apple/Handlers/RNLongPressHandler.m +4 -0
- package/apple/Handlers/RNPanHandler.m +44 -7
- package/apple/Handlers/RNTapHandler.m +35 -4
- package/apple/RNGHUIKit.h +10 -10
- package/apple/RNGestureHandler.h +2 -0
- package/apple/RNGestureHandler.mm +47 -6
- package/apple/RNGestureHandlerButton.mm +5 -3
- package/apple/RNGestureHandlerManager.mm +63 -6
- package/apple/RNGestureHandlerModule.mm +20 -0
- package/apple/RNGestureHandlerPointerTracker.m +64 -10
- package/apple/RNGestureHandlerPointerType.h +1 -0
- package/apple/RNManualActivationRecognizer.m +25 -6
- package/lib/commonjs/components/GestureComponents.js +21 -1
- package/lib/commonjs/components/GestureComponents.js.map +1 -1
- package/lib/commonjs/components/GestureHandlerButton.web.js +2 -1
- package/lib/commonjs/components/GestureHandlerButton.web.js.map +1 -1
- package/lib/commonjs/components/Pressable/Pressable.js +28 -3
- package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
- package/lib/commonjs/components/Pressable/index.js.map +1 -1
- package/lib/commonjs/components/ReanimatedDrawerLayout.js +4 -2
- package/lib/commonjs/components/ReanimatedDrawerLayout.js.map +1 -1
- package/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js +32 -9
- package/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
- package/lib/commonjs/components/Swipeable.js.map +1 -1
- package/lib/commonjs/components/Text.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableHighlight.js +1 -1
- package/lib/commonjs/components/touchables/TouchableHighlight.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableNativeFeedback.android.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableOpacity.js +1 -0
- package/lib/commonjs/components/touchables/TouchableOpacity.js.map +1 -1
- package/lib/commonjs/getShadowNodeFromRef.js +6 -2
- package/lib/commonjs/getShadowNodeFromRef.js.map +1 -1
- package/lib/commonjs/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.js +56 -11
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js +2 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useMountReactions.js +6 -0
- package/lib/commonjs/handlers/gestures/GestureDetector/useMountReactions.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js +3 -2
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gestureStateManager.web.js.map +1 -1
- package/lib/commonjs/handlers/gestures/panGesture.js +6 -3
- package/lib/commonjs/handlers/gestures/panGesture.js.map +1 -1
- package/lib/commonjs/hostInstance.js +39 -0
- package/lib/commonjs/hostInstance.js.map +1 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/mocks/mocks.js +1 -0
- package/lib/commonjs/mocks/mocks.js.map +1 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
- package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
- package/lib/commonjs/web/detectors/RotationGestureDetector.js +1 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js +3 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +9 -1
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js +8 -9
- package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/TapGestureHandler.js +1 -1
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +14 -0
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/commonjs/web/tools/WheelEventManager.js +4 -0
- package/lib/commonjs/web/tools/WheelEventManager.js.map +1 -1
- package/lib/module/components/GestureComponents.js +23 -2
- package/lib/module/components/GestureComponents.js.map +1 -1
- package/lib/module/components/GestureHandlerButton.web.js +2 -1
- package/lib/module/components/GestureHandlerButton.web.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +28 -3
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/Pressable/index.js.map +1 -1
- package/lib/module/components/ReanimatedDrawerLayout.js +4 -2
- package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -1
- package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +34 -11
- package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/components/Swipeable.js.map +1 -1
- package/lib/module/components/Text.js.map +1 -1
- package/lib/module/components/touchables/TouchableHighlight.js +2 -2
- package/lib/module/components/touchables/TouchableHighlight.js.map +1 -1
- package/lib/module/components/touchables/TouchableNativeFeedback.android.js.map +1 -1
- package/lib/module/components/touchables/TouchableOpacity.js +1 -0
- package/lib/module/components/touchables/TouchableOpacity.js.map +1 -1
- package/lib/module/getShadowNodeFromRef.js +7 -2
- package/lib/module/getShadowNodeFromRef.js.map +1 -1
- package/lib/module/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/Wrap.js +56 -11
- package/lib/module/handlers/gestures/GestureDetector/Wrap.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/index.js +2 -1
- package/lib/module/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useMountReactions.js +6 -0
- package/lib/module/handlers/gestures/GestureDetector/useMountReactions.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js +3 -2
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/module/handlers/gestures/gestureStateManager.web.js.map +1 -1
- package/lib/module/handlers/gestures/panGesture.js +6 -3
- package/lib/module/handlers/gestures/panGesture.js.map +1 -1
- package/lib/module/hostInstance.js +32 -0
- package/lib/module/hostInstance.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/mocks.js +3 -2
- package/lib/module/mocks/mocks.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
- package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
- package/lib/module/web/detectors/RotationGestureDetector.js +1 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js +3 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/NativeViewGestureHandler.js +9 -1
- package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/PanGestureHandler.js +8 -9
- package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/TapGestureHandler.js +1 -1
- package/lib/module/web/tools/GestureHandlerOrchestrator.js +14 -0
- package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/module/web/tools/WheelEventManager.js +4 -0
- package/lib/module/web/tools/WheelEventManager.js.map +1 -1
- package/lib/typescript/components/GestureButtons.d.ts +3 -1
- package/lib/typescript/components/GestureButtons.d.ts.map +1 -1
- package/lib/typescript/components/GestureButtonsProps.d.ts +10 -0
- package/lib/typescript/components/GestureButtonsProps.d.ts.map +1 -1
- package/lib/typescript/components/GestureComponents.d.ts +8 -7
- package/lib/typescript/components/GestureComponents.d.ts.map +1 -1
- package/lib/typescript/components/GestureComponents.web.d.ts +12 -4
- package/lib/typescript/components/GestureComponents.web.d.ts.map +1 -1
- package/lib/typescript/components/GestureHandlerButton.web.d.ts +2 -2
- package/lib/typescript/components/GestureHandlerButton.web.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/Pressable.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/PressableProps.d.ts +1 -1
- package/lib/typescript/components/Pressable/PressableProps.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/index.d.ts +1 -1
- package/lib/typescript/components/Pressable/index.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedDrawerLayout.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts.map +1 -1
- package/lib/typescript/components/Swipeable.d.ts.map +1 -1
- package/lib/typescript/components/touchables/TouchableHighlight.d.ts +1 -1
- package/lib/typescript/components/touchables/TouchableHighlight.d.ts.map +1 -1
- package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts +1 -1
- package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts.map +1 -1
- package/lib/typescript/components/touchables/TouchableOpacity.d.ts.map +1 -1
- package/lib/typescript/getShadowNodeFromRef.d.ts.map +1 -1
- package/lib/typescript/handlers/PanGestureHandler.d.ts +12 -0
- package/lib/typescript/handlers/PanGestureHandler.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/Wrap.d.ts +11 -0
- package/lib/typescript/handlers/gestures/GestureDetector/Wrap.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/index.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useDetectorUpdater.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useMountReactions.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useViewRefHandler.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts +8 -1
- package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/panGesture.d.ts +6 -3
- package/lib/typescript/handlers/gestures/panGesture.d.ts.map +1 -1
- package/lib/typescript/hostInstance.d.ts +10 -0
- package/lib/typescript/hostInstance.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/mocks/mocks.d.ts +67 -15
- package/lib/typescript/mocks/mocks.d.ts.map +1 -1
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +6 -7
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts.map +1 -1
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +9 -10
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts.map +1 -1
- package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +2 -2
- package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts.map +1 -1
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts.map +1 -1
- package/lib/typescript/web/handlers/PanGestureHandler.d.ts.map +1 -1
- package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +1 -0
- package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts.map +1 -1
- package/lib/typescript/web/tools/WheelEventManager.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/components/GestureButtonsProps.ts +14 -0
- package/src/components/GestureComponents.tsx +38 -7
- package/src/components/GestureHandlerButton.web.tsx +7 -3
- package/src/components/Pressable/Pressable.tsx +33 -4
- package/src/components/Pressable/PressableProps.tsx +1 -1
- package/src/components/Pressable/index.ts +1 -0
- package/src/components/ReanimatedDrawerLayout.tsx +4 -1
- package/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +49 -10
- package/src/components/Swipeable.tsx +6 -2
- package/src/components/Text.tsx +3 -3
- package/src/components/touchables/TouchableHighlight.tsx +4 -2
- package/src/components/touchables/TouchableNativeFeedback.android.tsx +8 -2
- package/src/components/touchables/TouchableOpacity.tsx +1 -0
- package/src/getShadowNodeFromRef.ts +11 -4
- package/src/handlers/PanGestureHandler.ts +15 -0
- package/src/handlers/gestures/GestureDetector/Wrap.tsx +78 -13
- package/src/handlers/gestures/GestureDetector/index.tsx +4 -1
- package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +4 -1
- package/src/handlers/gestures/GestureDetector/useMountReactions.ts +6 -0
- package/src/handlers/gestures/GestureDetector/useViewRefHandler.ts +5 -2
- package/src/handlers/gestures/gestureStateManager.web.ts +9 -1
- package/src/handlers/gestures/panGesture.ts +6 -3
- package/src/hostInstance.ts +57 -0
- package/src/index.ts +1 -0
- package/src/mocks/mocks.tsx +6 -2
- package/src/specs/NativeRNGestureHandlerModule.ts +16 -10
- package/src/specs/RNGestureHandlerButtonNativeComponent.ts +16 -14
- package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +3 -3
- package/src/web/detectors/RotationGestureDetector.ts +1 -1
- package/src/web/handlers/LongPressGestureHandler.ts +3 -1
- package/src/web/handlers/NativeViewGestureHandler.ts +11 -2
- package/src/web/handlers/PanGestureHandler.ts +8 -11
- package/src/web/handlers/TapGestureHandler.ts +1 -1
- package/src/web/tools/GestureHandlerOrchestrator.ts +19 -0
- package/src/web/tools/WheelEventManager.ts +1 -0
package/android/build.gradle
CHANGED
|
@@ -2,17 +2,18 @@ import groovy.json.JsonSlurper
|
|
|
2
2
|
import com.android.build.gradle.tasks.ExternalNativeBuildJsonTask
|
|
3
3
|
|
|
4
4
|
buildscript {
|
|
5
|
-
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['RNGH_kotlinVersion']
|
|
6
|
-
|
|
7
5
|
repositories {
|
|
8
6
|
mavenCentral()
|
|
9
7
|
google()
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
dependencies {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
if (project == rootProject) {
|
|
12
|
+
def kotlin_version = project.properties['RNGH_kotlinVersion']
|
|
13
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
|
|
14
|
+
classpath("com.android.tools.build:gradle:8.10.1")
|
|
15
|
+
classpath("com.diffplug.spotless:spotless-plugin-gradle:7.0.4")
|
|
16
|
+
}
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -62,7 +63,22 @@ if (isNewArchitectureEnabled()) {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
apply plugin: 'com.android.library'
|
|
65
|
-
|
|
66
|
+
|
|
67
|
+
def shouldEnableAgpFallback() {
|
|
68
|
+
def agpMajorVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()
|
|
69
|
+
if (agpMajorVersion <= 8) {
|
|
70
|
+
return true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
def propertyVal = providers.gradleProperty("android.builtInKotlin").orNull
|
|
74
|
+
def isBuiltInKotlinEnabled = propertyVal != null ? propertyVal.toBoolean() : true
|
|
75
|
+
|
|
76
|
+
return !isBuiltInKotlinEnabled
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (shouldEnableAgpFallback()) {
|
|
80
|
+
apply plugin: 'kotlin-android'
|
|
81
|
+
}
|
|
66
82
|
|
|
67
83
|
if (project == rootProject) {
|
|
68
84
|
apply from: "spotless.gradle"
|
|
@@ -190,17 +206,17 @@ android {
|
|
|
190
206
|
}
|
|
191
207
|
|
|
192
208
|
sourceSets.main {
|
|
193
|
-
|
|
209
|
+
kotlin {
|
|
194
210
|
if (shouldUseCommonInterfaceFromReanimated()) {
|
|
195
|
-
|
|
211
|
+
directories.add('reanimated/src/main/java')
|
|
196
212
|
} else {
|
|
197
|
-
|
|
213
|
+
directories.add('noreanimated/src/main/java')
|
|
198
214
|
}
|
|
199
215
|
|
|
200
216
|
if (shouldUseCommonInterfaceFromRNSVG()) {
|
|
201
|
-
|
|
217
|
+
directories.add('svg/src/main/java')
|
|
202
218
|
} else {
|
|
203
|
-
|
|
219
|
+
directories.add('nosvg/src/main/java')
|
|
204
220
|
}
|
|
205
221
|
|
|
206
222
|
if (isNewArchitectureEnabled()) {
|
|
@@ -16,4 +16,4 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemor
|
|
|
16
16
|
# This option should only be used with decoupled projects. More details, visit
|
|
17
17
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
18
18
|
# org.gradle.parallel=true
|
|
19
|
-
RNGH_kotlinVersion=2.0
|
|
19
|
+
RNGH_kotlinVersion=2.2.0
|
|
@@ -4,7 +4,6 @@ import android.app.Activity
|
|
|
4
4
|
import android.content.Context
|
|
5
5
|
import android.content.ContextWrapper
|
|
6
6
|
import android.graphics.PointF
|
|
7
|
-
import android.os.Build
|
|
8
7
|
import android.view.MotionEvent
|
|
9
8
|
import android.view.MotionEvent.PointerCoords
|
|
10
9
|
import android.view.MotionEvent.PointerProperties
|
|
@@ -426,10 +425,15 @@ open class GestureHandler {
|
|
|
426
425
|
}
|
|
427
426
|
|
|
428
427
|
private fun dispatchTouchUpEvent(event: MotionEvent, sourceEvent: MotionEvent) {
|
|
428
|
+
val pointerId = event.getPointerId(event.actionIndex)
|
|
429
|
+
|
|
430
|
+
if (trackedPointers[pointerId] == null) {
|
|
431
|
+
return
|
|
432
|
+
}
|
|
433
|
+
|
|
429
434
|
extractAllPointersData()
|
|
430
435
|
changedTouchesPayload = null
|
|
431
436
|
touchEventType = RNGestureHandlerTouchEvent.EVENT_TOUCH_UP
|
|
432
|
-
val pointerId = event.getPointerId(event.actionIndex)
|
|
433
437
|
val offsetX = sourceEvent.rawX - sourceEvent.x
|
|
434
438
|
val offsetY = sourceEvent.rawY - sourceEvent.y
|
|
435
439
|
|
|
@@ -754,44 +758,38 @@ open class GestureHandler {
|
|
|
754
758
|
return clickedButton and mouseButton != 0
|
|
755
759
|
}
|
|
756
760
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
761
|
+
// Decides whether the gesture should ignore this event. While using a mouse we receive both the
|
|
762
|
+
// touch-compatible stream (ACTION_DOWN/UP/...) and the BUTTON_* events, so we act on only the
|
|
763
|
+
// latter, and we drop events coming from a button other than the configured `mouseButton`.
|
|
764
|
+
// Non-mouse input is never skipped here.
|
|
765
|
+
protected fun shouldSkipEvent(sourceEvent: MotionEvent): Boolean {
|
|
766
|
+
if (sourceEvent.getToolType(0) != MotionEvent.TOOL_TYPE_MOUSE) {
|
|
767
|
+
return false
|
|
768
|
+
}
|
|
760
769
|
|
|
761
770
|
with(sourceEvent) {
|
|
762
|
-
//
|
|
763
|
-
if (
|
|
764
|
-
|
|
771
|
+
// While using mouse, we want to ignore default events for touch.
|
|
772
|
+
if (actionMasked == MotionEvent.ACTION_DOWN ||
|
|
773
|
+
actionMasked == MotionEvent.ACTION_UP ||
|
|
774
|
+
actionMasked == MotionEvent.ACTION_POINTER_UP ||
|
|
775
|
+
actionMasked == MotionEvent.ACTION_POINTER_DOWN
|
|
765
776
|
) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
action == MotionEvent.ACTION_UP ||
|
|
769
|
-
action == MotionEvent.ACTION_POINTER_UP ||
|
|
770
|
-
action == MotionEvent.ACTION_POINTER_DOWN
|
|
771
|
-
) {
|
|
772
|
-
return@shouldActivateWithMouse false
|
|
773
|
-
}
|
|
777
|
+
return@shouldSkipEvent true
|
|
778
|
+
}
|
|
774
779
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
780
|
+
// Skip events from a button other than the configured one. For BUTTON_* events the clicked
|
|
781
|
+
// button is read from `actionButton`.
|
|
782
|
+
if (actionMasked != MotionEvent.ACTION_MOVE && !isButtonInConfig(actionButton)) {
|
|
783
|
+
return@shouldSkipEvent true
|
|
784
|
+
}
|
|
779
785
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
}
|
|
784
|
-
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
785
|
-
// We do not fully support mouse below API 23, so we will ignore BUTTON events.
|
|
786
|
-
if (action == MotionEvent.ACTION_BUTTON_PRESS ||
|
|
787
|
-
action == MotionEvent.ACTION_BUTTON_RELEASE
|
|
788
|
-
) {
|
|
789
|
-
return@shouldActivateWithMouse false
|
|
790
|
-
}
|
|
786
|
+
// For ACTION_MOVE the pressed button is read from `buttonState`.
|
|
787
|
+
if (actionMasked == MotionEvent.ACTION_MOVE && !isButtonInConfig(buttonState)) {
|
|
788
|
+
return@shouldSkipEvent true
|
|
791
789
|
}
|
|
792
790
|
}
|
|
793
791
|
|
|
794
|
-
return
|
|
792
|
+
return false
|
|
795
793
|
}
|
|
796
794
|
|
|
797
795
|
/**
|
|
@@ -984,7 +982,8 @@ open class GestureHandler {
|
|
|
984
982
|
const val POINTER_TYPE_TOUCH = 0
|
|
985
983
|
const val POINTER_TYPE_STYLUS = 1
|
|
986
984
|
const val POINTER_TYPE_MOUSE = 2
|
|
987
|
-
const val
|
|
985
|
+
const val POINTER_TYPE_KEY = 3
|
|
986
|
+
const val POINTER_TYPE_OTHER = 4
|
|
988
987
|
private const val MAX_POINTERS_COUNT = 12
|
|
989
988
|
private lateinit var pointerProps: Array<PointerProperties?>
|
|
990
989
|
private lateinit var pointerCoords: Array<PointerCoords?>
|
package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt
CHANGED
|
@@ -2,6 +2,7 @@ package com.swmansion.gesturehandler.core
|
|
|
2
2
|
|
|
3
3
|
import android.graphics.Matrix
|
|
4
4
|
import android.graphics.PointF
|
|
5
|
+
import android.util.SparseArray
|
|
5
6
|
import android.view.MotionEvent
|
|
6
7
|
import android.view.View
|
|
7
8
|
import android.view.ViewGroup
|
|
@@ -26,7 +27,20 @@ class GestureHandlerOrchestrator(
|
|
|
26
27
|
var minimumAlphaForTraversal = DEFAULT_MIN_ALPHA_FOR_TRAVERSAL
|
|
27
28
|
private val gestureHandlers = arrayListOf<GestureHandler>()
|
|
28
29
|
private val awaitingHandlers = arrayListOf<GestureHandler>()
|
|
29
|
-
|
|
30
|
+
|
|
31
|
+
// Pool of reusable lists for snapshotting `gestureHandlers` during event delivery.
|
|
32
|
+
private val handlerListPool = ArrayDeque<ArrayList<GestureHandler>>()
|
|
33
|
+
|
|
34
|
+
private fun obtainHandlerList() = handlerListPool.pollLast() ?: ArrayList<GestureHandler>()
|
|
35
|
+
|
|
36
|
+
private fun recycleHandlerList(list: ArrayList<GestureHandler>) {
|
|
37
|
+
list.clear()
|
|
38
|
+
handlerListPool.addLast(list)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Used by `cancelTouchesInInterceptedViews`.
|
|
42
|
+
private val viewsToCancel = arrayListOf<View>()
|
|
43
|
+
private val pointerDownPoints = SparseArray<PointF>()
|
|
30
44
|
|
|
31
45
|
// In `onHandlerStateChange` method we iterate through `awaitingHandlers`, but calling `tryActivate` may modify this list.
|
|
32
46
|
// To avoid `ConcurrentModificationException` we iterate through copy. There is one more problem though - if handler was
|
|
@@ -46,6 +60,7 @@ class GestureHandlerOrchestrator(
|
|
|
46
60
|
fun onTouchEvent(event: MotionEvent): Boolean {
|
|
47
61
|
isHandlingTouch = true
|
|
48
62
|
val action = event.actionMasked
|
|
63
|
+
trackPointerDownPoints(event)
|
|
49
64
|
if (action == MotionEvent.ACTION_DOWN ||
|
|
50
65
|
action == MotionEvent.ACTION_POINTER_DOWN ||
|
|
51
66
|
action == MotionEvent.ACTION_HOVER_MOVE
|
|
@@ -105,7 +120,7 @@ class GestureHandlerOrchestrator(
|
|
|
105
120
|
|
|
106
121
|
private fun shouldBeCancelledByActiveHandler(handler: GestureHandler) = gestureHandlers.any {
|
|
107
122
|
handler.hasCommonPointers(it) &&
|
|
108
|
-
it.
|
|
123
|
+
it.isActive &&
|
|
109
124
|
!canRunSimultaneously(handler, it) &&
|
|
110
125
|
handler.isDescendantOf(it)
|
|
111
126
|
}
|
|
@@ -141,6 +156,13 @@ class GestureHandlerOrchestrator(
|
|
|
141
156
|
/*package*/
|
|
142
157
|
fun onHandlerStateChange(handler: GestureHandler, newState: Int, prevState: Int) {
|
|
143
158
|
handlingChangeSemaphore += 1
|
|
159
|
+
|
|
160
|
+
if (handler.isAwaiting &&
|
|
161
|
+
(newState == GestureHandler.STATE_CANCELLED || newState == GestureHandler.STATE_FAILED)
|
|
162
|
+
) {
|
|
163
|
+
handler.isAwaiting = false
|
|
164
|
+
}
|
|
165
|
+
|
|
144
166
|
if (isFinished(newState)) {
|
|
145
167
|
// We have to loop through copy in order to avoid modifying collection
|
|
146
168
|
// while iterating over its elements
|
|
@@ -252,20 +274,24 @@ class GestureHandlerOrchestrator(
|
|
|
252
274
|
}
|
|
253
275
|
|
|
254
276
|
private fun deliverEventToGestureHandlers(event: MotionEvent) {
|
|
255
|
-
//
|
|
256
|
-
// as a result of state updates
|
|
257
|
-
|
|
258
|
-
|
|
277
|
+
// Snapshot handlers into a pooled list, because the list of active handlers can change
|
|
278
|
+
// as a result of state updates (and delivery can be re-entrant).
|
|
279
|
+
val handlersToProcess = obtainHandlerList()
|
|
280
|
+
handlersToProcess.addAll(gestureHandlers)
|
|
259
281
|
|
|
260
282
|
// We want to deliver events to active handlers first in order of their activation (handlers
|
|
261
283
|
// that activated first will first get event delivered). Otherwise we deliver events in the
|
|
262
284
|
// order in which handlers has been added ("most direct" children goes first). Therefore we rely
|
|
263
285
|
// on Arrays.sort providing a stable sort (as children are registered in order in which they
|
|
264
286
|
// should be tested)
|
|
265
|
-
|
|
287
|
+
handlersToProcess.sortWith(handlersComparator)
|
|
266
288
|
|
|
267
|
-
|
|
268
|
-
|
|
289
|
+
try {
|
|
290
|
+
for (handler in handlersToProcess) {
|
|
291
|
+
deliverEventToGestureHandler(handler, event)
|
|
292
|
+
}
|
|
293
|
+
} finally {
|
|
294
|
+
recycleHandlerList(handlersToProcess)
|
|
269
295
|
}
|
|
270
296
|
}
|
|
271
297
|
|
|
@@ -276,12 +302,9 @@ class GestureHandlerOrchestrator(
|
|
|
276
302
|
handler.cancel()
|
|
277
303
|
}
|
|
278
304
|
|
|
279
|
-
//
|
|
305
|
+
// Iterate over a copy, because the list of active handlers can change
|
|
280
306
|
// as a result of state updates
|
|
281
|
-
|
|
282
|
-
preparedHandlers.addAll(gestureHandlers)
|
|
283
|
-
|
|
284
|
-
for (handler in gestureHandlers.asReversed()) {
|
|
307
|
+
for (handler in gestureHandlers.reversed()) {
|
|
285
308
|
handler.cancel()
|
|
286
309
|
}
|
|
287
310
|
}
|
|
@@ -314,7 +337,7 @@ class GestureHandlerOrchestrator(
|
|
|
314
337
|
if (!handler.isAwaiting || action != MotionEvent.ACTION_MOVE) {
|
|
315
338
|
val isFirstEvent = handler.state == 0
|
|
316
339
|
handler.handle(event, sourceEvent)
|
|
317
|
-
if (handler.isActive) {
|
|
340
|
+
if (handler.state == GestureHandler.STATE_ACTIVE && handler.isActive) {
|
|
318
341
|
// After handler is done waiting for other one to fail its progress should be
|
|
319
342
|
// reset, otherwise there may be a visible jump in values sent by the handler.
|
|
320
343
|
// When handler is waiting it's already activated but the `isAwaiting` flag
|
|
@@ -622,6 +645,112 @@ class GestureHandlerOrchestrator(
|
|
|
622
645
|
return false
|
|
623
646
|
}
|
|
624
647
|
|
|
648
|
+
private fun trackPointerDownPoints(event: MotionEvent) {
|
|
649
|
+
val index = event.actionIndex
|
|
650
|
+
when (event.actionMasked) {
|
|
651
|
+
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN ->
|
|
652
|
+
pointerDownPoints.put(event.getPointerId(index), PointF(event.getX(index), event.getY(index)))
|
|
653
|
+
MotionEvent.ACTION_POINTER_UP ->
|
|
654
|
+
pointerDownPoints.remove(event.getPointerId(index))
|
|
655
|
+
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL ->
|
|
656
|
+
pointerDownPoints.clear()
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
fun cancelTouchesInInterceptedViews(event: MotionEvent) {
|
|
661
|
+
viewsToCancel.clear()
|
|
662
|
+
for (i in 0 until pointerDownPoints.size()) {
|
|
663
|
+
val point = pointerDownPoints.valueAt(i)
|
|
664
|
+
tempCoords[0] = point.x
|
|
665
|
+
tempCoords[1] = point.y
|
|
666
|
+
collectViewsAtPoint(wrapperView, tempCoords, viewsToCancel)
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (viewsToCancel.isEmpty()) {
|
|
670
|
+
return
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
val activeHandlers = gestureHandlers.filter { it.isActive }
|
|
674
|
+
val cancelEvent = MotionEvent.obtain(event).apply { action = MotionEvent.ACTION_CANCEL }
|
|
675
|
+
|
|
676
|
+
for (view in viewsToCancel) {
|
|
677
|
+
if (view === wrapperView || isViewDrivenByActiveNativeGesture(view, activeHandlers)) {
|
|
678
|
+
continue
|
|
679
|
+
}
|
|
680
|
+
view.onTouchEvent(cancelEvent)
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
cancelEvent.recycle()
|
|
684
|
+
viewsToCancel.clear()
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Whether the view's touch is still owned by a NativeViewGestureHandler that survived arbitration.
|
|
688
|
+
// Only those are fed through `onTouchEvent`, so only those break if cancelled. Other handlers are
|
|
689
|
+
// orchestrator-driven and unaffected.
|
|
690
|
+
private fun isViewDrivenByActiveNativeGesture(view: View, activeHandlers: List<GestureHandler>) =
|
|
691
|
+
handlerRegistry.getHandlersForView(view)?.let { handlers ->
|
|
692
|
+
synchronized(handlers) {
|
|
693
|
+
handlers.any { nativeGestureSurvivesArbitration(it, activeHandlers) }
|
|
694
|
+
}
|
|
695
|
+
} ?: false
|
|
696
|
+
|
|
697
|
+
// A native handler survives arbitration if it is active, or it does not conflict with any active handler.
|
|
698
|
+
private fun nativeGestureSurvivesArbitration(handler: GestureHandler, activeHandlers: List<GestureHandler>) =
|
|
699
|
+
handler is NativeViewGestureHandler &&
|
|
700
|
+
(handler.isActive || activeHandlers.none { shouldHandlerBeCancelledBy(handler, it) })
|
|
701
|
+
|
|
702
|
+
// Collects the view path under the point (topmost child first, like touch dispatch), leaf to root.
|
|
703
|
+
private fun collectViewsAtPoint(view: View, coords: FloatArray, out: MutableList<View>): Boolean {
|
|
704
|
+
if (shouldIgnoreSubtreeIfGestureHandlerRootView(view)) {
|
|
705
|
+
// A nested active root view manages its own subtree (and its own interception cancellation).
|
|
706
|
+
return false
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
val pointerEvents = viewConfigHelper.getPointerEventsConfigForView(view)
|
|
710
|
+
if (pointerEvents == PointerEventsConfig.NONE) {
|
|
711
|
+
return false
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
var found = false
|
|
715
|
+
if (view is ViewGroup && pointerEvents != PointerEventsConfig.BOX_ONLY) {
|
|
716
|
+
for (i in view.childCount - 1 downTo 0) {
|
|
717
|
+
val child = view.getChildAt(i)
|
|
718
|
+
if (!canReceiveEvents(child)) {
|
|
719
|
+
continue
|
|
720
|
+
}
|
|
721
|
+
val childPoint = tempPoint
|
|
722
|
+
transformPointToChildViewCoords(coords[0], coords[1], view, child, childPoint)
|
|
723
|
+
if (isClipping(child) && !isTransformedTouchPointInView(childPoint.x, childPoint.y, child)) {
|
|
724
|
+
continue
|
|
725
|
+
}
|
|
726
|
+
val restoreX = coords[0]
|
|
727
|
+
val restoreY = coords[1]
|
|
728
|
+
coords[0] = childPoint.x
|
|
729
|
+
coords[1] = childPoint.y
|
|
730
|
+
found = collectViewsAtPoint(child, coords, out)
|
|
731
|
+
coords[0] = restoreX
|
|
732
|
+
coords[1] = restoreY
|
|
733
|
+
|
|
734
|
+
if (found) {
|
|
735
|
+
break
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// BOX_NONE views can't be the target themselves, only their children can
|
|
741
|
+
val selfIsTarget = pointerEvents != PointerEventsConfig.BOX_NONE &&
|
|
742
|
+
isTransformedTouchPointInView(coords[0], coords[1], view)
|
|
743
|
+
|
|
744
|
+
if (found || selfIsTarget) {
|
|
745
|
+
// `out` may already contain this view when several pointers share part of their path.
|
|
746
|
+
if (!out.contains(view)) {
|
|
747
|
+
out.add(view)
|
|
748
|
+
}
|
|
749
|
+
return true
|
|
750
|
+
}
|
|
751
|
+
return false
|
|
752
|
+
}
|
|
753
|
+
|
|
625
754
|
private fun traverseWithPointerEvents(view: View, coords: FloatArray, pointerId: Int, event: MotionEvent): Boolean =
|
|
626
755
|
if (shouldIgnoreSubtreeIfGestureHandlerRootView(view)) {
|
|
627
756
|
// When we encounter another active root view while traversing the view hierarchy, we want
|
|
@@ -29,13 +29,14 @@ class LongPressGestureHandler(context: Context) : GestureHandler() {
|
|
|
29
29
|
val systemDefaultMaxDist = DEFAULT_MAX_DIST_DP * context.resources.displayMetrics.density
|
|
30
30
|
defaultMaxDist = systemDefaultMaxDist
|
|
31
31
|
maxDist = defaultMaxDist
|
|
32
|
-
numberOfPointersRequired =
|
|
32
|
+
numberOfPointersRequired = DEFAULT_NUMBER_OF_POINTERS_REQUIRED
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
override fun resetConfig() {
|
|
36
36
|
super.resetConfig()
|
|
37
37
|
minDurationMs = DEFAULT_MIN_DURATION_MS
|
|
38
38
|
maxDist = defaultMaxDist
|
|
39
|
+
numberOfPointersRequired = DEFAULT_NUMBER_OF_POINTERS_REQUIRED
|
|
39
40
|
shouldCancelWhenOutside = DEFAULT_SHOULD_CANCEL_WHEN_OUTSIDE
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -66,7 +67,7 @@ class LongPressGestureHandler(context: Context) : GestureHandler() {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
|
69
|
-
if (
|
|
70
|
+
if (shouldSkipEvent(sourceEvent)) {
|
|
70
71
|
return
|
|
71
72
|
}
|
|
72
73
|
|
|
@@ -99,7 +100,8 @@ class LongPressGestureHandler(context: Context) : GestureHandler() {
|
|
|
99
100
|
currentPointers == numberOfPointersRequired &&
|
|
100
101
|
(
|
|
101
102
|
sourceEvent.actionMasked == MotionEvent.ACTION_DOWN ||
|
|
102
|
-
sourceEvent.actionMasked == MotionEvent.ACTION_POINTER_DOWN
|
|
103
|
+
sourceEvent.actionMasked == MotionEvent.ACTION_POINTER_DOWN ||
|
|
104
|
+
sourceEvent.actionMasked == MotionEvent.ACTION_BUTTON_PRESS
|
|
103
105
|
)
|
|
104
106
|
) {
|
|
105
107
|
handler = Handler(Looper.getMainLooper())
|
|
@@ -207,5 +209,6 @@ class LongPressGestureHandler(context: Context) : GestureHandler() {
|
|
|
207
209
|
private const val DEFAULT_SHOULD_CANCEL_WHEN_OUTSIDE = true
|
|
208
210
|
private const val DEFAULT_MIN_DURATION_MS: Long = 500
|
|
209
211
|
private const val DEFAULT_MAX_DIST_DP = 10f
|
|
212
|
+
private const val DEFAULT_NUMBER_OF_POINTERS_REQUIRED = 1
|
|
210
213
|
}
|
|
211
214
|
}
|
|
@@ -109,6 +109,9 @@ class NativeViewGestureHandler : GestureHandler() {
|
|
|
109
109
|
cancel()
|
|
110
110
|
} else {
|
|
111
111
|
hook.sendTouchEvent(view, event)
|
|
112
|
+
if (shouldStopNestedScroll()) {
|
|
113
|
+
view.stopNestedScroll()
|
|
114
|
+
}
|
|
112
115
|
|
|
113
116
|
if ((state == STATE_UNDETERMINED || state == STATE_BEGAN) && hook.canActivate(view)) {
|
|
114
117
|
activate()
|
|
@@ -156,9 +159,19 @@ class NativeViewGestureHandler : GestureHandler() {
|
|
|
156
159
|
action = MotionEvent.ACTION_CANCEL
|
|
157
160
|
}
|
|
158
161
|
hook.sendTouchEvent(view, event)
|
|
162
|
+
if (shouldStopNestedScroll()) {
|
|
163
|
+
view?.stopNestedScroll()
|
|
164
|
+
}
|
|
159
165
|
event.recycle()
|
|
160
166
|
}
|
|
161
167
|
|
|
168
|
+
// Once the handler is active, it delivers touches straight to the view's `onTouchEvent`. Normally
|
|
169
|
+
// touches arrive through `View.dispatchTouchEvent`, which also ends the nested scroll when the finger
|
|
170
|
+
// goes up. Because we skip it, the nested scroll stays open and the parent never finds out that the
|
|
171
|
+
// gesture is over - e.g. SwipeRefreshLayout never fires refresh (#4485). While the handler is not
|
|
172
|
+
// active, the view still receives touches the regular way, so Android takes care of it.
|
|
173
|
+
private fun shouldStopNestedScroll() = state == STATE_ACTIVE && hook.shouldStopNestedScroll()
|
|
174
|
+
|
|
162
175
|
override fun onCancel() = dispatchCancelEventToView()
|
|
163
176
|
|
|
164
177
|
override fun onFail() = dispatchCancelEventToView()
|
|
@@ -211,6 +224,12 @@ class NativeViewGestureHandler : GestureHandler() {
|
|
|
211
224
|
*/
|
|
212
225
|
fun canBegin(event: MotionEvent) = true
|
|
213
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Whether the view's nested scroll should be stopped when the active gesture ends. Touches
|
|
229
|
+
* are fed through `onTouchEvent`, so `View.dispatchTouchEvent` never gets to do it.
|
|
230
|
+
*/
|
|
231
|
+
fun shouldStopNestedScroll() = false
|
|
232
|
+
|
|
214
233
|
/**
|
|
215
234
|
* Checks whether handler can activate. Used by TextViewHook.
|
|
216
235
|
*/
|
|
@@ -336,6 +355,10 @@ class NativeViewGestureHandler : GestureHandler() {
|
|
|
336
355
|
|
|
337
356
|
private class ScrollViewHook : NativeViewGestureHandlerHook {
|
|
338
357
|
override fun shouldCancelRootViewGestureHandlerIfNecessary() = true
|
|
358
|
+
|
|
359
|
+
// ScrollView starts a nested scroll on DOWN but never stops it itself. Without this the
|
|
360
|
+
// parent's `onStopNestedScroll` never runs, e.g. SwipeRefreshLayout never triggers refresh.
|
|
361
|
+
override fun shouldStopNestedScroll() = true
|
|
339
362
|
}
|
|
340
363
|
|
|
341
364
|
private class ReactViewGroupHook : NativeViewGestureHandlerHook {
|
|
@@ -11,6 +11,7 @@ import com.facebook.react.uimanager.PixelUtil
|
|
|
11
11
|
import com.swmansion.gesturehandler.core.GestureUtils.getLastPointerX
|
|
12
12
|
import com.swmansion.gesturehandler.core.GestureUtils.getLastPointerY
|
|
13
13
|
import com.swmansion.gesturehandler.react.eventbuilders.PanGestureHandlerEventDataBuilder
|
|
14
|
+
import kotlin.math.abs
|
|
14
15
|
|
|
15
16
|
class PanGestureHandler(context: Context?) : GestureHandler() {
|
|
16
17
|
var velocityX = 0f
|
|
@@ -113,15 +114,11 @@ class PanGestureHandler(context: Context?) : GestureHandler() {
|
|
|
113
114
|
return true
|
|
114
115
|
}
|
|
115
116
|
val vx = velocityX
|
|
116
|
-
if (minVelocityX != MIN_VALUE_IGNORE &&
|
|
117
|
-
(minVelocityX < 0 && vx <= minVelocityX || minVelocityX in 0.0f..vx)
|
|
118
|
-
) {
|
|
117
|
+
if (minVelocityX != MIN_VALUE_IGNORE && abs(vx) >= abs(minVelocityX)) {
|
|
119
118
|
return true
|
|
120
119
|
}
|
|
121
120
|
val vy = velocityY
|
|
122
|
-
if (minVelocityY != MIN_VALUE_IGNORE &&
|
|
123
|
-
(minVelocityY < 0 && vx <= minVelocityY || minVelocityY in 0.0f..vx)
|
|
124
|
-
) {
|
|
121
|
+
if (minVelocityY != MIN_VALUE_IGNORE && abs(vy) >= abs(minVelocityY)) {
|
|
125
122
|
return true
|
|
126
123
|
}
|
|
127
124
|
val velocitySq = vx * vx + vy * vy
|
|
@@ -149,7 +146,7 @@ class PanGestureHandler(context: Context?) : GestureHandler() {
|
|
|
149
146
|
}
|
|
150
147
|
|
|
151
148
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
|
152
|
-
if (
|
|
149
|
+
if (shouldSkipEvent(sourceEvent)) {
|
|
153
150
|
return
|
|
154
151
|
}
|
|
155
152
|
|
|
@@ -19,3 +19,6 @@ fun Context.isScreenReaderOn() =
|
|
|
19
19
|
fun MotionEvent.isHoverAction(): Boolean = action == MotionEvent.ACTION_HOVER_MOVE ||
|
|
20
20
|
action == MotionEvent.ACTION_HOVER_ENTER ||
|
|
21
21
|
action == MotionEvent.ACTION_HOVER_EXIT
|
|
22
|
+
|
|
23
|
+
fun MotionEvent.isButtonAction(): Boolean = actionMasked == MotionEvent.ACTION_BUTTON_PRESS ||
|
|
24
|
+
actionMasked == MotionEvent.ACTION_BUTTON_RELEASE
|
|
@@ -554,6 +554,8 @@ class RNGestureHandlerButtonViewManager :
|
|
|
554
554
|
// by default Viewgroup would pass hotspot change events
|
|
555
555
|
}
|
|
556
556
|
|
|
557
|
+
override fun shouldDelayChildPressedState(): Boolean = false
|
|
558
|
+
|
|
557
559
|
private fun findGestureHandlerRootView(): RNGestureHandlerRootView? {
|
|
558
560
|
var parent: ViewParent? = this.parent
|
|
559
561
|
var gestureHandlerRootView: RNGestureHandlerRootView? = null
|
package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt
CHANGED
|
@@ -19,6 +19,7 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView:
|
|
|
19
19
|
private val jsGestureHandler: GestureHandler?
|
|
20
20
|
val rootView: ViewGroup
|
|
21
21
|
private var shouldIntercept = false
|
|
22
|
+
private var wasIntercepting = false
|
|
22
23
|
private var passingTouch = false
|
|
23
24
|
|
|
24
25
|
init {
|
|
@@ -118,6 +119,14 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView:
|
|
|
118
119
|
passingTouch = true
|
|
119
120
|
orchestrator!!.onTouchEvent(event)
|
|
120
121
|
passingTouch = false
|
|
122
|
+
|
|
123
|
+
// On the transition into interception, cancel the native views the pointers landed on - the
|
|
124
|
+
// framework's ACTION_CANCEL never reaches them since RNGH ignores `onInterceptTouchEvent`
|
|
125
|
+
if (shouldIntercept && !wasIntercepting) {
|
|
126
|
+
orchestrator!!.cancelTouchesInInterceptedViews(event)
|
|
127
|
+
}
|
|
128
|
+
wasIntercepting = shouldIntercept
|
|
129
|
+
|
|
121
130
|
return shouldIntercept
|
|
122
131
|
}
|
|
123
132
|
|
package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt
CHANGED
|
@@ -40,12 +40,14 @@ class RNGestureHandlerRootView(context: Context?) : ReactViewGroup(context) {
|
|
|
40
40
|
super.dispatchTouchEvent(event)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
override fun dispatchGenericMotionEvent(ev: MotionEvent) =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
override fun dispatchGenericMotionEvent(ev: MotionEvent) = if (rootViewEnabled &&
|
|
44
|
+
(ev.isHoverAction() || ev.isButtonAction()) &&
|
|
45
|
+
rootHelper!!.dispatchTouchEvent(ev)
|
|
46
|
+
) {
|
|
47
|
+
true
|
|
48
|
+
} else {
|
|
49
|
+
super.dispatchGenericMotionEvent(ev)
|
|
50
|
+
}
|
|
49
51
|
|
|
50
52
|
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
|
|
51
53
|
if (rootViewEnabled) {
|
package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt
CHANGED
|
@@ -54,13 +54,8 @@ class RNGestureHandlerTouchEvent private constructor() : Event<RNGestureHandlerT
|
|
|
54
54
|
putInt("eventType", handler.touchEventType)
|
|
55
55
|
putInt("pointerType", handler.pointerType)
|
|
56
56
|
|
|
57
|
-
handler.consumeChangedTouchesPayload()
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
handler.consumeAllTouchesPayload()?.let {
|
|
62
|
-
putArray("allTouches", it)
|
|
63
|
-
}
|
|
57
|
+
putArray("changedTouches", handler.consumeChangedTouchesPayload() ?: Arguments.createArray())
|
|
58
|
+
putArray("allTouches", handler.consumeAllTouchesPayload() ?: Arguments.createArray())
|
|
64
59
|
|
|
65
60
|
if (handler.isAwaiting && handler.state == GestureHandler.STATE_ACTIVE) {
|
|
66
61
|
putInt("state", GestureHandler.STATE_BEGAN)
|