react-native-gesture-handler 2.15.0 → 2.16.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/noreanimated/src/main/java/com/swmansion/gesturehandler/ReanimatedEventDispatcher.kt +2 -0
- package/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java +9 -0
- package/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java +3 -0
- package/android/src/main/java/com/swmansion/gesturehandler/RNGestureHandlerPackage.kt +11 -6
- package/android/src/main/java/com/swmansion/gesturehandler/core/DiagonalDirections.kt +8 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt +65 -24
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +86 -22
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +54 -29
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureUtils.kt +3 -0
- 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/core/Vector.kt +66 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +119 -19
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEnabledRootView.kt +2 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.kt +1 -4
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +8 -5
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +7 -4
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +1 -1
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerStateChangeEvent.kt +1 -4
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt +4 -7
- 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 +8 -14
- 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 +50 -26
- package/apple/Handlers/RNRotationHandler.m +43 -29
- package/apple/Handlers/RNTapHandler.m +6 -4
- package/apple/RNGestureHandler.h +9 -0
- package/apple/RNGestureHandler.m +41 -4
- 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/Directions.js +19 -6
- package/lib/commonjs/Directions.js.map +1 -1
- package/lib/commonjs/PointerType.js +16 -0
- package/lib/commonjs/PointerType.js.map +1 -0
- package/lib/commonjs/RNGestureHandlerModule.web.js +7 -61
- package/lib/commonjs/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/commonjs/components/DrawerLayout.js.map +1 -1
- 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/components/Swipeable.js +3 -1
- package/lib/commonjs/components/Swipeable.js.map +1 -1
- package/lib/commonjs/components/touchables/GenericTouchable.js +1 -0
- package/lib/commonjs/components/touchables/GenericTouchable.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/customDirectEventTypes.js +14 -0
- package/lib/commonjs/handlers/customDirectEventTypes.js.map +1 -0
- package/lib/commonjs/handlers/customDirectEventTypes.web.js +11 -0
- package/lib/commonjs/handlers/customDirectEventTypes.web.js.map +1 -0
- package/lib/commonjs/handlers/gestureHandlerCommon.js +13 -2
- package/lib/commonjs/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector.js +10 -0
- package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gesture.js.map +1 -1
- package/lib/commonjs/index.js +11 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/mocks.js +2 -0
- package/lib/commonjs/mocks.js.map +1 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/commonjs/web/Gestures.js +66 -0
- package/lib/commonjs/web/Gestures.js.map +1 -0
- package/lib/commonjs/web/constants.js +3 -8
- package/lib/commonjs/web/constants.js.map +1 -1
- package/lib/commonjs/web/handlers/FlingGestureHandler.js +36 -12
- package/lib/commonjs/web/handlers/FlingGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +10 -5
- package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/IGestureHandler.js +2 -0
- package/lib/commonjs/web/handlers/IGestureHandler.js.map +1 -0
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +5 -6
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/commonjs/web/interfaces.js +1 -23
- package/lib/commonjs/web/interfaces.js.map +1 -1
- package/lib/commonjs/web/tools/EventManager.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +117 -118
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +10 -5
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/commonjs/web/tools/InteractionManager.js +12 -3
- package/lib/commonjs/web/tools/InteractionManager.js.map +1 -1
- package/lib/commonjs/web/tools/NodeManager.js.map +1 -1
- package/lib/commonjs/web/tools/PointerEventManager.js +77 -27
- package/lib/commonjs/web/tools/PointerEventManager.js.map +1 -1
- package/lib/commonjs/web/tools/TouchEventManager.js +29 -6
- package/lib/commonjs/web/tools/TouchEventManager.js.map +1 -1
- package/lib/commonjs/web/tools/Vector.js +58 -0
- package/lib/commonjs/web/tools/Vector.js.map +1 -0
- package/lib/commonjs/web/utils.js +14 -0
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/commonjs/web_hammer/NodeManager.js.map +1 -1
- package/lib/module/Directions.js +16 -4
- package/lib/module/Directions.js.map +1 -1
- package/lib/module/PointerType.js +9 -0
- package/lib/module/PointerType.js.map +1 -0
- package/lib/module/RNGestureHandlerModule.web.js +2 -39
- package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/module/components/DrawerLayout.js.map +1 -1
- 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/components/Swipeable.js +3 -1
- package/lib/module/components/Swipeable.js.map +1 -1
- package/lib/module/components/touchables/GenericTouchable.js +1 -0
- package/lib/module/components/touchables/GenericTouchable.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 +5 -1
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/customDirectEventTypes.js +3 -0
- package/lib/module/handlers/customDirectEventTypes.js.map +1 -0
- package/lib/module/handlers/customDirectEventTypes.web.js +5 -0
- package/lib/module/handlers/customDirectEventTypes.web.js.map +1 -0
- package/lib/module/handlers/gestureHandlerCommon.js +11 -1
- package/lib/module/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector.js +10 -0
- package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/module/handlers/gestures/gesture.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks.js +2 -0
- package/lib/module/mocks.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/module/web/Gestures.js +39 -0
- package/lib/module/web/Gestures.js.map +1 -0
- package/lib/module/web/constants.js +1 -6
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/handlers/FlingGestureHandler.js +34 -12
- package/lib/module/web/handlers/FlingGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +7 -4
- package/lib/module/web/handlers/GestureHandler.js.map +1 -1
- package/lib/module/web/handlers/IGestureHandler.js +2 -0
- package/lib/module/web/handlers/IGestureHandler.js.map +1 -0
- package/lib/module/web/handlers/NativeViewGestureHandler.js +5 -6
- package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/module/web/interfaces.js +0 -20
- package/lib/module/web/interfaces.js.map +1 -1
- package/lib/module/web/tools/EventManager.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerOrchestrator.js +116 -117
- package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js +9 -4
- package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/module/web/tools/InteractionManager.js +9 -3
- package/lib/module/web/tools/InteractionManager.js.map +1 -1
- package/lib/module/web/tools/NodeManager.js.map +1 -1
- package/lib/module/web/tools/PointerEventManager.js +75 -27
- package/lib/module/web/tools/PointerEventManager.js.map +1 -1
- package/lib/module/web/tools/TouchEventManager.js +28 -6
- package/lib/module/web/tools/TouchEventManager.js.map +1 -1
- package/lib/module/web/tools/Vector.js +47 -0
- package/lib/module/web/tools/Vector.js.map +1 -0
- package/lib/module/web/utils.js +4 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/module/web_hammer/NodeManager.js.map +1 -1
- package/lib/typescript/Directions.d.ts +7 -0
- package/lib/typescript/PointerType.d.ts +6 -0
- package/lib/typescript/RNGestureHandlerModule.web.d.ts +4 -39
- package/lib/typescript/components/DrawerLayout.d.ts +1 -2
- 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/components/touchables/GenericTouchable.d.ts +2 -1
- package/lib/typescript/getShadowNodeFromRef.d.ts +1 -1
- package/lib/typescript/handlers/NativeViewGestureHandler.d.ts +1 -1
- package/lib/typescript/handlers/customDirectEventTypes.d.ts +1 -0
- package/lib/typescript/handlers/customDirectEventTypes.web.d.ts +2 -0
- package/lib/typescript/handlers/gestureHandlerCommon.d.ts +13 -2
- package/lib/typescript/handlers/gestures/GestureDetector.d.ts +2 -1
- package/lib/typescript/handlers/gestures/gesture.d.ts +1 -2
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/mocks.d.ts +1 -0
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +6 -6
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +4 -1
- package/lib/typescript/web/Gestures.d.ts +36 -0
- package/lib/typescript/web/constants.d.ts +1 -6
- package/lib/typescript/web/handlers/FlingGestureHandler.d.ts +3 -3
- package/lib/typescript/web/handlers/GestureHandler.d.ts +12 -9
- package/lib/typescript/web/handlers/IGestureHandler.d.ts +38 -0
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
- package/lib/typescript/web/interfaces.d.ts +9 -16
- package/lib/typescript/web/tools/EventManager.d.ts +15 -12
- package/lib/typescript/web/tools/GestureHandlerDelegate.d.ts +3 -4
- package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +7 -5
- package/lib/typescript/web/tools/GestureHandlerWebDelegate.d.ts +3 -3
- package/lib/typescript/web/tools/InteractionManager.d.ts +6 -6
- package/lib/typescript/web/tools/NodeManager.d.ts +4 -3
- package/lib/typescript/web/tools/PointerEventManager.d.ts +11 -2
- package/lib/typescript/web/tools/TouchEventManager.d.ts +6 -1
- package/lib/typescript/web/tools/Vector.d.ts +15 -0
- package/lib/typescript/web/utils.d.ts +6 -4
- package/lib/typescript/web_hammer/NodeManager.d.ts +1 -1
- package/package.json +2 -1
- package/src/Directions.ts +21 -4
- package/src/PointerType.ts +6 -0
- package/src/RNGestureHandlerModule.web.ts +3 -44
- package/src/components/DrawerLayout.tsx +1 -1
- 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/components/Swipeable.tsx +2 -0
- package/src/components/touchables/GenericTouchable.tsx +3 -0
- package/src/getShadowNodeFromRef.ts +28 -6
- package/src/handlers/createHandler.tsx +14 -2
- package/src/handlers/customDirectEventTypes.ts +2 -0
- package/src/handlers/customDirectEventTypes.web.ts +5 -0
- package/src/handlers/gestureHandlerCommon.ts +30 -1
- package/src/handlers/gestures/GestureDetector.tsx +15 -0
- package/src/handlers/gestures/gesture.ts +1 -1
- package/src/index.ts +2 -1
- package/src/mocks.ts +2 -0
- package/src/specs/NativeRNGestureHandlerModule.ts +8 -8
- package/src/specs/RNGestureHandlerButtonNativeComponent.ts +4 -0
- package/src/web/Gestures.ts +41 -0
- package/src/web/constants.ts +1 -7
- package/src/web/handlers/FlingGestureHandler.ts +54 -24
- package/src/web/handlers/GestureHandler.ts +17 -12
- package/src/web/handlers/IGestureHandler.ts +50 -0
- package/src/web/handlers/NativeViewGestureHandler.ts +5 -6
- package/src/web/interfaces.ts +15 -17
- package/src/web/tools/EventManager.ts +16 -14
- package/src/web/tools/GestureHandlerDelegate.ts +3 -4
- package/src/web/tools/GestureHandlerOrchestrator.ts +162 -147
- package/src/web/tools/GestureHandlerWebDelegate.ts +14 -9
- package/src/web/tools/InteractionManager.ts +18 -12
- package/src/web/tools/NodeManager.ts +4 -3
- package/src/web/tools/PointerEventManager.ts +189 -154
- package/src/web/tools/TouchEventManager.ts +128 -120
- package/src/web/tools/Vector.ts +60 -0
- package/src/web/utils.ts +16 -4
- package/src/web_hammer/NodeManager.ts +1 -1
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}",
|
package/android/noreanimated/src/main/java/com/swmansion/gesturehandler/ReanimatedEventDispatcher.kt
CHANGED
@@ -4,6 +4,8 @@ import com.facebook.react.bridge.ReactContext
|
|
4
4
|
import com.facebook.react.uimanager.events.Event
|
5
5
|
|
6
6
|
class ReanimatedEventDispatcher {
|
7
|
+
@Suppress("UNUSED_PARAMETER", "COMMENT_IN_SUPPRESSION")
|
8
|
+
// This is necessary on new architecture
|
7
9
|
fun <T : Event<T>>sendEvent(event: T, reactApplicationContext: ReactContext) {
|
8
10
|
// no-op
|
9
11
|
}
|
@@ -43,6 +43,15 @@ public class RNGestureHandlerButtonManagerDelegate<T extends View, U extends Bas
|
|
43
43
|
case "touchSoundDisabled":
|
44
44
|
mViewManager.setTouchSoundDisabled(view, value == null ? false : (boolean) value);
|
45
45
|
break;
|
46
|
+
case "borderWidth":
|
47
|
+
mViewManager.setBorderWidth(view, value == null ? 0f : ((Double) value).floatValue());
|
48
|
+
break;
|
49
|
+
case "borderColor":
|
50
|
+
mViewManager.setBorderColor(view, ColorPropConverter.getColor(value, view.getContext()));
|
51
|
+
break;
|
52
|
+
case "borderStyle":
|
53
|
+
mViewManager.setBorderStyle(view, value == null ? "solid" : (String) value);
|
54
|
+
break;
|
46
55
|
default:
|
47
56
|
super.setProperty(view, propName, value);
|
48
57
|
}
|
@@ -20,4 +20,7 @@ public interface RNGestureHandlerButtonManagerInterface<T extends View> {
|
|
20
20
|
void setRippleColor(T view, @Nullable Integer value);
|
21
21
|
void setRippleRadius(T view, int value);
|
22
22
|
void setTouchSoundDisabled(T view, boolean value);
|
23
|
+
void setBorderWidth(T view, float value);
|
24
|
+
void setBorderColor(T view, @Nullable Integer value);
|
25
|
+
void setBorderStyle(T view, @Nullable String value);
|
23
26
|
}
|
@@ -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
|
@@ -55,20 +60,20 @@ class RNGestureHandlerPackage : TurboReactPackage(), ViewManagerOnDemandReactPac
|
|
55
60
|
try {
|
56
61
|
val reactModuleInfoProviderClass =
|
57
62
|
Class.forName("com.swmansion.gesturehandler.RNGestureHandlerPackage$\$ReactModuleInfoProvider")
|
58
|
-
return reactModuleInfoProviderClass.newInstance() as ReactModuleInfoProvider
|
63
|
+
return reactModuleInfoProviderClass.getDeclaredConstructor().newInstance() as ReactModuleInfoProvider
|
59
64
|
} catch (e: ClassNotFoundException) {
|
60
65
|
return ReactModuleInfoProvider {
|
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
|
+
true, // Has constants is hardcoded to return true, so replacing it with `true` changes nothing.
|
70
75
|
reactModule.isCxxModule,
|
71
|
-
|
76
|
+
true
|
72
77
|
)
|
73
78
|
)
|
74
79
|
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
package com.swmansion.gesturehandler.core
|
2
|
+
|
3
|
+
object DiagonalDirections {
|
4
|
+
const val DIRECTION_RIGHT_UP = GestureHandler.DIRECTION_RIGHT or GestureHandler.DIRECTION_UP
|
5
|
+
const val DIRECTION_RIGHT_DOWN = GestureHandler.DIRECTION_RIGHT or GestureHandler.DIRECTION_DOWN
|
6
|
+
const val DIRECTION_LEFT_UP = GestureHandler.DIRECTION_LEFT or GestureHandler.DIRECTION_UP
|
7
|
+
const val DIRECTION_LEFT_DOWN = GestureHandler.DIRECTION_LEFT or GestureHandler.DIRECTION_DOWN
|
8
|
+
}
|
@@ -3,18 +3,18 @@ package com.swmansion.gesturehandler.core
|
|
3
3
|
import android.os.Handler
|
4
4
|
import android.os.Looper
|
5
5
|
import android.view.MotionEvent
|
6
|
+
import android.view.VelocityTracker
|
6
7
|
|
7
8
|
class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
|
8
9
|
var numberOfPointersRequired = DEFAULT_NUMBER_OF_TOUCHES_REQUIRED
|
9
10
|
var direction = DEFAULT_DIRECTION
|
10
11
|
|
11
12
|
private val maxDurationMs = DEFAULT_MAX_DURATION_MS
|
12
|
-
private val
|
13
|
-
private var startX = 0f
|
14
|
-
private var startY = 0f
|
13
|
+
private val minVelocity = DEFAULT_MIN_VELOCITY
|
15
14
|
private var handler: Handler? = null
|
16
15
|
private var maxNumberOfPointersSimultaneously = 0
|
17
16
|
private val failDelayed = Runnable { fail() }
|
17
|
+
private var velocityTracker: VelocityTracker? = null
|
18
18
|
|
19
19
|
override fun resetConfig() {
|
20
20
|
super.resetConfig()
|
@@ -23,8 +23,7 @@ class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
private fun startFling(event: MotionEvent) {
|
26
|
-
|
27
|
-
startY = event.rawY
|
26
|
+
velocityTracker = VelocityTracker.obtain()
|
28
27
|
begin()
|
29
28
|
maxNumberOfPointersSimultaneously = 1
|
30
29
|
if (handler == null) {
|
@@ -35,26 +34,48 @@ class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
|
|
35
34
|
handler!!.postDelayed(failDelayed, maxDurationMs)
|
36
35
|
}
|
37
36
|
|
38
|
-
private fun tryEndFling(event: MotionEvent)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
private fun tryEndFling(event: MotionEvent): Boolean {
|
38
|
+
addVelocityMovement(velocityTracker, event)
|
39
|
+
|
40
|
+
val velocityVector = Vector.fromVelocity(velocityTracker!!)
|
41
|
+
|
42
|
+
fun getVelocityAlignment(
|
43
|
+
direction: Int,
|
44
|
+
maxDeviationCosine: Double,
|
45
|
+
): Boolean = (
|
46
|
+
(this.direction and direction) == direction &&
|
47
|
+
velocityVector.isSimilar(Vector.fromDirection(direction), maxDeviationCosine)
|
49
48
|
)
|
50
|
-
) {
|
51
|
-
handler!!.removeCallbacksAndMessages(null)
|
52
|
-
activate()
|
53
|
-
true
|
54
|
-
} else {
|
55
|
-
false
|
56
|
-
}
|
57
49
|
|
50
|
+
val axialAlignmentsList = arrayOf(
|
51
|
+
DIRECTION_LEFT,
|
52
|
+
DIRECTION_RIGHT,
|
53
|
+
DIRECTION_UP,
|
54
|
+
DIRECTION_DOWN,
|
55
|
+
).map { direction -> getVelocityAlignment(direction, MAX_AXIAL_DEVIATION) }
|
56
|
+
|
57
|
+
val diagonalAlignmentsList = arrayOf(
|
58
|
+
DiagonalDirections.DIRECTION_RIGHT_UP,
|
59
|
+
DiagonalDirections.DIRECTION_RIGHT_DOWN,
|
60
|
+
DiagonalDirections.DIRECTION_LEFT_UP,
|
61
|
+
DiagonalDirections.DIRECTION_LEFT_DOWN,
|
62
|
+
).map { direction -> getVelocityAlignment(direction, MAX_DIAGONAL_DEVIATION) }
|
63
|
+
|
64
|
+
val isAligned = axialAlignmentsList.any { it } or diagonalAlignmentsList.any { it }
|
65
|
+
val isFast = velocityVector.magnitude > this.minVelocity
|
66
|
+
|
67
|
+
return if (
|
68
|
+
maxNumberOfPointersSimultaneously == numberOfPointersRequired &&
|
69
|
+
isAligned &&
|
70
|
+
isFast
|
71
|
+
) {
|
72
|
+
handler!!.removeCallbacksAndMessages(null)
|
73
|
+
activate()
|
74
|
+
true
|
75
|
+
} else {
|
76
|
+
false
|
77
|
+
}
|
78
|
+
}
|
58
79
|
override fun activate(force: Boolean) {
|
59
80
|
super.activate(force)
|
60
81
|
end()
|
@@ -67,6 +88,10 @@ class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
|
|
67
88
|
}
|
68
89
|
|
69
90
|
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
|
91
|
+
if (!shouldActivateWithMouse(sourceEvent)) {
|
92
|
+
return
|
93
|
+
}
|
94
|
+
|
70
95
|
val state = state
|
71
96
|
if (state == STATE_UNDETERMINED) {
|
72
97
|
startFling(sourceEvent)
|
@@ -88,13 +113,29 @@ class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
|
|
88
113
|
}
|
89
114
|
|
90
115
|
override fun onReset() {
|
116
|
+
velocityTracker?.recycle()
|
117
|
+
velocityTracker = null
|
91
118
|
handler?.removeCallbacksAndMessages(null)
|
92
119
|
}
|
93
120
|
|
121
|
+
private fun addVelocityMovement(tracker: VelocityTracker?, event: MotionEvent) {
|
122
|
+
val offsetX = event.rawX - event.x
|
123
|
+
val offsetY = event.rawY - event.y
|
124
|
+
event.offsetLocation(offsetX, offsetY)
|
125
|
+
tracker!!.addMovement(event)
|
126
|
+
event.offsetLocation(-offsetX, -offsetY)
|
127
|
+
}
|
128
|
+
|
94
129
|
companion object {
|
95
130
|
private const val DEFAULT_MAX_DURATION_MS: Long = 800
|
96
|
-
private const val
|
131
|
+
private const val DEFAULT_MIN_VELOCITY: Long = 2000
|
132
|
+
private const val DEFAULT_ALIGNMENT_CONE: Double = 30.0
|
97
133
|
private const val DEFAULT_DIRECTION = DIRECTION_RIGHT
|
98
134
|
private const val DEFAULT_NUMBER_OF_TOUCHES_REQUIRED = 1
|
135
|
+
|
136
|
+
private val MAX_AXIAL_DEVIATION: Double =
|
137
|
+
GestureUtils.coneToDeviation(DEFAULT_ALIGNMENT_CONE)
|
138
|
+
private val MAX_DIAGONAL_DEVIATION: Double =
|
139
|
+
GestureUtils.coneToDeviation(90 - DEFAULT_ALIGNMENT_CONE)
|
99
140
|
}
|
100
141
|
}
|
@@ -4,13 +4,13 @@ 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.
|
7
|
+
import android.os.Build
|
8
8
|
import android.view.MotionEvent
|
9
9
|
import android.view.MotionEvent.PointerCoords
|
10
10
|
import android.view.MotionEvent.PointerProperties
|
11
11
|
import android.view.View
|
12
|
-
import android.view.Window
|
13
12
|
import com.facebook.react.bridge.Arguments
|
13
|
+
import com.facebook.react.bridge.ReactContext
|
14
14
|
import com.facebook.react.bridge.UiThreadUtil
|
15
15
|
import com.facebook.react.bridge.WritableArray
|
16
16
|
import com.facebook.react.uimanager.PixelUtil
|
@@ -67,6 +67,10 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
67
67
|
protected var orchestrator: GestureHandlerOrchestrator? = null
|
68
68
|
private var onTouchEventListener: OnTouchEventListener? = null
|
69
69
|
private var interactionController: GestureHandlerInteractionController? = null
|
70
|
+
var pointerType: Int = POINTER_TYPE_OTHER
|
71
|
+
private set
|
72
|
+
|
73
|
+
protected var mouseButton = 0
|
70
74
|
|
71
75
|
@Suppress("UNCHECKED_CAST")
|
72
76
|
protected fun self(): ConcreteGestureHandlerT = this as ConcreteGestureHandlerT
|
@@ -159,6 +163,10 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
159
163
|
fun setInteractionController(controller: GestureHandlerInteractionController?): ConcreteGestureHandlerT =
|
160
164
|
applySelf { interactionController = controller }
|
161
165
|
|
166
|
+
fun setMouseButton(mouseButton: Int) = apply {
|
167
|
+
this.mouseButton = mouseButton
|
168
|
+
}
|
169
|
+
|
162
170
|
fun prepare(view: View?, orchestrator: GestureHandlerOrchestrator?) {
|
163
171
|
check(!(this.view != null || this.orchestrator != null)) { "Already prepared or hasn't been reset" }
|
164
172
|
Arrays.fill(trackedPointerIDs, -1)
|
@@ -167,12 +175,9 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
167
175
|
this.view = view
|
168
176
|
this.orchestrator = orchestrator
|
169
177
|
|
170
|
-
val
|
171
|
-
if (
|
172
|
-
|
173
|
-
decorView.getWindowVisibleDisplayFrame(frame)
|
174
|
-
windowOffset[0] = frame.left
|
175
|
-
windowOffset[1] = frame.top
|
178
|
+
val content = getActivity(view?.context)?.findViewById<View>(android.R.id.content)
|
179
|
+
if (content != null) {
|
180
|
+
content.getLocationOnScreen(windowOffset)
|
176
181
|
} else {
|
177
182
|
windowOffset[0] = 0
|
178
183
|
windowOffset[1] = 0
|
@@ -183,13 +188,13 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
183
188
|
|
184
189
|
protected open fun onPrepare() {}
|
185
190
|
|
186
|
-
private fun
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
191
|
+
private fun getActivity(context: Context?): Activity? =
|
192
|
+
when (context) {
|
193
|
+
is ReactContext -> context.currentActivity
|
194
|
+
is Activity -> context
|
195
|
+
is ContextWrapper -> getActivity(context.baseContext)
|
196
|
+
else -> null
|
197
|
+
}
|
193
198
|
|
194
199
|
private fun findNextLocalPointerId(): Int {
|
195
200
|
var localPointerId = 0
|
@@ -371,6 +376,11 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
371
376
|
lastAbsolutePositionY = GestureUtils.getLastPointerY(adaptedTransformedEvent, true)
|
372
377
|
lastEventOffsetX = adaptedTransformedEvent.rawX - adaptedTransformedEvent.x
|
373
378
|
lastEventOffsetY = adaptedTransformedEvent.rawY - adaptedTransformedEvent.y
|
379
|
+
|
380
|
+
if (sourceEvent.action == MotionEvent.ACTION_DOWN || sourceEvent.action == MotionEvent.ACTION_HOVER_ENTER || sourceEvent.action == MotionEvent.ACTION_HOVER_MOVE) {
|
381
|
+
setPointerType(sourceEvent)
|
382
|
+
}
|
383
|
+
|
374
384
|
if (sourceEvent.action == MotionEvent.ACTION_HOVER_ENTER ||
|
375
385
|
sourceEvent.action == MotionEvent.ACTION_HOVER_MOVE ||
|
376
386
|
sourceEvent.action == MotionEvent.ACTION_HOVER_EXIT
|
@@ -642,7 +652,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
642
652
|
}
|
643
653
|
|
644
654
|
fun cancel() {
|
645
|
-
if (state == STATE_ACTIVE || state == STATE_UNDETERMINED || state == STATE_BEGAN) {
|
655
|
+
if (state == STATE_ACTIVE || state == STATE_UNDETERMINED || state == STATE_BEGAN || this.isAwaiting) {
|
646
656
|
onCancel()
|
647
657
|
moveToState(STATE_CANCELLED)
|
648
658
|
}
|
@@ -688,6 +698,46 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
688
698
|
protected open fun onReset() {}
|
689
699
|
protected open fun onCancel() {}
|
690
700
|
|
701
|
+
private fun isButtonInConfig(clickedButton: Int): Boolean {
|
702
|
+
if (mouseButton == 0) {
|
703
|
+
return clickedButton == MotionEvent.BUTTON_PRIMARY
|
704
|
+
}
|
705
|
+
|
706
|
+
return clickedButton and mouseButton != 0
|
707
|
+
}
|
708
|
+
|
709
|
+
protected fun shouldActivateWithMouse(sourceEvent: MotionEvent): Boolean {
|
710
|
+
// 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.
|
711
|
+
// On API >= 23, we will use events with infix BUTTON, otherwise we use standard action events (like ACTION_DOWN).
|
712
|
+
|
713
|
+
with(sourceEvent) {
|
714
|
+
// To use actionButton, we need API >= 23.
|
715
|
+
if (getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
716
|
+
// While using mouse, we want to ignore default events for touch.
|
717
|
+
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) {
|
718
|
+
return@shouldActivateWithMouse false
|
719
|
+
}
|
720
|
+
|
721
|
+
// 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.
|
722
|
+
if (action != MotionEvent.ACTION_MOVE && !isButtonInConfig(actionButton)) {
|
723
|
+
return@shouldActivateWithMouse false
|
724
|
+
}
|
725
|
+
|
726
|
+
// When we receive ACTION_MOVE, we have to check buttonState field.
|
727
|
+
if (action == MotionEvent.ACTION_MOVE && !isButtonInConfig(buttonState)) {
|
728
|
+
return@shouldActivateWithMouse false
|
729
|
+
}
|
730
|
+
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
731
|
+
// We do not fully support mouse below API 23, so we will ignore BUTTON events.
|
732
|
+
if (action == MotionEvent.ACTION_BUTTON_PRESS || action == MotionEvent.ACTION_BUTTON_RELEASE) {
|
733
|
+
return@shouldActivateWithMouse false
|
734
|
+
}
|
735
|
+
}
|
736
|
+
}
|
737
|
+
|
738
|
+
return true
|
739
|
+
}
|
740
|
+
|
691
741
|
/**
|
692
742
|
* Transforms a point in the coordinate space of the wrapperView (GestureHandlerRootView) to
|
693
743
|
* coordinate space of the view the gesture is attached to.
|
@@ -708,7 +758,6 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
708
758
|
orchestrator = null
|
709
759
|
Arrays.fill(trackedPointerIDs, -1)
|
710
760
|
trackedPointersIDsCount = 0
|
711
|
-
|
712
761
|
trackedPointersCount = 0
|
713
762
|
trackedPointers.fill(null)
|
714
763
|
touchEventType = RNGestureHandlerTouchEvent.EVENT_UNDETERMINED
|
@@ -721,6 +770,17 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
721
770
|
isWithinBounds = false
|
722
771
|
}
|
723
772
|
|
773
|
+
private fun setPointerType(event: MotionEvent) {
|
774
|
+
val pointerIndex = event.actionIndex
|
775
|
+
|
776
|
+
pointerType = when (event.getToolType(pointerIndex)) {
|
777
|
+
MotionEvent.TOOL_TYPE_FINGER -> POINTER_TYPE_TOUCH
|
778
|
+
MotionEvent.TOOL_TYPE_STYLUS -> POINTER_TYPE_STYLUS
|
779
|
+
MotionEvent.TOOL_TYPE_MOUSE -> POINTER_TYPE_MOUSE
|
780
|
+
else -> POINTER_TYPE_OTHER
|
781
|
+
}
|
782
|
+
}
|
783
|
+
|
724
784
|
fun setOnTouchEventListener(listener: OnTouchEventListener?): GestureHandler<*> {
|
725
785
|
onTouchEventListener = listener
|
726
786
|
return this
|
@@ -763,19 +823,23 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
763
823
|
const val ACTION_TYPE_NATIVE_ANIMATED_EVENT = 2
|
764
824
|
const val ACTION_TYPE_JS_FUNCTION_OLD_API = 3
|
765
825
|
const val ACTION_TYPE_JS_FUNCTION_NEW_API = 4
|
826
|
+
const val POINTER_TYPE_TOUCH = 0
|
827
|
+
const val POINTER_TYPE_STYLUS = 1
|
828
|
+
const val POINTER_TYPE_MOUSE = 2
|
829
|
+
const val POINTER_TYPE_OTHER = 3
|
766
830
|
private const val MAX_POINTERS_COUNT = 12
|
767
831
|
private lateinit var pointerProps: Array<PointerProperties?>
|
768
832
|
private lateinit var pointerCoords: Array<PointerCoords?>
|
769
833
|
private fun initPointerProps(size: Int) {
|
770
|
-
var
|
834
|
+
var pointerPropsSize = size
|
771
835
|
if (!Companion::pointerProps.isInitialized) {
|
772
836
|
pointerProps = arrayOfNulls(MAX_POINTERS_COUNT)
|
773
837
|
pointerCoords = arrayOfNulls(MAX_POINTERS_COUNT)
|
774
838
|
}
|
775
|
-
while (
|
776
|
-
pointerProps[
|
777
|
-
pointerCoords[
|
778
|
-
|
839
|
+
while (pointerPropsSize > 0 && pointerProps[pointerPropsSize - 1] == null) {
|
840
|
+
pointerProps[pointerPropsSize - 1] = PointerProperties()
|
841
|
+
pointerCoords[pointerPropsSize - 1] = PointerCoords()
|
842
|
+
pointerPropsSize--
|
779
843
|
}
|
780
844
|
}
|
781
845
|
|
package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt
CHANGED
@@ -7,6 +7,7 @@ import android.view.View
|
|
7
7
|
import android.view.ViewGroup
|
8
8
|
import android.widget.EditText
|
9
9
|
import java.util.*
|
10
|
+
import kotlin.collections.HashSet
|
10
11
|
|
11
12
|
class GestureHandlerOrchestrator(
|
12
13
|
private val wrapperView: ViewGroup,
|
@@ -22,6 +23,14 @@ class GestureHandlerOrchestrator(
|
|
22
23
|
private val gestureHandlers = arrayListOf<GestureHandler<*>>()
|
23
24
|
private val awaitingHandlers = arrayListOf<GestureHandler<*>>()
|
24
25
|
private val preparedHandlers = arrayListOf<GestureHandler<*>>()
|
26
|
+
|
27
|
+
// In `onHandlerStateChange` method we iterate through `awaitingHandlers`, but calling `tryActivate` may modify this list.
|
28
|
+
// To avoid `ConcurrentModificationException` we iterate through copy. There is one more problem though - if handler was
|
29
|
+
// removed from `awaitingHandlers`, it was still present in copy of original list. This hashset helps us identify which handlers
|
30
|
+
// are really inside `awaitingHandlers`.
|
31
|
+
// `contains` method on HashSet has O(1) complexity, so calling it inside for loop won't result in O(n^2) (contrary to ArrayList)
|
32
|
+
private val awaitingHandlersTags = HashSet<Int>()
|
33
|
+
|
25
34
|
private var isHandlingTouch = false
|
26
35
|
private var handlingChangeSemaphore = 0
|
27
36
|
private var finishedHandlersCleanupScheduled = false
|
@@ -73,16 +82,18 @@ class GestureHandlerOrchestrator(
|
|
73
82
|
finishedHandlersCleanupScheduled = false
|
74
83
|
}
|
75
84
|
|
76
|
-
private fun hasOtherHandlerToWaitFor(handler: GestureHandler<*>)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
}
|
81
|
-
}
|
82
|
-
return false
|
83
|
-
}
|
85
|
+
private fun hasOtherHandlerToWaitFor(handler: GestureHandler<*>) =
|
86
|
+
gestureHandlers.any { !isFinished(it.state) && shouldHandlerWaitForOther(handler, it) }
|
87
|
+
|
88
|
+
private fun shouldBeCancelledByFinishedHandler(handler: GestureHandler<*>) = gestureHandlers.any { shouldHandlerWaitForOther(handler, it) && it.state == GestureHandler.STATE_END }
|
84
89
|
|
85
90
|
private fun tryActivate(handler: GestureHandler<*>) {
|
91
|
+
// If we are waiting for a gesture that has successfully finished, we should cancel handler
|
92
|
+
if (shouldBeCancelledByFinishedHandler(handler)) {
|
93
|
+
handler.cancel()
|
94
|
+
return
|
95
|
+
}
|
96
|
+
|
86
97
|
// see if there is anyone else who we need to wait for
|
87
98
|
if (hasOtherHandlerToWaitFor(handler)) {
|
88
99
|
addAwaitingHandler(handler)
|
@@ -94,34 +105,47 @@ class GestureHandlerOrchestrator(
|
|
94
105
|
}
|
95
106
|
|
96
107
|
private fun cleanupAwaitingHandlers() {
|
97
|
-
|
108
|
+
val awaitingHandlersCopy = awaitingHandlers.toList()
|
109
|
+
|
110
|
+
for (handler in awaitingHandlersCopy) {
|
111
|
+
if (!handler.isAwaiting) {
|
112
|
+
awaitingHandlers.remove(handler)
|
113
|
+
awaitingHandlersTags.remove(handler.tag)
|
114
|
+
}
|
115
|
+
}
|
98
116
|
}
|
99
117
|
|
100
118
|
/*package*/
|
101
119
|
fun onHandlerStateChange(handler: GestureHandler<*>, newState: Int, prevState: Int) {
|
102
120
|
handlingChangeSemaphore += 1
|
103
121
|
if (isFinished(newState)) {
|
122
|
+
// We have to loop through copy in order to avoid modifying collection
|
123
|
+
// while iterating over its elements
|
124
|
+
val currentlyAwaitingHandlers = awaitingHandlers.toList()
|
125
|
+
|
104
126
|
// 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)
|
127
|
+
for (otherHandler in currentlyAwaitingHandlers) {
|
128
|
+
if (!shouldHandlerWaitForOther(otherHandler, handler) || !awaitingHandlersTags.contains(otherHandler.tag)) {
|
129
|
+
continue
|
130
|
+
}
|
131
|
+
|
132
|
+
if (newState == GestureHandler.STATE_END) {
|
133
|
+
// gesture has ended, we need to kill the awaiting handler
|
134
|
+
otherHandler.cancel()
|
135
|
+
if (otherHandler.state == GestureHandler.STATE_END) {
|
136
|
+
// Handle edge case, where discrete gestures end immediately after activation thus
|
137
|
+
// their state is set to END and when the gesture they are waiting for activates they
|
138
|
+
// should be cancelled, however `cancel` was never sent as gestures were already in the END state.
|
139
|
+
// Send synthetic BEGAN -> CANCELLED to properly handle JS logic
|
140
|
+
otherHandler.dispatchStateChange(
|
141
|
+
GestureHandler.STATE_CANCELLED,
|
142
|
+
GestureHandler.STATE_BEGAN
|
143
|
+
)
|
124
144
|
}
|
145
|
+
otherHandler.isAwaiting = false
|
146
|
+
} else {
|
147
|
+
// gesture has failed recognition, we may try activating
|
148
|
+
tryActivate(otherHandler)
|
125
149
|
}
|
126
150
|
}
|
127
151
|
cleanupAwaitingHandlers()
|
@@ -168,7 +192,6 @@ class GestureHandlerOrchestrator(
|
|
168
192
|
// Clear all awaiting handlers waiting for the current handler to fail
|
169
193
|
for (otherHandler in awaitingHandlers.reversed()) {
|
170
194
|
if (shouldHandlerBeCancelledBy(otherHandler, handler)) {
|
171
|
-
otherHandler.cancel()
|
172
195
|
otherHandler.isAwaiting = false
|
173
196
|
}
|
174
197
|
}
|
@@ -383,6 +406,8 @@ class GestureHandlerOrchestrator(
|
|
383
406
|
}
|
384
407
|
|
385
408
|
awaitingHandlers.add(handler)
|
409
|
+
awaitingHandlersTags.add(handler.tag)
|
410
|
+
|
386
411
|
with(handler) {
|
387
412
|
isAwaiting = true
|
388
413
|
activationIndex = this@GestureHandlerOrchestrator.activationIndex++
|
@@ -1,6 +1,7 @@
|
|
1
1
|
package com.swmansion.gesturehandler.core
|
2
2
|
|
3
3
|
import android.view.MotionEvent
|
4
|
+
import kotlin.math.cos
|
4
5
|
|
5
6
|
object GestureUtils {
|
6
7
|
fun getLastPointerX(event: MotionEvent, averageTouches: Boolean): Float {
|
@@ -44,4 +45,6 @@ object GestureUtils {
|
|
44
45
|
event.getY(lastPointerIdx)
|
45
46
|
}
|
46
47
|
}
|
48
|
+
fun coneToDeviation(angle: Double): Double =
|
49
|
+
cos(Math.toRadians(angle / 2.0))
|
47
50
|
}
|
@@ -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
|