@react-native-oh-tpl/react-native-gesture-handler 2.14.1-2.14.8 → 2.14.1-2.14.9
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 +3 -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.cpp +149 -0
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +21 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentDescriptor.h +36 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonJSIBinder.h +32 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.cpp +22 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.h +15 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentDescriptor.h +36 -0
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +25 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +27 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +234 -0
- package/harmony/gesture_handler/src/main/ets/core/CircularBuffer.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +684 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +335 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +35 -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/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 +12 -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 +19 -0
- package/harmony/gesture_handler/src/main/ets/core/index.ts +13 -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/gesture-handlers/NativeViewGestureHandler.ts +113 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +342 -0
- 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/gesture-handlers/TapGestureHandler.ts +206 -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/namespace/RNGestureHandlerModule.ts +24 -0
- package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerButton.ts +139 -0
- package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerRootView.ts +101 -0
- package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +22 -0
- 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 +104 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerButton.ets +38 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +230 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerRootView.ets +53 -0
- 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 +119 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -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 +8 -5
- 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 +1 -3
- 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 +43 -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 +68 -69
- 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,101 @@
|
|
1
|
+
// This file was generated.
|
2
|
+
import {
|
3
|
+
Descriptor as ComponentDescriptor,
|
4
|
+
ViewBaseProps,
|
5
|
+
ViewRawProps,
|
6
|
+
ViewDescriptorWrapperBase,
|
7
|
+
ColorValue,
|
8
|
+
Color,
|
9
|
+
RNInstance,
|
10
|
+
Tag,
|
11
|
+
RNComponentCommandReceiver,
|
12
|
+
ViewPropsSelector,
|
13
|
+
} from '@rnoh/react-native-openharmony/ts';
|
14
|
+
|
15
|
+
|
16
|
+
export namespace RNGestureHandlerRootView {
|
17
|
+
export const NAME = "RNGestureHandlerRootView" as const
|
18
|
+
|
19
|
+
export interface DirectRawProps {
|
20
|
+
}
|
21
|
+
|
22
|
+
export interface Props extends ViewBaseProps {}
|
23
|
+
|
24
|
+
export interface State {}
|
25
|
+
|
26
|
+
export interface RawProps extends ViewRawProps, DirectRawProps {}
|
27
|
+
|
28
|
+
export class PropsSelector extends ViewPropsSelector<Props, RawProps> {
|
29
|
+
|
30
|
+
}
|
31
|
+
|
32
|
+
export type Descriptor = ComponentDescriptor<
|
33
|
+
typeof NAME,
|
34
|
+
Props,
|
35
|
+
State,
|
36
|
+
RawProps
|
37
|
+
>;
|
38
|
+
|
39
|
+
export class DescriptorWrapper extends ViewDescriptorWrapperBase<
|
40
|
+
typeof NAME,
|
41
|
+
Props,
|
42
|
+
State,
|
43
|
+
RawProps,
|
44
|
+
PropsSelector
|
45
|
+
> {
|
46
|
+
protected createPropsSelector() {
|
47
|
+
return new PropsSelector(this.descriptor.props, this.descriptor.rawProps)
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
export interface EventPayloadByName {
|
52
|
+
}
|
53
|
+
|
54
|
+
export class EventEmitter {
|
55
|
+
constructor(private rnInstance: RNInstance, private tag: Tag) {}
|
56
|
+
|
57
|
+
emit<TEventName extends keyof EventPayloadByName>(eventName: TEventName, payload: EventPayloadByName[TEventName]) {
|
58
|
+
this.rnInstance.emitComponentEvent(this.tag, eventName, payload)
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
export interface CommandArgvByName {
|
63
|
+
}
|
64
|
+
|
65
|
+
export class CommandReceiver {
|
66
|
+
private listenersByCommandName = new Map<string, Set<(...args: any[]) => void>>()
|
67
|
+
private cleanUp: (() => void) | undefined = undefined
|
68
|
+
|
69
|
+
constructor(private componentCommandReceiver: RNComponentCommandReceiver, private tag: Tag) {
|
70
|
+
}
|
71
|
+
|
72
|
+
subscribe<TCommandName extends keyof CommandArgvByName>(commandName: TCommandName, listener: (argv: CommandArgvByName[TCommandName]) => void) {
|
73
|
+
if (!this.listenersByCommandName.has(commandName)) {
|
74
|
+
this.listenersByCommandName.set(commandName, new Set())
|
75
|
+
}
|
76
|
+
this.listenersByCommandName.get(commandName)!.add(listener)
|
77
|
+
const hasRegisteredCommandReceiver = !!this.cleanUp
|
78
|
+
if (!hasRegisteredCommandReceiver) {
|
79
|
+
this.cleanUp = this.componentCommandReceiver.registerCommandCallback(this.tag, (commandName: string, argv: any[]) => {
|
80
|
+
if (this.listenersByCommandName.has(commandName)) {
|
81
|
+
const listeners = this.listenersByCommandName.get(commandName)!
|
82
|
+
listeners.forEach(listener => {
|
83
|
+
listener(argv)
|
84
|
+
})
|
85
|
+
}
|
86
|
+
})
|
87
|
+
}
|
88
|
+
|
89
|
+
return () => {
|
90
|
+
this.listenersByCommandName.get(commandName)?.delete(listener)
|
91
|
+
if (this.listenersByCommandName.get(commandName)?.size ?? 0 === 0) {
|
92
|
+
this.listenersByCommandName.delete(commandName)
|
93
|
+
}
|
94
|
+
if (this.listenersByCommandName.size === 0) {
|
95
|
+
this.cleanUp?.()
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
}
|
@@ -0,0 +1,240 @@
|
|
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
|
+
export class GestureHandlerArkUIAdapter {
|
15
|
+
private activePointerIds = new Set<number>();
|
16
|
+
private pointersIdInBounds = new Set<number>();
|
17
|
+
private gestureHandlers = new Set<GestureHandler>();
|
18
|
+
private view: View;
|
19
|
+
private logger: RNGHLogger;
|
20
|
+
|
21
|
+
constructor(view: View, logger: RNGHLogger) {
|
22
|
+
this.logger = logger.cloneWithPrefix(`ArkUIAdapter(viewTag: ${view.getTag()})`)
|
23
|
+
this.view = view;
|
24
|
+
}
|
25
|
+
|
26
|
+
attachGestureHandler(gestureHandler: GestureHandler) {
|
27
|
+
this.gestureHandlers.add(gestureHandler)
|
28
|
+
}
|
29
|
+
|
30
|
+
handleTouch(e: TouchEvent) {
|
31
|
+
for (const changedTouch of e.changedTouches) {
|
32
|
+
if (this.shouldSkipTouch(changedTouch)) continue;
|
33
|
+
const wasInBounds = this.pointersIdInBounds.has(changedTouch.id);
|
34
|
+
const isInBounds = this.isInBounds({
|
35
|
+
x: changedTouch.windowX,
|
36
|
+
y: changedTouch.windowY,
|
37
|
+
});
|
38
|
+
this.logger.info(
|
39
|
+
`handleTouch: ${JSON.stringify({
|
40
|
+
type: changedTouch.type,
|
41
|
+
wasInBounds,
|
42
|
+
isInBounds,
|
43
|
+
})}`,
|
44
|
+
);
|
45
|
+
const adaptedEvent = this.adaptTouchEvent(e, changedTouch);
|
46
|
+
this.gestureHandlers.forEach(gh => {
|
47
|
+
switch (adaptedEvent.eventType) {
|
48
|
+
case EventType.DOWN:
|
49
|
+
gh.onPointerDown(adaptedEvent);
|
50
|
+
break;
|
51
|
+
case EventType.ADDITIONAL_POINTER_DOWN:
|
52
|
+
gh.onAdditionalPointerAdd(adaptedEvent);
|
53
|
+
break;
|
54
|
+
case EventType.UP:
|
55
|
+
gh.onPointerUp(adaptedEvent);
|
56
|
+
break;
|
57
|
+
case EventType.ADDITIONAL_POINTER_UP:
|
58
|
+
gh.onAdditionalPointerRemove(adaptedEvent);
|
59
|
+
break;
|
60
|
+
case EventType.MOVE:
|
61
|
+
if (!wasInBounds && !isInBounds)
|
62
|
+
gh.onPointerOutOfBounds(adaptedEvent);
|
63
|
+
else gh.onPointerMove(adaptedEvent);
|
64
|
+
break;
|
65
|
+
case EventType.ENTER:
|
66
|
+
gh.onPointerEnter(adaptedEvent);
|
67
|
+
break;
|
68
|
+
case EventType.OUT:
|
69
|
+
gh.onPointerOut(adaptedEvent);
|
70
|
+
break;
|
71
|
+
case EventType.CANCEL:
|
72
|
+
gh.onPointerCancel(adaptedEvent);
|
73
|
+
break;
|
74
|
+
}
|
75
|
+
})
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
private shouldSkipTouch(changedTouch: TouchObject): boolean {
|
80
|
+
return (
|
81
|
+
changedTouch.type === TouchType.Down &&
|
82
|
+
!this.isInBounds({
|
83
|
+
x: changedTouch.windowX,
|
84
|
+
y: changedTouch.windowY,
|
85
|
+
})
|
86
|
+
);
|
87
|
+
}
|
88
|
+
|
89
|
+
private adaptTouchEvent(
|
90
|
+
e: TouchEvent,
|
91
|
+
changedTouch: TouchObject,
|
92
|
+
): IncomingEvent {
|
93
|
+
const xAbsolute = changedTouch.windowX;
|
94
|
+
const yAbsolute = changedTouch.windowY;
|
95
|
+
|
96
|
+
const eventType = this.mapTouchTypeToEventType(
|
97
|
+
changedTouch.type,
|
98
|
+
this.isInBounds({ x: xAbsolute, y: yAbsolute }),
|
99
|
+
changedTouch.id,
|
100
|
+
this.pointersIdInBounds.has(changedTouch.id),
|
101
|
+
);
|
102
|
+
this.logger.cloneWithPrefix("adaptTouchEvent").debug({ eventType, activePointersCount: this.activePointerIds.size })
|
103
|
+
this.updateIsInBoundsByPointerId(
|
104
|
+
changedTouch.type,
|
105
|
+
changedTouch.id,
|
106
|
+
xAbsolute,
|
107
|
+
yAbsolute,
|
108
|
+
);
|
109
|
+
this.updateActivePointers(changedTouch.type, changedTouch.id);
|
110
|
+
return {
|
111
|
+
x: xAbsolute,
|
112
|
+
y: yAbsolute,
|
113
|
+
offsetX: xAbsolute - this.view.getBoundingRect().x,
|
114
|
+
offsetY: yAbsolute - this.view.getBoundingRect().y,
|
115
|
+
pointerId: changedTouch.id,
|
116
|
+
eventType: eventType,
|
117
|
+
pointerType: PointerType.TOUCH,
|
118
|
+
buttons: 0,
|
119
|
+
time: e.timestamp,
|
120
|
+
allTouches: e.touches.map(touch => this.mapTouchObjectToTouch(touch)),
|
121
|
+
changedTouches: e.changedTouches.map(touch =>
|
122
|
+
this.mapTouchObjectToTouch(touch),
|
123
|
+
),
|
124
|
+
touchEventType: this.mapTouchTypeToTouchEventType(changedTouch.type),
|
125
|
+
};
|
126
|
+
}
|
127
|
+
|
128
|
+
private updateIsInBoundsByPointerId(
|
129
|
+
touchType: TouchType,
|
130
|
+
pointerId: number,
|
131
|
+
x: number,
|
132
|
+
y: number,
|
133
|
+
) {
|
134
|
+
switch (touchType) {
|
135
|
+
case TouchType.Down:
|
136
|
+
if (this.isInBounds({ x, y })) this.pointersIdInBounds.add(pointerId);
|
137
|
+
break;
|
138
|
+
case TouchType.Move:
|
139
|
+
if (this.isInBounds({ x, y })) this.pointersIdInBounds.add(pointerId);
|
140
|
+
else this.pointersIdInBounds.delete(pointerId);
|
141
|
+
break;
|
142
|
+
case TouchType.Up:
|
143
|
+
this.pointersIdInBounds.delete(pointerId);
|
144
|
+
break;
|
145
|
+
case TouchType.Cancel:
|
146
|
+
this.pointersIdInBounds.delete(pointerId);
|
147
|
+
break;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
private isInBounds(point: Point): boolean {
|
152
|
+
const x = point.x;
|
153
|
+
const y = point.y;
|
154
|
+
const rect = this.view.getBoundingRect();
|
155
|
+
this.logger.cloneWithPrefix("isInBounds").debug({ rect })
|
156
|
+
const result =
|
157
|
+
x >= rect.x &&
|
158
|
+
x <= rect.x + rect.width &&
|
159
|
+
y >= rect.y &&
|
160
|
+
y <= rect.y + rect.height;
|
161
|
+
return result;
|
162
|
+
}
|
163
|
+
|
164
|
+
private updateActivePointers(touchType: TouchType, pointerId: number): void {
|
165
|
+
switch (touchType) {
|
166
|
+
case TouchType.Down:
|
167
|
+
this.activePointerIds.add(pointerId);
|
168
|
+
break;
|
169
|
+
case TouchType.Up:
|
170
|
+
this.activePointerIds.delete(pointerId);
|
171
|
+
break;
|
172
|
+
case TouchType.Cancel:
|
173
|
+
this.activePointerIds.clear();
|
174
|
+
break;
|
175
|
+
default:
|
176
|
+
return;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
private mapTouchObjectToTouch(touchObject: TouchObject): Touch {
|
181
|
+
return {
|
182
|
+
id: touchObject.id,
|
183
|
+
x: touchObject.x,
|
184
|
+
y: touchObject.y,
|
185
|
+
absoluteX: touchObject.windowX,
|
186
|
+
absoluteY: touchObject.windowY,
|
187
|
+
};
|
188
|
+
}
|
189
|
+
|
190
|
+
private mapTouchTypeToEventType(
|
191
|
+
touchType: TouchType,
|
192
|
+
isCurrentlyInBounds: boolean,
|
193
|
+
pointerId: number,
|
194
|
+
wasInBounds: boolean,
|
195
|
+
): EventType {
|
196
|
+
/**
|
197
|
+
* If user manages to drag finger out of GestureHandlerRootView,
|
198
|
+
* we don't receive UP event.
|
199
|
+
*/
|
200
|
+
let activePointersCount = this.activePointerIds.size
|
201
|
+
if (this.activePointerIds.has(pointerId)) {
|
202
|
+
activePointersCount--;
|
203
|
+
}
|
204
|
+
|
205
|
+
switch (touchType) {
|
206
|
+
case TouchType.Down:
|
207
|
+
if (activePointersCount > 0) return EventType.ADDITIONAL_POINTER_DOWN;
|
208
|
+
else return EventType.DOWN;
|
209
|
+
case TouchType.Up:
|
210
|
+
if (activePointersCount > 1) return EventType.ADDITIONAL_POINTER_UP;
|
211
|
+
else return EventType.UP;
|
212
|
+
case TouchType.Move:
|
213
|
+
if (isCurrentlyInBounds) {
|
214
|
+
return wasInBounds ? EventType.MOVE : EventType.ENTER;
|
215
|
+
} else {
|
216
|
+
return wasInBounds ? EventType.OUT : EventType.MOVE;
|
217
|
+
}
|
218
|
+
case TouchType.Cancel:
|
219
|
+
return EventType.CANCEL;
|
220
|
+
default:
|
221
|
+
console.error('RNGH', 'Unknown touchType:', touchType);
|
222
|
+
throw new Error('Unknown touchType');
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
private mapTouchTypeToTouchEventType(touchType: TouchType): TouchEventType {
|
227
|
+
switch (touchType) {
|
228
|
+
case TouchType.Down:
|
229
|
+
return TouchEventType.DOWN;
|
230
|
+
case TouchType.Up:
|
231
|
+
return TouchEventType.UP;
|
232
|
+
case TouchType.Move:
|
233
|
+
return TouchEventType.MOVE;
|
234
|
+
case TouchType.Cancel:
|
235
|
+
return TouchEventType.CANCELLED;
|
236
|
+
default:
|
237
|
+
return TouchEventType.UNDETERMINED;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import {RNPackage, TurboModulesFactory} from "@rnoh/react-native-openharmony/ts";
|
2
|
+
import type {TurboModule, TurboModuleContext} from "@rnoh/react-native-openharmony/ts";
|
3
|
+
import {RNGestureHandlerModule} from './RNGestureHandlerModule';
|
4
|
+
|
5
|
+
class GestureHandlerTurboModulesFactory extends TurboModulesFactory {
|
6
|
+
createTurboModule(name: string): TurboModule | null {
|
7
|
+
if (name === RNGestureHandlerModule.NAME) {
|
8
|
+
return new RNGestureHandlerModule(this.ctx);
|
9
|
+
}
|
10
|
+
return null;
|
11
|
+
}
|
12
|
+
|
13
|
+
hasTurboModule(name: string): boolean {
|
14
|
+
return name === RNGestureHandlerModule.NAME;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
export class GestureHandlerPackage extends RNPackage {
|
19
|
+
createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory {
|
20
|
+
return new GestureHandlerTurboModulesFactory(ctx);
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { RNOHContext } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import { RNGHLogger, RNGHLoggerMessage } from "../core"
|
3
|
+
|
4
|
+
export class StandardRNGHLogger implements RNGHLogger {
|
5
|
+
constructor(
|
6
|
+
private rnohLogger: RNOHContext['logger'],
|
7
|
+
private prefix: string,
|
8
|
+
) {
|
9
|
+
}
|
10
|
+
|
11
|
+
error(msg: string) {
|
12
|
+
this.rnohLogger.error(`${this.prefix}::${msg}`);
|
13
|
+
}
|
14
|
+
|
15
|
+
info(msg: string) {
|
16
|
+
this.rnohLogger.info(`${this.prefix}::${msg}`);
|
17
|
+
}
|
18
|
+
|
19
|
+
debug(msg: RNGHLoggerMessage) {
|
20
|
+
this.rnohLogger.debug(`${this.prefix}::${this.stringifyMsg(msg)}`);
|
21
|
+
}
|
22
|
+
|
23
|
+
private stringifyMsg(msg: RNGHLoggerMessage): string {
|
24
|
+
if (typeof msg === "string") {
|
25
|
+
return msg
|
26
|
+
} else {
|
27
|
+
return JSON.stringify(msg)
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
cloneWithPrefix(prefix: string) {
|
32
|
+
return new StandardRNGHLogger(this.rnohLogger, `${this.prefix}::${prefix}`);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
export class FakeRNGHLogger implements RNGHLogger {
|
37
|
+
info(msg: string) {
|
38
|
+
}
|
39
|
+
|
40
|
+
debug(msg: string) {
|
41
|
+
}
|
42
|
+
|
43
|
+
error(msg: string): void {
|
44
|
+
}
|
45
|
+
|
46
|
+
cloneWithPrefix(prefix: string) {
|
47
|
+
return new FakeRNGHLogger();
|
48
|
+
}
|
49
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import { RNInstance } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import { OutgoingEventDispatcher, GestureStateChangeEvent, GestureUpdateEvent, GestureTouchEvent, RNGHLogger } from "../core"
|
3
|
+
|
4
|
+
export class JSEventDispatcher implements OutgoingEventDispatcher {
|
5
|
+
constructor(private rnInstance: RNInstance, private logger: RNGHLogger) {
|
6
|
+
}
|
7
|
+
|
8
|
+
public onGestureHandlerStateChange(event: GestureStateChangeEvent) {
|
9
|
+
this.logger.info(`onGestureHandlerStateChange`);
|
10
|
+
this.rnInstance.emitDeviceEvent('onGestureHandlerStateChange', event);
|
11
|
+
}
|
12
|
+
|
13
|
+
public onGestureHandlerEvent(
|
14
|
+
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
15
|
+
) {
|
16
|
+
this.logger.info(`onGestureHandlerEvent`);
|
17
|
+
this.rnInstance.emitDeviceEvent('onGestureHandlerEvent', event);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
export class AnimatedEventDispatcher implements OutgoingEventDispatcher {
|
22
|
+
constructor(
|
23
|
+
private rnInstance: RNInstance,
|
24
|
+
private logger: RNGHLogger,
|
25
|
+
private viewTag: number,
|
26
|
+
) {}
|
27
|
+
|
28
|
+
public onGestureHandlerStateChange(event: GestureStateChangeEvent) {
|
29
|
+
this.logger.info(`onGestureHandlerStateChange`);
|
30
|
+
this.rnInstance.emitDeviceEvent('onGestureHandlerStateChange', event);
|
31
|
+
}
|
32
|
+
|
33
|
+
public onGestureHandlerEvent(
|
34
|
+
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
35
|
+
) {
|
36
|
+
this.logger.info(`onGestureHandlerEvent`);
|
37
|
+
this.rnInstance.emitComponentEvent(
|
38
|
+
this.viewTag,
|
39
|
+
'onGestureHandlerEvent',
|
40
|
+
event,
|
41
|
+
);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
export class ReanimatedEventDispatcher implements OutgoingEventDispatcher {
|
46
|
+
constructor(
|
47
|
+
private rnInstance: RNInstance,
|
48
|
+
private logger: RNGHLogger,
|
49
|
+
private viewTag: number,
|
50
|
+
) {}
|
51
|
+
|
52
|
+
public onGestureHandlerStateChange(event: GestureStateChangeEvent) {
|
53
|
+
this.logger.info(`onGestureHandlerStateChange`);
|
54
|
+
this.rnInstance.emitComponentEvent(
|
55
|
+
this.viewTag,
|
56
|
+
'onGestureHandlerStateChange',
|
57
|
+
event,
|
58
|
+
);
|
59
|
+
}
|
60
|
+
|
61
|
+
public onGestureHandlerEvent(
|
62
|
+
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
63
|
+
) {
|
64
|
+
this.logger.info(`onGestureHandlerEvent`);
|
65
|
+
this.rnInstance.emitComponentEvent(
|
66
|
+
this.viewTag,
|
67
|
+
'onGestureHandlerEvent',
|
68
|
+
event,
|
69
|
+
);
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,104 @@
|
|
1
|
+
import { Tag } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import { GestureHandlerArkUIAdapter } from './GestureHandlerArkUIAdapter';
|
3
|
+
import { RNGHLogger, GestureHandlerRegistry, View } from '../core';
|
4
|
+
import { TouchEvent, TouchType } from './types';
|
5
|
+
|
6
|
+
export interface ViewFinder {
|
7
|
+
getTouchableViewsAt(
|
8
|
+
pointRelativeToRoot: {
|
9
|
+
x: number,
|
10
|
+
y: number
|
11
|
+
},
|
12
|
+
rootTag: Tag
|
13
|
+
): View[]
|
14
|
+
}
|
15
|
+
|
16
|
+
export class RNGHRootTouchHandlerArkTS {
|
17
|
+
private adapterByViewTag: Map<number, GestureHandlerArkUIAdapter> = new Map(); // TODO: remove adapter when view is removed
|
18
|
+
/**
|
19
|
+
* A view is ACTIVE in a window defined by two POINTER_DOWN events
|
20
|
+
*/
|
21
|
+
private activeViewTags = new Set<number>();
|
22
|
+
private viewFinder: ViewFinder;
|
23
|
+
private gestureHandlerRegistry: GestureHandlerRegistry;
|
24
|
+
private logger: RNGHLogger;
|
25
|
+
private rootTag: Tag;
|
26
|
+
|
27
|
+
constructor(
|
28
|
+
rootTag: Tag,
|
29
|
+
viewFinder: ViewFinder,
|
30
|
+
gestureHandlerRegistry: GestureHandlerRegistry,
|
31
|
+
logger: RNGHLogger,
|
32
|
+
) {
|
33
|
+
this.rootTag = rootTag;
|
34
|
+
this.viewFinder = viewFinder;
|
35
|
+
this.gestureHandlerRegistry = gestureHandlerRegistry;
|
36
|
+
this.logger = logger;
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
*
|
41
|
+
* @param touchEvent - TouchEvent. The type is any to allow providing the type in ets file (any and unknowns aren't allowed in ets files).
|
42
|
+
* @param touchableViews - Optional. List of views that can have gesture handler attached for given touch. If not provided, viewFinder will be used.
|
43
|
+
*/
|
44
|
+
public handleTouch(touchEvent: any, touchableViews: View[] | null = null) {
|
45
|
+
const e = touchEvent as TouchEvent;
|
46
|
+
if (e.type === TouchType.Down) {
|
47
|
+
this.activeViewTags.clear();
|
48
|
+
}
|
49
|
+
for (const changedTouch of e.changedTouches) {
|
50
|
+
const views = touchableViews ?? this.viewFinder.getTouchableViewsAt(
|
51
|
+
{
|
52
|
+
x: changedTouch.windowX,
|
53
|
+
y: changedTouch.windowY,
|
54
|
+
},
|
55
|
+
this.rootTag,
|
56
|
+
);
|
57
|
+
for (const view of views) {
|
58
|
+
for (const handler of this.gestureHandlerRegistry.getGestureHandlersByViewTag(
|
59
|
+
view.getTag(),
|
60
|
+
)) {
|
61
|
+
this.logger.info(
|
62
|
+
`Found GestureHandler ${handler.getTag()} for view ${view.getTag()}`,
|
63
|
+
);
|
64
|
+
|
65
|
+
// create adapter if necessary
|
66
|
+
if (!this.adapterByViewTag.has(view.getTag())) {
|
67
|
+
this.adapterByViewTag.set(
|
68
|
+
view.getTag(),
|
69
|
+
new GestureHandlerArkUIAdapter(
|
70
|
+
view,
|
71
|
+
this.logger,
|
72
|
+
),
|
73
|
+
);
|
74
|
+
}
|
75
|
+
|
76
|
+
// attach handler (there might be multiple handlers per view)
|
77
|
+
this.adapterByViewTag.get(view.getTag())!.attachGestureHandler(handler) // TODO: detachGestureHandler
|
78
|
+
|
79
|
+
// register active view tags
|
80
|
+
if (e.type === TouchType.Down) {
|
81
|
+
this.activeViewTags.add(view.getTag());
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
// send touch to gesture handlers
|
87
|
+
for (const viewTag of this.activeViewTags) {
|
88
|
+
const adapter = this.adapterByViewTag.get(viewTag);
|
89
|
+
if (adapter) {
|
90
|
+
adapter.handleTouch(e);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
public cancelTouches() {
|
97
|
+
for (const activeViewTag of this.activeViewTags) {
|
98
|
+
this.gestureHandlerRegistry.getGestureHandlersByViewTag(activeViewTag).forEach(gh => {
|
99
|
+
gh.cancel()
|
100
|
+
gh.reset()
|
101
|
+
})
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import { RNGHRootTouchHandlerArkTS } from './RNGHRootTouchHandlerArkTS';
|
2
|
+
import { TouchEvent as TouchEventArkTS, TouchType, TouchObject } from './types';
|
3
|
+
import { RNGHLogger, View } from '../core';
|
4
|
+
import { RawTouchableView } from "./View"
|
5
|
+
|
6
|
+
type RawTouchPoint = {
|
7
|
+
pointerId: number;
|
8
|
+
windowX: number;
|
9
|
+
windowY: number;
|
10
|
+
};
|
11
|
+
|
12
|
+
export type RawTouchEvent = {
|
13
|
+
action: number;
|
14
|
+
actionTouch: RawTouchPoint;
|
15
|
+
touchPoints: RawTouchPoint[];
|
16
|
+
sourceType: number;
|
17
|
+
timestamp: number;
|
18
|
+
/** TouchableViews is a list of views from root to leaf which contain the touch point specified by `actionTouch` in their boundary boxes. */
|
19
|
+
touchableViews: RawTouchableView[]
|
20
|
+
};
|
21
|
+
|
22
|
+
const CACHED_TOUCHES_MAP = new Map<number, RawTouchPoint>();
|
23
|
+
let lastChangedPointerId: number | null = null;
|
24
|
+
const MAX_SIZE = 10;
|
25
|
+
const areRawTouchPointsEqual = (a: RawTouchPoint, b: RawTouchPoint) =>
|
26
|
+
a.pointerId === b.pointerId &&
|
27
|
+
a.windowX === b.windowX &&
|
28
|
+
a.windowY === b.windowY;
|
29
|
+
|
30
|
+
|
31
|
+
export class RNGHRootTouchHandlerCAPI {
|
32
|
+
private logger: RNGHLogger;
|
33
|
+
|
34
|
+
constructor(
|
35
|
+
logger: RNGHLogger,
|
36
|
+
private touchHandlerArkTS: RNGHRootTouchHandlerArkTS,
|
37
|
+
) {
|
38
|
+
this.logger = logger.cloneWithPrefix('RNGHRootTouchHandlerCAPI');
|
39
|
+
}
|
40
|
+
|
41
|
+
handleTouch(rawTouchEvent: RawTouchEvent, touchableViews: View[]) {
|
42
|
+
this.touchHandlerArkTS.handleTouch(
|
43
|
+
touchEventArkTSFromRawTouchEvent(rawTouchEvent), touchableViews
|
44
|
+
);
|
45
|
+
}
|
46
|
+
|
47
|
+
cancelTouches() {
|
48
|
+
this.touchHandlerArkTS.cancelTouches()
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
function touchEventArkTSFromRawTouchEvent(raw: RawTouchEvent): TouchEventArkTS {
|
53
|
+
const touchType = touchTypeFromAction(raw.action);
|
54
|
+
const actionTouch = raw.actionTouch;
|
55
|
+
let hasTouchChanged = true;
|
56
|
+
let lastChangedTouch: RawTouchPoint = actionTouch;
|
57
|
+
if (CACHED_TOUCHES_MAP.has(actionTouch.pointerId)) {
|
58
|
+
if (areRawTouchPointsEqual(actionTouch, CACHED_TOUCHES_MAP.get(actionTouch.pointerId) as RawTouchPoint)) {
|
59
|
+
hasTouchChanged = false;
|
60
|
+
} else {
|
61
|
+
lastChangedPointerId = actionTouch.pointerId;
|
62
|
+
CACHED_TOUCHES_MAP.set(actionTouch.pointerId, actionTouch);
|
63
|
+
}
|
64
|
+
} else {
|
65
|
+
// remove first element if the cache is full
|
66
|
+
if (CACHED_TOUCHES_MAP.size >= MAX_SIZE) {
|
67
|
+
CACHED_TOUCHES_MAP.delete(CACHED_TOUCHES_MAP.keys().next().value);
|
68
|
+
}
|
69
|
+
lastChangedPointerId = actionTouch.pointerId;
|
70
|
+
CACHED_TOUCHES_MAP.set(actionTouch.pointerId, actionTouch);
|
71
|
+
}
|
72
|
+
lastChangedTouch = CACHED_TOUCHES_MAP.get(lastChangedPointerId as number) as RawTouchPoint
|
73
|
+
return {
|
74
|
+
type: touchTypeFromAction(raw.action),
|
75
|
+
touches: raw.touchPoints.map(tp =>
|
76
|
+
touchObjectFromTouchPoint(tp, touchType),
|
77
|
+
),
|
78
|
+
changedTouches: [
|
79
|
+
touchObjectFromTouchPoint(lastChangedTouch, touchType),
|
80
|
+
],
|
81
|
+
timestamp: raw.timestamp / Math.pow(10, 6),
|
82
|
+
};
|
83
|
+
}
|
84
|
+
|
85
|
+
function touchTypeFromAction(action: number): TouchType {
|
86
|
+
switch (action) {
|
87
|
+
case 1:
|
88
|
+
return TouchType.Down;
|
89
|
+
case 2:
|
90
|
+
return TouchType.Move;
|
91
|
+
case 3:
|
92
|
+
return TouchType.Up;
|
93
|
+
default:
|
94
|
+
return TouchType.Cancel;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
function touchObjectFromTouchPoint(
|
99
|
+
touchPoint: RawTouchPoint,
|
100
|
+
touchType: TouchType,
|
101
|
+
): TouchObject {
|
102
|
+
return {
|
103
|
+
id: touchPoint.pointerId,
|
104
|
+
windowX: touchPoint.windowX,
|
105
|
+
windowY: touchPoint.windowY,
|
106
|
+
x: touchPoint.windowX,
|
107
|
+
y: touchPoint.windowY,
|
108
|
+
type: touchType,
|
109
|
+
};
|
110
|
+
}
|