@react-native-oh-tpl/react-native-gesture-handler 2.14.8-rc.1 → 2.14.14
Sign up to get free protection for your applications and to get access to all the features.
- package/DrawerLayout/index.ts +2 -2
- package/Swipeable/index.ts +2 -2
- package/harmony/gesture_handler/BuildProfile.ets +17 -0
- package/harmony/gesture_handler/build-profile.json5 +19 -0
- package/harmony/gesture_handler/hvigorfile.ts +2 -0
- package/harmony/gesture_handler/index.ets +2 -0
- package/harmony/gesture_handler/oh-package-lock.json5 +18 -0
- package/harmony/gesture_handler/oh-package.json5 +12 -0
- package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +8 -0
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +12 -0
- package/harmony/gesture_handler/src/main/cpp/RnohReactNativeHarmonyGestureHandlerPackage.cpp +123 -0
- package/harmony/gesture_handler/src/main/cpp/RnohReactNativeHarmonyGestureHandlerPackage.h +15 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +27 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +245 -0
- package/harmony/gesture_handler/src/main/ets/RNOHPackage.ets +17 -0
- package/harmony/gesture_handler/src/main/ets/core/CircularBuffer.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +739 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +344 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +63 -0
- package/harmony/gesture_handler/src/main/ets/core/IncomingEvent.ts +78 -0
- package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
- package/harmony/gesture_handler/src/main/ets/core/LeastSquareSolver.ts +182 -0
- package/harmony/gesture_handler/src/main/ets/core/Multiset.ts +26 -0
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEvent.ts +34 -0
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/core/PointerTracker.ts +239 -0
- package/harmony/gesture_handler/src/main/ets/core/RNGHError.ts +5 -0
- package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +16 -0
- package/harmony/gesture_handler/src/main/ets/core/State.ts +47 -0
- package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
- package/harmony/gesture_handler/src/main/ets/core/VelocityTracker.ts +106 -0
- package/harmony/gesture_handler/src/main/ets/core/View.ts +21 -0
- package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +7 -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 +219 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +67 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +139 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +50 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +124 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +361 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +174 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +172 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +216 -0
- 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/rnoh/GestureHandlerPackage.ts +25 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +107 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +94 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootViewController.ts +182 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHView.ts +62 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHViewController.ts +262 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHViewRegistry.ts +19 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +267 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +15 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +25 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/types.ts +25 -0
- package/harmony/gesture_handler/src/main/module.json5 +9 -0
- package/harmony/gesture_handler/src/main/resources/base/element/color.json +8 -0
- package/harmony/gesture_handler/src/main/resources/base/element/string.json +16 -0
- package/harmony/gesture_handler/src/main/resources/base/media/icon.png +0 -0
- package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -0
- package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +16 -0
- package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +16 -0
- package/harmony/gesture_handler/ts.ts +2 -0
- package/harmony/gesture_handler.har +0 -0
- package/lib/commonjs/RNGestureHandlerModule.js +3 -2
- package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/components/GestureHandlerRootView.js +3 -3
- package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
- package/lib/commonjs/handlers/createHandler.js +18 -15
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/index.js +36 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +2 -1
- package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +3 -2
- package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +3 -2
- package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.js.map +1 -1
- package/lib/module/components/GestureHandlerRootView.js.map +1 -1
- package/lib/module/handlers/createHandler.js +15 -12
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/index.js +5 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
- package/lib/typescript/RNGestureHandlerModule.d.ts +2 -2
- package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
- package/lib/typescript/handlers/createHandler.d.ts +11 -11
- package/lib/typescript/index.d.ts +47 -42
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +14 -14
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +14 -14
- package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +6 -6
- package/package.json +78 -70
- package/src/RNGestureHandlerModule.ts +4 -4
- package/src/components/GestureHandlerRootView.tsx +23 -23
- package/src/handlers/createHandler.tsx +534 -534
- package/src/index.ts +172 -172
- package/src/specs/NativeRNGestureHandlerModule.ts +26 -26
- package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -18
- package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +6 -6
@@ -0,0 +1,262 @@
|
|
1
|
+
import { Point } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import {
|
3
|
+
GestureHandler,
|
4
|
+
IncomingEvent,
|
5
|
+
EventType,
|
6
|
+
PointerType,
|
7
|
+
TouchEventType,
|
8
|
+
Touch,
|
9
|
+
RNGHLogger,
|
10
|
+
View
|
11
|
+
} from '../core';
|
12
|
+
import { TouchEvent, TouchType, TouchObject } from './types';
|
13
|
+
|
14
|
+
|
15
|
+
export class RNGHViewController {
|
16
|
+
private activePointerIds = new Set<number>();
|
17
|
+
private pointerIdsInBounds = new Set<number>();
|
18
|
+
private gestureHandlers = new Set<GestureHandler>();
|
19
|
+
private view: View;
|
20
|
+
private logger: RNGHLogger;
|
21
|
+
|
22
|
+
constructor(view: View, logger: RNGHLogger) {
|
23
|
+
this.logger = logger.cloneAndJoinPrefix(`RNGHViewTouchHandler`)
|
24
|
+
this.view = view;
|
25
|
+
}
|
26
|
+
|
27
|
+
attachGestureHandler(gestureHandler: GestureHandler) {
|
28
|
+
this.gestureHandlers.add(gestureHandler)
|
29
|
+
}
|
30
|
+
|
31
|
+
handleTouch(e: TouchEvent) {
|
32
|
+
const logger = this.logger.cloneAndJoinPrefix("handleTouch")
|
33
|
+
for (const changedTouch of e.changedTouches) {
|
34
|
+
if (this.shouldSkipTouch(changedTouch)) {
|
35
|
+
continue;
|
36
|
+
}
|
37
|
+
const wasInBounds = this.pointerIdsInBounds.has(changedTouch.id);
|
38
|
+
const isInBounds = this.isInBounds({
|
39
|
+
x: changedTouch.windowX,
|
40
|
+
y: changedTouch.windowY,
|
41
|
+
});
|
42
|
+
logger.debug(
|
43
|
+
{
|
44
|
+
viewTag: this.view.getTag(),
|
45
|
+
type: changedTouch.type,
|
46
|
+
wasInBounds,
|
47
|
+
isInBounds,
|
48
|
+
},
|
49
|
+
);
|
50
|
+
const adaptedEvent = this.adaptTouchEvent(e, changedTouch);
|
51
|
+
this.gestureHandlers.forEach(gh => {
|
52
|
+
switch (adaptedEvent.eventType) {
|
53
|
+
case EventType.DOWN:
|
54
|
+
gh.onPointerDown(adaptedEvent);
|
55
|
+
break;
|
56
|
+
case EventType.ADDITIONAL_POINTER_DOWN:
|
57
|
+
gh.onAdditionalPointerAdd(adaptedEvent);
|
58
|
+
break;
|
59
|
+
case EventType.UP:
|
60
|
+
gh.onPointerUp(adaptedEvent);
|
61
|
+
break;
|
62
|
+
case EventType.ADDITIONAL_POINTER_UP:
|
63
|
+
gh.onAdditionalPointerRemove(adaptedEvent);
|
64
|
+
break;
|
65
|
+
case EventType.MOVE:
|
66
|
+
if (!wasInBounds && !isInBounds) {
|
67
|
+
gh.onPointerOutOfBounds(adaptedEvent);
|
68
|
+
} else {
|
69
|
+
gh.onPointerMove(adaptedEvent);
|
70
|
+
}
|
71
|
+
break;
|
72
|
+
case EventType.ENTER:
|
73
|
+
gh.onPointerEnter(adaptedEvent);
|
74
|
+
break;
|
75
|
+
case EventType.OUT:
|
76
|
+
gh.onPointerOut(adaptedEvent);
|
77
|
+
break;
|
78
|
+
case EventType.CANCEL:
|
79
|
+
gh.onPointerCancel(adaptedEvent);
|
80
|
+
break;
|
81
|
+
}
|
82
|
+
})
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
private shouldSkipTouch(changedTouch: TouchObject): boolean {
|
87
|
+
return (
|
88
|
+
changedTouch.type === TouchType.Down &&
|
89
|
+
!this.isInBounds({
|
90
|
+
x: changedTouch.windowX,
|
91
|
+
y: changedTouch.windowY,
|
92
|
+
})
|
93
|
+
);
|
94
|
+
}
|
95
|
+
|
96
|
+
private adaptTouchEvent(
|
97
|
+
e: TouchEvent,
|
98
|
+
changedTouch: TouchObject,
|
99
|
+
): IncomingEvent {
|
100
|
+
const xAbsolute = changedTouch.windowX;
|
101
|
+
const yAbsolute = changedTouch.windowY;
|
102
|
+
|
103
|
+
const eventType = this.mapTouchTypeToEventType(
|
104
|
+
changedTouch.type,
|
105
|
+
this.isInBounds({ x: xAbsolute, y: yAbsolute }),
|
106
|
+
changedTouch.id,
|
107
|
+
this.pointerIdsInBounds.has(changedTouch.id),
|
108
|
+
);
|
109
|
+
this.logger.cloneAndJoinPrefix("adaptTouchEvent")
|
110
|
+
.debug({ eventType, activePointersCount: this.activePointerIds.size })
|
111
|
+
this.updateIsInBoundsByPointerId(
|
112
|
+
changedTouch.type,
|
113
|
+
changedTouch.id,
|
114
|
+
xAbsolute,
|
115
|
+
yAbsolute,
|
116
|
+
);
|
117
|
+
this.updateActivePointers(changedTouch.type, changedTouch.id);
|
118
|
+
return {
|
119
|
+
x: xAbsolute,
|
120
|
+
y: yAbsolute,
|
121
|
+
offsetX: xAbsolute - this.view.getBoundingRect().x,
|
122
|
+
offsetY: yAbsolute - this.view.getBoundingRect().y,
|
123
|
+
pointerId: changedTouch.id,
|
124
|
+
eventType: eventType,
|
125
|
+
pointerType: PointerType.TOUCH,
|
126
|
+
buttons: 0,
|
127
|
+
time: e.timestamp,
|
128
|
+
allTouches: e.touches.map(touch => this.mapTouchObjectToTouch(touch)),
|
129
|
+
changedTouches: e.changedTouches.map(touch =>
|
130
|
+
this.mapTouchObjectToTouch(touch),
|
131
|
+
),
|
132
|
+
touchEventType: this.mapTouchTypeToTouchEventType(changedTouch.type),
|
133
|
+
};
|
134
|
+
}
|
135
|
+
|
136
|
+
private updateIsInBoundsByPointerId(
|
137
|
+
touchType: TouchType,
|
138
|
+
pointerId: number,
|
139
|
+
x: number,
|
140
|
+
y: number,
|
141
|
+
) {
|
142
|
+
switch (touchType) {
|
143
|
+
case TouchType.Down:
|
144
|
+
if (this.isInBounds({ x, y })) {
|
145
|
+
this.pointerIdsInBounds.add(pointerId);
|
146
|
+
}
|
147
|
+
break;
|
148
|
+
case TouchType.Move:
|
149
|
+
if (this.isInBounds({
|
150
|
+
x,
|
151
|
+
y
|
152
|
+
})) {
|
153
|
+
this.pointerIdsInBounds.add(pointerId);
|
154
|
+
} else {
|
155
|
+
this.pointerIdsInBounds.delete(pointerId);
|
156
|
+
}
|
157
|
+
break;
|
158
|
+
case TouchType.Up:
|
159
|
+
this.pointerIdsInBounds.delete(pointerId);
|
160
|
+
break;
|
161
|
+
case TouchType.Cancel:
|
162
|
+
this.pointerIdsInBounds.delete(pointerId);
|
163
|
+
break;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
private isInBounds(point: Point): boolean {
|
168
|
+
const x = point.x;
|
169
|
+
const y = point.y;
|
170
|
+
const rect = this.view.getBoundingRect();
|
171
|
+
this.logger.cloneAndJoinPrefix("isInBounds").debug({ rect })
|
172
|
+
const result =
|
173
|
+
x >= rect.x &&
|
174
|
+
x <= rect.x + rect.width &&
|
175
|
+
y >= rect.y &&
|
176
|
+
y <= rect.y + rect.height;
|
177
|
+
return result;
|
178
|
+
}
|
179
|
+
|
180
|
+
private updateActivePointers(touchType: TouchType, pointerId: number): void {
|
181
|
+
switch (touchType) {
|
182
|
+
case TouchType.Down:
|
183
|
+
this.activePointerIds.add(pointerId);
|
184
|
+
break;
|
185
|
+
case TouchType.Up:
|
186
|
+
this.activePointerIds.delete(pointerId);
|
187
|
+
break;
|
188
|
+
case TouchType.Cancel:
|
189
|
+
this.activePointerIds.clear();
|
190
|
+
break;
|
191
|
+
default:
|
192
|
+
return;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
private mapTouchObjectToTouch(touchObject: TouchObject): Touch {
|
197
|
+
return {
|
198
|
+
id: touchObject.id,
|
199
|
+
x: touchObject.x,
|
200
|
+
y: touchObject.y,
|
201
|
+
absoluteX: touchObject.windowX,
|
202
|
+
absoluteY: touchObject.windowY,
|
203
|
+
};
|
204
|
+
}
|
205
|
+
|
206
|
+
private mapTouchTypeToEventType(
|
207
|
+
touchType: TouchType,
|
208
|
+
isCurrentlyInBounds: boolean,
|
209
|
+
pointerId: number,
|
210
|
+
wasInBounds: boolean,
|
211
|
+
): EventType {
|
212
|
+
/**
|
213
|
+
* If user manages to drag finger out of GestureHandlerRootView,
|
214
|
+
* we don't receive UP event.
|
215
|
+
*/
|
216
|
+
let activePointersCount = this.activePointerIds.size
|
217
|
+
if (this.activePointerIds.has(pointerId)) {
|
218
|
+
activePointersCount--;
|
219
|
+
}
|
220
|
+
|
221
|
+
switch (touchType) {
|
222
|
+
case TouchType.Down:
|
223
|
+
if (activePointersCount > 0) {
|
224
|
+
return EventType.ADDITIONAL_POINTER_DOWN;
|
225
|
+
} else {
|
226
|
+
return EventType.DOWN;
|
227
|
+
}
|
228
|
+
case TouchType.Up:
|
229
|
+
if (activePointersCount > 1) {
|
230
|
+
return EventType.ADDITIONAL_POINTER_UP;
|
231
|
+
} else {
|
232
|
+
return EventType.UP;
|
233
|
+
}
|
234
|
+
case TouchType.Move:
|
235
|
+
if (isCurrentlyInBounds) {
|
236
|
+
return wasInBounds ? EventType.MOVE : EventType.ENTER;
|
237
|
+
} else {
|
238
|
+
return wasInBounds ? EventType.OUT : EventType.MOVE;
|
239
|
+
}
|
240
|
+
case TouchType.Cancel:
|
241
|
+
return EventType.CANCEL;
|
242
|
+
default:
|
243
|
+
console.error('RNGH', 'Unknown touchType:', touchType);
|
244
|
+
throw new Error('Unknown touchType');
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
private mapTouchTypeToTouchEventType(touchType: TouchType): TouchEventType {
|
249
|
+
switch (touchType) {
|
250
|
+
case TouchType.Down:
|
251
|
+
return TouchEventType.DOWN;
|
252
|
+
case TouchType.Up:
|
253
|
+
return TouchEventType.UP;
|
254
|
+
case TouchType.Move:
|
255
|
+
return TouchEventType.MOVE;
|
256
|
+
case TouchType.Cancel:
|
257
|
+
return TouchEventType.CANCELLED;
|
258
|
+
default:
|
259
|
+
return TouchEventType.UNDETERMINED;
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { Tag, } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import { View, ViewRegistry } from '../core';
|
3
|
+
|
4
|
+
|
5
|
+
export class RNGHViewRegistry implements ViewRegistry {
|
6
|
+
private viewByTag = new Map<Tag, View>()
|
7
|
+
|
8
|
+
save(view: View) {
|
9
|
+
this.viewByTag.set(view.getTag(), view)
|
10
|
+
}
|
11
|
+
|
12
|
+
deleteByTag(viewTag: Tag) {
|
13
|
+
this.viewByTag.delete(viewTag)
|
14
|
+
}
|
15
|
+
|
16
|
+
getViewByTag(viewTag: Tag) {
|
17
|
+
return this.viewByTag.get(viewTag);
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,267 @@
|
|
1
|
+
import { UITurboModule, UITurboModuleContext, Tag } from "@rnoh/react-native-openharmony/ts";
|
2
|
+
import { TM } from "@rnoh/react-native-openharmony/generated/ts"
|
3
|
+
import {
|
4
|
+
GestureHandlerRegistry,
|
5
|
+
State,
|
6
|
+
OutgoingEventDispatcher,
|
7
|
+
RNGHLogger,
|
8
|
+
InteractionManager,
|
9
|
+
ViewRegistry
|
10
|
+
} from '../core';
|
11
|
+
import { GestureHandlerFactory } from "../gesture-handlers"
|
12
|
+
import { RNGHViewRegistry } from './RNGHViewRegistry';
|
13
|
+
import { DevelopmentRNGHLogger, ProductionRNGHLogger } from './Logger';
|
14
|
+
import { JSEventDispatcher, AnimatedEventDispatcher, ReanimatedEventDispatcher } from './OutgoingEventDispatchers'
|
15
|
+
import { RNOHScrollLockerCAPI } from "./RNOHScrollLocker"
|
16
|
+
import { RNGHRootViewController, RawTouchEvent } from "./RNGHRootViewController"
|
17
|
+
import { RNGHView } from "./RNGHView"
|
18
|
+
import { RNOHGestureResponder } from "./RNOHGestureResponder"
|
19
|
+
|
20
|
+
export enum ActionType {
|
21
|
+
REANIMATED_WORKLET = 1,
|
22
|
+
NATIVE_ANIMATED_EVENT = 2,
|
23
|
+
JS_FUNCTION_OLD_API = 3,
|
24
|
+
JS_FUNCTION_NEW_API = 4,
|
25
|
+
}
|
26
|
+
|
27
|
+
|
28
|
+
export class RNGestureHandlerModule extends UITurboModule implements TM.RNGestureHandlerModule.Spec {
|
29
|
+
static readonly NAME = "RNGestureHandlerModule"
|
30
|
+
|
31
|
+
private gestureHandlerRegistry: GestureHandlerRegistry
|
32
|
+
private gestureHandlerFactory: GestureHandlerFactory | undefined = undefined
|
33
|
+
private viewRegistry: ViewRegistry | undefined = undefined
|
34
|
+
private logger: RNGHLogger
|
35
|
+
private cleanLogger: RNGHLogger
|
36
|
+
private rootViewControllerByRootTag = new Map<Tag, RNGHRootViewController>()
|
37
|
+
private interactionManager: InteractionManager
|
38
|
+
|
39
|
+
constructor(ctx: UITurboModuleContext, isDevModeEnabled: boolean = false) {
|
40
|
+
super(ctx)
|
41
|
+
this.cleanLogger =
|
42
|
+
isDevModeEnabled && ctx.isDebugModeEnabled ? new DevelopmentRNGHLogger(ctx.logger, "RNGH") :
|
43
|
+
new ProductionRNGHLogger(ctx.logger, "RNGH")
|
44
|
+
this.logger = this.cleanLogger.cloneAndJoinPrefix("RNGestureHandlerModule")
|
45
|
+
const logger = this.logger.cloneAndJoinPrefix("constructor")
|
46
|
+
const stopTracing = logger.startTracing()
|
47
|
+
this.interactionManager = new InteractionManager(this.cleanLogger)
|
48
|
+
this.gestureHandlerRegistry = new GestureHandlerRegistry(this.viewRegistry, this.cleanLogger)
|
49
|
+
if (this.ctx.rnInstance.getArchitecture() === "C_API") {
|
50
|
+
this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::TOUCH_EVENT", (e: any) => {
|
51
|
+
this.onTouch(e)
|
52
|
+
})
|
53
|
+
this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::ROOT_CREATED", (rootTag: any) => {
|
54
|
+
this.onGHRootCreated(rootTag)
|
55
|
+
})
|
56
|
+
this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::CANCEL_TOUCHES", (rootTag: any) => {
|
57
|
+
const touchHandler = this.rootViewControllerByRootTag.get(rootTag)
|
58
|
+
touchHandler?.cancelTouches()
|
59
|
+
})
|
60
|
+
}
|
61
|
+
stopTracing()
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Called from C++.
|
66
|
+
*/
|
67
|
+
private onGHRootCreated(rootTag: Tag) {
|
68
|
+
const stopTracing = this.logger.cloneAndJoinPrefix("onGHRootCreated").startTracing()
|
69
|
+
this.rootViewControllerByRootTag.set(rootTag, new RNGHRootViewController(this.logger, this.gestureHandlerRegistry));
|
70
|
+
stopTracing()
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Called from C++.
|
75
|
+
*/
|
76
|
+
private onTouch(e: RawTouchEvent & { rootTag: Tag }) {
|
77
|
+
const logger = this.logger.cloneAndJoinPrefix("onTouch")
|
78
|
+
const stopTracing = logger.startTracing();
|
79
|
+
(() => {
|
80
|
+
if (!(this.viewRegistry instanceof RNGHViewRegistry)) {
|
81
|
+
logger.error("Expected ViewRegistryCAPI")
|
82
|
+
return;
|
83
|
+
}
|
84
|
+
const rootViewController = this.rootViewControllerByRootTag.get(e.rootTag)
|
85
|
+
if (!rootViewController) {
|
86
|
+
logger.error(`Couldn't find a rootViewController for a gesture root tag: ${e.rootTag}`)
|
87
|
+
return;
|
88
|
+
}
|
89
|
+
// update view registry
|
90
|
+
e.touchableViews.forEach(touchableView => {
|
91
|
+
const view = this.viewRegistry.getViewByTag(touchableView.tag)
|
92
|
+
if (view) {
|
93
|
+
if (!(view instanceof RNGHView)) {
|
94
|
+
logger.error(`Expected ViewCAPI`)
|
95
|
+
return
|
96
|
+
}
|
97
|
+
view.updateBoundingBox(touchableView)
|
98
|
+
view.setButtonRole(touchableView.buttonRole)
|
99
|
+
} else {
|
100
|
+
this.viewRegistry.save(new RNGHView(touchableView))
|
101
|
+
}
|
102
|
+
})
|
103
|
+
rootViewController.handleTouch(e, e.touchableViews.map(({ tag }) => this.viewRegistry.getViewByTag(tag)));
|
104
|
+
})()
|
105
|
+
stopTracing()
|
106
|
+
}
|
107
|
+
|
108
|
+
// -------------------------------------------------------------------------------------------------------------------
|
109
|
+
|
110
|
+
public install() {
|
111
|
+
const stopTracing = this.ctx.logger.clone("install").startTracing()
|
112
|
+
this.viewRegistry = new RNGHViewRegistry()
|
113
|
+
const scrollLocker = new RNOHScrollLockerCAPI(this.ctx.rnInstance, this.cleanLogger);
|
114
|
+
const rnGestureResponder = new RNOHGestureResponder(this.ctx.rnInstance)
|
115
|
+
this.gestureHandlerFactory =
|
116
|
+
new GestureHandlerFactory(this.cleanLogger, scrollLocker, this.interactionManager, rnGestureResponder)
|
117
|
+
stopTracing()
|
118
|
+
return true
|
119
|
+
}
|
120
|
+
|
121
|
+
public createGestureHandler(
|
122
|
+
handlerName: string,
|
123
|
+
handlerTag: number,
|
124
|
+
config: Readonly<Record<string, unknown>>
|
125
|
+
) {
|
126
|
+
const logger = this.logger.cloneAndJoinPrefix("createGestureHandler")
|
127
|
+
const stopTracing = logger.startTracing();
|
128
|
+
(() => {
|
129
|
+
if (!this.gestureHandlerFactory) {
|
130
|
+
logger.error("Trying to create a gesture handler before creating gesture handler factory")
|
131
|
+
return
|
132
|
+
}
|
133
|
+
logger.debug({ handlerName, handlerTag, config })
|
134
|
+
const gestureHandler = this.gestureHandlerFactory.create(handlerName, handlerTag)
|
135
|
+
this.gestureHandlerRegistry.addGestureHandler(gestureHandler)
|
136
|
+
this.interactionManager.configureInteractions(gestureHandler, config);
|
137
|
+
gestureHandler.updateGestureConfig(config)
|
138
|
+
})()
|
139
|
+
stopTracing()
|
140
|
+
}
|
141
|
+
|
142
|
+
public attachGestureHandler(
|
143
|
+
handlerTag: number,
|
144
|
+
viewTag: number,
|
145
|
+
actionType: ActionType
|
146
|
+
) {
|
147
|
+
const logger = this.logger.cloneAndJoinPrefix("attachGestureHandler")
|
148
|
+
const stopTracing = logger.startTracing();
|
149
|
+
(() => {
|
150
|
+
const eventDispatcher = this.createEventDispatcher(actionType, viewTag)
|
151
|
+
if (!eventDispatcher) {
|
152
|
+
logger.error("RNGH: Couldn't create EventDispatcher")
|
153
|
+
return
|
154
|
+
}
|
155
|
+
const viewRegistry = this.viewRegistry
|
156
|
+
let view = this.viewRegistry.getViewByTag(viewTag)
|
157
|
+
if (!view && viewRegistry instanceof RNGHViewRegistry) {
|
158
|
+
view = new RNGHView({
|
159
|
+
tag: viewTag,
|
160
|
+
x: 0,
|
161
|
+
y: 0,
|
162
|
+
width: 0,
|
163
|
+
height: 0,
|
164
|
+
buttonRole: false
|
165
|
+
})
|
166
|
+
viewRegistry.save(view)
|
167
|
+
}
|
168
|
+
if (!view) {
|
169
|
+
logger.error("Expected view")
|
170
|
+
return;
|
171
|
+
}
|
172
|
+
this.gestureHandlerRegistry.bindGestureHandlerWithView(handlerTag, view)
|
173
|
+
this.gestureHandlerRegistry.getGestureHandlersByViewTag(view.getTag()).forEach((handler) => {
|
174
|
+
if (handler.isGestureContinuous() && eventDispatcher instanceof JSEventDispatcher) {
|
175
|
+
logger.warn(`Using JSEventDispatcher for a continuous gesture (${handler.getName()}). Gesture-driven animations may not be smooth. Consider using Animated.event.`)
|
176
|
+
}
|
177
|
+
})
|
178
|
+
this.gestureHandlerRegistry
|
179
|
+
.getGestureHandlerByHandlerTag(handlerTag)
|
180
|
+
.setEventDispatcher(eventDispatcher)
|
181
|
+
})()
|
182
|
+
stopTracing()
|
183
|
+
}
|
184
|
+
|
185
|
+
private createEventDispatcher(actionType: ActionType, viewTag: number): OutgoingEventDispatcher | null {
|
186
|
+
switch (actionType) {
|
187
|
+
case ActionType.REANIMATED_WORKLET:
|
188
|
+
return new ReanimatedEventDispatcher(this.ctx.rnInstance,
|
189
|
+
this.cleanLogger, viewTag)
|
190
|
+
case ActionType.NATIVE_ANIMATED_EVENT:
|
191
|
+
return new AnimatedEventDispatcher(this.ctx.rnInstance,
|
192
|
+
this.cleanLogger, viewTag)
|
193
|
+
case ActionType.JS_FUNCTION_OLD_API:
|
194
|
+
case ActionType.JS_FUNCTION_NEW_API:
|
195
|
+
return new JSEventDispatcher(this.ctx.rnInstance, this.cleanLogger);
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
public updateGestureHandler(
|
200
|
+
handlerTag: number,
|
201
|
+
newConfig: Readonly<Record<string, unknown>>
|
202
|
+
) {
|
203
|
+
const stopTracing = this.logger.cloneAndJoinPrefix("updateGestureHandler").startTracing()
|
204
|
+
const gestureHandler = this.gestureHandlerRegistry.getGestureHandlerByHandlerTag(handlerTag)
|
205
|
+
this.interactionManager.configureInteractions(gestureHandler, newConfig);
|
206
|
+
gestureHandler.updateGestureConfig(newConfig)
|
207
|
+
stopTracing()
|
208
|
+
}
|
209
|
+
|
210
|
+
public dropGestureHandler(handlerTag: number) {
|
211
|
+
const stopTracing = this.logger.cloneAndJoinPrefix("dropGestureHandler").startTracing()
|
212
|
+
this.interactionManager.dropRelationsForHandlerWithTag(handlerTag)
|
213
|
+
this.gestureHandlerRegistry.removeGestureHandlerByHandlerTag(handlerTag)
|
214
|
+
stopTracing()
|
215
|
+
}
|
216
|
+
|
217
|
+
public handleSetJSResponder(tag: number, blockNativeResponder: boolean) {
|
218
|
+
this.logger.cloneAndJoinPrefix("handleSetJSResponder").warn("not implemented")
|
219
|
+
}
|
220
|
+
|
221
|
+
public handleClearJSResponder() {
|
222
|
+
this.logger.cloneAndJoinPrefix("handleClearJSResponder").warn("not implemented")
|
223
|
+
}
|
224
|
+
|
225
|
+
public flushOperations() {
|
226
|
+
// no-op
|
227
|
+
}
|
228
|
+
|
229
|
+
// -------------------------------------------------------------------------------------------------------------------
|
230
|
+
|
231
|
+
public getGestureHandlerRegistry() {
|
232
|
+
return this.gestureHandlerRegistry
|
233
|
+
}
|
234
|
+
|
235
|
+
public getLogger() {
|
236
|
+
return this.logger
|
237
|
+
}
|
238
|
+
|
239
|
+
public getViewRegistry() {
|
240
|
+
if (!this.viewRegistry) {
|
241
|
+
this.logger.error("Tried to get viewRegistry before it was initialized")
|
242
|
+
throw new Error("Tried to get viewRegistry before it was initialized")
|
243
|
+
}
|
244
|
+
return this.viewRegistry
|
245
|
+
}
|
246
|
+
|
247
|
+
public setGestureHandlerState(handlerTag: number, newState: State) {
|
248
|
+
const handler = this.getGestureHandlerRegistry().getGestureHandlerByHandlerTag(handlerTag);
|
249
|
+
switch (newState) {
|
250
|
+
case State.ACTIVE:
|
251
|
+
handler.activate();
|
252
|
+
break;
|
253
|
+
case State.BEGAN:
|
254
|
+
handler.begin();
|
255
|
+
break;
|
256
|
+
case State.END:
|
257
|
+
handler.end();
|
258
|
+
break;
|
259
|
+
case State.FAILED:
|
260
|
+
handler.fail();
|
261
|
+
break;
|
262
|
+
case State.CANCELLED:
|
263
|
+
handler.cancel();
|
264
|
+
break;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { RNInstance } from "@rnoh/react-native-openharmony/ts"
|
2
|
+
import { RNGestureResponder } from "../core"
|
3
|
+
|
4
|
+
|
5
|
+
export class RNOHGestureResponder implements RNGestureResponder {
|
6
|
+
constructor(private rnInstance: RNInstance) {
|
7
|
+
}
|
8
|
+
|
9
|
+
lock(viewTag: number): () => void {
|
10
|
+
this.rnInstance.postMessageToCpp("RNGH::ROOT_VIEW_IS_HANDLING_TOUCHES", { descendantViewTag: viewTag, isHandlingTouches: true })
|
11
|
+
return () => {
|
12
|
+
this.rnInstance.postMessageToCpp("RNGH::ROOT_VIEW_IS_HANDLING_TOUCHES", { descendantViewTag: viewTag, isHandlingTouches: false })
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { RNInstance } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import { ScrollLocker, RNGHLogger } from '../core';
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
export class RNOHScrollLockerCAPI implements ScrollLocker {
|
7
|
+
private logger: RNGHLogger
|
8
|
+
|
9
|
+
constructor(private rnInstance: RNInstance, logger: RNGHLogger) {
|
10
|
+
this.logger = logger.cloneAndJoinPrefix("RNOHScrollLockerCAPI")
|
11
|
+
}
|
12
|
+
|
13
|
+
lockScrollContainingViewTag(viewTag: number) {
|
14
|
+
this.rnInstance.postMessageToCpp('RNGH::SET_NATIVE_RESPONDERS_BLOCK', {
|
15
|
+
targetTag: viewTag,
|
16
|
+
shouldBlock: true,
|
17
|
+
});
|
18
|
+
return () => {
|
19
|
+
this.rnInstance.postMessageToCpp('RNGH::SET_NATIVE_RESPONDERS_BLOCK', {
|
20
|
+
targetTag: viewTag,
|
21
|
+
shouldBlock: false,
|
22
|
+
});
|
23
|
+
};
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export enum TouchType {
|
2
|
+
Down,
|
3
|
+
Up,
|
4
|
+
Move,
|
5
|
+
Cancel
|
6
|
+
}
|
7
|
+
|
8
|
+
interface BaseEvent {
|
9
|
+
timestamp: number;
|
10
|
+
}
|
11
|
+
|
12
|
+
export interface TouchObject {
|
13
|
+
type: TouchType;
|
14
|
+
id: number;
|
15
|
+
windowX: number;
|
16
|
+
windowY: number;
|
17
|
+
x: number;
|
18
|
+
y: number;
|
19
|
+
}
|
20
|
+
|
21
|
+
export interface TouchEvent extends BaseEvent {
|
22
|
+
type: TouchType;
|
23
|
+
touches: TouchObject[];
|
24
|
+
changedTouches: TouchObject[];
|
25
|
+
}
|
Binary file
|