@react-native-oh-tpl/react-native-gesture-handler 2.12.9 → 2.14.1-2.14.13
Sign up to get free protection for your applications and to get access to all the features.
- package/DrawerLayout/index.ts +2 -0
- package/Swipeable/index.ts +2 -0
- package/harmony/gesture_handler/BuildProfile.ets +15 -3
- package/harmony/gesture_handler/hvigorfile.ts +1 -1
- package/harmony/gesture_handler/index.ets +2 -2
- package/harmony/gesture_handler/oh-package-lock.json5 +4 -3
- package/harmony/gesture_handler/oh-package.json5 +3 -3
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +64 -18
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +3 -3
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +2 -2
- package/harmony/gesture_handler/src/main/cpp/{RNGestureHandlerButtonComponentInstance.h → componentInstances/RNGestureHandlerButtonComponentInstance.h} +2 -2
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +242 -0
- package/harmony/gesture_handler/src/main/ets/{GestureHandler.ts → core/GestureHandler.ts} +54 -27
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +63 -0
- package/harmony/gesture_handler/src/main/ets/{Event.ts → core/IncomingEvent.ts} +30 -20
- package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
- package/harmony/gesture_handler/src/main/ets/{OutgoingEvent.ts → core/OutgoingEvent.ts} +1 -1
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/{PointerTracker.ts → core/PointerTracker.ts} +4 -4
- package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
- package/harmony/gesture_handler/src/main/ets/{VelocityTracker.ts → core/VelocityTracker.ts} +13 -5
- package/harmony/gesture_handler/src/main/ets/core/View.ts +21 -0
- package/harmony/gesture_handler/src/main/ets/core/ViewFinder.ts +11 -0
- package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +8 -0
- package/harmony/gesture_handler/src/main/ets/core/index.ts +15 -0
- package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +15 -15
- package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
- package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
- package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
- package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
- package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
- package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
- package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +98 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +79 -29
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +134 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +97 -0
- package/harmony/gesture_handler/src/main/module.json5 +8 -6
- package/harmony/gesture_handler/ts.ts +2 -2
- package/harmony/gesture_handler.har +0 -0
- package/lib/commonjs/index.js +126 -141
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +13 -146
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +39 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +13 -10
- package/src/index.ts +140 -140
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -78
- package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
- package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
- package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
- package/harmony/gesture_handler/src/main/ets/GestureHandlerRegistry.ts +0 -28
- package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
- package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
- package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
- package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
- package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
- package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
- package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
- package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
- /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{types.ts → rnoh/types.ts} +0 -0
@@ -1,24 +1,28 @@
|
|
1
1
|
import type { GestureHandlerOrchestrator } from "./GestureHandlerOrchestrator"
|
2
2
|
import type { PointerTracker } from "./PointerTracker"
|
3
3
|
import type { View } from "./View"
|
4
|
-
import type { EventDispatcher } from "./EventDispatcher"
|
5
4
|
import type { InteractionManager } from "./InteractionManager"
|
6
5
|
import type { RNGHLogger } from './RNGHLogger'
|
6
|
+
import { OutgoingEventDispatcher } from "./OutgoingEventDispatcher"
|
7
7
|
import { State, getStateName } from "./State"
|
8
|
-
import { HitSlop, Directions,
|
8
|
+
import { HitSlop, Directions, IncomingEvent, PointerType, TouchEventType, EventType } from "./IncomingEvent"
|
9
9
|
import { GestureStateChangeEvent, GestureTouchEvent, TouchData } from "./OutgoingEvent"
|
10
10
|
|
11
11
|
|
12
|
+
export type GHTag = number
|
13
|
+
|
12
14
|
export interface Handler {
|
13
|
-
handlerTag:
|
15
|
+
handlerTag: GHTag;
|
14
16
|
}
|
15
17
|
|
16
18
|
export const DEFAULT_TOUCH_SLOP = 15;
|
17
19
|
|
18
20
|
export interface GestureConfig {
|
19
21
|
enabled?: boolean;
|
22
|
+
manualActivation?: boolean;
|
20
23
|
simultaneousHandlers?: Handler[] | null;
|
21
24
|
waitFor?: Handler[] | null;
|
25
|
+
blocksHandlers?: Handler[] | null;
|
22
26
|
hitSlop?: HitSlop;
|
23
27
|
shouldCancelWhenOutside?: boolean;
|
24
28
|
activateAfterLongPress?: number;
|
@@ -49,7 +53,7 @@ export interface GestureConfig {
|
|
49
53
|
maxDeltaY?: number;
|
50
54
|
shouldActivateOnStart?: boolean;
|
51
55
|
disallowInterruption?: boolean;
|
52
|
-
direction?:
|
56
|
+
direction?: Directions;
|
53
57
|
needsPointerData?: boolean
|
54
58
|
// --- Tap
|
55
59
|
minNumberOfPointers?: number
|
@@ -61,6 +65,10 @@ export interface ScrollLocker {
|
|
61
65
|
lockScrollContainingViewTag(viewTag: number): () => void
|
62
66
|
}
|
63
67
|
|
68
|
+
export interface RNGestureResponder {
|
69
|
+
lock: (viewTag: number) => () => void
|
70
|
+
}
|
71
|
+
|
64
72
|
export type GestureHandlerDependencies = {
|
65
73
|
handlerTag: number
|
66
74
|
orchestrator: GestureHandlerOrchestrator
|
@@ -68,6 +76,7 @@ export type GestureHandlerDependencies = {
|
|
68
76
|
interactionManager: InteractionManager
|
69
77
|
logger: RNGHLogger
|
70
78
|
scrollLocker: ScrollLocker
|
79
|
+
rnGestureResponder: RNGestureResponder
|
71
80
|
}
|
72
81
|
|
73
82
|
export abstract class GestureHandler<TGestureConfig extends GestureConfig = GestureConfig> {
|
@@ -86,10 +95,11 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
86
95
|
protected handlerTag: number
|
87
96
|
protected orchestrator: GestureHandlerOrchestrator
|
88
97
|
protected tracker: PointerTracker
|
89
|
-
protected eventDispatcher:
|
98
|
+
protected eventDispatcher: OutgoingEventDispatcher
|
90
99
|
protected interactionManager: InteractionManager
|
91
100
|
protected logger: RNGHLogger
|
92
101
|
protected scrollLocker: ScrollLocker
|
102
|
+
protected rnGestureResponder: RNGestureResponder
|
93
103
|
|
94
104
|
constructor(deps: GestureHandlerDependencies
|
95
105
|
) {
|
@@ -99,15 +109,16 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
99
109
|
this.interactionManager = deps.interactionManager
|
100
110
|
this.logger = deps.logger
|
101
111
|
this.scrollLocker = deps.scrollLocker
|
112
|
+
this.rnGestureResponder = deps.rnGestureResponder
|
102
113
|
}
|
103
114
|
|
104
|
-
public setEventDispatcher(eventDispatcher:
|
115
|
+
public setEventDispatcher(eventDispatcher: OutgoingEventDispatcher) {
|
105
116
|
// TurboModule provides info about kind of event dispatcher when attaching GH to a view, not when GH is created.
|
106
117
|
// This method must be called before any other
|
107
118
|
this.eventDispatcher = eventDispatcher
|
108
119
|
}
|
109
120
|
|
110
|
-
public onPointerDown(e:
|
121
|
+
public onPointerDown(e: IncomingEvent) {
|
111
122
|
this.logger.info("onPointerDown")
|
112
123
|
this.orchestrator.registerHandlerIfNotPresent(this);
|
113
124
|
this.pointerType = e.pointerType;
|
@@ -119,7 +130,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
119
130
|
}
|
120
131
|
}
|
121
132
|
|
122
|
-
protected sendTouchEvent(e:
|
133
|
+
protected sendTouchEvent(e: IncomingEvent) {
|
123
134
|
if (!this.config.enabled) {
|
124
135
|
return;
|
125
136
|
}
|
@@ -133,7 +144,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
133
144
|
}
|
134
145
|
}
|
135
146
|
|
136
|
-
protected transformToTouchEvent(event:
|
147
|
+
protected transformToTouchEvent(event: IncomingEvent): GestureTouchEvent | undefined {
|
137
148
|
const rect = this.view.getBoundingRect();
|
138
149
|
|
139
150
|
const all: TouchData[] = [];
|
@@ -226,22 +237,22 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
226
237
|
};
|
227
238
|
}
|
228
239
|
|
229
|
-
public onPointerUp(e:
|
240
|
+
public onPointerUp(e: IncomingEvent): void {
|
230
241
|
this.logger.info("onPointerUp")
|
231
242
|
if (this.config.needsPointerData) this.sendTouchEvent(e)
|
232
243
|
}
|
233
244
|
|
234
|
-
public onAdditionalPointerAdd(e:
|
245
|
+
public onAdditionalPointerAdd(e: IncomingEvent): void {
|
235
246
|
this.logger.info("onAdditionalPointerAdd")
|
236
247
|
if (this.config.needsPointerData) this.sendTouchEvent(e)
|
237
248
|
}
|
238
249
|
|
239
|
-
public onAdditionalPointerRemove(e:
|
250
|
+
public onAdditionalPointerRemove(e: IncomingEvent): void {
|
240
251
|
this.logger.info("onAdditionalPointerRemove")
|
241
252
|
if (this.config.needsPointerData) this.sendTouchEvent(e)
|
242
253
|
}
|
243
254
|
|
244
|
-
public onPointerMove(e:
|
255
|
+
public onPointerMove(e: IncomingEvent): void {
|
245
256
|
this.logger.info("onPointerMove")
|
246
257
|
this.tryToSendMoveEvent(false);
|
247
258
|
if (this.config.needsPointerData) {
|
@@ -265,14 +276,14 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
265
276
|
}
|
266
277
|
}
|
267
278
|
|
268
|
-
public onPointerEnter(e:
|
279
|
+
public onPointerEnter(e: IncomingEvent): void {
|
269
280
|
this.logger.info("onPointerEnter")
|
270
281
|
if (this.config.needsPointerData) {
|
271
282
|
this.sendTouchEvent(e)
|
272
283
|
}
|
273
284
|
}
|
274
285
|
|
275
|
-
public onPointerOut(e:
|
286
|
+
public onPointerOut(e: IncomingEvent): void {
|
276
287
|
this.logger.info("onPointerOut")
|
277
288
|
if (this.shouldCancelWhenOutside) {
|
278
289
|
switch (this.currentState) {
|
@@ -290,7 +301,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
290
301
|
}
|
291
302
|
}
|
292
303
|
|
293
|
-
public onPointerCancel(e:
|
304
|
+
public onPointerCancel(e: IncomingEvent): void {
|
294
305
|
this.logger.info("onPointerCancel")
|
295
306
|
if (this.config.needsPointerData) {
|
296
307
|
this.sendTouchEvent(e);
|
@@ -299,7 +310,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
299
310
|
this.reset();
|
300
311
|
}
|
301
312
|
|
302
|
-
public onPointerOutOfBounds(e:
|
313
|
+
public onPointerOutOfBounds(e: IncomingEvent): void {
|
303
314
|
this.logger.info("onPointerOutOfBounds")
|
304
315
|
this.tryToSendMoveEvent(true);
|
305
316
|
if (this.config.needsPointerData) {
|
@@ -403,7 +414,7 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
403
414
|
|
404
415
|
public activate(): void {
|
405
416
|
this.logger.info("activate")
|
406
|
-
if (this.currentState === State.UNDETERMINED || this.currentState === State.BEGAN) {
|
417
|
+
if (!this.config.manualActivation || this.currentState === State.UNDETERMINED || this.currentState === State.BEGAN) {
|
407
418
|
this.moveToState(State.ACTIVE)
|
408
419
|
}
|
409
420
|
}
|
@@ -417,7 +428,11 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
417
428
|
this.cancelTouches()
|
418
429
|
}
|
419
430
|
this.orchestrator.onHandlerStateChange(this, state, oldState)
|
420
|
-
this.
|
431
|
+
this.onStateChange(state, oldState)
|
432
|
+
|
433
|
+
if (!this.isEnabled() && this.isFinished()) {
|
434
|
+
this.currentState = State.UNDETERMINED;
|
435
|
+
}
|
421
436
|
}
|
422
437
|
|
423
438
|
private isFinished() {
|
@@ -464,8 +479,8 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
464
479
|
this.eventDispatcher.onGestureHandlerEvent(cancelEvent)
|
465
480
|
}
|
466
481
|
|
467
|
-
protected
|
468
|
-
this.logger.info(`
|
482
|
+
protected onStateChange(newState: State, oldState: State) {
|
483
|
+
this.logger.info(`onStateChange: from ${getStateName(oldState)} to ${getStateName(newState)}`)
|
469
484
|
}
|
470
485
|
|
471
486
|
|
@@ -535,14 +550,16 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
535
550
|
oldState: State,
|
536
551
|
newState: State
|
537
552
|
}): void {
|
538
|
-
this.logger.
|
553
|
+
const logger = this.logger.cloneWithPrefix(`sendEvent(newState=${getStateName(newState)}, oldState=${getStateName(oldState)})`)
|
539
554
|
const stateChangeEvent = this.createStateChangeEvent(newState, oldState);
|
540
555
|
if (this.lastSentState !== newState) {
|
541
556
|
this.lastSentState = newState;
|
557
|
+
logger.debug("calling onGestureHandlerStateChange")
|
542
558
|
this.eventDispatcher.onGestureHandlerStateChange(stateChangeEvent);
|
543
559
|
}
|
544
560
|
if (this.currentState === State.ACTIVE) {
|
545
561
|
stateChangeEvent.oldState = undefined;
|
562
|
+
logger.debug("calling onGestureHandlerEvent")
|
546
563
|
this.eventDispatcher.onGestureHandlerEvent(stateChangeEvent);
|
547
564
|
}
|
548
565
|
}
|
@@ -562,8 +579,14 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
562
579
|
};
|
563
580
|
}
|
564
581
|
|
565
|
-
protected transformNativeEvent() {
|
566
|
-
|
582
|
+
protected transformNativeEvent(): Record<string, unknown> {
|
583
|
+
const rect = this.view.getBoundingRect();
|
584
|
+
return {
|
585
|
+
x: this.tracker.getLastAvgX() - rect.x,
|
586
|
+
y: this.tracker.getLastAvgY() - rect.y,
|
587
|
+
absoluteX: this.tracker.getLastAvgX(),
|
588
|
+
absoluteY: this.tracker.getLastAvgY(),
|
589
|
+
};
|
567
590
|
}
|
568
591
|
|
569
592
|
setAwaiting(isAwaiting: boolean): void {
|
@@ -583,11 +606,14 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
583
606
|
}
|
584
607
|
|
585
608
|
shouldWaitFor(otherHandler: GestureHandler): boolean {
|
586
|
-
|
609
|
+
const logger = this.logger.cloneWithPrefix(`shouldWaitFor(${otherHandler.getTag()})`)
|
610
|
+
const result = (
|
587
611
|
this !== otherHandler &&
|
588
612
|
(this.shouldWaitForHandlerFailure(otherHandler) ||
|
589
613
|
otherHandler.shouldRequireToWaitForFailure(this))
|
590
614
|
);
|
615
|
+
logger.debug(result)
|
616
|
+
return result
|
591
617
|
}
|
592
618
|
|
593
619
|
reset(): void {
|
@@ -595,7 +621,6 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
595
621
|
this.tracker.resetTracker();
|
596
622
|
this.onReset();
|
597
623
|
this.resetProgress();
|
598
|
-
// TODO: reset ArkUIAdapters
|
599
624
|
// this.eventManagers.forEach((manager: EventManager) =>
|
600
625
|
// manager.resetManager()
|
601
626
|
// );
|
@@ -640,8 +665,10 @@ export abstract class GestureHandler<TGestureConfig extends GestureConfig = Gest
|
|
640
665
|
}
|
641
666
|
|
642
667
|
shouldRecognizeSimultaneously(otherHandler: GestureHandler): boolean {
|
643
|
-
|
668
|
+
this.logger.cloneWithPrefix(`shouldRecognizeSimultaneously(${otherHandler.getTag()})`).debug("")
|
669
|
+
if (otherHandler === this) {
|
644
670
|
return true;
|
671
|
+
}
|
645
672
|
return this.interactionManager.shouldRecognizeSimultaneously(this, otherHandler);
|
646
673
|
}
|
647
674
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { GestureHandler } from "./GestureHandler"
|
2
|
-
import { State } from "./State"
|
3
|
-
import { PointerType } from "./
|
2
|
+
import { State, getStateName } from "./State"
|
3
|
+
import { PointerType } from "./IncomingEvent"
|
4
4
|
import { RNGHLogger } from "./RNGHLogger"
|
5
5
|
|
6
6
|
export class GestureHandlerOrchestrator {
|
@@ -13,92 +13,133 @@ export class GestureHandlerOrchestrator {
|
|
13
13
|
}
|
14
14
|
|
15
15
|
public onHandlerStateChange(handler: GestureHandler, newState: State, oldState: State, sendIfDisabled?: boolean) {
|
16
|
-
this.logger.
|
17
|
-
|
16
|
+
const logger = this.logger.cloneWithPrefix(`onHandlerStateChange(handler=${handler.getTag()}, newState=${getStateName(newState)}, oldState=${getStateName(oldState)})`)
|
17
|
+
logger.debug("start")
|
18
|
+
|
19
|
+
if (!handler.isEnabled() && !sendIfDisabled) {
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
|
23
|
+
// this.handlingChangeSemaphore += 1;
|
24
|
+
|
18
25
|
if (this.isFinishedState(newState)) {
|
19
|
-
this.
|
26
|
+
this.awaitingHandlers.forEach((otherHandler) => {
|
27
|
+
if (otherHandler.shouldWaitFor(handler)) {
|
28
|
+
if (newState === State.END) {
|
29
|
+
otherHandler?.cancel();
|
30
|
+
if (otherHandler.getState() === State.END) {
|
31
|
+
// Handle edge case, where discrete gestures end immediately after activation thus
|
32
|
+
// their state is set to END and when the gesture they are waiting for activates they
|
33
|
+
// should be cancelled, however `cancel` was never sent as gestures were already in the END state.
|
34
|
+
// Send synthetic BEGAN -> CANCELLED to properly handle JS logic
|
35
|
+
otherHandler.sendEvent({ newState: State.CANCELLED, oldState: State.BEGAN });
|
36
|
+
}
|
37
|
+
otherHandler?.setAwaiting(false);
|
38
|
+
} else {
|
39
|
+
this.tryActivate(otherHandler);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
});
|
20
43
|
}
|
44
|
+
|
21
45
|
if (newState === State.ACTIVE) {
|
22
|
-
this.tryActivate(handler)
|
46
|
+
this.tryActivate(handler);
|
23
47
|
} else if (oldState === State.ACTIVE || oldState === State.END) {
|
24
48
|
if (handler.isActive()) {
|
25
|
-
handler.sendEvent({ newState, oldState })
|
26
|
-
} else if (
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
// makeActive method.
|
32
|
-
handler.sendEvent({ newState, oldState: State.BEGAN })
|
49
|
+
handler.sendEvent({ newState, oldState });
|
50
|
+
} else if (
|
51
|
+
oldState === State.ACTIVE &&
|
52
|
+
(newState === State.CANCELLED || newState === State.FAILED)
|
53
|
+
) {
|
54
|
+
handler.sendEvent({ newState, oldState: State.BEGAN });
|
33
55
|
}
|
34
|
-
} else if (
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
handler.sendEvent({ newState, oldState })
|
56
|
+
} else if (
|
57
|
+
oldState !== State.UNDETERMINED ||
|
58
|
+
newState !== State.CANCELLED
|
59
|
+
) {
|
60
|
+
handler.sendEvent({ newState, oldState });
|
40
61
|
}
|
41
|
-
this.cleanUpHandlers(handler)
|
42
|
-
}
|
43
62
|
|
44
|
-
|
45
|
-
return [State.END, State.FAILED, State.CANCELLED].includes(state)
|
46
|
-
}
|
63
|
+
// this.handlingChangeSemaphore -= 1;
|
47
64
|
|
48
|
-
|
49
|
-
|
50
|
-
|
65
|
+
this.cleanUpFinishedHandlers();
|
66
|
+
if (!this.awaitingHandlers.has(handler)) {
|
67
|
+
this.cleanupAwaitingHandlers(handler);
|
68
|
+
}
|
51
69
|
}
|
52
70
|
|
53
|
-
private
|
54
|
-
|
55
|
-
if (handler.shouldWaitFor(awaitingHandler)) {
|
56
|
-
if (newState === State.END) {
|
57
|
-
awaitingHandler.cancel()
|
58
|
-
if (awaitingHandler.getState() === State.END) {
|
59
|
-
// Handle edge case, where discrete gestures end immediately after activation thus
|
60
|
-
// their state is set to END and when the gesture they are waiting for activates they
|
61
|
-
// should be cancelled, however `cancel` was never sent as gestures were already in the END state.
|
62
|
-
// Send synthetic BEGAN -> CANCELLED to properly handle JS logic
|
63
|
-
awaitingHandler.sendEvent({ newState: State.CANCELLED, oldState: State.BEGAN })
|
64
|
-
}
|
65
|
-
awaitingHandler.setAwaiting(false)
|
66
|
-
} else {
|
67
|
-
this.tryActivate(awaitingHandler)
|
68
|
-
}
|
69
|
-
}
|
70
|
-
})
|
71
|
+
private isFinishedState(state: State) {
|
72
|
+
return [State.END, State.FAILED, State.CANCELLED].includes(state)
|
71
73
|
}
|
72
74
|
|
73
75
|
private tryActivate(handler: GestureHandler): void {
|
76
|
+
const logger = this.logger.cloneWithPrefix(`tryActivate(${handler.getTag()})`)
|
77
|
+
logger.debug({
|
78
|
+
gestureHandlers: this.gestureHandlers.map(gh => gh.getTag()),
|
79
|
+
awaitingHandlers: Array.from(this.awaitingHandlers).map(gh => gh.getTag()),
|
80
|
+
handlersToCancel: this.handlersToCancel.map(gh => gh.getTag())
|
81
|
+
})
|
82
|
+
if (this.shouldBeCancelledByFinishedHandler(handler)) {
|
83
|
+
logger.debug("failed to activate - cancelling")
|
84
|
+
handler.cancel();
|
85
|
+
return;
|
86
|
+
}
|
74
87
|
if (this.hasOtherHandlerToWaitFor(handler)) {
|
75
|
-
this.addAwaitingHandler(handler)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
this.addAwaitingHandler(handler);
|
89
|
+
logger.debug("request ignored - has other handler waiting")
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
const handlerState = handler.getState();
|
93
|
+
if (handlerState === State.CANCELLED || handlerState === State.FAILED) {
|
94
|
+
logger.debug("request ignored - handler is in cancelled or failed state")
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
if (this.shouldActivate(handler)) {
|
98
|
+
logger.debug("activating")
|
99
|
+
this.makeActive(handler);
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
if (handlerState === State.ACTIVE) {
|
103
|
+
logger.debug("failed to activate - handler is already active, marking as fail")
|
104
|
+
handler.fail();
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
if (handlerState === State.BEGAN) {
|
108
|
+
logger.debug("handler is in BEGAN state but shouldActivate returned false - cancelling")
|
109
|
+
handler.cancel();
|
89
110
|
}
|
90
111
|
}
|
91
112
|
|
113
|
+
private shouldBeCancelledByFinishedHandler(
|
114
|
+
handler: GestureHandler
|
115
|
+
): boolean {
|
116
|
+
const shouldBeCancelled = (otherHandler: GestureHandler) => {
|
117
|
+
return (
|
118
|
+
handler.shouldWaitFor(otherHandler) &&
|
119
|
+
otherHandler.getState() === State.END
|
120
|
+
);
|
121
|
+
};
|
122
|
+
return this.gestureHandlers.some(shouldBeCancelled);
|
123
|
+
}
|
124
|
+
|
92
125
|
private hasOtherHandlerToWaitFor(handler: GestureHandler): boolean {
|
126
|
+
const logger = this.logger.cloneWithPrefix(`hasOtherHandlerToWaitFor(handler=${handler.getTag()})`)
|
93
127
|
for (const otherHandler of this.gestureHandlers) {
|
94
|
-
if (
|
128
|
+
if (otherHandler === handler) {
|
129
|
+
return false
|
130
|
+
}
|
131
|
+
if (!this.isFinishedState(otherHandler.getState()) && handler.shouldWaitFor(otherHandler)) {
|
132
|
+
logger.debug("true")
|
95
133
|
return true
|
96
134
|
}
|
97
135
|
}
|
136
|
+
logger.debug("false")
|
98
137
|
return false;
|
99
138
|
}
|
100
139
|
|
101
140
|
private addAwaitingHandler(handler: GestureHandler) {
|
141
|
+
const logger = this.logger.cloneWithPrefix(`addAwaitingHandler(handlerTag=${handler.getTag()})`)
|
142
|
+
logger.debug({ awaitingHandlers: this.awaitingHandlers })
|
102
143
|
if (!this.awaitingHandlers.has(handler)) {
|
103
144
|
this.awaitingHandlers.add(handler)
|
104
145
|
handler.setAwaiting(true)
|
@@ -119,17 +160,29 @@ export class GestureHandlerOrchestrator {
|
|
119
160
|
handler: GestureHandler,
|
120
161
|
otherHandler: GestureHandler
|
121
162
|
}): boolean {
|
122
|
-
|
163
|
+
const logger = this.logger.cloneWithPrefix(`shouldHandlerBeCancelledByOtherHandler(${handler.getTag()}, ${otherHandler.getTag()})`)
|
164
|
+
if (this.canRunSimultaneously(handler, otherHandler)) {
|
165
|
+
logger.debug("false")
|
123
166
|
return false;
|
124
|
-
|
125
|
-
|
126
|
-
|
167
|
+
}
|
168
|
+
if (handler !== otherHandler && (handler.isAwaiting() || handler.getState() === State.ACTIVE)) {
|
169
|
+
const result = handler.shouldBeCancelledByOther(otherHandler)
|
170
|
+
logger.debug(`${result} (1)`)
|
171
|
+
return result
|
172
|
+
}
|
173
|
+
const result = this.checkOverlap(handler, otherHandler)
|
174
|
+
logger.debug(`${result} (2)`)
|
175
|
+
return result;
|
127
176
|
}
|
128
177
|
|
129
178
|
private canRunSimultaneously(handlerA: GestureHandler, handlerB: GestureHandler) {
|
130
|
-
|
179
|
+
const logger = this.logger.cloneWithPrefix("canRunSimultaneously")
|
180
|
+
const result = handlerA === handlerB
|
131
181
|
|| handlerA.shouldRecognizeSimultaneously(handlerB)
|
132
182
|
|| handlerB.shouldRecognizeSimultaneously(handlerA)
|
183
|
+
|
184
|
+
logger.debug({ result, handlerA: handlerA.getTag(), handlerB: handlerB.getTag() })
|
185
|
+
return result
|
133
186
|
}
|
134
187
|
|
135
188
|
private checkOverlap(
|
@@ -222,6 +275,8 @@ export class GestureHandlerOrchestrator {
|
|
222
275
|
}
|
223
276
|
|
224
277
|
private cleanupAwaitingHandlers(handler: GestureHandler): void {
|
278
|
+
const logger = this.logger.cloneWithPrefix(`cleanupAwaitingHandlers(handler=${handler.getTag()})`)
|
279
|
+
logger.debug({ awaitingHandlers: this.awaitingHandlers })
|
225
280
|
for (const awaitingHandler of this.awaitingHandlers) {
|
226
281
|
if (
|
227
282
|
awaitingHandler.isAwaiting() &&
|
@@ -241,7 +296,7 @@ export class GestureHandlerOrchestrator {
|
|
241
296
|
}
|
242
297
|
|
243
298
|
public registerHandlerIfNotPresent(handler: GestureHandler) {
|
244
|
-
this.logger.info(
|
299
|
+
this.logger.info(`registerHandlerIfNotPresent(${handler.getTag()})`)
|
245
300
|
if (this.gestureHandlers.includes(handler)) return;
|
246
301
|
this.gestureHandlers.push(handler);
|
247
302
|
handler.setActive(false);
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import { GestureHandler } from "./GestureHandler"
|
2
|
+
import { View } from "./View"
|
3
|
+
import { RNGHLogger } from "./RNGHLogger"
|
4
|
+
import { ViewRegistry } from "./ViewRegistry"
|
5
|
+
|
6
|
+
export class GestureHandlerRegistry {
|
7
|
+
private gestureHandlerByHandlerTag: Map<number, GestureHandler> = new Map()
|
8
|
+
private gestureHandlersByViewTag: Map<number, Set<GestureHandler>> = new Map()
|
9
|
+
private viewRegistry: ViewRegistry | undefined
|
10
|
+
private logger: RNGHLogger
|
11
|
+
|
12
|
+
constructor(viewRegistry: ViewRegistry | undefined, logger: RNGHLogger) {
|
13
|
+
this.logger = logger.cloneWithPrefix("GestureHandlerRegistry")
|
14
|
+
this.viewRegistry = viewRegistry
|
15
|
+
}
|
16
|
+
|
17
|
+
public addGestureHandler(gestureHandler: GestureHandler) {
|
18
|
+
this.gestureHandlerByHandlerTag.set(gestureHandler.getTag(), gestureHandler)
|
19
|
+
}
|
20
|
+
|
21
|
+
public bindGestureHandlerWithView(gestureHandlerTag: number, view: View) {
|
22
|
+
this.logger.cloneWithPrefix("bindGestureHandlerWithView").debug({gestureHandlerTag, viewTag: view.getTag()})
|
23
|
+
const viewTag = view.getTag()
|
24
|
+
if (!this.gestureHandlersByViewTag.has(viewTag))
|
25
|
+
this.gestureHandlersByViewTag.set(viewTag, new Set())
|
26
|
+
const gestureHandler = this.gestureHandlerByHandlerTag.get(gestureHandlerTag)
|
27
|
+
this.gestureHandlersByViewTag.get(viewTag).add(gestureHandler)
|
28
|
+
gestureHandler.onViewAttached(view)
|
29
|
+
}
|
30
|
+
|
31
|
+
public getGestureHandlersByViewTag(viewTag: number): GestureHandler[] {
|
32
|
+
return Array.from(this.gestureHandlersByViewTag.get(viewTag) ?? [])
|
33
|
+
}
|
34
|
+
|
35
|
+
public removeGestureHandlerByHandlerTag(handlerTag: number) {
|
36
|
+
const gestureHandler = this.gestureHandlerByHandlerTag.get(handlerTag)
|
37
|
+
if (!gestureHandler) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
const viewTag = gestureHandler.getView()?.getTag();
|
41
|
+
if (viewTag) {
|
42
|
+
const gestureHandlers = this.gestureHandlersByViewTag.get(viewTag)
|
43
|
+
if (gestureHandlers) {
|
44
|
+
gestureHandlers.delete(gestureHandler)
|
45
|
+
if (gestureHandlers.size === 0) {
|
46
|
+
this.gestureHandlersByViewTag.delete(viewTag)
|
47
|
+
this.viewRegistry?.deleteByTag(viewTag)
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
if (gestureHandler.getView()) {
|
52
|
+
// Handler is in "prepared" state which means it is registered in the orchestrator and can
|
53
|
+
// receive touch events. This means that before we remove it from the registry we need to
|
54
|
+
// "cancel" it so that orchestrator does no longer keep a reference to it.
|
55
|
+
gestureHandler.cancel()
|
56
|
+
}
|
57
|
+
this.gestureHandlerByHandlerTag.delete(handlerTag)
|
58
|
+
}
|
59
|
+
|
60
|
+
public getGestureHandlerByHandlerTag(handlerTag: number): GestureHandler {
|
61
|
+
return this.gestureHandlerByHandlerTag.get(handlerTag)
|
62
|
+
}
|
63
|
+
}
|
@@ -9,13 +9,30 @@ export interface HitSlop {
|
|
9
9
|
height?: number;
|
10
10
|
}
|
11
11
|
|
12
|
+
const RIGHT = 1;
|
13
|
+
const LEFT = 2;
|
14
|
+
const UP = 4;
|
15
|
+
const DOWN = 8;
|
16
|
+
|
12
17
|
export const Directions = {
|
13
|
-
RIGHT:
|
14
|
-
LEFT:
|
15
|
-
UP:
|
16
|
-
DOWN:
|
18
|
+
RIGHT: RIGHT,
|
19
|
+
LEFT: LEFT,
|
20
|
+
UP: UP,
|
21
|
+
DOWN: DOWN,
|
17
22
|
} as const;
|
18
23
|
|
24
|
+
export type Directions = typeof Directions[keyof typeof Directions];
|
25
|
+
|
26
|
+
export const DiagonalDirections = {
|
27
|
+
UP_RIGHT: UP | RIGHT,
|
28
|
+
DOWN_RIGHT: DOWN | RIGHT,
|
29
|
+
UP_LEFT: UP | LEFT,
|
30
|
+
DOWN_LEFT: DOWN | LEFT,
|
31
|
+
} as const;
|
32
|
+
|
33
|
+
export type DiagonalDirections =
|
34
|
+
typeof DiagonalDirections[keyof typeof DiagonalDirections];
|
35
|
+
|
19
36
|
export enum PointerType {
|
20
37
|
NONE = 'none',
|
21
38
|
MOUSE = 'mouse',
|
@@ -24,14 +41,14 @@ export enum PointerType {
|
|
24
41
|
}
|
25
42
|
|
26
43
|
export enum EventType {
|
27
|
-
DOWN,
|
28
|
-
ADDITIONAL_POINTER_DOWN,
|
29
|
-
UP,
|
30
|
-
ADDITIONAL_POINTER_UP,
|
31
|
-
MOVE,
|
32
|
-
ENTER,
|
33
|
-
OUT,
|
34
|
-
CANCEL,
|
44
|
+
DOWN = "DOWN",
|
45
|
+
ADDITIONAL_POINTER_DOWN = "ADDITIONAL_POINTER_DOWN",
|
46
|
+
UP = "UP",
|
47
|
+
ADDITIONAL_POINTER_UP = "ADDITIONAL_POINTER_UP",
|
48
|
+
MOVE = "MOVE",
|
49
|
+
ENTER = "ENTER",
|
50
|
+
OUT = "OUT",
|
51
|
+
CANCEL = "CANCEL",
|
35
52
|
}
|
36
53
|
|
37
54
|
export type Touch = {id: number, x: number, y: number, absoluteX: number, absoluteY: number}
|
@@ -44,7 +61,7 @@ export enum TouchEventType {
|
|
44
61
|
CANCELLED = 4,
|
45
62
|
}
|
46
63
|
|
47
|
-
export interface
|
64
|
+
export interface IncomingEvent {
|
48
65
|
x: number;
|
49
66
|
y: number;
|
50
67
|
offsetX: number;
|
@@ -59,10 +76,3 @@ export interface AdaptedEvent {
|
|
59
76
|
touchEventType?: TouchEventType;
|
60
77
|
}
|
61
78
|
|
62
|
-
export interface TrackerElement {
|
63
|
-
lastX: number;
|
64
|
-
lastY: number;
|
65
|
-
timeStamp: number;
|
66
|
-
velocityX: number;
|
67
|
-
velocityY: number;
|
68
|
-
}
|