react-native-gesture-handler 2.15.0 → 2.16.0-rc.0
Sign up to get free protection for your applications and to get access to all the features.
- package/RNGestureHandler.podspec +2 -23
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/RNGestureHandlerPackage.kt +9 -4
- package/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt +4 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +69 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +25 -19
- package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +5 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +5 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt +7 -3
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +8 -5
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +3 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/eventbuilders/GestureHandlerEventDataBuilder.kt +3 -0
- package/android/src/main/jni/cpp-adapter.cpp +18 -22
- package/apple/Handlers/RNFlingHandler.m +5 -4
- package/apple/Handlers/RNForceTouchHandler.m +3 -1
- package/apple/Handlers/RNHoverHandler.m +2 -1
- package/apple/Handlers/RNLongPressHandler.m +3 -1
- package/apple/Handlers/RNManualHandler.m +1 -0
- package/apple/Handlers/RNNativeViewHandler.mm +9 -7
- package/apple/Handlers/RNPanHandler.m +7 -2
- package/apple/Handlers/RNPinchHandler.m +38 -25
- package/apple/Handlers/RNRotationHandler.m +43 -29
- package/apple/Handlers/RNTapHandler.m +6 -4
- package/apple/RNGestureHandler.h +9 -0
- package/apple/RNGestureHandler.m +38 -3
- package/apple/RNGestureHandlerEvents.h +18 -9
- package/apple/RNGestureHandlerEvents.m +29 -11
- package/apple/RNGestureHandlerManager.h +5 -0
- package/apple/RNGestureHandlerManager.mm +32 -6
- package/apple/RNGestureHandlerModule.h +5 -3
- package/apple/RNGestureHandlerModule.mm +33 -19
- package/apple/RNGestureHandlerPointerType.h +8 -0
- package/lib/commonjs/PointerType.js +16 -0
- package/lib/commonjs/PointerType.js.map +1 -0
- package/lib/commonjs/components/GestureHandlerRootView.android.js +17 -2
- package/lib/commonjs/components/GestureHandlerRootView.android.js.map +1 -1
- package/lib/commonjs/components/GestureHandlerRootView.js +15 -2
- package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
- package/lib/commonjs/components/GestureHandlerRootView.web.js +15 -2
- package/lib/commonjs/components/GestureHandlerRootView.web.js.map +1 -1
- package/lib/commonjs/getShadowNodeFromRef.js +19 -2
- package/lib/commonjs/getShadowNodeFromRef.js.map +1 -1
- package/lib/commonjs/handlers/createHandler.js +5 -0
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +6 -3
- package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/interfaces.js +3 -13
- package/lib/commonjs/web/interfaces.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +3 -3
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/commonjs/web/tools/PointerEventManager.js +29 -7
- package/lib/commonjs/web/tools/PointerEventManager.js.map +1 -1
- package/lib/commonjs/web/tools/TouchEventManager.js +3 -1
- package/lib/commonjs/web/tools/TouchEventManager.js.map +1 -1
- package/lib/commonjs/web/utils.js +6 -0
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/PointerType.js +9 -0
- package/lib/module/PointerType.js.map +1 -0
- package/lib/module/components/GestureHandlerRootView.android.js +15 -2
- package/lib/module/components/GestureHandlerRootView.android.js.map +1 -1
- package/lib/module/components/GestureHandlerRootView.js +15 -3
- package/lib/module/components/GestureHandlerRootView.js.map +1 -1
- package/lib/module/components/GestureHandlerRootView.web.js +15 -3
- package/lib/module/components/GestureHandlerRootView.web.js.map +1 -1
- package/lib/module/getShadowNodeFromRef.js +19 -2
- package/lib/module/getShadowNodeFromRef.js.map +1 -1
- package/lib/module/handlers/createHandler.js +6 -1
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +5 -3
- package/lib/module/web/handlers/GestureHandler.js.map +1 -1
- package/lib/module/web/interfaces.js +2 -11
- package/lib/module/web/interfaces.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerOrchestrator.js +2 -2
- package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/module/web/tools/PointerEventManager.js +30 -9
- package/lib/module/web/tools/PointerEventManager.js.map +1 -1
- package/lib/module/web/tools/TouchEventManager.js +2 -1
- package/lib/module/web/tools/TouchEventManager.js.map +1 -1
- package/lib/module/web/utils.js +2 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/PointerType.d.ts +6 -0
- package/lib/typescript/components/GestureHandlerRootView.android.d.ts +1 -1
- package/lib/typescript/components/GestureHandlerRootView.d.ts +1 -1
- package/lib/typescript/components/GestureHandlerRootView.web.d.ts +1 -1
- package/lib/typescript/getShadowNodeFromRef.d.ts +1 -1
- package/lib/typescript/handlers/gestureHandlerCommon.d.ts +2 -0
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +6 -6
- package/lib/typescript/web/handlers/GestureHandler.d.ts +2 -1
- package/lib/typescript/web/interfaces.d.ts +4 -8
- package/lib/typescript/web/utils.d.ts +2 -0
- package/package.json +1 -1
- package/src/PointerType.ts +6 -0
- package/src/components/GestureHandlerRootView.android.tsx +13 -5
- package/src/components/GestureHandlerRootView.tsx +10 -5
- package/src/components/GestureHandlerRootView.web.tsx +10 -5
- package/src/getShadowNodeFromRef.ts +28 -6
- package/src/handlers/createHandler.tsx +6 -0
- package/src/handlers/gestureHandlerCommon.ts +2 -0
- package/src/index.ts +1 -0
- package/src/specs/NativeRNGestureHandlerModule.ts +8 -8
- package/src/web/handlers/GestureHandler.ts +3 -2
- package/src/web/interfaces.ts +4 -9
- package/src/web/tools/GestureHandlerOrchestrator.ts +2 -2
- package/src/web/tools/PointerEventManager.ts +34 -14
- package/src/web/tools/TouchEventManager.ts +2 -6
- package/src/web/utils.ts +9 -0
package/RNGestureHandler.podspec
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
|
-
new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
|
4
|
-
apple_platform = new_arch_enabled ? '11.0' : '9.0'
|
5
|
-
|
6
3
|
Pod::Spec.new do |s|
|
7
4
|
# NPM package specification
|
8
5
|
package = JSON.parse(File.read(File.join(File.dirname(__FILE__), "package.json")))
|
@@ -16,29 +13,11 @@ Pod::Spec.new do |s|
|
|
16
13
|
s.source = { :git => "https://github.com/software-mansion/react-native-gesture-handler", :tag => "#{s.version}" }
|
17
14
|
s.source_files = "apple/**/*.{h,m,mm}"
|
18
15
|
s.requires_arc = true
|
19
|
-
s.platforms = { ios:
|
16
|
+
s.platforms = { ios: '11.0', tvos: '11.0', osx: '10.15', visionos: '1.0' }
|
20
17
|
|
21
18
|
if defined?(install_modules_dependencies()) != nil
|
22
19
|
install_modules_dependencies(s);
|
23
20
|
else
|
24
|
-
|
25
|
-
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
26
|
-
|
27
|
-
s.pod_target_xcconfig = {
|
28
|
-
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/RCT-Folly"',
|
29
|
-
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
|
30
|
-
}
|
31
|
-
s.compiler_flags = folly_compiler_flags + ' -DRCT_NEW_ARCH_ENABLED'
|
32
|
-
|
33
|
-
s.dependency "React"
|
34
|
-
s.dependency "React-RCTFabric" # This is for fabric component
|
35
|
-
s.dependency "React-Codegen"
|
36
|
-
s.dependency "RCT-Folly"
|
37
|
-
s.dependency "RCTRequired"
|
38
|
-
s.dependency "RCTTypeSafety"
|
39
|
-
s.dependency "ReactCommon/turbomodule/core"
|
40
|
-
else
|
41
|
-
s.dependency "React-Core"
|
42
|
-
end
|
21
|
+
s.dependency "React-Core"
|
43
22
|
end
|
44
23
|
end
|
package/android/build.gradle
CHANGED
@@ -136,7 +136,7 @@ android {
|
|
136
136
|
var appProject = rootProject.allprojects.find {it.plugins.hasPlugin('com.android.application')}
|
137
137
|
externalNativeBuild {
|
138
138
|
cmake {
|
139
|
-
cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-Werror", "-std=c++
|
139
|
+
cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-Werror", "-std=c++20", "-DANDROID"
|
140
140
|
arguments "-DAPP_BUILD_DIR=${appProject.buildDir}",
|
141
141
|
"-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
|
142
142
|
"-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
|
@@ -6,14 +6,19 @@ import com.facebook.react.bridge.ModuleSpec
|
|
6
6
|
import com.facebook.react.bridge.NativeModule
|
7
7
|
import com.facebook.react.bridge.ReactApplicationContext
|
8
8
|
import com.facebook.react.module.annotations.ReactModule
|
9
|
+
import com.facebook.react.module.annotations.ReactModuleList
|
9
10
|
import com.facebook.react.module.model.ReactModuleInfo
|
10
11
|
import com.facebook.react.module.model.ReactModuleInfoProvider
|
11
|
-
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
12
12
|
import com.facebook.react.uimanager.ViewManager
|
13
13
|
import com.swmansion.gesturehandler.react.RNGestureHandlerButtonViewManager
|
14
14
|
import com.swmansion.gesturehandler.react.RNGestureHandlerModule
|
15
15
|
import com.swmansion.gesturehandler.react.RNGestureHandlerRootViewManager
|
16
16
|
|
17
|
+
@ReactModuleList(
|
18
|
+
nativeModules = [
|
19
|
+
RNGestureHandlerModule::class
|
20
|
+
]
|
21
|
+
)
|
17
22
|
class RNGestureHandlerPackage : TurboReactPackage(), ViewManagerOnDemandReactPackage {
|
18
23
|
private val viewManagers: Map<String, ModuleSpec> by lazy {
|
19
24
|
mapOf(
|
@@ -44,7 +49,7 @@ class RNGestureHandlerPackage : TurboReactPackage(), ViewManagerOnDemandReactPac
|
|
44
49
|
) = viewManagers[viewManagerName]?.provider?.get() as? ViewManager<*, *>
|
45
50
|
|
46
51
|
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
47
|
-
return if (name == RNGestureHandlerModule.
|
52
|
+
return if (name == RNGestureHandlerModule.NAME) {
|
48
53
|
RNGestureHandlerModule(reactContext)
|
49
54
|
} else {
|
50
55
|
null
|
@@ -61,14 +66,14 @@ class RNGestureHandlerPackage : TurboReactPackage(), ViewManagerOnDemandReactPac
|
|
61
66
|
val reactModule: ReactModule = RNGestureHandlerModule::class.java.getAnnotation(ReactModule::class.java)!!
|
62
67
|
|
63
68
|
mutableMapOf(
|
64
|
-
RNGestureHandlerModule.
|
69
|
+
RNGestureHandlerModule.NAME to ReactModuleInfo(
|
65
70
|
reactModule.name,
|
66
71
|
RNGestureHandlerModule::class.java.name,
|
67
72
|
reactModule.canOverrideExistingModule,
|
68
73
|
reactModule.needsEagerInit,
|
69
74
|
reactModule.hasConstants,
|
70
75
|
reactModule.isCxxModule,
|
71
|
-
|
76
|
+
true
|
72
77
|
)
|
73
78
|
)
|
74
79
|
}
|
@@ -67,6 +67,10 @@ class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
70
|
+
if (!shouldActivateWithMouse(sourceEvent)) {
|
71
|
+
return
|
72
|
+
}
|
73
|
+
|
70
74
|
val state = state
|
71
75
|
if (state == STATE_UNDETERMINED) {
|
72
76
|
startFling(sourceEvent)
|
@@ -5,6 +5,7 @@ import android.content.Context
|
|
5
5
|
import android.content.ContextWrapper
|
6
6
|
import android.graphics.PointF
|
7
7
|
import android.graphics.Rect
|
8
|
+
import android.os.Build
|
8
9
|
import android.view.MotionEvent
|
9
10
|
import android.view.MotionEvent.PointerCoords
|
10
11
|
import android.view.MotionEvent.PointerProperties
|
@@ -67,6 +68,10 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
67
68
|
protected var orchestrator: GestureHandlerOrchestrator? = null
|
68
69
|
private var onTouchEventListener: OnTouchEventListener? = null
|
69
70
|
private var interactionController: GestureHandlerInteractionController? = null
|
71
|
+
var pointerType: Int = POINTER_TYPE_OTHER
|
72
|
+
private set
|
73
|
+
|
74
|
+
protected var mouseButton = 0
|
70
75
|
|
71
76
|
@Suppress("UNCHECKED_CAST")
|
72
77
|
protected fun self(): ConcreteGestureHandlerT = this as ConcreteGestureHandlerT
|
@@ -159,6 +164,10 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
159
164
|
fun setInteractionController(controller: GestureHandlerInteractionController?): ConcreteGestureHandlerT =
|
160
165
|
applySelf { interactionController = controller }
|
161
166
|
|
167
|
+
fun setMouseButton(mouseButton: Int) = apply {
|
168
|
+
this.mouseButton = mouseButton
|
169
|
+
}
|
170
|
+
|
162
171
|
fun prepare(view: View?, orchestrator: GestureHandlerOrchestrator?) {
|
163
172
|
check(!(this.view != null || this.orchestrator != null)) { "Already prepared or hasn't been reset" }
|
164
173
|
Arrays.fill(trackedPointerIDs, -1)
|
@@ -371,6 +380,11 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
371
380
|
lastAbsolutePositionY = GestureUtils.getLastPointerY(adaptedTransformedEvent, true)
|
372
381
|
lastEventOffsetX = adaptedTransformedEvent.rawX - adaptedTransformedEvent.x
|
373
382
|
lastEventOffsetY = adaptedTransformedEvent.rawY - adaptedTransformedEvent.y
|
383
|
+
|
384
|
+
if (sourceEvent.action == MotionEvent.ACTION_DOWN || sourceEvent.action == MotionEvent.ACTION_HOVER_ENTER || sourceEvent.action == MotionEvent.ACTION_HOVER_MOVE) {
|
385
|
+
setPointerType(sourceEvent)
|
386
|
+
}
|
387
|
+
|
374
388
|
if (sourceEvent.action == MotionEvent.ACTION_HOVER_ENTER ||
|
375
389
|
sourceEvent.action == MotionEvent.ACTION_HOVER_MOVE ||
|
376
390
|
sourceEvent.action == MotionEvent.ACTION_HOVER_EXIT
|
@@ -688,6 +702,46 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
688
702
|
protected open fun onReset() {}
|
689
703
|
protected open fun onCancel() {}
|
690
704
|
|
705
|
+
private fun isButtonInConfig(clickedButton: Int): Boolean {
|
706
|
+
if (mouseButton == 0) {
|
707
|
+
return clickedButton == MotionEvent.BUTTON_PRIMARY
|
708
|
+
}
|
709
|
+
|
710
|
+
return clickedButton and mouseButton != 0
|
711
|
+
}
|
712
|
+
|
713
|
+
protected fun shouldActivateWithMouse(sourceEvent: MotionEvent): Boolean {
|
714
|
+
// While using mouse, we get both sets of events, for example ACTION_DOWN and ACTION_BUTTON_PRESS. That's why we want to take actions to only one of them.
|
715
|
+
// On API >= 23, we will use events with infix BUTTON, otherwise we use standard action events (like ACTION_DOWN).
|
716
|
+
|
717
|
+
with(sourceEvent) {
|
718
|
+
// To use actionButton, we need API >= 23.
|
719
|
+
if (getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
720
|
+
// While using mouse, we want to ignore default events for touch.
|
721
|
+
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) {
|
722
|
+
return@shouldActivateWithMouse false
|
723
|
+
}
|
724
|
+
|
725
|
+
// We don't want to do anything if wrong button was clicked. If we received event for BUTTON, we have to use actionButton to get which one was clicked.
|
726
|
+
if (action != MotionEvent.ACTION_MOVE && !isButtonInConfig(actionButton)) {
|
727
|
+
return@shouldActivateWithMouse false
|
728
|
+
}
|
729
|
+
|
730
|
+
// When we receive ACTION_MOVE, we have to check buttonState field.
|
731
|
+
if (action == MotionEvent.ACTION_MOVE && !isButtonInConfig(buttonState)) {
|
732
|
+
return@shouldActivateWithMouse false
|
733
|
+
}
|
734
|
+
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
735
|
+
// We do not fully support mouse below API 23, so we will ignore BUTTON events.
|
736
|
+
if (action == MotionEvent.ACTION_BUTTON_PRESS || action == MotionEvent.ACTION_BUTTON_RELEASE) {
|
737
|
+
return@shouldActivateWithMouse false
|
738
|
+
}
|
739
|
+
}
|
740
|
+
}
|
741
|
+
|
742
|
+
return true
|
743
|
+
}
|
744
|
+
|
691
745
|
/**
|
692
746
|
* Transforms a point in the coordinate space of the wrapperView (GestureHandlerRootView) to
|
693
747
|
* coordinate space of the view the gesture is attached to.
|
@@ -721,6 +775,17 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
721
775
|
isWithinBounds = false
|
722
776
|
}
|
723
777
|
|
778
|
+
private fun setPointerType(event: MotionEvent) {
|
779
|
+
val pointerIndex = event.actionIndex
|
780
|
+
|
781
|
+
pointerType = when (event.getToolType(pointerIndex)) {
|
782
|
+
MotionEvent.TOOL_TYPE_FINGER -> POINTER_TYPE_TOUCH
|
783
|
+
MotionEvent.TOOL_TYPE_STYLUS -> POINTER_TYPE_STYLUS
|
784
|
+
MotionEvent.TOOL_TYPE_MOUSE -> POINTER_TYPE_MOUSE
|
785
|
+
else -> POINTER_TYPE_OTHER
|
786
|
+
}
|
787
|
+
}
|
788
|
+
|
724
789
|
fun setOnTouchEventListener(listener: OnTouchEventListener?): GestureHandler<*> {
|
725
790
|
onTouchEventListener = listener
|
726
791
|
return this
|
@@ -763,6 +828,10 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
763
828
|
const val ACTION_TYPE_NATIVE_ANIMATED_EVENT = 2
|
764
829
|
const val ACTION_TYPE_JS_FUNCTION_OLD_API = 3
|
765
830
|
const val ACTION_TYPE_JS_FUNCTION_NEW_API = 4
|
831
|
+
const val POINTER_TYPE_TOUCH = 0
|
832
|
+
const val POINTER_TYPE_STYLUS = 1
|
833
|
+
const val POINTER_TYPE_MOUSE = 2
|
834
|
+
const val POINTER_TYPE_OTHER = 3
|
766
835
|
private const val MAX_POINTERS_COUNT = 12
|
767
836
|
private lateinit var pointerProps: Array<PointerProperties?>
|
768
837
|
private lateinit var pointerCoords: Array<PointerCoords?>
|
package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt
CHANGED
@@ -101,27 +101,33 @@ class GestureHandlerOrchestrator(
|
|
101
101
|
fun onHandlerStateChange(handler: GestureHandler<*>, newState: Int, prevState: Int) {
|
102
102
|
handlingChangeSemaphore += 1
|
103
103
|
if (isFinished(newState)) {
|
104
|
+
// We have to loop through copy in order to avoid modifying collection
|
105
|
+
// while iterating over its elements
|
106
|
+
val currentlyAwaitingHandlers = awaitingHandlers.toList()
|
107
|
+
|
104
108
|
// if there were handlers awaiting completion of this handler, we can trigger active state
|
105
|
-
for (otherHandler in
|
106
|
-
if (shouldHandlerWaitForOther(otherHandler, handler)) {
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
// gesture has failed recognition, we may try activating
|
123
|
-
tryActivate(otherHandler)
|
109
|
+
for (otherHandler in currentlyAwaitingHandlers) {
|
110
|
+
if (!shouldHandlerWaitForOther(otherHandler, handler)) {
|
111
|
+
continue
|
112
|
+
}
|
113
|
+
|
114
|
+
if (newState == GestureHandler.STATE_END) {
|
115
|
+
// gesture has ended, we need to kill the awaiting handler
|
116
|
+
otherHandler.cancel()
|
117
|
+
if (otherHandler.state == GestureHandler.STATE_END) {
|
118
|
+
// Handle edge case, where discrete gestures end immediately after activation thus
|
119
|
+
// their state is set to END and when the gesture they are waiting for activates they
|
120
|
+
// should be cancelled, however `cancel` was never sent as gestures were already in the END state.
|
121
|
+
// Send synthetic BEGAN -> CANCELLED to properly handle JS logic
|
122
|
+
otherHandler.dispatchStateChange(
|
123
|
+
GestureHandler.STATE_CANCELLED,
|
124
|
+
GestureHandler.STATE_BEGAN
|
125
|
+
)
|
124
126
|
}
|
127
|
+
otherHandler.isAwaiting = false
|
128
|
+
} else {
|
129
|
+
// gesture has failed recognition, we may try activating
|
130
|
+
tryActivate(otherHandler)
|
125
131
|
}
|
126
132
|
}
|
127
133
|
cleanupAwaitingHandlers()
|
@@ -38,6 +38,10 @@ class LongPressGestureHandler(context: Context) : GestureHandler<LongPressGestur
|
|
38
38
|
}
|
39
39
|
|
40
40
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
41
|
+
if (!shouldActivateWithMouse(sourceEvent)) {
|
42
|
+
return
|
43
|
+
}
|
44
|
+
|
41
45
|
if (state == STATE_UNDETERMINED) {
|
42
46
|
previousTime = SystemClock.uptimeMillis()
|
43
47
|
startTime = previousTime
|
@@ -51,7 +55,7 @@ class LongPressGestureHandler(context: Context) : GestureHandler<LongPressGestur
|
|
51
55
|
activate()
|
52
56
|
}
|
53
57
|
}
|
54
|
-
if (sourceEvent.actionMasked == MotionEvent.ACTION_UP) {
|
58
|
+
if (sourceEvent.actionMasked == MotionEvent.ACTION_UP || sourceEvent.actionMasked == MotionEvent.ACTION_BUTTON_RELEASE) {
|
55
59
|
handler?.let {
|
56
60
|
it.removeCallbacksAndMessages(null)
|
57
61
|
handler = null
|
@@ -208,6 +208,10 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
208
208
|
}
|
209
209
|
|
210
210
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
211
|
+
if (!shouldActivateWithMouse(sourceEvent)) {
|
212
|
+
return
|
213
|
+
}
|
214
|
+
|
211
215
|
val state = state
|
212
216
|
val action = sourceEvent.actionMasked
|
213
217
|
if (action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) {
|
@@ -246,7 +250,7 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
246
250
|
velocityX = velocityTracker!!.xVelocity
|
247
251
|
velocityY = velocityTracker!!.yVelocity
|
248
252
|
}
|
249
|
-
if (action == MotionEvent.ACTION_UP) {
|
253
|
+
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_BUTTON_RELEASE) {
|
250
254
|
if (state == STATE_ACTIVE) {
|
251
255
|
end()
|
252
256
|
} else {
|
@@ -105,6 +105,10 @@ class TapGestureHandler : GestureHandler<TapGestureHandler>() {
|
|
105
105
|
}
|
106
106
|
|
107
107
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
108
|
+
if (!shouldActivateWithMouse(sourceEvent)) {
|
109
|
+
return
|
110
|
+
}
|
111
|
+
|
108
112
|
val state = state
|
109
113
|
val action = sourceEvent.actionMasked
|
110
114
|
if (state == STATE_UNDETERMINED) {
|
@@ -130,14 +134,14 @@ class TapGestureHandler : GestureHandler<TapGestureHandler>() {
|
|
130
134
|
if (shouldFail()) {
|
131
135
|
fail()
|
132
136
|
} else if (state == STATE_UNDETERMINED) {
|
133
|
-
if (action == MotionEvent.ACTION_DOWN) {
|
137
|
+
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_BUTTON_PRESS) {
|
134
138
|
begin()
|
135
139
|
}
|
136
140
|
startTap()
|
137
141
|
} else if (state == STATE_BEGAN) {
|
138
|
-
if (action == MotionEvent.ACTION_UP) {
|
142
|
+
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_BUTTON_RELEASE) {
|
139
143
|
endTap()
|
140
|
-
} else if (action == MotionEvent.ACTION_DOWN) {
|
144
|
+
} else if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_BUTTON_PRESS) {
|
141
145
|
startTap()
|
142
146
|
}
|
143
147
|
}
|
@@ -47,7 +47,7 @@ import com.swmansion.gesturehandler.react.eventbuilders.TapGestureHandlerEventDa
|
|
47
47
|
// UIManagerModule.resolveRootTagFromReactTag() was deprecated and will be removed in the next RN release
|
48
48
|
// ref: https://github.com/facebook/react-native/commit/acbf9e18ea666b07c1224a324602a41d0a66985e
|
49
49
|
@Suppress("DEPRECATION")
|
50
|
-
@ReactModule(name = RNGestureHandlerModule.
|
50
|
+
@ReactModule(name = RNGestureHandlerModule.NAME)
|
51
51
|
class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
52
52
|
NativeRNGestureHandlerModuleSpec(reactContext), GestureHandlerStateManager {
|
53
53
|
private abstract class HandlerFactory<T : GestureHandler<T>> {
|
@@ -71,6 +71,9 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
|
71
71
|
if (config.hasKey(KEY_MANUAL_ACTIVATION)) {
|
72
72
|
handler.setManualActivation(config.getBoolean(KEY_MANUAL_ACTIVATION))
|
73
73
|
}
|
74
|
+
if (config.hasKey("mouseButton")) {
|
75
|
+
handler.setMouseButton(config.getInt("mouseButton"))
|
76
|
+
}
|
74
77
|
}
|
75
78
|
|
76
79
|
abstract fun createEventBuilder(handler: T): GestureHandlerEventDataBuilder<T>
|
@@ -331,7 +334,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
|
331
334
|
private val interactionManager = RNGestureHandlerInteractionManager()
|
332
335
|
private val roots: MutableList<RNGestureHandlerRootHelper> = ArrayList()
|
333
336
|
private val reanimatedEventDispatcher = ReanimatedEventDispatcher()
|
334
|
-
override fun getName() =
|
337
|
+
override fun getName() = NAME
|
335
338
|
|
336
339
|
@Suppress("UNCHECKED_CAST")
|
337
340
|
private fun <T : GestureHandler<T>> createGestureHandlerHelper(
|
@@ -476,7 +479,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
|
476
479
|
)
|
477
480
|
}
|
478
481
|
|
479
|
-
override fun
|
482
|
+
override fun invalidate() {
|
480
483
|
registry.dropAllHandlers()
|
481
484
|
interactionManager.reset()
|
482
485
|
synchronized(roots) {
|
@@ -489,7 +492,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
|
489
492
|
}
|
490
493
|
}
|
491
494
|
}
|
492
|
-
super.
|
495
|
+
super.invalidate()
|
493
496
|
}
|
494
497
|
|
495
498
|
fun registerRootHelper(root: RNGestureHandlerRootHelper) {
|
@@ -645,7 +648,7 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
|
645
648
|
}
|
646
649
|
|
647
650
|
companion object {
|
648
|
-
const val
|
651
|
+
const val NAME = "RNGestureHandlerModule"
|
649
652
|
private const val KEY_SHOULD_CANCEL_WHEN_OUTSIDE = "shouldCancelWhenOutside"
|
650
653
|
private const val KEY_ENABLED = "enabled"
|
651
654
|
private const val KEY_NEEDS_POINTER_DATA = "needsPointerData"
|
package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt
CHANGED
@@ -10,6 +10,7 @@ import com.facebook.react.bridge.ReactContext
|
|
10
10
|
import com.facebook.react.bridge.UiThreadUtil
|
11
11
|
import com.facebook.react.common.ReactConstants
|
12
12
|
import com.facebook.react.uimanager.RootView
|
13
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
13
14
|
import com.swmansion.gesturehandler.core.GestureHandler
|
14
15
|
import com.swmansion.gesturehandler.core.GestureHandlerOrchestrator
|
15
16
|
|
@@ -24,7 +25,7 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView:
|
|
24
25
|
UiThreadUtil.assertOnUiThread()
|
25
26
|
val wrappedViewTag = wrappedView.id
|
26
27
|
check(wrappedViewTag >= 1) { "Expect view tag to be set for $wrappedView" }
|
27
|
-
val module = context.getNativeModule(RNGestureHandlerModule::class.java)!!
|
28
|
+
val module = (context as ThemedReactContext).reactApplicationContext.getNativeModule(RNGestureHandlerModule::class.java)!!
|
28
29
|
val registry = module.registry
|
29
30
|
rootView = findRootViewTag(wrappedView)
|
30
31
|
Log.i(
|
@@ -49,7 +50,7 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView:
|
|
49
50
|
ReactConstants.TAG,
|
50
51
|
"[GESTURE HANDLER] Tearing down gesture handler registered for root view $rootView"
|
51
52
|
)
|
52
|
-
val module = context.getNativeModule(RNGestureHandlerModule::class.java)!!
|
53
|
+
val module = (context as ThemedReactContext).reactApplicationContext.getNativeModule(RNGestureHandlerModule::class.java)!!
|
53
54
|
with(module) {
|
54
55
|
registry.dropHandler(jsGestureHandler!!.tag)
|
55
56
|
unregisterRootHelper(this@RNGestureHandlerRootHelper)
|
@@ -7,16 +7,19 @@ abstract class GestureHandlerEventDataBuilder<T : GestureHandler<T>>(handler: T)
|
|
7
7
|
private val numberOfPointers: Int
|
8
8
|
private val handlerTag: Int
|
9
9
|
private val state: Int
|
10
|
+
private val pointerType: Int
|
10
11
|
|
11
12
|
init {
|
12
13
|
numberOfPointers = handler.numberOfPointers
|
13
14
|
handlerTag = handler.tag
|
14
15
|
state = handler.state
|
16
|
+
pointerType = handler.pointerType
|
15
17
|
}
|
16
18
|
|
17
19
|
open fun buildEventData(eventData: WritableMap) {
|
18
20
|
eventData.putInt("numberOfPointers", numberOfPointers)
|
19
21
|
eventData.putInt("handlerTag", handlerTag)
|
20
22
|
eventData.putInt("state", state)
|
23
|
+
eventData.putInt("pointerType", pointerType)
|
21
24
|
}
|
22
25
|
}
|
@@ -7,29 +7,25 @@ using namespace facebook;
|
|
7
7
|
using namespace react;
|
8
8
|
|
9
9
|
void decorateRuntime(jsi::Runtime &runtime) {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
auto isFormsStackingContext = jsi::Function::createFromHostFunction(
|
11
|
+
runtime,
|
12
|
+
jsi::PropNameID::forAscii(runtime, "isFormsStackingContext"),
|
13
|
+
1,
|
14
|
+
[](jsi::Runtime &runtime,
|
15
|
+
const jsi::Value &thisValue,
|
16
|
+
const jsi::Value *arguments,
|
17
|
+
size_t count) -> jsi::Value {
|
18
|
+
if (!arguments[0].isObject()) {
|
19
|
+
return jsi::Value::null();
|
20
|
+
}
|
21
|
+
auto shadowNode = arguments[0]
|
22
|
+
.asObject(runtime).getNativeState<ShadowNode>(runtime);
|
23
|
+
bool isFormsStackingContext = shadowNode->getTraits().check(ShadowNodeTraits::FormsStackingContext);
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
bool isFormsStackingContext = shadowNode->getTraits().check(
|
27
|
-
ShadowNodeTraits::FormsStackingContext);
|
28
|
-
|
29
|
-
return jsi::Value(isFormsStackingContext);
|
30
|
-
});
|
31
|
-
runtime.global().setProperty(
|
32
|
-
runtime, "isFormsStackingContext", std::move(isFormsStackingContext));
|
25
|
+
return jsi::Value(isFormsStackingContext);
|
26
|
+
});
|
27
|
+
runtime.global().setProperty(
|
28
|
+
runtime, "isFormsStackingContext", std::move(isFormsStackingContext));
|
33
29
|
}
|
34
30
|
|
35
31
|
extern "C" JNIEXPORT void JNICALL
|
@@ -26,6 +26,7 @@
|
|
26
26
|
|
27
27
|
- (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
|
28
28
|
{
|
29
|
+
[_gestureHandler setCurrentPointerType:event];
|
29
30
|
_lastPoint = [[[touches allObjects] objectAtIndex:0] locationInView:_gestureHandler.recognizer.view];
|
30
31
|
[_gestureHandler reset];
|
31
32
|
[super touchesBegan:touches withEvent:event];
|
@@ -141,16 +142,16 @@
|
|
141
142
|
|
142
143
|
RNBetterSwipeGestureRecognizer *recognizer = (RNBetterSwipeGestureRecognizer *)_recognizer;
|
143
144
|
|
144
|
-
CGPoint viewAbsolutePosition =
|
145
|
-
|
146
|
-
toView:RCTKeyWindow().rootViewController.view];
|
145
|
+
CGPoint viewAbsolutePosition = [recognizer.view convertPoint:recognizer.view.bounds.origin
|
146
|
+
toView:RCTKeyWindow().rootViewController.view];
|
147
147
|
CGPoint locationInView = [recognizer getLastLocation];
|
148
148
|
|
149
149
|
return [RNGestureHandlerEventExtraData
|
150
150
|
forPosition:locationInView
|
151
151
|
withAbsolutePosition:CGPointMake(
|
152
152
|
viewAbsolutePosition.x + locationInView.x, viewAbsolutePosition.y + locationInView.y)
|
153
|
-
withNumberOfTouches:recognizer.numberOfTouches
|
153
|
+
withNumberOfTouches:recognizer.numberOfTouches
|
154
|
+
withPointerType:_pointerType];
|
154
155
|
}
|
155
156
|
@end
|
156
157
|
|
@@ -40,6 +40,7 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
40
40
|
|
41
41
|
- (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
|
42
42
|
{
|
43
|
+
[_gestureHandler setCurrentPointerType:event];
|
43
44
|
if (_firstTouch) {
|
44
45
|
// ignore rest of fingers
|
45
46
|
return;
|
@@ -171,7 +172,8 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
171
172
|
return [RNGestureHandlerEventExtraData forForce:recognizer.force
|
172
173
|
forPosition:[recognizer locationInView:recognizer.view]
|
173
174
|
withAbsolutePosition:[recognizer locationInView:recognizer.view.window]
|
174
|
-
withNumberOfTouches:recognizer.numberOfTouches
|
175
|
+
withNumberOfTouches:recognizer.numberOfTouches
|
176
|
+
withPointerType:_pointerType];
|
175
177
|
}
|
176
178
|
|
177
179
|
@end
|
@@ -155,7 +155,8 @@ API_AVAILABLE(ios(13.4))
|
|
155
155
|
- (RNGestureHandlerEventExtraData *)eventExtraData:(UIGestureRecognizer *)recognizer
|
156
156
|
{
|
157
157
|
return [RNGestureHandlerEventExtraData forPosition:[recognizer locationInView:recognizer.view]
|
158
|
-
withAbsolutePosition:[recognizer locationInView:recognizer.view.window]
|
158
|
+
withAbsolutePosition:[recognizer locationInView:recognizer.view.window]
|
159
|
+
withPointerType:UITouchTypePencil];
|
159
160
|
}
|
160
161
|
|
161
162
|
@end
|
@@ -59,6 +59,7 @@
|
|
59
59
|
|
60
60
|
- (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
|
61
61
|
{
|
62
|
+
[_gestureHandler setCurrentPointerType:event];
|
62
63
|
[super touchesBegan:touches withEvent:event];
|
63
64
|
[_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
|
64
65
|
|
@@ -181,7 +182,8 @@
|
|
181
182
|
return [RNGestureHandlerEventExtraData forPosition:[recognizer locationInView:recognizer.view]
|
182
183
|
withAbsolutePosition:[recognizer locationInView:recognizer.view.window]
|
183
184
|
withNumberOfTouches:recognizer.numberOfTouches
|
184
|
-
withDuration:[(RNBetterLongPressGestureRecognizer *)recognizer getDuration]
|
185
|
+
withDuration:[(RNBetterLongPressGestureRecognizer *)recognizer getDuration]
|
186
|
+
withPointerType:_pointerType];
|
185
187
|
}
|
186
188
|
@end
|
187
189
|
|
@@ -24,6 +24,7 @@
|
|
24
24
|
|
25
25
|
- (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
|
26
26
|
{
|
27
|
+
[_gestureHandler setCurrentPointerType:event];
|
27
28
|
[super touchesBegan:touches withEvent:event];
|
28
29
|
[_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
|
29
30
|
|