react-native-gesture-handler 2.6.0 → 2.6.1

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 (177) hide show
  1. package/android/build.gradle +2 -2
  2. package/ios/RNGestureHandler.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  3. package/ios/RNGestureHandler.xcodeproj/project.xcworkspace/xcuserdata/jakubpiasecki.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  4. package/ios/RNGestureHandler.xcodeproj/xcuserdata/jakubpiasecki.xcuserdatad/xcschemes/xcschememanagement.plist +19 -0
  5. package/lib/commonjs/EnableExperimentalWebImplementation.js +7 -0
  6. package/lib/commonjs/EnableExperimentalWebImplementation.js.map +1 -1
  7. package/lib/commonjs/RNGestureHandlerModule.js +1 -1
  8. package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
  9. package/lib/commonjs/RNGestureHandlerModule.macos.js +20 -9
  10. package/lib/commonjs/RNGestureHandlerModule.macos.js.map +1 -1
  11. package/lib/commonjs/RNGestureHandlerModule.web.js +23 -10
  12. package/lib/commonjs/RNGestureHandlerModule.web.js.map +1 -1
  13. package/lib/commonjs/components/GestureComponents.web.js +1 -1
  14. package/lib/commonjs/components/GestureComponents.web.js.map +1 -1
  15. package/lib/commonjs/fabric/RNGestureHandlerButtonNativeComponent.js +1 -5
  16. package/lib/commonjs/fabric/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  17. package/lib/commonjs/fabric/RNGestureHandlerRootViewNativeComponent.js +1 -5
  18. package/lib/commonjs/fabric/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  19. package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
  20. package/lib/commonjs/handlers/gestures/eventReceiver.js +14 -20
  21. package/lib/commonjs/handlers/gestures/eventReceiver.js.map +1 -1
  22. package/lib/commonjs/handlers/gestures/gestureStateManager.web.js +32 -0
  23. package/lib/commonjs/handlers/gestures/gestureStateManager.web.js.map +1 -0
  24. package/lib/commonjs/web/detectors/RotationGestureDetector.js +13 -17
  25. package/lib/commonjs/web/detectors/RotationGestureDetector.js.map +1 -1
  26. package/lib/commonjs/web/detectors/ScaleGestureDetector.js +3 -14
  27. package/lib/commonjs/web/detectors/ScaleGestureDetector.js.map +1 -1
  28. package/lib/commonjs/web/handlers/FlingGestureHandler.js +37 -12
  29. package/lib/commonjs/web/handlers/FlingGestureHandler.js.map +1 -1
  30. package/lib/commonjs/web/handlers/GestureHandler.js +282 -79
  31. package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
  32. package/lib/commonjs/web/handlers/LongPressGestureHandler.js +23 -18
  33. package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
  34. package/lib/commonjs/web/handlers/ManualGestureHandler.js +51 -0
  35. package/lib/commonjs/web/handlers/ManualGestureHandler.js.map +1 -0
  36. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +81 -22
  37. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
  38. package/lib/commonjs/web/handlers/PanGestureHandler.js +57 -40
  39. package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
  40. package/lib/commonjs/web/handlers/PinchGestureHandler.js +43 -34
  41. package/lib/commonjs/web/handlers/PinchGestureHandler.js.map +1 -1
  42. package/lib/commonjs/web/handlers/RotationGestureHandler.js +45 -39
  43. package/lib/commonjs/web/handlers/RotationGestureHandler.js.map +1 -1
  44. package/lib/commonjs/web/handlers/TapGestureHandler.js +52 -50
  45. package/lib/commonjs/web/handlers/TapGestureHandler.js.map +1 -1
  46. package/lib/commonjs/web/interfaces.js +22 -1
  47. package/lib/commonjs/web/interfaces.js.map +1 -1
  48. package/lib/commonjs/web/tools/EventManager.js +40 -96
  49. package/lib/commonjs/web/tools/EventManager.js.map +1 -1
  50. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +109 -30
  51. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  52. package/lib/commonjs/web/tools/InteractionManager.js +24 -10
  53. package/lib/commonjs/web/tools/InteractionManager.js.map +1 -1
  54. package/lib/commonjs/web/tools/NodeManager.js.map +1 -1
  55. package/lib/commonjs/web/tools/PointerEventManager.js +130 -0
  56. package/lib/commonjs/web/tools/PointerEventManager.js.map +1 -0
  57. package/lib/commonjs/web/tools/PointerTracker.js +97 -7
  58. package/lib/commonjs/web/tools/PointerTracker.js.map +1 -1
  59. package/lib/commonjs/web/tools/TouchEventManager.js +138 -0
  60. package/lib/commonjs/web/tools/TouchEventManager.js.map +1 -0
  61. package/lib/commonjs/web/utils.js +15 -0
  62. package/lib/commonjs/web/utils.js.map +1 -0
  63. package/lib/module/EnableExperimentalWebImplementation.js +5 -0
  64. package/lib/module/EnableExperimentalWebImplementation.js.map +1 -1
  65. package/lib/module/RNGestureHandlerModule.js +1 -1
  66. package/lib/module/RNGestureHandlerModule.js.map +1 -1
  67. package/lib/module/RNGestureHandlerModule.macos.js +19 -10
  68. package/lib/module/RNGestureHandlerModule.macos.js.map +1 -1
  69. package/lib/module/RNGestureHandlerModule.web.js +22 -11
  70. package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
  71. package/lib/module/components/GestureComponents.web.js +1 -1
  72. package/lib/module/components/GestureComponents.web.js.map +1 -1
  73. package/lib/module/fabric/RNGestureHandlerButtonNativeComponent.js +1 -5
  74. package/lib/module/fabric/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  75. package/lib/module/fabric/RNGestureHandlerRootViewNativeComponent.js +1 -4
  76. package/lib/module/fabric/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  77. package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
  78. package/lib/module/handlers/gestures/eventReceiver.js +14 -20
  79. package/lib/module/handlers/gestures/eventReceiver.js.map +1 -1
  80. package/lib/module/handlers/gestures/gestureStateManager.web.js +21 -0
  81. package/lib/module/handlers/gestures/gestureStateManager.web.js.map +1 -0
  82. package/lib/module/web/detectors/RotationGestureDetector.js +13 -17
  83. package/lib/module/web/detectors/RotationGestureDetector.js.map +1 -1
  84. package/lib/module/web/detectors/ScaleGestureDetector.js +3 -14
  85. package/lib/module/web/detectors/ScaleGestureDetector.js.map +1 -1
  86. package/lib/module/web/handlers/FlingGestureHandler.js +37 -12
  87. package/lib/module/web/handlers/FlingGestureHandler.js.map +1 -1
  88. package/lib/module/web/handlers/GestureHandler.js +276 -79
  89. package/lib/module/web/handlers/GestureHandler.js.map +1 -1
  90. package/lib/module/web/handlers/LongPressGestureHandler.js +23 -18
  91. package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
  92. package/lib/module/web/handlers/ManualGestureHandler.js +39 -0
  93. package/lib/module/web/handlers/ManualGestureHandler.js.map +1 -0
  94. package/lib/module/web/handlers/NativeViewGestureHandler.js +80 -22
  95. package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
  96. package/lib/module/web/handlers/PanGestureHandler.js +57 -41
  97. package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
  98. package/lib/module/web/handlers/PinchGestureHandler.js +43 -33
  99. package/lib/module/web/handlers/PinchGestureHandler.js.map +1 -1
  100. package/lib/module/web/handlers/RotationGestureHandler.js +45 -38
  101. package/lib/module/web/handlers/RotationGestureHandler.js.map +1 -1
  102. package/lib/module/web/handlers/TapGestureHandler.js +52 -50
  103. package/lib/module/web/handlers/TapGestureHandler.js.map +1 -1
  104. package/lib/module/web/interfaces.js +19 -0
  105. package/lib/module/web/interfaces.js.map +1 -1
  106. package/lib/module/web/tools/EventManager.js +39 -95
  107. package/lib/module/web/tools/EventManager.js.map +1 -1
  108. package/lib/module/web/tools/GestureHandlerOrchestrator.js +107 -30
  109. package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  110. package/lib/module/web/tools/InteractionManager.js +24 -10
  111. package/lib/module/web/tools/InteractionManager.js.map +1 -1
  112. package/lib/module/web/tools/NodeManager.js.map +1 -1
  113. package/lib/module/web/tools/PointerEventManager.js +116 -0
  114. package/lib/module/web/tools/PointerEventManager.js.map +1 -0
  115. package/lib/module/web/tools/PointerTracker.js +97 -7
  116. package/lib/module/web/tools/PointerTracker.js.map +1 -1
  117. package/lib/module/web/tools/TouchEventManager.js +124 -0
  118. package/lib/module/web/tools/TouchEventManager.js.map +1 -0
  119. package/lib/module/web/utils.js +8 -0
  120. package/lib/module/web/utils.js.map +1 -0
  121. package/lib/typescript/RNGestureHandlerModule.macos.d.ts +5 -2
  122. package/lib/typescript/RNGestureHandlerModule.web.d.ts +5 -2
  123. package/lib/typescript/components/touchables/TouchableNativeFeedback.android.d.ts +1 -1
  124. package/lib/typescript/fabric/RNGestureHandlerButtonNativeComponent.d.ts +3 -3
  125. package/lib/typescript/fabric/RNGestureHandlerRootViewNativeComponent.d.ts +3 -2
  126. package/lib/typescript/handlers/gestures/gestureStateManager.web.d.ts +4 -0
  127. package/lib/typescript/web/detectors/RotationGestureDetector.d.ts +7 -7
  128. package/lib/typescript/web/detectors/ScaleGestureDetector.d.ts +6 -7
  129. package/lib/typescript/web/handlers/FlingGestureHandler.d.ts +12 -10
  130. package/lib/typescript/web/handlers/GestureHandler.d.ts +41 -32
  131. package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts +6 -9
  132. package/lib/typescript/web/handlers/ManualGestureHandler.d.ts +11 -0
  133. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +15 -6
  134. package/lib/typescript/web/handlers/PanGestureHandler.d.ts +15 -23
  135. package/lib/typescript/web/handlers/PinchGestureHandler.d.ts +11 -12
  136. package/lib/typescript/web/handlers/RotationGestureHandler.d.ts +12 -12
  137. package/lib/typescript/web/handlers/TapGestureHandler.d.ts +11 -14
  138. package/lib/typescript/web/interfaces.d.ts +50 -10
  139. package/lib/typescript/web/tools/EventManager.d.ts +28 -26
  140. package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +4 -2
  141. package/lib/typescript/web/tools/InteractionManager.d.ts +3 -0
  142. package/lib/typescript/web/tools/NodeManager.d.ts +3 -3
  143. package/lib/typescript/web/tools/PointerEventManager.d.ts +6 -0
  144. package/lib/typescript/web/tools/PointerTracker.d.ts +29 -5
  145. package/lib/typescript/web/tools/TouchEventManager.d.ts +6 -0
  146. package/lib/typescript/web/utils.d.ts +4 -0
  147. package/package.json +2 -2
  148. package/src/EnableExperimentalWebImplementation.ts +9 -0
  149. package/src/RNGestureHandlerModule.macos.ts +25 -10
  150. package/src/RNGestureHandlerModule.ts +4 -1
  151. package/src/RNGestureHandlerModule.web.ts +20 -7
  152. package/src/components/GestureComponents.web.tsx +1 -1
  153. package/src/fabric/RNGestureHandlerButtonNativeComponent.ts +2 -12
  154. package/src/fabric/RNGestureHandlerRootViewNativeComponent.ts +2 -8
  155. package/src/handlers/gestures/GestureDetector.tsx +0 -1
  156. package/src/handlers/gestures/eventReceiver.ts +23 -24
  157. package/src/handlers/gestures/gestureStateManager.web.ts +24 -0
  158. package/src/web/detectors/RotationGestureDetector.ts +20 -52
  159. package/src/web/detectors/ScaleGestureDetector.ts +9 -45
  160. package/src/web/handlers/FlingGestureHandler.ts +45 -22
  161. package/src/web/handlers/GestureHandler.ts +306 -97
  162. package/src/web/handlers/LongPressGestureHandler.ts +30 -24
  163. package/src/web/handlers/ManualGestureHandler.ts +39 -0
  164. package/src/web/handlers/NativeViewGestureHandler.ts +81 -24
  165. package/src/web/handlers/PanGestureHandler.ts +68 -53
  166. package/src/web/handlers/PinchGestureHandler.ts +47 -44
  167. package/src/web/handlers/RotationGestureHandler.ts +52 -51
  168. package/src/web/handlers/TapGestureHandler.ts +74 -56
  169. package/src/web/interfaces.ts +57 -10
  170. package/src/web/tools/EventManager.ts +58 -148
  171. package/src/web/tools/GestureHandlerOrchestrator.ts +115 -47
  172. package/src/web/tools/InteractionManager.ts +25 -9
  173. package/src/web/tools/NodeManager.ts +6 -6
  174. package/src/web/tools/PointerEventManager.ts +134 -0
  175. package/src/web/tools/PointerTracker.ts +120 -10
  176. package/src/web/tools/TouchEventManager.ts +167 -0
  177. package/src/web/utils.ts +8 -0
@@ -30,7 +30,17 @@ export interface Config extends Record<string, ConfigArgs> {
30
30
  simultaneousHandlers?: Handler[] | null;
31
31
  waitFor?: Handler[] | null;
32
32
  hitSlop?: HitSlop;
33
+ shouldCancelWhenOutside?: boolean;
33
34
 
35
+ activateAfterLongPress?: number;
36
+ failOffsetXStart?: number;
37
+ failOffsetYStart?: number;
38
+ failOffsetXEnd?: number;
39
+ failOffsetYEnd?: number;
40
+ activeOffsetXStart?: number;
41
+ activeOffsetXEnd?: number;
42
+ activeOffsetYStart?: number;
43
+ activeOffsetYEnd?: number;
34
44
  minPointers?: number;
35
45
  maxPointers?: number;
36
46
  minDist?: number;
@@ -41,14 +51,6 @@ export interface Config extends Record<string, ConfigArgs> {
41
51
  minVelocitySq?: number;
42
52
  maxDist?: number;
43
53
  maxDistSq?: number;
44
- failOffsetXStart?: number;
45
- failOffsetYStart?: number;
46
- failOffsetXEnd?: number;
47
- failOffsetYEnd?: number;
48
- activeOffsetXStart?: number;
49
- activeOffsetXEnd?: number;
50
- activeOffsetYStart?: number;
51
- activeOffsetYEnd?: number;
52
54
  numberOfPointers?: number;
53
55
  minDurationMs?: number;
54
56
  numberOfTaps?: number;
@@ -56,6 +58,8 @@ export interface Config extends Record<string, ConfigArgs> {
56
58
  maxDelayMs?: number;
57
59
  maxDeltaX?: number;
58
60
  maxDeltaY?: number;
61
+ shouldActivateOnStart?: boolean;
62
+ disallowInterruption?: boolean;
59
63
  direction?: Directions;
60
64
  }
61
65
 
@@ -69,26 +73,54 @@ interface NativeEvent extends Record<string, NativeEventArgs> {
69
73
  oldState?: State;
70
74
  }
71
75
 
76
+ export interface PointerData {
77
+ id: number;
78
+ x: number;
79
+ y: number;
80
+ absoluteX: number;
81
+ absoluteY: number;
82
+ }
83
+
84
+ type TouchNativeArgs = number | State | TouchEventType | PointerData[];
85
+
86
+ interface NativeTouchEvent extends Record<string, TouchNativeArgs> {
87
+ handlerTag: number;
88
+ state: State;
89
+ eventType: TouchEventType;
90
+ changedTouches: PointerData[];
91
+ allTouches: PointerData[];
92
+ numberOfTouches: number;
93
+ }
94
+
72
95
  export interface ResultEvent extends Record<string, NativeEvent | number> {
73
96
  nativeEvent: NativeEvent;
74
97
  timeStamp: number;
75
98
  }
76
99
 
100
+ export interface ResultTouchEvent
101
+ extends Record<string, NativeTouchEvent | number> {
102
+ nativeEvent: NativeTouchEvent;
103
+ timeStamp: number;
104
+ }
105
+
77
106
  export interface PropsRef {
78
107
  onGestureHandlerEvent: () => void;
79
108
  onGestureHandlerStateChange: () => void;
80
109
  }
81
110
 
82
- export interface AdaptedPointerEvent {
111
+ export interface AdaptedEvent {
83
112
  x: number;
84
113
  y: number;
85
114
  offsetX: number;
86
115
  offsetY: number;
87
116
  pointerId: number;
88
117
  eventType: EventTypes;
89
- pointerType: string;
118
+ pointerType: PointerType;
90
119
  buttons: number;
91
120
  time: number;
121
+ allTouches?: TouchList;
122
+ changedTouches?: TouchList;
123
+ touchEventType?: TouchEventType;
92
124
  }
93
125
 
94
126
  export enum MouseButtons {
@@ -112,3 +144,18 @@ export enum EventTypes {
112
144
  OUT,
113
145
  CANCEL,
114
146
  }
147
+
148
+ export enum TouchEventType {
149
+ UNDETERMINED,
150
+ DOWN,
151
+ MOVE,
152
+ UP,
153
+ CANCELLED,
154
+ }
155
+
156
+ export enum PointerType {
157
+ NONE = 'none',
158
+ MOUSE = 'mouse',
159
+ TOUCH = 'touch',
160
+ PEN = 'pen',
161
+ }
@@ -1,186 +1,96 @@
1
1
  /* eslint-disable @typescript-eslint/no-empty-function */
2
+ import { AdaptedEvent, EventTypes, TouchEventType } from '../interfaces';
2
3
 
3
- import { EventTypes, AdaptedPointerEvent, MouseButtons } from '../interfaces';
4
-
5
- export default class EventManager {
6
- private activePointers: number[] = [];
7
- private readonly view: HTMLElement;
4
+ export default abstract class EventManager {
5
+ protected readonly view: HTMLElement;
6
+ protected pointersInBounds: number[] = [];
7
+ protected activePointersCounter: number;
8
8
 
9
9
  constructor(view: HTMLElement) {
10
10
  this.view = view;
11
+ this.activePointersCounter = 0;
11
12
  }
12
13
 
13
- public setListeners() {
14
- this.view.addEventListener('pointerdown', (event: PointerEvent): void => {
15
- if (
16
- !this.isPointerInBounds({
17
- x: event.clientX,
18
- y: event.clientY,
19
- })
20
- ) {
21
- return;
22
- }
23
-
24
- const adaptedEvent: AdaptedPointerEvent = this.mapEvent(
25
- event,
26
- EventTypes.DOWN
27
- );
28
- const target = event.target as HTMLElement;
29
-
30
- target.setPointerCapture(adaptedEvent.pointerId);
31
- this.addActivePointer(adaptedEvent.pointerId);
32
- this.onPointerDown(adaptedEvent);
33
- });
34
-
35
- this.view.addEventListener('pointerup', (event: PointerEvent): void => {
36
- const adaptedEvent: AdaptedPointerEvent = this.mapEvent(
37
- event,
38
- EventTypes.UP
39
- );
40
- const target = event.target as HTMLElement;
41
-
42
- this.onPointerUp(adaptedEvent);
43
- target.releasePointerCapture(adaptedEvent.pointerId);
44
- this.removeActivePointer(adaptedEvent.pointerId);
45
- });
46
-
47
- this.view.addEventListener('pointermove', (event: PointerEvent): void => {
48
- if (
49
- event.pointerType === 'mouse' &&
50
- event.buttons !== MouseButtons.LEFT
51
- ) {
52
- return;
53
- }
54
-
55
- const adaptedEvent: AdaptedPointerEvent = this.mapEvent(
56
- event,
57
- EventTypes.MOVE
58
- );
59
-
60
- const inBounds: boolean = this.isPointerInBounds({
61
- x: adaptedEvent.x,
62
- y: adaptedEvent.y,
63
- });
64
-
65
- const pointerIndex: number = this.activePointers.indexOf(
66
- adaptedEvent.pointerId
67
- );
68
-
69
- if (inBounds) {
70
- if (pointerIndex < 0) {
71
- adaptedEvent.eventType = EventTypes.ENTER;
72
- this.onPointerEnter(adaptedEvent);
73
- this.addActivePointer(adaptedEvent.pointerId);
74
- } else {
75
- this.onPointerMove(adaptedEvent);
76
- }
77
- } else {
78
- if (pointerIndex >= 0) {
79
- adaptedEvent.eventType = EventTypes.OUT;
80
- this.onPointerOut(adaptedEvent);
81
- this.removeActivePointer(adaptedEvent.pointerId);
82
- } else {
83
- this.onPointerOutOfBounds(adaptedEvent);
84
- }
85
- }
86
- });
87
-
88
- this.view.addEventListener('pointercancel', (event: PointerEvent): void => {
89
- event.preventDefault();
90
-
91
- const adaptedEvent: AdaptedPointerEvent = this.mapEvent(
92
- event,
93
- EventTypes.CANCEL
94
- );
95
-
96
- this.onPointerCancel(adaptedEvent);
97
- });
14
+ public abstract setListeners(): void;
15
+ protected abstract mapEvent(
16
+ event: Event,
17
+ eventType: EventTypes,
18
+ index?: number,
19
+ touchEventType?: TouchEventType
20
+ ): AdaptedEvent;
21
+
22
+ protected onPointerDown(_event: AdaptedEvent): void {}
23
+ protected onPointerAdd(_event: AdaptedEvent): void {}
24
+ protected onPointerUp(_event: AdaptedEvent): void {}
25
+ protected onPointerRemove(_event: AdaptedEvent): void {}
26
+ protected onPointerMove(_event: AdaptedEvent): void {}
27
+ protected onPointerOut(_event: AdaptedEvent): void {}
28
+ protected onPointerEnter(_event: AdaptedEvent): void {}
29
+ protected onPointerCancel(_event: AdaptedEvent): void {
30
+ // When pointer cancel is triggered and there are more pointers on the view, only one pointer is cancelled
31
+ // Because we want all pointers to be cancelled by that event, we are doing it manually by reseting handler and changing activePointersCounter to 0
32
+ // Events that correspond to removing the pointer (pointerup, touchend) have condition, that they don't perform any action when activePointersCounter
33
+ // is equal to 0. This prevents counter from going to negative values, when pointers are removed from view after one of them has been cancelled
98
34
  }
35
+ protected onPointerOutOfBounds(_event: AdaptedEvent): void {}
99
36
 
100
- private onPointerDown(_event: AdaptedPointerEvent): void {}
101
- private onPointerUp(_event: AdaptedPointerEvent): void {}
102
- private onPointerMove(_event: AdaptedPointerEvent): void {}
103
- private onPointerOut(_event: AdaptedPointerEvent): void {}
104
- private onPointerEnter(_event: AdaptedPointerEvent): void {}
105
- private onPointerCancel(_event: AdaptedPointerEvent): void {}
106
- private onPointerOutOfBounds(_event: AdaptedPointerEvent): void {}
107
-
108
- public setOnPointerDown(
109
- callback: (event: AdaptedPointerEvent) => void
110
- ): void {
37
+ public setOnPointerDown(callback: (event: AdaptedEvent) => void): void {
111
38
  this.onPointerDown = callback;
112
39
  }
113
- public setOnPointerUp(callback: (event: AdaptedPointerEvent) => void): void {
40
+ public setOnPointerAdd(callback: (event: AdaptedEvent) => void): void {
41
+ this.onPointerAdd = callback;
42
+ }
43
+ public setOnPointerUp(callback: (event: AdaptedEvent) => void): void {
114
44
  this.onPointerUp = callback;
115
45
  }
116
- public setOnPointerMove(
117
- callback: (event: AdaptedPointerEvent) => void
118
- ): void {
46
+ public setOnPointerRemove(callback: (event: AdaptedEvent) => void): void {
47
+ this.onPointerRemove = callback;
48
+ }
49
+ public setOnPointerMove(callback: (event: AdaptedEvent) => void): void {
119
50
  this.onPointerMove = callback;
120
51
  }
121
- public setOnPointerOut(callback: (event: AdaptedPointerEvent) => void): void {
52
+ public setOnPointerOut(callback: (event: AdaptedEvent) => void): void {
122
53
  this.onPointerOut = callback;
123
54
  }
124
- public setOnPointerEnter(
125
- callback: (event: AdaptedPointerEvent) => void
126
- ): void {
55
+ public setOnPointerEnter(callback: (event: AdaptedEvent) => void): void {
127
56
  this.onPointerEnter = callback;
128
57
  }
129
- public setOnPointerCancel(
130
- callback: (event: AdaptedPointerEvent) => void
131
- ): void {
58
+ public setOnPointerCancel(callback: (event: AdaptedEvent) => void): void {
132
59
  this.onPointerCancel = callback;
133
60
  }
134
61
  public setOnPointerOutOfBounds(
135
- callback: (event: AdaptedPointerEvent) => void
62
+ callback: (event: AdaptedEvent) => void
136
63
  ): void {
137
64
  this.onPointerOutOfBounds = callback;
138
65
  }
139
66
 
140
- private mapEvent(
141
- event: PointerEvent,
142
- eventType: EventTypes
143
- ): AdaptedPointerEvent {
144
- return {
145
- x: event.clientX,
146
- y: event.clientY,
147
- offsetX: event.offsetX,
148
- offsetY: event.offsetY,
149
- pointerId: event.pointerId,
150
- eventType: eventType,
151
- pointerType: event.pointerType,
152
- buttons: event.buttons,
153
- time: event.timeStamp,
154
- };
155
- }
156
-
157
- public isPointerInBounds({ x, y }: { x: number; y: number }): boolean {
158
- if (!this.view) {
159
- return false;
160
- }
161
-
162
- const rect: DOMRect = this.view.getBoundingClientRect();
163
-
164
- return (
165
- x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
166
- );
167
- }
168
-
169
- private addActivePointer(pointerId: number): void {
170
- if (this.activePointers.indexOf(pointerId) >= 0) {
67
+ protected markAsInBounds(pointerId: number): void {
68
+ if (this.pointersInBounds.indexOf(pointerId) >= 0) {
171
69
  return;
172
70
  }
173
71
 
174
- this.activePointers.push(pointerId);
72
+ this.pointersInBounds.push(pointerId);
175
73
  }
176
74
 
177
- private removeActivePointer(pointerId: number): void {
178
- const index: number = this.activePointers.indexOf(pointerId);
75
+ protected markAsOutOfBounds(pointerId: number): void {
76
+ const index: number = this.pointersInBounds.indexOf(pointerId);
179
77
 
180
78
  if (index < 0) {
181
79
  return;
182
80
  }
183
81
 
184
- this.activePointers.splice(index, 1);
82
+ this.pointersInBounds.splice(index, 1);
83
+ }
84
+
85
+ public resetManager(): void {
86
+ // Reseting activePointersCounter is necessary to make gestures such as pinch work properly
87
+ // There are gestures that end when there is still one active pointer (like pinch/rotation)
88
+ // When these gestures end, they are reset, but they still receive events from pointer that is active
89
+ // This causes trouble, since only onPointerDown registers gesture in orchestrator, and while gestures receive
90
+ // Events from active pointer after they finished, next pointerdown event will be registered as additional pointer, not the first one
91
+ // This casues trouble like gestures getting stuck in END state, even though they should have gone to UNDETERMINED
92
+
93
+ this.activePointersCounter = 0;
94
+ this.pointersInBounds = [];
185
95
  }
186
96
  }
@@ -1,8 +1,9 @@
1
1
  import { State } from '../../State';
2
- import { AdaptedPointerEvent } from '../interfaces';
2
+ import { PointerType } from '../interfaces';
3
3
 
4
4
  import GestureHandler from '../handlers/GestureHandler';
5
5
  import PointerTracker from './PointerTracker';
6
+ import { isPointerInBounds } from '../utils';
6
7
 
7
8
  export default class GestureHandlerOrchestrator {
8
9
  private static instance: GestureHandlerOrchestrator;
@@ -31,13 +32,19 @@ export default class GestureHandlerOrchestrator {
31
32
  handler.setActivationIndex(Number.MAX_VALUE);
32
33
  }
33
34
 
35
+ public removeHandlerFromOrchestrator(handler: GestureHandler): void {
36
+ this.gestureHandlers.splice(this.gestureHandlers.indexOf(handler), 1);
37
+ this.awaitingHandlers.splice(this.awaitingHandlers.indexOf(handler), 1);
38
+ this.handlersToCancel.splice(this.handlersToCancel.indexOf(handler), 1);
39
+ }
40
+
34
41
  private cleanupFinishedHandlers(): void {
35
42
  for (let i = this.gestureHandlers.length - 1; i >= 0; --i) {
36
43
  const handler = this.gestureHandlers[i];
44
+
37
45
  if (!handler) {
38
46
  continue;
39
47
  }
40
-
41
48
  if (this.isFinished(handler.getState()) && !handler.isAwaiting()) {
42
49
  this.gestureHandlers.splice(i, 1);
43
50
 
@@ -62,15 +69,35 @@ export default class GestureHandlerOrchestrator {
62
69
  return hasToWait;
63
70
  }
64
71
 
65
- private tryActivate(
66
- handler: GestureHandler,
67
- event: AdaptedPointerEvent
68
- ): void {
72
+ private tryActivate(handler: GestureHandler): void {
69
73
  if (this.hasOtherHandlerToWaitFor(handler)) {
70
74
  this.addAwaitingHandler(handler);
71
- } else {
72
- this.makeActive(handler, event);
75
+ } else if (
76
+ handler.getState() !== State.CANCELLED &&
77
+ handler.getState() !== State.FAILED
78
+ ) {
79
+ if (this.shouldActivate(handler)) {
80
+ this.makeActive(handler);
81
+ } else {
82
+ switch (handler.getState()) {
83
+ case State.ACTIVE:
84
+ handler.fail();
85
+ break;
86
+ case State.BEGAN:
87
+ handler.cancel();
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ private shouldActivate(handler: GestureHandler): boolean {
94
+ for (const otherHandler of this.gestureHandlers) {
95
+ if (this.shouldHandlerBeCancelledBy(handler, otherHandler)) {
96
+ return false;
97
+ }
73
98
  }
99
+
100
+ return true;
74
101
  }
75
102
 
76
103
  private cleanupAwaitingHandlers(handler: GestureHandler): void {
@@ -89,36 +116,50 @@ export default class GestureHandlerOrchestrator {
89
116
  handler: GestureHandler,
90
117
  newState: State,
91
118
  oldState: State,
92
- event: AdaptedPointerEvent
119
+ sendIfDisabled?: boolean
93
120
  ): void {
121
+ if (!handler.isEnabled() && !sendIfDisabled) {
122
+ return;
123
+ }
124
+
94
125
  this.handlingChangeSemaphore += 1;
95
126
 
96
127
  if (this.isFinished(newState)) {
97
128
  this.awaitingHandlers.forEach((otherHandler) => {
98
129
  if (this.shouldHandlerWaitForOther(otherHandler, handler)) {
99
130
  if (newState === State.END) {
100
- otherHandler?.cancel(event);
131
+ otherHandler?.cancel();
132
+ if (otherHandler.getState() === State.END) {
133
+ // Handle edge case, where discrete gestures end immediately after activation thus
134
+ // their state is set to END and when the gesture they are waiting for activates they
135
+ // should be cancelled, however `cancel` was never sent as gestures were already in the END state.
136
+ // Send synthetic BEGAN -> CANCELLED to properly handle JS logic
137
+ otherHandler.sendEvent(State.CANCELLED, State.BEGAN);
138
+ }
101
139
  otherHandler?.setAwaiting(false);
102
140
  } else {
103
- this.tryActivate(otherHandler, event);
141
+ this.tryActivate(otherHandler);
104
142
  }
105
143
  }
106
144
  });
107
145
  }
108
146
 
109
147
  if (newState === State.ACTIVE) {
110
- this.tryActivate(handler, event);
148
+ this.tryActivate(handler);
111
149
  } else if (oldState === State.ACTIVE || oldState === State.END) {
112
150
  if (handler.isActive()) {
113
- handler.sendEvent(event, newState, oldState);
114
- } else if (oldState === State.ACTIVE) {
115
- handler.sendEvent(event, newState, State.BEGAN);
151
+ handler.sendEvent(newState, oldState);
152
+ } else if (
153
+ oldState === State.ACTIVE &&
154
+ (newState === State.CANCELLED || newState === State.FAILED)
155
+ ) {
156
+ handler.sendEvent(newState, State.BEGAN);
116
157
  }
117
158
  } else if (
118
159
  oldState !== State.UNDETERMINED ||
119
160
  newState !== State.CANCELLED
120
161
  ) {
121
- handler.sendEvent(event, newState, oldState);
162
+ handler.sendEvent(newState, oldState);
122
163
  }
123
164
 
124
165
  this.handlingChangeSemaphore -= 1;
@@ -130,10 +171,7 @@ export default class GestureHandlerOrchestrator {
130
171
  }
131
172
  }
132
173
 
133
- private makeActive(
134
- handler: GestureHandler,
135
- event: AdaptedPointerEvent
136
- ): void {
174
+ private makeActive(handler: GestureHandler): void {
137
175
  const currentState = handler.getState();
138
176
 
139
177
  handler.setActive(true);
@@ -142,33 +180,38 @@ export default class GestureHandlerOrchestrator {
142
180
 
143
181
  this.gestureHandlers.forEach((otherHandler) => {
144
182
  // Order of arguments is correct - we check whether current handler should cancel existing handlers
183
+
145
184
  if (this.shouldHandlerBeCancelledBy(otherHandler, handler)) {
146
185
  this.handlersToCancel.push(otherHandler);
147
186
  }
148
187
  });
149
188
 
150
189
  for (let i = this.handlersToCancel.length - 1; i >= 0; --i) {
151
- this.handlersToCancel[i]?.cancel(event);
190
+ this.handlersToCancel[i]?.cancel();
152
191
  }
153
192
  this.awaitingHandlers.forEach((otherHandler) => {
154
193
  if (this.shouldHandlerBeCancelledBy(otherHandler, handler)) {
155
- otherHandler?.cancel(event);
194
+ otherHandler?.cancel();
156
195
  otherHandler?.setAwaiting(true);
157
196
  }
158
197
  });
159
198
 
160
- handler.sendEvent(event, State.ACTIVE, State.BEGAN);
199
+ handler.sendEvent(State.ACTIVE, State.BEGAN);
161
200
 
162
201
  if (currentState !== State.ACTIVE) {
163
- handler.sendEvent(event, State.END, State.ACTIVE);
202
+ handler.sendEvent(State.END, State.ACTIVE);
164
203
  if (currentState !== State.END) {
165
- handler.sendEvent(event, State.UNDETERMINED, State.END);
204
+ handler.sendEvent(State.UNDETERMINED, State.END);
166
205
  }
167
206
  }
168
207
 
169
208
  if (handler.isAwaiting()) {
170
209
  handler.setAwaiting(false);
171
- handler.end(event);
210
+ for (let i = 0; i < this.awaitingHandlers.length; ++i) {
211
+ if (this.awaitingHandlers[i] === handler) {
212
+ this.awaitingHandlers.splice(i, 1);
213
+ }
214
+ }
172
215
  }
173
216
 
174
217
  this.handlersToCancel = [];
@@ -241,16 +284,6 @@ export default class GestureHandlerOrchestrator {
241
284
  handler: GestureHandler,
242
285
  otherHandler: GestureHandler
243
286
  ): boolean {
244
- const handlerPointers: number[] = handler.getTrackedPointersID();
245
- const otherPointers: number[] = otherHandler.getTrackedPointersID();
246
-
247
- if (
248
- !PointerTracker.shareCommonPointers(handlerPointers, otherPointers) &&
249
- handler.getView() !== otherHandler.getView()
250
- ) {
251
- return this.checkOverlap(handler, otherHandler);
252
- }
253
-
254
287
  if (this.canRunSimultaneously(handler, otherHandler)) {
255
288
  return false;
256
289
  }
@@ -263,6 +296,16 @@ export default class GestureHandlerOrchestrator {
263
296
  return handler.shouldBeCancelledByOther(otherHandler);
264
297
  }
265
298
 
299
+ const handlerPointers: number[] = handler.getTrackedPointersID();
300
+ const otherPointers: number[] = otherHandler.getTrackedPointersID();
301
+
302
+ if (
303
+ !PointerTracker.shareCommonPointers(handlerPointers, otherPointers) &&
304
+ handler.getView() !== otherHandler.getView()
305
+ ) {
306
+ return this.checkOverlap(handler, otherHandler);
307
+ }
308
+
266
309
  return true;
267
310
  }
268
311
 
@@ -286,12 +329,8 @@ export default class GestureHandlerOrchestrator {
286
329
  const handlerY: number = handler.getTracker().getLastY(pointer);
287
330
 
288
331
  if (
289
- handler
290
- .getEventManager()
291
- .isPointerInBounds({ x: handlerX, y: handlerY }) &&
292
- otherHandler
293
- .getEventManager()
294
- .isPointerInBounds({ x: handlerX, y: handlerY })
332
+ isPointerInBounds(handler.getView(), { x: handlerX, y: handlerY }) &&
333
+ isPointerInBounds(otherHandler.getView(), { x: handlerX, y: handlerY })
295
334
  ) {
296
335
  overlap = true;
297
336
  }
@@ -302,10 +341,8 @@ export default class GestureHandlerOrchestrator {
302
341
  const otherY: number = otherHandler.getTracker().getLastY(pointer);
303
342
 
304
343
  if (
305
- handler.getEventManager().isPointerInBounds({ x: otherX, y: otherY }) &&
306
- otherHandler
307
- .getEventManager()
308
- .isPointerInBounds({ x: otherX, y: otherY })
344
+ isPointerInBounds(handler.getView(), { x: otherX, y: otherY }) &&
345
+ isPointerInBounds(otherHandler.getView(), { x: otherX, y: otherY })
309
346
  ) {
310
347
  overlap = true;
311
348
  }
@@ -320,9 +357,40 @@ export default class GestureHandlerOrchestrator {
320
357
  );
321
358
  }
322
359
 
360
+ // This function is called when handler receives touchdown event
361
+ // If handler is using mouse or pen as a pointer and any handler receives touch event,
362
+ // mouse/pen event dissappears - it doesn't send onPointerCancel nor onPointerUp (and others)
363
+ // This became a problem because handler was left at active state without any signal to end or fail
364
+ // To handle this, when new touch event is received, we loop through active handlers and check which type of
365
+ // pointer they're using. If there are any handler with mouse/pen as a pointer, we cancel them
366
+ public cancelMouseAndPenGestures(currentHandler: GestureHandler): void {
367
+ this.gestureHandlers.forEach((handler: GestureHandler) => {
368
+ if (
369
+ handler.getPointerType() !== PointerType.MOUSE &&
370
+ handler.getPointerType() !== PointerType.PEN
371
+ ) {
372
+ return;
373
+ }
374
+
375
+ if (handler !== currentHandler) {
376
+ handler.cancel();
377
+ } else {
378
+ // Handler that received touch event should have its pointer tracker reset
379
+ // This allows handler to smoothly change from mouse/pen to touch
380
+ // The drawback is, that when we try to use mouse/pen one more time, it doesn't send onPointerDown at the first time
381
+ // so it is required to click two times to get handler to work
382
+ //
383
+ // However, handler will receive manually created onPointerEnter that is triggered in EventManager in onPointerMove method.
384
+ // There may be possibility to use that fact to make handler respond properly to first mouse click
385
+ handler.getTracker().resetTracker();
386
+ }
387
+ });
388
+ }
389
+
323
390
  public static getInstance(): GestureHandlerOrchestrator {
324
- if (!GestureHandlerOrchestrator.instance)
391
+ if (!GestureHandlerOrchestrator.instance) {
325
392
  GestureHandlerOrchestrator.instance = new GestureHandlerOrchestrator();
393
+ }
326
394
 
327
395
  return GestureHandlerOrchestrator.instance;
328
396
  }