@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.
Files changed (115) hide show
  1. package/DrawerLayout/index.ts +2 -2
  2. package/Swipeable/index.ts +2 -2
  3. package/harmony/gesture_handler/BuildProfile.ets +17 -0
  4. package/harmony/gesture_handler/build-profile.json5 +19 -0
  5. package/harmony/gesture_handler/hvigorfile.ts +2 -0
  6. package/harmony/gesture_handler/index.ets +3 -0
  7. package/harmony/gesture_handler/oh-package-lock.json5 +18 -0
  8. package/harmony/gesture_handler/oh-package.json5 +12 -0
  9. package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +8 -0
  10. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +149 -0
  11. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +21 -0
  12. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonComponentDescriptor.h +36 -0
  13. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerButtonJSIBinder.h +32 -0
  14. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.cpp +22 -0
  15. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerModule.h +15 -0
  16. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentDescriptor.h +36 -0
  17. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +25 -0
  18. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +27 -0
  19. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +234 -0
  20. package/harmony/gesture_handler/src/main/ets/core/CircularBuffer.ts +42 -0
  21. package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +684 -0
  22. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +335 -0
  23. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +35 -0
  24. package/harmony/gesture_handler/src/main/ets/core/IncomingEvent.ts +78 -0
  25. package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
  26. package/harmony/gesture_handler/src/main/ets/core/LeastSquareSolver.ts +182 -0
  27. package/harmony/gesture_handler/src/main/ets/core/OutgoingEvent.ts +34 -0
  28. package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
  29. package/harmony/gesture_handler/src/main/ets/core/PointerTracker.ts +239 -0
  30. package/harmony/gesture_handler/src/main/ets/core/RNGHError.ts +5 -0
  31. package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
  32. package/harmony/gesture_handler/src/main/ets/core/State.ts +47 -0
  33. package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
  34. package/harmony/gesture_handler/src/main/ets/core/VelocityTracker.ts +106 -0
  35. package/harmony/gesture_handler/src/main/ets/core/View.ts +19 -0
  36. package/harmony/gesture_handler/src/main/ets/core/index.ts +13 -0
  37. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  38. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  39. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  40. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  41. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  42. package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +113 -0
  43. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +342 -0
  44. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  45. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  46. package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +206 -0
  47. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  48. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  49. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +24 -0
  50. package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerButton.ts +139 -0
  51. package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerRootView.ts +101 -0
  52. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  53. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -0
  54. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +22 -0
  56. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  57. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  58. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +104 -0
  59. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  60. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerButton.ets +38 -0
  61. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +230 -0
  62. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerRootView.ets +53 -0
  63. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  64. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  65. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +119 -0
  66. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -0
  67. package/harmony/gesture_handler/src/main/ets/rnoh/types.ts +25 -0
  68. package/harmony/gesture_handler/src/main/module.json5 +9 -0
  69. package/harmony/gesture_handler/src/main/resources/base/element/color.json +8 -0
  70. package/harmony/gesture_handler/src/main/resources/base/element/string.json +16 -0
  71. package/harmony/gesture_handler/src/main/resources/base/media/icon.png +0 -0
  72. package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -0
  73. package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +16 -0
  74. package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +16 -0
  75. package/harmony/gesture_handler/ts.ts +2 -0
  76. package/harmony/gesture_handler.har +0 -0
  77. package/lib/commonjs/RNGestureHandlerModule.js +3 -2
  78. package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
  79. package/lib/commonjs/components/GestureHandlerRootView.js +3 -3
  80. package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
  81. package/lib/commonjs/handlers/createHandler.js +18 -15
  82. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  83. package/lib/commonjs/index.js +8 -5
  84. package/lib/commonjs/index.js.map +1 -1
  85. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +2 -1
  86. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
  87. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +3 -2
  88. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  89. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +3 -2
  90. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  91. package/lib/module/RNGestureHandlerModule.js.map +1 -1
  92. package/lib/module/components/GestureHandlerRootView.js.map +1 -1
  93. package/lib/module/handlers/createHandler.js +15 -12
  94. package/lib/module/handlers/createHandler.js.map +1 -1
  95. package/lib/module/index.js +1 -3
  96. package/lib/module/index.js.map +1 -1
  97. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  98. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  99. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  100. package/lib/typescript/RNGestureHandlerModule.d.ts +2 -2
  101. package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
  102. package/lib/typescript/handlers/createHandler.d.ts +11 -11
  103. package/lib/typescript/index.d.ts +43 -42
  104. package/lib/typescript/index.d.ts.map +1 -1
  105. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +14 -14
  106. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +14 -14
  107. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +6 -6
  108. package/package.json +68 -69
  109. package/src/RNGestureHandlerModule.ts +4 -4
  110. package/src/components/GestureHandlerRootView.tsx +23 -23
  111. package/src/handlers/createHandler.tsx +534 -534
  112. package/src/index.ts +172 -172
  113. package/src/specs/NativeRNGestureHandlerModule.ts +26 -26
  114. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -18
  115. 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,2 @@
1
+ export * from "./RNGestureHandlerButton"
2
+ export * from "./RNGestureHandlerRootView"
@@ -0,0 +1,2 @@
1
+ export * as RNC from "./components/ts"
2
+ export * as TM from "./RNGestureHandlerModule"
@@ -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
+ }