react-native-gesture-handler 1.10.3 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +7 -6
- package/android/build.gradle +49 -1
- package/android/common/src/main/java/com/swmansion/common/GestureHandlerStateManager.kt +5 -0
- package/android/gradle.properties +19 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/BaseGestureHandlerInteractionController.kt +18 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/Extensions.kt +11 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/FlingGestureHandler.kt +96 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandler.kt +713 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerInteractionController.kt +8 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerOrchestrator.kt +562 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerRegistry.kt +8 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerRegistryImpl.kt +21 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureUtils.kt +49 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/LongPressGestureHandler.kt +97 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/ManualGestureHandler.kt +11 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/NativeViewGestureHandler.kt +129 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/OnTouchEventListener.kt +9 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/PanGestureHandler.kt +289 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/PinchGestureHandler.kt +88 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/{PointerEventsConfig.java → PointerEventsConfig.kt} +3 -5
- package/android/lib/src/main/java/com/swmansion/gesturehandler/RotationGestureDetector.kt +125 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/RotationGestureHandler.kt +79 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/TapGestureHandler.kt +167 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/ViewConfigurationHelper.kt +10 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +348 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEnabledRootView.kt +57 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.kt +59 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEventDataExtractor.kt +8 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerInteractionManager.kt +61 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +686 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerPackage.kt +17 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRegistry.kt +95 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +132 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootInterface.kt +5 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +68 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.kt +34 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerStateChangeEvent.kt +66 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt +69 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNViewConfigurationHelper.kt +51 -0
- package/ios/Handlers/RNFlingHandler.m +78 -5
- package/ios/Handlers/RNForceTouchHandler.m +29 -4
- package/ios/Handlers/RNLongPressHandler.m +105 -3
- package/ios/Handlers/RNManualHandler.h +4 -0
- package/ios/Handlers/RNManualHandler.m +73 -0
- package/ios/Handlers/RNNativeViewHandler.m +30 -2
- package/ios/Handlers/RNPanHandler.m +64 -4
- package/ios/Handlers/RNPinchHandler.m +61 -2
- package/ios/Handlers/RNRotationHandler.m +60 -1
- package/ios/Handlers/RNTapHandler.m +55 -8
- package/ios/RNGestureHandler.h +18 -4
- package/ios/RNGestureHandler.m +123 -13
- package/ios/RNGestureHandlerEvents.h +9 -0
- package/ios/RNGestureHandlerEvents.m +34 -0
- package/ios/RNGestureHandlerManager.h +7 -0
- package/ios/RNGestureHandlerManager.m +62 -34
- package/ios/RNGestureHandlerModule.m +39 -3
- package/ios/RNGestureHandlerPointerTracker.h +25 -0
- package/ios/RNGestureHandlerPointerTracker.m +237 -0
- package/ios/RNGestureHandlerRegistry.h +1 -0
- package/ios/RNGestureHandlerRegistry.m +10 -0
- package/ios/RNGestureHandlerStateManager.h +5 -0
- package/ios/RNManualActivationRecognizer.h +10 -0
- package/ios/RNManualActivationRecognizer.m +80 -0
- package/ios/RNRootViewGestureRecognizer.m +1 -1
- package/ios/RNTouchEventType.h +9 -0
- package/lib/commonjs/EventType.js +16 -0
- package/lib/commonjs/EventType.js.map +1 -0
- package/lib/commonjs/GestureHandlerRootView.android.js +1 -13
- package/lib/commonjs/GestureHandlerRootView.android.js.map +1 -1
- package/lib/commonjs/GestureHandlerRootView.js +11 -3
- package/lib/commonjs/GestureHandlerRootView.js.map +1 -1
- package/lib/commonjs/RNGestureHandlerModule.js +3 -1
- package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/RNGestureHandlerModule.web.js +2 -2
- package/lib/commonjs/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/commonjs/components/DrawerLayout.js +41 -37
- package/lib/commonjs/components/DrawerLayout.js.map +1 -1
- package/lib/commonjs/components/GestureButtons.js.map +1 -1
- package/lib/commonjs/components/GestureComponents.js +31 -12
- package/lib/commonjs/components/GestureComponents.js.map +1 -1
- package/lib/commonjs/components/Swipeable.js +10 -6
- package/lib/commonjs/components/Swipeable.js.map +1 -1
- package/lib/commonjs/components/touchables/GenericTouchable.js +2 -1
- package/lib/commonjs/components/touchables/GenericTouchable.js.map +1 -1
- package/lib/commonjs/components/touchables/TouchableOpacity.js +1 -1
- package/lib/commonjs/components/touchables/TouchableOpacity.js.map +1 -1
- package/lib/commonjs/gestureHandlerRootHOC.js +1 -1
- package/lib/commonjs/gestureHandlerRootHOC.js.map +1 -1
- package/lib/commonjs/handlers/FlingGestureHandler.js +23 -0
- package/lib/commonjs/handlers/FlingGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/ForceTouchGestureHandler.js +44 -0
- package/lib/commonjs/handlers/ForceTouchGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/LongPressGestureHandler.js +23 -0
- package/lib/commonjs/handlers/LongPressGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/NativeViewGestureHandler.js +6 -4
- package/lib/commonjs/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/PanGestureHandler.js +121 -0
- package/lib/commonjs/handlers/PanGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/PinchGestureHandler.js +21 -0
- package/lib/commonjs/handlers/PinchGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/RotationGestureHandler.js +21 -0
- package/lib/commonjs/handlers/RotationGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/TapGestureHandler.js +23 -0
- package/lib/commonjs/handlers/TapGestureHandler.js.map +1 -0
- package/lib/commonjs/handlers/createHandler.js +52 -83
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestureHandlerCommon.js +80 -0
- package/lib/commonjs/handlers/gestureHandlerCommon.js.map +1 -0
- package/lib/commonjs/handlers/gestures/GestureDetector.js +440 -0
- package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -0
- package/lib/commonjs/handlers/gestures/eventReceiver.js +135 -0
- package/lib/commonjs/handlers/gestures/eventReceiver.js.map +1 -0
- package/lib/commonjs/handlers/gestures/flingGesture.js +34 -0
- package/lib/commonjs/handlers/gestures/flingGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/forceTouchGesture.js +65 -0
- package/lib/commonjs/handlers/gestures/forceTouchGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/gesture.js +193 -0
- package/lib/commonjs/handlers/gestures/gesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/gestureComposition.js +94 -0
- package/lib/commonjs/handlers/gestures/gestureComposition.js.map +1 -0
- package/lib/commonjs/handlers/gestures/gestureObjects.js +85 -0
- package/lib/commonjs/handlers/gestures/gestureObjects.js.map +1 -0
- package/lib/commonjs/handlers/gestures/gestureStateManager.js +58 -0
- package/lib/commonjs/handlers/gestures/gestureStateManager.js.map +1 -0
- package/lib/commonjs/handlers/gestures/longPressGesture.js +34 -0
- package/lib/commonjs/handlers/gestures/longPressGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/manualGesture.js +31 -0
- package/lib/commonjs/handlers/gestures/manualGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/nativeGesture.js +34 -0
- package/lib/commonjs/handlers/gestures/nativeGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/panGesture.js +144 -0
- package/lib/commonjs/handlers/gestures/panGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/pinchGesture.js +45 -0
- package/lib/commonjs/handlers/gestures/pinchGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/reanimatedWrapper.js +24 -0
- package/lib/commonjs/handlers/gestures/reanimatedWrapper.js.map +1 -0
- package/lib/commonjs/handlers/gestures/rotationGesture.js +45 -0
- package/lib/commonjs/handlers/gestures/rotationGesture.js.map +1 -0
- package/lib/commonjs/handlers/gestures/tapGesture.js +59 -0
- package/lib/commonjs/handlers/gestures/tapGesture.js.map +1 -0
- package/lib/commonjs/handlers/handlersRegistry.js +31 -0
- package/lib/commonjs/handlers/handlersRegistry.js.map +1 -0
- package/lib/commonjs/index.js +146 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/init.js +13 -0
- package/lib/commonjs/init.js.map +1 -0
- package/lib/commonjs/mocks.js +31 -2
- package/lib/commonjs/mocks.js.map +1 -1
- package/lib/commonjs/utils.js +15 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/commonjs/web/Errors.js +1 -1
- package/lib/commonjs/web/Errors.js.map +1 -1
- package/lib/commonjs/web/GestureHandler.js +4 -6
- package/lib/commonjs/web/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/NodeManager.js +8 -2
- package/lib/commonjs/web/NodeManager.js.map +1 -1
- package/lib/module/EventType.js +8 -0
- package/lib/module/EventType.js.map +1 -0
- package/lib/module/GestureHandlerRootView.android.js +2 -14
- package/lib/module/GestureHandlerRootView.android.js.map +1 -1
- package/lib/module/GestureHandlerRootView.js +5 -1
- package/lib/module/GestureHandlerRootView.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.js +3 -1
- package/lib/module/RNGestureHandlerModule.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.web.js +2 -2
- package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/module/components/DrawerLayout.js +43 -40
- package/lib/module/components/DrawerLayout.js.map +1 -1
- package/lib/module/components/GestureButtons.js.map +1 -1
- package/lib/module/components/GestureComponents.js +29 -11
- package/lib/module/components/GestureComponents.js.map +1 -1
- package/lib/module/components/Swipeable.js +9 -6
- package/lib/module/components/Swipeable.js.map +1 -1
- package/lib/module/components/touchables/GenericTouchable.js +2 -1
- package/lib/module/components/touchables/GenericTouchable.js.map +1 -1
- package/lib/module/components/touchables/TouchableOpacity.js +1 -1
- package/lib/module/components/touchables/TouchableOpacity.js.map +1 -1
- package/lib/module/gestureHandlerRootHOC.js +1 -1
- package/lib/module/gestureHandlerRootHOC.js.map +1 -1
- package/lib/module/handlers/FlingGestureHandler.js +10 -0
- package/lib/module/handlers/FlingGestureHandler.js.map +1 -0
- package/lib/module/handlers/ForceTouchGestureHandler.js +29 -0
- package/lib/module/handlers/ForceTouchGestureHandler.js.map +1 -0
- package/lib/module/handlers/LongPressGestureHandler.js +10 -0
- package/lib/module/handlers/LongPressGestureHandler.js.map +1 -0
- package/lib/module/handlers/NativeViewGestureHandler.js +4 -3
- package/lib/module/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/module/handlers/PanGestureHandler.js +106 -0
- package/lib/module/handlers/PanGestureHandler.js.map +1 -0
- package/lib/module/handlers/PinchGestureHandler.js +9 -0
- package/lib/module/handlers/PinchGestureHandler.js.map +1 -0
- package/lib/module/handlers/RotationGestureHandler.js +9 -0
- package/lib/module/handlers/RotationGestureHandler.js.map +1 -0
- package/lib/module/handlers/TapGestureHandler.js +10 -0
- package/lib/module/handlers/TapGestureHandler.js.map +1 -0
- package/lib/module/handlers/createHandler.js +41 -76
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestureHandlerCommon.js +66 -0
- package/lib/module/handlers/gestureHandlerCommon.js.map +1 -0
- package/lib/module/handlers/gestures/GestureDetector.js +402 -0
- package/lib/module/handlers/gestures/GestureDetector.js.map +1 -0
- package/lib/module/handlers/gestures/eventReceiver.js +120 -0
- package/lib/module/handlers/gestures/eventReceiver.js.map +1 -0
- package/lib/module/handlers/gestures/flingGesture.js +24 -0
- package/lib/module/handlers/gestures/flingGesture.js.map +1 -0
- package/lib/module/handlers/gestures/forceTouchGesture.js +56 -0
- package/lib/module/handlers/gestures/forceTouchGesture.js.map +1 -0
- package/lib/module/handlers/gestures/gesture.js +175 -0
- package/lib/module/handlers/gestures/gesture.js.map +1 -0
- package/lib/module/handlers/gestures/gestureComposition.js +79 -0
- package/lib/module/handlers/gestures/gestureComposition.js.map +1 -0
- package/lib/module/handlers/gestures/gestureObjects.js +67 -0
- package/lib/module/handlers/gestures/gestureObjects.js.map +1 -0
- package/lib/module/handlers/gestures/gestureStateManager.js +48 -0
- package/lib/module/handlers/gestures/gestureStateManager.js.map +1 -0
- package/lib/module/handlers/gestures/longPressGesture.js +24 -0
- package/lib/module/handlers/gestures/longPressGesture.js.map +1 -0
- package/lib/module/handlers/gestures/manualGesture.js +22 -0
- package/lib/module/handlers/gestures/manualGesture.js.map +1 -0
- package/lib/module/handlers/gestures/nativeGesture.js +24 -0
- package/lib/module/handlers/gestures/nativeGesture.js.map +1 -0
- package/lib/module/handlers/gestures/panGesture.js +135 -0
- package/lib/module/handlers/gestures/panGesture.js.map +1 -0
- package/lib/module/handlers/gestures/pinchGesture.js +36 -0
- package/lib/module/handlers/gestures/pinchGesture.js.map +1 -0
- package/lib/module/handlers/gestures/reanimatedWrapper.js +19 -0
- package/lib/module/handlers/gestures/reanimatedWrapper.js.map +1 -0
- package/lib/module/handlers/gestures/rotationGesture.js +36 -0
- package/lib/module/handlers/gestures/rotationGesture.js.map +1 -0
- package/lib/module/handlers/gestures/tapGesture.js +49 -0
- package/lib/module/handlers/gestures/tapGesture.js.map +1 -0
- package/lib/module/handlers/handlersRegistry.js +16 -0
- package/lib/module/handlers/handlersRegistry.js.map +1 -0
- package/lib/module/index.js +22 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/init.js +5 -0
- package/lib/module/init.js.map +1 -0
- package/lib/module/mocks.js +31 -2
- package/lib/module/mocks.js.map +1 -1
- package/lib/module/utils.js +8 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/module/web/Errors.js +1 -1
- package/lib/module/web/Errors.js.map +1 -1
- package/lib/module/web/GestureHandler.js +4 -6
- package/lib/module/web/GestureHandler.js.map +1 -1
- package/lib/module/web/NodeManager.js +8 -2
- package/lib/module/web/NodeManager.js.map +1 -1
- package/lib/typescript/EventType.d.ts +8 -0
- package/lib/typescript/GestureHandlerRootView.android.d.ts +2 -4
- package/lib/typescript/GestureHandlerRootView.d.ts +5 -2
- package/lib/typescript/RNGestureHandlerModule.d.ts +1 -1
- package/lib/typescript/RNGestureHandlerModule.web.d.ts +1 -1
- package/lib/typescript/components/DrawerLayout.d.ts +50 -1
- package/lib/typescript/components/GestureButtons.d.ts +36 -0
- package/lib/typescript/components/GestureComponents.d.ts +8 -35
- package/lib/typescript/components/Swipeable.d.ts +73 -6
- package/lib/typescript/components/touchables/GenericTouchable.d.ts +2 -2
- package/lib/typescript/components/touchables/TouchableHighlight.d.ts +1 -0
- package/lib/typescript/components/touchables/TouchableOpacity.d.ts +1 -0
- package/lib/typescript/handlers/FlingGestureHandler.d.ts +33 -0
- package/lib/typescript/handlers/ForceTouchGestureHandler.d.ts +43 -0
- package/lib/typescript/handlers/LongPressGestureHandler.d.ts +55 -0
- package/lib/typescript/handlers/NativeViewGestureHandler.d.ts +19 -4
- package/lib/typescript/handlers/PanGestureHandler.d.ts +137 -0
- package/lib/typescript/handlers/PinchGestureHandler.d.ts +28 -0
- package/lib/typescript/handlers/RotationGestureHandler.d.ts +28 -0
- package/lib/typescript/handlers/TapGestureHandler.d.ts +56 -0
- package/lib/typescript/handlers/createHandler.d.ts +1 -1
- package/lib/typescript/handlers/gestureHandlerCommon.d.ts +62 -0
- package/lib/typescript/handlers/gestureHandlerTypesCompat.d.ts +8 -1
- package/lib/typescript/handlers/gestures/GestureDetector.d.ts +16 -0
- package/lib/typescript/handlers/gestures/eventReceiver.d.ts +2 -0
- package/lib/typescript/handlers/gestures/flingGesture.d.ts +9 -0
- package/lib/typescript/handlers/gestures/forceTouchGesture.d.ts +16 -0
- package/lib/typescript/handlers/gestures/gesture.d.ts +97 -0
- package/lib/typescript/handlers/gestures/gestureComposition.d.ts +21 -0
- package/lib/typescript/handlers/gestures/gestureObjects.d.ts +39 -0
- package/lib/typescript/handlers/gestures/gestureStateManager.d.ts +9 -0
- package/lib/typescript/handlers/gestures/longPressGesture.d.ts +9 -0
- package/lib/typescript/handlers/gestures/manualGesture.d.ts +7 -0
- package/lib/typescript/handlers/gestures/nativeGesture.d.ts +9 -0
- package/lib/typescript/handlers/gestures/panGesture.d.ts +26 -0
- package/lib/typescript/handlers/gestures/pinchGesture.d.ts +12 -0
- package/lib/typescript/handlers/gestures/reanimatedWrapper.d.ts +14 -0
- package/lib/typescript/handlers/gestures/rotationGesture.d.ts +12 -0
- package/lib/typescript/handlers/gestures/tapGesture.d.ts +14 -0
- package/lib/typescript/handlers/handlersRegistry.d.ts +6 -0
- package/lib/typescript/index.d.ts +29 -2
- package/lib/typescript/init.d.ts +1 -0
- package/lib/typescript/mocks.d.ts +21 -2
- package/lib/typescript/utils.d.ts +1 -0
- package/lib/typescript/web/FlingGestureHandler.d.ts +0 -1
- package/lib/typescript/web/GestureHandler.d.ts +0 -1
- package/lib/typescript/web/PanGestureHandler.d.ts +0 -1
- package/lib/typescript/web/PinchGestureHandler.d.ts +0 -1
- package/lib/typescript/web/PressGestureHandler.d.ts +0 -1
- package/lib/typescript/web/RotationGestureHandler.d.ts +0 -1
- package/lib/typescript/web/TapGestureHandler.d.ts +0 -1
- package/package.json +8 -5
- package/src/EventType.ts +10 -0
- package/src/GestureHandlerRootView.android.tsx +9 -25
- package/src/GestureHandlerRootView.tsx +11 -2
- package/src/RNGestureHandlerModule.ts +5 -1
- package/src/RNGestureHandlerModule.web.ts +1 -0
- package/src/components/DrawerLayout.tsx +114 -41
- package/src/components/GestureButtons.tsx +45 -5
- package/src/components/GestureComponents.tsx +47 -41
- package/src/components/Swipeable.tsx +108 -21
- package/src/components/touchables/GenericTouchable.tsx +2 -1
- package/src/components/touchables/TouchableOpacity.tsx +1 -1
- package/src/handlers/FlingGestureHandler.ts +57 -0
- package/src/handlers/ForceTouchGestureHandler.ts +83 -0
- package/src/handlers/LongPressGestureHandler.ts +84 -0
- package/src/handlers/NativeViewGestureHandler.ts +31 -7
- package/src/handlers/PanGestureHandler.ts +321 -0
- package/src/handlers/PinchGestureHandler.ts +46 -0
- package/src/handlers/RotationGestureHandler.ts +46 -0
- package/src/handlers/TapGestureHandler.ts +90 -0
- package/src/handlers/createHandler.ts +54 -79
- package/src/handlers/gestureHandlerCommon.ts +185 -0
- package/src/handlers/gestureHandlerTypesCompat.ts +19 -5
- package/src/handlers/gestures/GestureDetector.tsx +519 -0
- package/src/handlers/gestures/eventReceiver.ts +151 -0
- package/src/handlers/gestures/flingGesture.ts +27 -0
- package/src/handlers/gestures/forceTouchGesture.ts +74 -0
- package/src/handlers/gestures/gesture.ts +292 -0
- package/src/handlers/gestures/gestureComposition.ts +109 -0
- package/src/handlers/gestures/gestureObjects.ts +79 -0
- package/src/handlers/gestures/gestureStateManager.ts +60 -0
- package/src/handlers/gestures/longPressGesture.ts +27 -0
- package/src/handlers/gestures/manualGesture.ts +31 -0
- package/src/handlers/gestures/nativeGesture.ts +27 -0
- package/src/handlers/gestures/panGesture.ts +147 -0
- package/src/handlers/gestures/pinchGesture.ts +51 -0
- package/src/handlers/gestures/reanimatedWrapper.ts +45 -0
- package/src/handlers/gestures/rotationGesture.ts +51 -0
- package/src/handlers/gestures/tapGesture.ts +52 -0
- package/src/handlers/handlersRegistry.ts +22 -0
- package/src/index.ts +57 -17
- package/src/init.ts +5 -0
- package/src/mocks.ts +42 -2
- package/src/utils.ts +7 -0
- package/src/web/GestureHandler.ts +1 -2
- package/src/web/NodeManager.ts +5 -0
- package/android/lib/src/main/java/com/swmansion/gesturehandler/BaseGestureHandlerInteractionController.java +0 -23
- package/android/lib/src/main/java/com/swmansion/gesturehandler/FlingGestureHandler.java +0 -110
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandler.java +0 -531
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerInteractionController.java +0 -8
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerOrchestrator.java +0 -543
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerRegistry.java +0 -10
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerRegistryImpl.java +0 -29
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureUtils.java +0 -53
- package/android/lib/src/main/java/com/swmansion/gesturehandler/LongPressGestureHandler.java +0 -81
- package/android/lib/src/main/java/com/swmansion/gesturehandler/NativeViewGestureHandler.java +0 -110
- package/android/lib/src/main/java/com/swmansion/gesturehandler/OnTouchEventListener.java +0 -8
- package/android/lib/src/main/java/com/swmansion/gesturehandler/PanGestureHandler.java +0 -312
- package/android/lib/src/main/java/com/swmansion/gesturehandler/PinchGestureHandler.java +0 -109
- package/android/lib/src/main/java/com/swmansion/gesturehandler/RotationGestureDetector.java +0 -169
- package/android/lib/src/main/java/com/swmansion/gesturehandler/RotationGestureHandler.java +0 -96
- package/android/lib/src/main/java/com/swmansion/gesturehandler/TapGestureHandler.java +0 -172
- package/android/lib/src/main/java/com/swmansion/gesturehandler/ViewConfigurationHelper.java +0 -10
- package/android/src/main/java/com/facebook/react/views/modal/RNGHModalUtils.java +0 -21
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.java +0 -296
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEnabledRootView.java +0 -72
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.java +0 -77
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEventDataExtractor.java +0 -8
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerInteractionManager.java +0 -86
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.java +0 -731
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerPackage.java +0 -31
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRegistry.java +0 -101
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.java +0 -151
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootInterface.java +0 -7
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.java +0 -76
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java +0 -49
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerStateChangeEvent.java +0 -82
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNViewConfigurationHelper.java +0 -61
- package/lib/commonjs/handlers/gestureHandlers.js +0 -236
- package/lib/commonjs/handlers/gestureHandlers.js.map +0 -1
- package/lib/module/handlers/gestureHandlers.js +0 -216
- package/lib/module/handlers/gestureHandlers.js.map +0 -1
- package/lib/typescript/handlers/gestureHandlers.d.ts +0 -158
- package/src/handlers/gestureHandlers.ts +0 -511
@@ -0,0 +1,8 @@
|
|
1
|
+
package com.swmansion.gesturehandler
|
2
|
+
|
3
|
+
interface GestureHandlerInteractionController {
|
4
|
+
fun shouldWaitForHandlerFailure(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
|
5
|
+
fun shouldRequireHandlerToWaitForFailure(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
|
6
|
+
fun shouldRecognizeSimultaneously(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
|
7
|
+
fun shouldHandlerBeCancelledBy(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
|
8
|
+
}
|
@@ -0,0 +1,562 @@
|
|
1
|
+
package com.swmansion.gesturehandler
|
2
|
+
|
3
|
+
import android.graphics.Matrix
|
4
|
+
import android.graphics.PointF
|
5
|
+
import android.view.MotionEvent
|
6
|
+
import android.view.View
|
7
|
+
import android.view.ViewGroup
|
8
|
+
import java.util.*
|
9
|
+
|
10
|
+
class GestureHandlerOrchestrator(
|
11
|
+
private val wrapperView: ViewGroup,
|
12
|
+
private val handlerRegistry: GestureHandlerRegistry,
|
13
|
+
private val viewConfigHelper: ViewConfigurationHelper,
|
14
|
+
) {
|
15
|
+
/**
|
16
|
+
* Minimum alpha (value from 0 to 1) that should be set to a view so that it can be treated as a
|
17
|
+
* gesture target. E.g. if set to 0.1 then views that less than 10% opaque will be ignored when
|
18
|
+
* traversing view hierarchy and looking for gesture handlers.
|
19
|
+
*/
|
20
|
+
var minimumAlphaForTraversal = DEFAULT_MIN_ALPHA_FOR_TRAVERSAL
|
21
|
+
|
22
|
+
private val gestureHandlers = arrayOfNulls<GestureHandler<*>?>(SIMULTANEOUS_GESTURE_HANDLER_LIMIT)
|
23
|
+
private val awaitingHandlers = arrayOfNulls<GestureHandler<*>?>(SIMULTANEOUS_GESTURE_HANDLER_LIMIT)
|
24
|
+
private val preparedHandlers = arrayOfNulls<GestureHandler<*>?>(SIMULTANEOUS_GESTURE_HANDLER_LIMIT)
|
25
|
+
private val handlersToCancel = arrayOfNulls<GestureHandler<*>?>(SIMULTANEOUS_GESTURE_HANDLER_LIMIT)
|
26
|
+
private var gestureHandlersCount = 0
|
27
|
+
private var awaitingHandlersCount = 0
|
28
|
+
private var isHandlingTouch = false
|
29
|
+
private var handlingChangeSemaphore = 0
|
30
|
+
private var finishedHandlersCleanupScheduled = false
|
31
|
+
private var activationIndex = 0
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Should be called from the view wrapper
|
35
|
+
*/
|
36
|
+
fun onTouchEvent(event: MotionEvent): Boolean {
|
37
|
+
isHandlingTouch = true
|
38
|
+
val action = event.actionMasked
|
39
|
+
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {
|
40
|
+
extractGestureHandlers(event)
|
41
|
+
} else if (action == MotionEvent.ACTION_CANCEL) {
|
42
|
+
cancelAll()
|
43
|
+
}
|
44
|
+
deliverEventToGestureHandlers(event)
|
45
|
+
isHandlingTouch = false
|
46
|
+
if (finishedHandlersCleanupScheduled && handlingChangeSemaphore == 0) {
|
47
|
+
cleanupFinishedHandlers()
|
48
|
+
}
|
49
|
+
return true
|
50
|
+
}
|
51
|
+
|
52
|
+
private fun scheduleFinishedHandlersCleanup() {
|
53
|
+
if (isHandlingTouch || handlingChangeSemaphore != 0) {
|
54
|
+
finishedHandlersCleanupScheduled = true
|
55
|
+
} else {
|
56
|
+
cleanupFinishedHandlers()
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
private inline fun compactHandlersIf(handlers: Array<GestureHandler<*>?>, count: Int, predicate: (handler: GestureHandler<*>?) -> Boolean): Int {
|
61
|
+
var out = 0
|
62
|
+
for (i in 0 until count) {
|
63
|
+
if (predicate(handlers[i])) {
|
64
|
+
handlers[out++] = handlers[i]
|
65
|
+
}
|
66
|
+
}
|
67
|
+
return out
|
68
|
+
}
|
69
|
+
|
70
|
+
private fun cleanupFinishedHandlers() {
|
71
|
+
var shouldCleanEmptyCells = false
|
72
|
+
for (i in gestureHandlersCount - 1 downTo 0) {
|
73
|
+
val handler = gestureHandlers[i]!!
|
74
|
+
if (isFinished(handler.state) && !handler.isAwaiting) {
|
75
|
+
gestureHandlers[i] = null
|
76
|
+
shouldCleanEmptyCells = true
|
77
|
+
handler.reset()
|
78
|
+
handler.apply {
|
79
|
+
isActive = false
|
80
|
+
isAwaiting = false
|
81
|
+
activationIndex = Int.MAX_VALUE
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
if (shouldCleanEmptyCells) {
|
86
|
+
gestureHandlersCount = compactHandlersIf(gestureHandlers, gestureHandlersCount) { handler ->
|
87
|
+
handler != null
|
88
|
+
}
|
89
|
+
}
|
90
|
+
finishedHandlersCleanupScheduled = false
|
91
|
+
}
|
92
|
+
|
93
|
+
private fun hasOtherHandlerToWaitFor(handler: GestureHandler<*>): Boolean {
|
94
|
+
for (i in 0 until gestureHandlersCount) {
|
95
|
+
val otherHandler = gestureHandlers[i]!!
|
96
|
+
if (!isFinished(otherHandler.state) && shouldHandlerWaitForOther(handler, otherHandler)) {
|
97
|
+
return true
|
98
|
+
}
|
99
|
+
}
|
100
|
+
return false
|
101
|
+
}
|
102
|
+
|
103
|
+
private fun tryActivate(handler: GestureHandler<*>) {
|
104
|
+
// see if there is anyone else who we need to wait for
|
105
|
+
if (hasOtherHandlerToWaitFor(handler)) {
|
106
|
+
addAwaitingHandler(handler)
|
107
|
+
} else {
|
108
|
+
// we can activate handler right away
|
109
|
+
makeActive(handler)
|
110
|
+
handler.isAwaiting = false
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
private fun cleanupAwaitingHandlers() {
|
115
|
+
awaitingHandlersCount = compactHandlersIf(awaitingHandlers, awaitingHandlersCount) { handler ->
|
116
|
+
handler!!.isAwaiting
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
/*package*/
|
121
|
+
fun onHandlerStateChange(handler: GestureHandler<*>, newState: Int, prevState: Int) {
|
122
|
+
handlingChangeSemaphore += 1
|
123
|
+
if (isFinished(newState)) {
|
124
|
+
// if there were handlers awaiting completion of this handler, we can trigger active state
|
125
|
+
for (i in 0 until awaitingHandlersCount) {
|
126
|
+
val otherHandler = awaitingHandlers[i]
|
127
|
+
if (shouldHandlerWaitForOther(otherHandler!!, handler)) {
|
128
|
+
if (newState == GestureHandler.STATE_END) {
|
129
|
+
// gesture has ended, we need to kill the awaiting handler
|
130
|
+
otherHandler.cancel()
|
131
|
+
otherHandler.isAwaiting = false
|
132
|
+
} else {
|
133
|
+
// gesture has failed recognition, we may try activating
|
134
|
+
tryActivate(otherHandler)
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
cleanupAwaitingHandlers()
|
139
|
+
}
|
140
|
+
if (newState == GestureHandler.STATE_ACTIVE) {
|
141
|
+
tryActivate(handler)
|
142
|
+
} else if (prevState == GestureHandler.STATE_ACTIVE || prevState == GestureHandler.STATE_END) {
|
143
|
+
if (handler.isActive) {
|
144
|
+
handler.dispatchStateChange(newState, prevState)
|
145
|
+
}
|
146
|
+
} else {
|
147
|
+
handler.dispatchStateChange(newState, prevState)
|
148
|
+
}
|
149
|
+
handlingChangeSemaphore -= 1
|
150
|
+
scheduleFinishedHandlersCleanup()
|
151
|
+
}
|
152
|
+
|
153
|
+
private fun makeActive(handler: GestureHandler<*>) {
|
154
|
+
val currentState = handler.state
|
155
|
+
with(handler) {
|
156
|
+
isAwaiting = false
|
157
|
+
isActive = true
|
158
|
+
activationIndex = this@GestureHandlerOrchestrator.activationIndex++
|
159
|
+
}
|
160
|
+
var toCancelCount = 0
|
161
|
+
// Cancel all handlers that are required to be cancel upon current handler's activation
|
162
|
+
for (i in 0 until gestureHandlersCount) {
|
163
|
+
val otherHandler = gestureHandlers[i]!!
|
164
|
+
if (shouldHandlerBeCancelledBy(otherHandler, handler)) {
|
165
|
+
handlersToCancel[toCancelCount++] = otherHandler
|
166
|
+
}
|
167
|
+
}
|
168
|
+
for (i in toCancelCount - 1 downTo 0) {
|
169
|
+
handlersToCancel[i]!!.cancel()
|
170
|
+
}
|
171
|
+
|
172
|
+
// Clear all awaiting handlers waiting for the current handler to fail
|
173
|
+
for (i in awaitingHandlersCount - 1 downTo 0) {
|
174
|
+
val otherHandler = awaitingHandlers[i]!!
|
175
|
+
if (shouldHandlerBeCancelledBy(otherHandler, handler)) {
|
176
|
+
otherHandler.cancel()
|
177
|
+
otherHandler.isAwaiting = false
|
178
|
+
}
|
179
|
+
}
|
180
|
+
cleanupAwaitingHandlers()
|
181
|
+
|
182
|
+
// Dispatch state change event if handler is no longer in the active state we should also
|
183
|
+
// trigger END state change and UNDETERMINED state change if necessary
|
184
|
+
handler.dispatchStateChange(GestureHandler.STATE_ACTIVE, GestureHandler.STATE_BEGAN)
|
185
|
+
if (currentState != GestureHandler.STATE_ACTIVE) {
|
186
|
+
handler.dispatchStateChange(GestureHandler.STATE_END, GestureHandler.STATE_ACTIVE)
|
187
|
+
if (currentState != GestureHandler.STATE_END) {
|
188
|
+
handler.dispatchStateChange(GestureHandler.STATE_UNDETERMINED, GestureHandler.STATE_END)
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
private fun deliverEventToGestureHandlers(event: MotionEvent) {
|
194
|
+
// Copy handlers to "prepared handlers" array, because the list of active handlers can change
|
195
|
+
// as a result of state updates
|
196
|
+
val handlersCount = gestureHandlersCount
|
197
|
+
|
198
|
+
gestureHandlers.copyInto(preparedHandlers, 0, 0, handlersCount)
|
199
|
+
// We want to deliver events to active handlers first in order of their activation (handlers
|
200
|
+
// that activated first will first get event delivered). Otherwise we deliver events in the
|
201
|
+
// order in which handlers has been added ("most direct" children goes first). Therefore we rely
|
202
|
+
// on Arrays.sort providing a stable sort (as children are registered in order in which they
|
203
|
+
// should be tested)
|
204
|
+
preparedHandlers.sortWith(handlersComparator, 0, handlersCount)
|
205
|
+
for (i in 0 until handlersCount) {
|
206
|
+
deliverEventToGestureHandler(preparedHandlers[i]!!, event)
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
private fun cancelAll() {
|
211
|
+
for (i in awaitingHandlersCount - 1 downTo 0) {
|
212
|
+
awaitingHandlers[i]!!.cancel()
|
213
|
+
}
|
214
|
+
// Copy handlers to "prepared handlers" array, because the list of active handlers can change
|
215
|
+
// as a result of state updates
|
216
|
+
val handlersCount = gestureHandlersCount
|
217
|
+
for (i in 0 until handlersCount) {
|
218
|
+
preparedHandlers[i] = gestureHandlers[i]
|
219
|
+
}
|
220
|
+
for (i in handlersCount - 1 downTo 0) {
|
221
|
+
preparedHandlers[i]!!.cancel()
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
private fun deliverEventToGestureHandler(handler: GestureHandler<*>, event: MotionEvent) {
|
226
|
+
if (!isViewAttachedUnderWrapper(handler.view)) {
|
227
|
+
handler.cancel()
|
228
|
+
return
|
229
|
+
}
|
230
|
+
if (!handler.wantEvents()) {
|
231
|
+
return
|
232
|
+
}
|
233
|
+
val action = event.actionMasked
|
234
|
+
val coords = tempCoords
|
235
|
+
extractCoordsForView(handler.view, event, coords)
|
236
|
+
val oldX = event.x
|
237
|
+
val oldY = event.y
|
238
|
+
// TODO: we may consider scaling events if necessary using MotionEvent.transform
|
239
|
+
// for now the events are only offset to the top left corner of the view but if
|
240
|
+
// view or any ot the parents is scaled the other pointers position will not reflect
|
241
|
+
// their actual place in the view. On the other hand not scaling seems like a better
|
242
|
+
// approach when we want to use pointer coordinates to calculate velocity or distance
|
243
|
+
// for pinch so I don't know yet if we should transform or not...
|
244
|
+
event.setLocation(coords[0], coords[1])
|
245
|
+
if (handler.needsPointerData) {
|
246
|
+
handler.updatePointerData(event)
|
247
|
+
}
|
248
|
+
|
249
|
+
if (!handler.isAwaiting || action != MotionEvent.ACTION_MOVE) {
|
250
|
+
handler.handle(event)
|
251
|
+
if (handler.isActive) {
|
252
|
+
handler.dispatchHandlerUpdate(event)
|
253
|
+
}
|
254
|
+
|
255
|
+
// if event was of type UP or POINTER_UP we request handler to stop tracking now that
|
256
|
+
// the event has been dispatched
|
257
|
+
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
|
258
|
+
val pointerId = event.getPointerId(event.actionIndex)
|
259
|
+
handler.stopTrackingPointer(pointerId)
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
event.setLocation(oldX, oldY)
|
264
|
+
}
|
265
|
+
|
266
|
+
/**
|
267
|
+
* isViewAttachedUnderWrapper checks whether all of parents for view related to handler
|
268
|
+
* view are attached. Since there might be an issue rarely observed when view
|
269
|
+
* has been detached and handler's state hasn't been change to canceled, failed or
|
270
|
+
* ended yet. Probably it's a result of some race condition and stopping delivering
|
271
|
+
* for this handler and changing its state to failed of end appear to be good enough solution.
|
272
|
+
*/
|
273
|
+
private fun isViewAttachedUnderWrapper(view: View?): Boolean {
|
274
|
+
if (view == null) {
|
275
|
+
return false
|
276
|
+
}
|
277
|
+
if (view === wrapperView) {
|
278
|
+
return true
|
279
|
+
}
|
280
|
+
var parent = view.parent
|
281
|
+
while (parent != null && parent !== wrapperView) {
|
282
|
+
parent = parent.parent
|
283
|
+
}
|
284
|
+
return parent === wrapperView
|
285
|
+
}
|
286
|
+
|
287
|
+
private fun extractCoordsForView(view: View?, event: MotionEvent, outputCoords: FloatArray) {
|
288
|
+
if (view === wrapperView) {
|
289
|
+
outputCoords[0] = event.x
|
290
|
+
outputCoords[1] = event.y
|
291
|
+
return
|
292
|
+
}
|
293
|
+
require(!(view == null || view.parent !is ViewGroup)) { "Parent is null? View is no longer in the tree" }
|
294
|
+
val parent = view.parent as ViewGroup
|
295
|
+
extractCoordsForView(parent, event, outputCoords)
|
296
|
+
val childPoint = tempPoint
|
297
|
+
transformTouchPointToViewCoords(outputCoords[0], outputCoords[1], parent, view, childPoint)
|
298
|
+
outputCoords[0] = childPoint.x
|
299
|
+
outputCoords[1] = childPoint.y
|
300
|
+
}
|
301
|
+
|
302
|
+
private fun addAwaitingHandler(handler: GestureHandler<*>) {
|
303
|
+
for (i in 0 until awaitingHandlersCount) {
|
304
|
+
if (awaitingHandlers[i] === handler) {
|
305
|
+
return
|
306
|
+
}
|
307
|
+
}
|
308
|
+
check(awaitingHandlersCount < awaitingHandlers.size) { "Too many recognizers" }
|
309
|
+
awaitingHandlers[awaitingHandlersCount++] = handler
|
310
|
+
with(handler) {
|
311
|
+
isAwaiting = true
|
312
|
+
activationIndex = this@GestureHandlerOrchestrator.activationIndex++
|
313
|
+
}
|
314
|
+
}
|
315
|
+
|
316
|
+
private fun recordHandlerIfNotPresent(handler: GestureHandler<*>, view: View) {
|
317
|
+
for (i in 0 until gestureHandlersCount) {
|
318
|
+
if (gestureHandlers[i] === handler) {
|
319
|
+
return
|
320
|
+
}
|
321
|
+
}
|
322
|
+
check(gestureHandlersCount < gestureHandlers.size) { "Too many recognizers" }
|
323
|
+
gestureHandlers[gestureHandlersCount++] = handler
|
324
|
+
handler.isActive = false
|
325
|
+
handler.isAwaiting = false
|
326
|
+
handler.activationIndex = Int.MAX_VALUE
|
327
|
+
handler.prepare(view, this)
|
328
|
+
}
|
329
|
+
|
330
|
+
private fun isViewOverflowingParent(view: View): Boolean {
|
331
|
+
val parent = view.parent as? ViewGroup ?: return false
|
332
|
+
val matrix = view.matrix
|
333
|
+
val localXY = matrixTransformCoords
|
334
|
+
localXY[0] = 0f
|
335
|
+
localXY[1] = 0f
|
336
|
+
matrix.mapPoints(localXY)
|
337
|
+
val left = localXY[0] + view.left
|
338
|
+
val top = localXY[1] + view.top
|
339
|
+
|
340
|
+
return left < 0f || left + view.width > parent.width || top < 0f || top + view.height > parent.height
|
341
|
+
}
|
342
|
+
|
343
|
+
private fun extractAncestorHandlers(view: View, coords: FloatArray, pointerId: Int): Boolean {
|
344
|
+
var found = false
|
345
|
+
var parent = view.parent
|
346
|
+
|
347
|
+
while (parent != null) {
|
348
|
+
if (parent is ViewGroup) {
|
349
|
+
val parentViewGroup: ViewGroup = parent
|
350
|
+
|
351
|
+
handlerRegistry.getHandlersForView(parent)?.let {
|
352
|
+
for (handler in it) {
|
353
|
+
if (handler.isEnabled && handler.isWithinBounds(view, coords[0], coords[1])) {
|
354
|
+
found = true
|
355
|
+
recordHandlerIfNotPresent(handler, parentViewGroup)
|
356
|
+
handler.startTrackingPointer(pointerId)
|
357
|
+
}
|
358
|
+
}
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
362
|
+
parent = parent.parent
|
363
|
+
}
|
364
|
+
|
365
|
+
return found
|
366
|
+
}
|
367
|
+
|
368
|
+
private fun recordViewHandlersForPointer(view: View, coords: FloatArray, pointerId: Int): Boolean {
|
369
|
+
var found = false
|
370
|
+
handlerRegistry.getHandlersForView(view)?.let {
|
371
|
+
val size = it.size
|
372
|
+
for (i in 0 until size) {
|
373
|
+
val handler = it[i]
|
374
|
+
if (handler.isEnabled && handler.isWithinBounds(view, coords[0], coords[1])) {
|
375
|
+
recordHandlerIfNotPresent(handler, view)
|
376
|
+
handler.startTrackingPointer(pointerId)
|
377
|
+
found = true
|
378
|
+
}
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
382
|
+
// if the pointer is inside the view but it overflows its parent, handlers attached to the parent
|
383
|
+
// might not have been extracted (pointer might be in a child, but may be outside parent)
|
384
|
+
if (coords[0] in 0f..view.width.toFloat() && coords[1] in 0f..view.height.toFloat()
|
385
|
+
&& isViewOverflowingParent(view) && extractAncestorHandlers(view, coords, pointerId)) {
|
386
|
+
found = true
|
387
|
+
}
|
388
|
+
|
389
|
+
return found
|
390
|
+
}
|
391
|
+
|
392
|
+
private fun extractGestureHandlers(event: MotionEvent) {
|
393
|
+
val actionIndex = event.actionIndex
|
394
|
+
val pointerId = event.getPointerId(actionIndex)
|
395
|
+
tempCoords[0] = event.getX(actionIndex)
|
396
|
+
tempCoords[1] = event.getY(actionIndex)
|
397
|
+
traverseWithPointerEvents(wrapperView, tempCoords, pointerId)
|
398
|
+
extractGestureHandlers(wrapperView, tempCoords, pointerId)
|
399
|
+
}
|
400
|
+
|
401
|
+
private fun extractGestureHandlers(viewGroup: ViewGroup, coords: FloatArray, pointerId: Int): Boolean {
|
402
|
+
val childrenCount = viewGroup.childCount
|
403
|
+
for (i in childrenCount - 1 downTo 0) {
|
404
|
+
val child = viewConfigHelper.getChildInDrawingOrderAtIndex(viewGroup, i)
|
405
|
+
if (canReceiveEvents(child)) {
|
406
|
+
val childPoint = tempPoint
|
407
|
+
transformTouchPointToViewCoords(coords[0], coords[1], viewGroup, child, childPoint)
|
408
|
+
val restoreX = coords[0]
|
409
|
+
val restoreY = coords[1]
|
410
|
+
coords[0] = childPoint.x
|
411
|
+
coords[1] = childPoint.y
|
412
|
+
var found = false
|
413
|
+
if (!isClipping(child) || isTransformedTouchPointInView(coords[0], coords[1], child)) {
|
414
|
+
// we only consider the view if touch is inside the view bounds or if the view's children
|
415
|
+
// can render outside of the view bounds (overflow visible)
|
416
|
+
found = traverseWithPointerEvents(child, coords, pointerId)
|
417
|
+
}
|
418
|
+
coords[0] = restoreX
|
419
|
+
coords[1] = restoreY
|
420
|
+
if (found) {
|
421
|
+
return true
|
422
|
+
}
|
423
|
+
}
|
424
|
+
}
|
425
|
+
return false
|
426
|
+
}
|
427
|
+
|
428
|
+
private fun traverseWithPointerEvents(view: View, coords: FloatArray, pointerId: Int): Boolean =
|
429
|
+
when (viewConfigHelper.getPointerEventsConfigForView(view)) {
|
430
|
+
PointerEventsConfig.NONE -> {
|
431
|
+
// This view and its children can't be the target
|
432
|
+
false
|
433
|
+
}
|
434
|
+
PointerEventsConfig.BOX_ONLY -> {
|
435
|
+
// This view is the target, its children don't matter
|
436
|
+
(recordViewHandlersForPointer(view, coords, pointerId)
|
437
|
+
|| shouldHandlerlessViewBecomeTouchTarget(view, coords))
|
438
|
+
}
|
439
|
+
PointerEventsConfig.BOX_NONE -> {
|
440
|
+
// This view can't be the target, but its children might
|
441
|
+
if (view is ViewGroup) {
|
442
|
+
extractGestureHandlers(view, coords, pointerId)
|
443
|
+
} else false
|
444
|
+
}
|
445
|
+
PointerEventsConfig.AUTO -> {
|
446
|
+
// Either this view or one of its children is the target
|
447
|
+
val found = if (view is ViewGroup) {
|
448
|
+
extractGestureHandlers(view, coords, pointerId)
|
449
|
+
} else false
|
450
|
+
|
451
|
+
(recordViewHandlersForPointer(view, coords, pointerId)
|
452
|
+
|| found || shouldHandlerlessViewBecomeTouchTarget(view, coords))
|
453
|
+
}
|
454
|
+
}
|
455
|
+
|
456
|
+
private fun canReceiveEvents(view: View) =
|
457
|
+
view.visibility == View.VISIBLE && view.alpha >= minimumAlphaForTraversal
|
458
|
+
|
459
|
+
// if view is not a view group it is clipping, otherwise we check for `getClipChildren` flag to
|
460
|
+
// be turned on and also confirm with the ViewConfigHelper implementation
|
461
|
+
private fun isClipping(view: View) =
|
462
|
+
view !is ViewGroup || viewConfigHelper.isViewClippingChildren(view)
|
463
|
+
|
464
|
+
|
465
|
+
companion object {
|
466
|
+
// The limit doesn't necessarily need to exists, it was just simpler to implement it that way
|
467
|
+
// it is also more allocation-wise efficient to have a fixed limit
|
468
|
+
private const val SIMULTANEOUS_GESTURE_HANDLER_LIMIT = 20
|
469
|
+
|
470
|
+
// Be default fully transparent views can receive touch
|
471
|
+
private const val DEFAULT_MIN_ALPHA_FOR_TRAVERSAL = 0f
|
472
|
+
private val tempPoint = PointF()
|
473
|
+
private val matrixTransformCoords = FloatArray(2)
|
474
|
+
private val inverseMatrix = Matrix()
|
475
|
+
private val tempCoords = FloatArray(2)
|
476
|
+
private val handlersComparator = Comparator<GestureHandler<*>?> { a, b ->
|
477
|
+
return@Comparator if (a.isActive && b.isActive || a.isAwaiting && b.isAwaiting) {
|
478
|
+
// both A and B are either active or awaiting activation, in which case we prefer one that
|
479
|
+
// has activated (or turned into "awaiting" state) earlier
|
480
|
+
Integer.signum(b.activationIndex - a.activationIndex)
|
481
|
+
} else if (a.isActive) {
|
482
|
+
-1 // only A is active
|
483
|
+
} else if (b.isActive) {
|
484
|
+
1 // only B is active
|
485
|
+
} else if (a.isAwaiting) {
|
486
|
+
-1 // only A is awaiting, B is inactive
|
487
|
+
} else if (b.isAwaiting) {
|
488
|
+
1 // only B is awaiting, A is inactive
|
489
|
+
} else {
|
490
|
+
0 // both A and B are inactive, stable order matters
|
491
|
+
}
|
492
|
+
}
|
493
|
+
|
494
|
+
private fun shouldHandlerlessViewBecomeTouchTarget(view: View, coords: FloatArray): Boolean {
|
495
|
+
// The following code is to match the iOS behavior where transparent parts of the views can
|
496
|
+
// pass touch events through them allowing sibling nodes to handle them.
|
497
|
+
|
498
|
+
// TODO: this is not an ideal solution as we only consider ViewGroups that has no background set
|
499
|
+
// TODO: ideally we should determine the pixel color under the given coordinates and return
|
500
|
+
// false if the color is transparent
|
501
|
+
val isLeafOrTransparent = view !is ViewGroup || view.getBackground() != null
|
502
|
+
return isLeafOrTransparent && isTransformedTouchPointInView(coords[0], coords[1], view)
|
503
|
+
}
|
504
|
+
|
505
|
+
private fun transformTouchPointToViewCoords(
|
506
|
+
x: Float,
|
507
|
+
y: Float,
|
508
|
+
parent: ViewGroup,
|
509
|
+
child: View,
|
510
|
+
outLocalPoint: PointF,
|
511
|
+
) {
|
512
|
+
var localX = x + parent.scrollX - child.left
|
513
|
+
var localY = y + parent.scrollY - child.top
|
514
|
+
val matrix = child.matrix
|
515
|
+
if (!matrix.isIdentity) {
|
516
|
+
val localXY = matrixTransformCoords
|
517
|
+
localXY[0] = localX
|
518
|
+
localXY[1] = localY
|
519
|
+
matrix.invert(inverseMatrix)
|
520
|
+
inverseMatrix.mapPoints(localXY)
|
521
|
+
localX = localXY[0]
|
522
|
+
localY = localXY[1]
|
523
|
+
}
|
524
|
+
outLocalPoint[localX] = localY
|
525
|
+
}
|
526
|
+
|
527
|
+
private fun isTransformedTouchPointInView(x: Float, y: Float, child: View) =
|
528
|
+
x in 0f..child.width.toFloat() && y in 0f..child.height.toFloat()
|
529
|
+
|
530
|
+
private fun shouldHandlerWaitForOther(handler: GestureHandler<*>, other: GestureHandler<*>): Boolean {
|
531
|
+
return handler !== other && (handler.shouldWaitForHandlerFailure(other)
|
532
|
+
|| other.shouldRequireToWaitForFailure(handler))
|
533
|
+
}
|
534
|
+
|
535
|
+
private fun canRunSimultaneously(a: GestureHandler<*>, b: GestureHandler<*>) =
|
536
|
+
a === b || a.shouldRecognizeSimultaneously(b) || b.shouldRecognizeSimultaneously(a)
|
537
|
+
|
538
|
+
|
539
|
+
private fun shouldHandlerBeCancelledBy(handler: GestureHandler<*>, other: GestureHandler<*>): Boolean {
|
540
|
+
if (!handler.hasCommonPointers(other)) {
|
541
|
+
// if two handlers share no common pointer one can never trigger cancel for the other
|
542
|
+
return false
|
543
|
+
}
|
544
|
+
if (canRunSimultaneously(handler, other)) {
|
545
|
+
// if handlers are allowed to run simultaneously, when first activates second can still remain
|
546
|
+
// in began state
|
547
|
+
return false
|
548
|
+
}
|
549
|
+
return if (handler !== other &&
|
550
|
+
(handler.isAwaiting || handler.state == GestureHandler.STATE_ACTIVE)) {
|
551
|
+
// in every other case as long as the handler is about to be activated or already in active
|
552
|
+
// state, we delegate the decision to the implementation of GestureHandler#shouldBeCancelledBy
|
553
|
+
handler.shouldBeCancelledBy(other)
|
554
|
+
} else true
|
555
|
+
}
|
556
|
+
|
557
|
+
private fun isFinished(state: Int) =
|
558
|
+
state == GestureHandler.STATE_CANCELLED
|
559
|
+
|| state == GestureHandler.STATE_FAILED
|
560
|
+
|| state == GestureHandler.STATE_END
|
561
|
+
}
|
562
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
package com.swmansion.gesturehandler
|
2
|
+
|
3
|
+
import android.view.View
|
4
|
+
import java.util.*
|
5
|
+
|
6
|
+
class GestureHandlerRegistryImpl : GestureHandlerRegistry {
|
7
|
+
private val handlers = WeakHashMap<View?, ArrayList<GestureHandler<*>>>()
|
8
|
+
fun <T : GestureHandler<*>> registerHandlerForView(view: View?, handler: T): T {
|
9
|
+
var listToAdd = handlers[view]
|
10
|
+
if (listToAdd == null) {
|
11
|
+
listToAdd = ArrayList(1)
|
12
|
+
listToAdd.add(handler)
|
13
|
+
handlers[view] = listToAdd
|
14
|
+
} else {
|
15
|
+
listToAdd.add(handler)
|
16
|
+
}
|
17
|
+
return handler
|
18
|
+
}
|
19
|
+
|
20
|
+
override fun getHandlersForView(view: View) = handlers[view]
|
21
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
package com.swmansion.gesturehandler
|
2
|
+
|
3
|
+
import android.view.MotionEvent
|
4
|
+
|
5
|
+
object GestureUtils {
|
6
|
+
fun getLastPointerX(event: MotionEvent, averageTouches: Boolean): Float {
|
7
|
+
val offset = event.rawX - event.x
|
8
|
+
val excludeIndex = if (event.actionMasked == MotionEvent.ACTION_POINTER_UP) event.actionIndex else -1
|
9
|
+
return if (averageTouches) {
|
10
|
+
var sum = 0f
|
11
|
+
var count = 0
|
12
|
+
for (i in 0 until event.pointerCount) {
|
13
|
+
if (i != excludeIndex) {
|
14
|
+
sum += event.getX(i) + offset
|
15
|
+
count++
|
16
|
+
}
|
17
|
+
}
|
18
|
+
sum / count
|
19
|
+
} else {
|
20
|
+
var lastPointerIdx = event.pointerCount - 1
|
21
|
+
if (lastPointerIdx == excludeIndex) {
|
22
|
+
lastPointerIdx--
|
23
|
+
}
|
24
|
+
event.getX(lastPointerIdx) + offset
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
fun getLastPointerY(event: MotionEvent, averageTouches: Boolean): Float {
|
29
|
+
val offset = event.rawY - event.y
|
30
|
+
val excludeIndex = if (event.actionMasked == MotionEvent.ACTION_POINTER_UP) event.actionIndex else -1
|
31
|
+
return if (averageTouches) {
|
32
|
+
var sum = 0f
|
33
|
+
var count = 0
|
34
|
+
for (i in 0 until event.pointerCount) {
|
35
|
+
if (i != excludeIndex) {
|
36
|
+
sum += event.getY(i) + offset
|
37
|
+
count++
|
38
|
+
}
|
39
|
+
}
|
40
|
+
sum / count
|
41
|
+
} else {
|
42
|
+
var lastPointerIdx = event.pointerCount - 1
|
43
|
+
if (lastPointerIdx == excludeIndex) {
|
44
|
+
lastPointerIdx -= 1
|
45
|
+
}
|
46
|
+
event.getY(lastPointerIdx) + offset
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|