react-native-gesture-handler 2.15.0 → 2.16.0-rc.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/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
|
|