react-native-gesture-handler 1.10.3 → 2.2.0

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