@react-native-oh-tpl/react-native-gesture-handler 2.14.7 → 2.14.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) 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 +242 -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 +690 -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 +63 -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 +21 -0
  36. package/harmony/gesture_handler/src/main/ets/core/ViewFinder.ts +11 -0
  37. package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +8 -0
  38. package/harmony/gesture_handler/src/main/ets/core/index.ts +15 -0
  39. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  40. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  41. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  42. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  43. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  44. package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +115 -0
  45. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +342 -0
  46. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  47. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  48. package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +206 -0
  49. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  50. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  51. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +24 -0
  52. package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerButton.ts +139 -0
  53. package/harmony/gesture_handler/src/main/ets/namespace/components/RNGestureHandlerRootView.ts +101 -0
  54. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  55. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -0
  56. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  57. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +22 -0
  58. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  59. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  60. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +98 -0
  61. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  62. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerButton.ets +38 -0
  63. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +233 -0
  64. package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerRootView.ets +53 -0
  65. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  66. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  67. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +134 -0
  68. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +97 -0
  69. package/harmony/gesture_handler/src/main/ets/rnoh/types.ts +25 -0
  70. package/harmony/gesture_handler/src/main/module.json5 +9 -0
  71. package/harmony/gesture_handler/src/main/resources/base/element/color.json +8 -0
  72. package/harmony/gesture_handler/src/main/resources/base/element/string.json +16 -0
  73. package/harmony/gesture_handler/src/main/resources/base/media/icon.png +0 -0
  74. package/harmony/gesture_handler/src/main/resources/base/profile/main_pages.json +5 -0
  75. package/harmony/gesture_handler/src/main/resources/en_US/element/string.json +16 -0
  76. package/harmony/gesture_handler/src/main/resources/zh_CN/element/string.json +16 -0
  77. package/harmony/gesture_handler/ts.ts +2 -0
  78. package/harmony/gesture_handler.har +0 -0
  79. package/lib/commonjs/RNGestureHandlerModule.js +3 -2
  80. package/lib/commonjs/RNGestureHandlerModule.js.map +1 -1
  81. package/lib/commonjs/components/GestureHandlerRootView.js +3 -3
  82. package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
  83. package/lib/commonjs/handlers/createHandler.js +18 -15
  84. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  85. package/lib/commonjs/index.js +36 -8
  86. package/lib/commonjs/index.js.map +1 -1
  87. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js +2 -1
  88. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
  89. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js +3 -2
  90. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  91. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js +3 -2
  92. package/lib/commonjs/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  93. package/lib/module/RNGestureHandlerModule.js.map +1 -1
  94. package/lib/module/components/GestureHandlerRootView.js.map +1 -1
  95. package/lib/module/handlers/createHandler.js +15 -12
  96. package/lib/module/handlers/createHandler.js.map +1 -1
  97. package/lib/module/index.js +5 -7
  98. package/lib/module/index.js.map +1 -1
  99. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  100. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  101. package/lib/module/specs/RNGestureHandlerRootViewNativeComponent.js.map +1 -1
  102. package/lib/typescript/RNGestureHandlerModule.d.ts +2 -2
  103. package/lib/typescript/components/GestureHandlerRootView.d.ts +6 -6
  104. package/lib/typescript/handlers/createHandler.d.ts +11 -11
  105. package/lib/typescript/index.d.ts +47 -42
  106. package/lib/typescript/index.d.ts.map +1 -1
  107. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +14 -14
  108. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +14 -14
  109. package/lib/typescript/specs/RNGestureHandlerRootViewNativeComponent.d.ts +6 -6
  110. package/package.json +73 -72
  111. package/src/RNGestureHandlerModule.ts +4 -4
  112. package/src/components/GestureHandlerRootView.tsx +23 -23
  113. package/src/handlers/createHandler.tsx +534 -534
  114. package/src/index.ts +172 -172
  115. package/src/specs/NativeRNGestureHandlerModule.ts +26 -26
  116. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +18 -18
  117. package/src/specs/RNGestureHandlerRootViewNativeComponent.ts +6 -6
@@ -0,0 +1,98 @@
1
+ import { Tag } from '@rnoh/react-native-openharmony/ts';
2
+ import { GestureHandlerArkUIAdapter } from './GestureHandlerArkUIAdapter';
3
+ import { RNGHLogger, GestureHandlerRegistry, View, ViewFinder } from '../core';
4
+ import { TouchEvent, TouchType } from './types';
5
+
6
+ export class RNGHRootTouchHandlerArkTS {
7
+ private adapterByViewTag: Map<number, GestureHandlerArkUIAdapter> = new Map(); // TODO: remove adapter when view is removed
8
+ /**
9
+ * A view is ACTIVE, if it recently received POINTER_DOWN event
10
+ */
11
+ private activeViewTags = new Set<number>();
12
+ private viewFinder: ViewFinder;
13
+ private gestureHandlerRegistry: GestureHandlerRegistry;
14
+ private logger: RNGHLogger;
15
+ private rootTag: Tag;
16
+
17
+ constructor(
18
+ rootTag: Tag,
19
+ viewFinder: ViewFinder,
20
+ gestureHandlerRegistry: GestureHandlerRegistry,
21
+ logger: RNGHLogger,
22
+ ) {
23
+ this.rootTag = rootTag;
24
+ this.viewFinder = viewFinder;
25
+ this.gestureHandlerRegistry = gestureHandlerRegistry;
26
+ this.logger = logger;
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @param touchEvent - TouchEvent. The type is any to allow providing the type in ets file (any and unknowns aren't allowed in ets files).
32
+ * @param touchableViews - Optional. List of views that can have gesture handler attached for given touch. If not provided, viewFinder will be used.
33
+ */
34
+ public handleTouch(touchEvent: any, touchableViews: View[] | null = null) {
35
+ const e = touchEvent as TouchEvent;
36
+ if (e.type === TouchType.Down) {
37
+ this.activeViewTags.clear();
38
+ }
39
+ for (const changedTouch of e.changedTouches) {
40
+ const views = touchableViews ?? this.viewFinder.getTouchableViewsAt(
41
+ {
42
+ x: changedTouch.windowX,
43
+ y: changedTouch.windowY,
44
+ },
45
+ this.rootTag,
46
+ );
47
+ for (const view of views) {
48
+ for (const handler of this.gestureHandlerRegistry.getGestureHandlersByViewTag(
49
+ view.getTag(),
50
+ )) {
51
+ this.logger.info(
52
+ `Found GestureHandler ${handler.getTag()} for view ${view.getTag()}`,
53
+ );
54
+
55
+ // create adapter if necessary
56
+ if (!this.adapterByViewTag.has(view.getTag())) {
57
+ this.adapterByViewTag.set(
58
+ view.getTag(),
59
+ new GestureHandlerArkUIAdapter(
60
+ view,
61
+ this.logger,
62
+ ),
63
+ );
64
+ }
65
+
66
+ // attach handler (there might be multiple handlers per view)
67
+ this.adapterByViewTag.get(view.getTag())!.attachGestureHandler(handler) // TODO: detachGestureHandler
68
+
69
+ // register active view tag
70
+ if (e.type === TouchType.Down) {
71
+ this.activeViewTags.add(view.getTag());
72
+ }
73
+ }
74
+ }
75
+
76
+ // send touch to gesture handlers, prioritize handling touch events for child components
77
+ if (this.activeViewTags.size > 0) {
78
+ const tags = Array.from(this.activeViewTags);
79
+ for (let i = tags.length - 1; i >= 0; i--) {
80
+ const tag = tags[i];
81
+ const adapter = this.adapterByViewTag.get(tag);
82
+ if (adapter) {
83
+ adapter.handleTouch(e);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ public cancelTouches() {
91
+ for (const activeViewTag of this.activeViewTags) {
92
+ this.gestureHandlerRegistry.getGestureHandlersByViewTag(activeViewTag).forEach(gh => {
93
+ gh.cancel()
94
+ gh.reset()
95
+ })
96
+ }
97
+ }
98
+ }
@@ -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
+ }
@@ -0,0 +1,38 @@
1
+ import { RNOHContext, RNViewBase, ComponentBuilderContext, RNComponentFactory, Tag } from "@rnoh/react-native-openharmony"
2
+ import { RNC } from "../namespace/ts"
3
+
4
+ export type RNGestureHandlerButtonDescriptor = RNC.RNGestureHandlerButton.Descriptor
5
+
6
+ @Component
7
+ export struct RNGestureHandlerButton {
8
+ static readonly NAME = RNC.RNGestureHandlerButton.NAME
9
+ public ctx!: RNOHContext
10
+ public tag: number = -1
11
+ @BuilderParam public buildCustomComponent: (componentBuilderContext: ComponentBuilderContext) => void
12
+
13
+ @State private descriptor: RNGestureHandlerButtonDescriptor = {} as RNGestureHandlerButtonDescriptor
14
+ private unsubscribes: (() => void)[] = []
15
+
16
+ aboutToAppear() {
17
+ this.handleDescriptorChange(this.ctx.descriptorRegistry.getDescriptor<RNGestureHandlerButtonDescriptor>(this.tag))
18
+ this.unsubscribes.push(this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag, (d) => {
19
+ this.handleDescriptorChange(d as RNGestureHandlerButtonDescriptor)
20
+ }))
21
+ }
22
+
23
+ aboutToDisappear() {
24
+ this.unsubscribes.forEach(unsubscribe => unsubscribe())
25
+ }
26
+
27
+ handleDescriptorChange(newDescriptor: RNGestureHandlerButtonDescriptor) {
28
+ this.descriptor = newDescriptor
29
+ }
30
+
31
+ build() {
32
+ RNViewBase({ ctx: this.ctx, tag: this.tag }) {
33
+ ForEach(this.descriptor.childrenTags, (childrenTag: Tag) => {
34
+ RNComponentFactory({ ctx: this.ctx, tag: childrenTag, buildCustomComponent: this.buildCustomComponent })
35
+ })
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,233 @@
1
+ import { TurboModule, TurboModuleContext, Tag } from "@rnoh/react-native-openharmony/ts";
2
+ import { TM } from "../namespace/ts"
3
+ import { GestureHandlerRegistry, State, OutgoingEventDispatcher, RNGHLogger, InteractionManager, ViewRegistry } from '../core';
4
+ import { GestureHandlerFactory } from "../gesture-handlers"
5
+ import { ViewRegistryArkTS, ViewRegistryCAPI } from './ViewRegistry';
6
+ import { StandardRNGHLogger, FakeRNGHLogger } from './Logger';
7
+ import { JSEventDispatcher, AnimatedEventDispatcher, ReanimatedEventDispatcher } from './OutgoingEventDispatchers'
8
+ import { RNOHScrollLockerArkTS, RNOHScrollLockerCAPI } from "./RNOHScrollLocker"
9
+ import { RNGHRootTouchHandlerCAPI, RawTouchEvent } from "./RNGHRootTouchHandlerCAPI"
10
+ import { RNGHRootTouchHandlerArkTS } from './RNGHRootTouchHandlerArkTS';
11
+ import { ViewCAPI } from "./View"
12
+ import { FakeRNGestureResponder, RNOHGestureResponder } from "./RNOHGestureResponder"
13
+
14
+ export enum ActionType {
15
+ REANIMATED_WORKLET = 1,
16
+ NATIVE_ANIMATED_EVENT = 2,
17
+ JS_FUNCTION_OLD_API = 3,
18
+ JS_FUNCTION_NEW_API = 4,
19
+ }
20
+
21
+
22
+ export class RNGestureHandlerModule extends TurboModule implements TM.RNGestureHandlerModule.Spec {
23
+ static NAME = "RNGestureHandlerModule"
24
+
25
+ private gestureHandlerRegistry: GestureHandlerRegistry
26
+ private gestureHandlerFactory: GestureHandlerFactory | undefined = undefined
27
+ private viewRegistry: ViewRegistry | undefined = undefined
28
+ private logger: RNGHLogger
29
+ private touchHandlerByRootTag = new Map<Tag, RNGHRootTouchHandlerCAPI>()
30
+ private interactionManager: InteractionManager
31
+
32
+ constructor(ctx: TurboModuleContext) {
33
+ super(ctx)
34
+ const debug = false
35
+ this.logger = debug ? new StandardRNGHLogger(ctx.logger, "RNGH") : new FakeRNGHLogger()
36
+ this.interactionManager = new InteractionManager(this.logger)
37
+ this.gestureHandlerRegistry = new GestureHandlerRegistry(this.viewRegistry, this.logger)
38
+
39
+ if (this.ctx.rnInstance.getArchitecture() === "C_API") {
40
+ this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::TOUCH_EVENT", (e: any) => {
41
+ this.onTouch(e)
42
+ })
43
+ this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::ROOT_CREATED", (rootTag: any) => {
44
+ this.onGHRootCreated(rootTag)
45
+ })
46
+ this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::CANCEL_TOUCHES", (rootTag: any) => {
47
+ const touchHandler = this.touchHandlerByRootTag.get(rootTag)
48
+ touchHandler?.cancelTouches()
49
+ })
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @architecture: C-API
55
+ * Called from C++.
56
+ */
57
+ private onGHRootCreated(rootTag: Tag) {
58
+ this.touchHandlerByRootTag.set(rootTag, new RNGHRootTouchHandlerCAPI(this.logger, new RNGHRootTouchHandlerArkTS(rootTag, this.viewRegistry, this.gestureHandlerRegistry, this.logger)));
59
+ }
60
+
61
+ /**
62
+ * @architecture: C-API
63
+ * Called from C++.
64
+ */
65
+ private onTouch(e: RawTouchEvent & { rootTag: Tag }) {
66
+ const logger = this.logger.cloneWithPrefix("onTouch")
67
+ if (!(this.viewRegistry instanceof ViewRegistryCAPI)) {
68
+ logger.error("Expected ViewRegistryCAPI")
69
+ return;
70
+ }
71
+ const touchHandler = this.touchHandlerByRootTag.get(e.rootTag)
72
+ if (!touchHandler) {
73
+ logger.error(`Couldn't find touch handler for gesture root tag: ${e.rootTag}`)
74
+ return;
75
+ }
76
+ // update view registry
77
+ e.touchableViews.forEach(touchableView => {
78
+ const view = this.viewRegistry.getViewByTag(touchableView.tag)
79
+ if (view) {
80
+ if (!(view instanceof ViewCAPI)) {
81
+ logger.error(`Expected ViewCAPI`)
82
+ return
83
+ }
84
+ view.updateBoundingBox(touchableView)
85
+ view.setButtonRole(touchableView.buttonRole)
86
+ } else {
87
+ this.viewRegistry.save(new ViewCAPI(touchableView))
88
+ }
89
+ })
90
+ // relay touch
91
+ touchHandler.handleTouch(e, e.touchableViews.map(({tag}) => this.viewRegistry.getViewByTag(tag)));
92
+ }
93
+
94
+ // -------------------------------------------------------------------------------------------------------------------
95
+
96
+ public install() {
97
+ this.viewRegistry = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new ViewRegistryArkTS(this.ctx.descriptorRegistry) : new ViewRegistryCAPI()
98
+ const scrollLocker = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new RNOHScrollLockerArkTS(this.ctx.rnInstance) : new RNOHScrollLockerCAPI(this.ctx.rnInstance, this.logger);
99
+ const rnGestureResponder = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new FakeRNGestureResponder() : new RNOHGestureResponder(this.ctx.rnInstance)
100
+ this.gestureHandlerFactory = new GestureHandlerFactory(this.logger, scrollLocker, this.interactionManager, rnGestureResponder)
101
+ return true
102
+ }
103
+
104
+ public createGestureHandler(
105
+ handlerName: string,
106
+ handlerTag: number,
107
+ config: Readonly<Record<string, unknown>>
108
+ ) {
109
+ const logger = this.logger.cloneWithPrefix("createGestureHandler")
110
+ if (!this.gestureHandlerFactory) {
111
+ this.ctx.logger.error("Trying to create a gesture handler before creating gesture handler factory")
112
+ return
113
+ }
114
+ logger.debug({ handlerName, handlerTag, config })
115
+ const gestureHandler = this.gestureHandlerFactory.create(handlerName, handlerTag)
116
+ this.gestureHandlerRegistry.addGestureHandler(gestureHandler)
117
+ this.interactionManager.configureInteractions(gestureHandler, config);
118
+ gestureHandler.updateGestureConfig(config)
119
+ }
120
+
121
+ public attachGestureHandler(
122
+ handlerTag: number,
123
+ viewTag: number,
124
+ actionType: ActionType
125
+ ) {
126
+ const eventDispatcher = this.createEventDispatcher(actionType, viewTag)
127
+ if (!eventDispatcher) {
128
+ this.ctx.logger.error("RNGH: Couldn't create EventDispatcher")
129
+ return
130
+ }
131
+ const viewRegistry = this.viewRegistry
132
+ let view = this.viewRegistry.getViewByTag(viewTag)
133
+ if (!view && viewRegistry instanceof ViewRegistryCAPI) {
134
+ view = new ViewCAPI({
135
+ tag: viewTag,
136
+ x: 0,
137
+ y: 0,
138
+ width: 0,
139
+ height: 0,
140
+ buttonRole: false
141
+ })
142
+ viewRegistry.save(view)
143
+ }
144
+ if (!view) {
145
+ this.ctx.logger.error("Expected view")
146
+ return;
147
+ }
148
+ this.gestureHandlerRegistry.bindGestureHandlerWithView(handlerTag, view)
149
+ this.gestureHandlerRegistry
150
+ .getGestureHandlerByHandlerTag(handlerTag)
151
+ .setEventDispatcher(eventDispatcher)
152
+ }
153
+
154
+ private createEventDispatcher(actionType: ActionType, viewTag: number): OutgoingEventDispatcher | null {
155
+ switch (actionType) {
156
+ case ActionType.REANIMATED_WORKLET:
157
+ return new ReanimatedEventDispatcher(this.ctx.rnInstance, this.logger.cloneWithPrefix('ReanimatedEventDispatcher'), viewTag)
158
+ case ActionType.NATIVE_ANIMATED_EVENT:
159
+ return new AnimatedEventDispatcher(this.ctx.rnInstance, this.logger.cloneWithPrefix('AnimatedEventDispatcher'), viewTag)
160
+ case ActionType.JS_FUNCTION_OLD_API:
161
+ case ActionType.JS_FUNCTION_NEW_API:
162
+ return new JSEventDispatcher(this.ctx.rnInstance, this.logger.cloneWithPrefix('JSEventDispatcher'));
163
+ }
164
+ }
165
+
166
+ public updateGestureHandler(
167
+ handlerTag: number,
168
+ newConfig: Readonly<Record<string, unknown>>
169
+ ) {
170
+ const gestureHandler = this.gestureHandlerRegistry.getGestureHandlerByHandlerTag(handlerTag)
171
+ this.interactionManager.configureInteractions(gestureHandler, newConfig);
172
+ gestureHandler.updateGestureConfig(newConfig)
173
+ }
174
+
175
+ public dropGestureHandler(handlerTag: number) {
176
+ this.interactionManager.dropRelationsForHandlerWithTag(handlerTag)
177
+ this.gestureHandlerRegistry.removeGestureHandlerByHandlerTag(handlerTag)
178
+ }
179
+
180
+ public handleSetJSResponder(tag: number, blockNativeResponder: boolean) {
181
+ this.warn("handleSetJSResponder is not implemented")
182
+ }
183
+
184
+ public handleClearJSResponder() {
185
+ this.warn("handleClearJSResponder is not implemented")
186
+ }
187
+
188
+ public flushOperations() {
189
+ // no-op
190
+ }
191
+
192
+ // -------------------------------------------------------------------------------------------------------------------
193
+ protected warn(message: string) {
194
+ this.ctx.logger.warn("RNGH: " + message)
195
+ }
196
+
197
+ public getGestureHandlerRegistry() {
198
+ return this.gestureHandlerRegistry
199
+ }
200
+
201
+ public getLogger() {
202
+ return this.logger
203
+ }
204
+
205
+ public getViewRegistry() {
206
+ if (!this.viewRegistry) {
207
+ this.logger.info("Tried to get viewRegistry before it was initialized")
208
+ throw new Error("Tried to get viewRegistry before it was initialized")
209
+ }
210
+ return this.viewRegistry
211
+ }
212
+
213
+ public setGestureHandlerState(handlerTag: number, newState: State) {
214
+ const handler = this.getGestureHandlerRegistry().getGestureHandlerByHandlerTag(handlerTag);
215
+ switch (newState) {
216
+ case State.ACTIVE:
217
+ handler.activate();
218
+ break;
219
+ case State.BEGAN:
220
+ handler.begin();
221
+ break;
222
+ case State.END:
223
+ handler.end();
224
+ break;
225
+ case State.FAILED:
226
+ handler.fail();
227
+ break;
228
+ case State.CANCELLED:
229
+ handler.cancel();
230
+ break;
231
+ }
232
+ }
233
+ }
@@ -0,0 +1,53 @@
1
+ import { RNOHContext, RNViewBase, ComponentBuilderContext, RNComponentFactory, Tag } from "@rnoh/react-native-openharmony"
2
+ import { RNC } from "../namespace/ts"
3
+ import { RNGHRootTouchHandlerArkTS as RNGHRootTouchHandler } from "./RNGHRootTouchHandlerArkTS"
4
+ import { RNGestureHandlerModule } from "./RNGestureHandlerModule"
5
+
6
+
7
+ export type RNGestureHandlerRootViewDescriptor = RNC.RNGestureHandlerRootView.Descriptor
8
+
9
+ @Component
10
+ export struct RNGestureHandlerRootView {
11
+ static readonly NAME = RNC.RNGestureHandlerRootView.NAME
12
+ ctx!: RNOHContext
13
+ tag: number = -1
14
+ @BuilderParam buildCustomComponent: (componentBuilderContext: ComponentBuilderContext) => void
15
+ @State descriptor: RNGestureHandlerRootViewDescriptor = {} as RNGestureHandlerRootViewDescriptor
16
+ private unsubscribes: (() => void)[] = []
17
+ private touchHandler: RNGHRootTouchHandler | undefined = undefined
18
+
19
+ aboutToAppear() {
20
+ const rnGestureHandlerModule = this.ctx.rnInstance.getTurboModule<RNGestureHandlerModule>(RNGestureHandlerModule.NAME)
21
+ const rootTag = this.ctx.descriptorRegistry.getDescriptorLineage(this.tag)[0].tag
22
+ this.touchHandler = new RNGHRootTouchHandler(rootTag, rnGestureHandlerModule.getViewRegistry(), rnGestureHandlerModule.getGestureHandlerRegistry(), rnGestureHandlerModule.getLogger())
23
+ this.handleDescriptorChange(this.ctx.descriptorRegistry.getDescriptor<RNGestureHandlerRootViewDescriptor>(this.tag))
24
+ this.unsubscribes.push(this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag, (d) => {
25
+ this.handleDescriptorChange(d as RNGestureHandlerRootViewDescriptor)
26
+ }))
27
+ }
28
+
29
+ aboutToDisappear() {
30
+ this.unsubscribes.forEach(unsubscribe => unsubscribe())
31
+ }
32
+
33
+ handleDescriptorChange(newDescriptor: RNGestureHandlerRootViewDescriptor) {
34
+ this.descriptor = newDescriptor
35
+ }
36
+
37
+ build() {
38
+ RNViewBase({ ctx: this.ctx, tag: this.tag }) {
39
+ ForEach(this.descriptor.childrenTags, (childrenTag: Tag) => {
40
+ RNComponentFactory({ ctx: this.ctx, tag: childrenTag, buildCustomComponent: this.buildCustomComponent })
41
+ })
42
+ Stack() {
43
+ }
44
+ .width("100%")
45
+ .height("100%")
46
+ .onTouch((e) => {
47
+ this.touchHandler?.handleTouch(e)
48
+ })
49
+ .hitTestBehavior(HitTestMode.Transparent)
50
+
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,24 @@
1
+ import { RNInstance } from "@rnoh/react-native-openharmony/ts"
2
+ import { RNGestureResponder } from "../core"
3
+
4
+ export class FakeRNGestureResponder {
5
+ lock() {
6
+ // Cancelling RN events isn't supported in ArkTS architecture.
7
+ return () => {}
8
+ }
9
+ }
10
+
11
+ /**
12
+ * Used in C-API architecture.
13
+ */
14
+ export class RNOHGestureResponder implements RNGestureResponder {
15
+ constructor(private rnInstance: RNInstance) {
16
+ }
17
+
18
+ lock(viewTag: number): () => void {
19
+ this.rnInstance.postMessageToCpp("RNGH::ROOT_VIEW_IS_HANDLING_TOUCHES", { descendantViewTag: viewTag, isHandlingTouches: true })
20
+ return () => {
21
+ this.rnInstance.postMessageToCpp("RNGH::ROOT_VIEW_IS_HANDLING_TOUCHES", { descendantViewTag: viewTag, isHandlingTouches: false })
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,32 @@
1
+ import { RNInstance } from '@rnoh/react-native-openharmony/ts';
2
+ import { ScrollLocker, RNGHLogger } from '../core';
3
+
4
+ export class RNOHScrollLockerArkTS implements ScrollLocker {
5
+ constructor(private rnInstance: RNInstance) {
6
+ }
7
+
8
+ lockScrollContainingViewTag(viewTag: number) {
9
+ return this.rnInstance.blockComponentsGestures(viewTag);
10
+ }
11
+ }
12
+
13
+ export class RNOHScrollLockerCAPI implements ScrollLocker {
14
+ private logger: RNGHLogger
15
+
16
+ constructor(private rnInstance: RNInstance, logger: RNGHLogger) {
17
+ this.logger = logger.cloneWithPrefix("RNOHScrollLockerCAPI")
18
+ }
19
+
20
+ lockScrollContainingViewTag(viewTag: number) {
21
+ this.rnInstance.postMessageToCpp('RNGH::SET_NATIVE_RESPONDERS_BLOCK', {
22
+ targetTag: viewTag,
23
+ shouldBlock: true,
24
+ });
25
+ return () => {
26
+ this.rnInstance.postMessageToCpp('RNGH::SET_NATIVE_RESPONDERS_BLOCK', {
27
+ targetTag: viewTag,
28
+ shouldBlock: false,
29
+ });
30
+ };
31
+ }
32
+ }