@react-native-oh-tpl/react-native-gesture-handler 2.12.9 → 2.14.1-2.14.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/DrawerLayout/index.ts +2 -0
  2. package/Swipeable/index.ts +2 -0
  3. package/harmony/gesture_handler/BuildProfile.ets +15 -3
  4. package/harmony/gesture_handler/hvigorfile.ts +1 -1
  5. package/harmony/gesture_handler/index.ets +2 -2
  6. package/harmony/gesture_handler/oh-package-lock.json5 +4 -3
  7. package/harmony/gesture_handler/oh-package.json5 +3 -3
  8. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +64 -18
  9. package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +3 -3
  10. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +2 -2
  11. package/harmony/gesture_handler/src/main/cpp/{RNGestureHandlerButtonComponentInstance.h → componentInstances/RNGestureHandlerButtonComponentInstance.h} +2 -2
  12. package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +242 -0
  13. package/harmony/gesture_handler/src/main/ets/{GestureHandler.ts → core/GestureHandler.ts} +54 -27
  14. package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
  15. package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +63 -0
  16. package/harmony/gesture_handler/src/main/ets/{Event.ts → core/IncomingEvent.ts} +30 -20
  17. package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
  18. package/harmony/gesture_handler/src/main/ets/{OutgoingEvent.ts → core/OutgoingEvent.ts} +1 -1
  19. package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
  20. package/harmony/gesture_handler/src/main/ets/{PointerTracker.ts → core/PointerTracker.ts} +4 -4
  21. package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
  22. package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
  23. package/harmony/gesture_handler/src/main/ets/{VelocityTracker.ts → core/VelocityTracker.ts} +13 -5
  24. package/harmony/gesture_handler/src/main/ets/core/View.ts +21 -0
  25. package/harmony/gesture_handler/src/main/ets/core/ViewFinder.ts +11 -0
  26. package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +8 -0
  27. package/harmony/gesture_handler/src/main/ets/core/index.ts +15 -0
  28. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  29. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  30. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  31. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  32. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  33. package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +15 -15
  34. package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
  35. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  36. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  37. package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
  38. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  39. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  40. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
  41. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
  42. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
  43. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  44. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
  45. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  46. package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
  47. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  48. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  49. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +98 -0
  50. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  51. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
  52. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +79 -29
  53. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
  54. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  56. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +134 -0
  57. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +97 -0
  58. package/harmony/gesture_handler/src/main/module.json5 +8 -6
  59. package/harmony/gesture_handler/ts.ts +2 -2
  60. package/harmony/gesture_handler.har +0 -0
  61. package/lib/commonjs/index.js +126 -141
  62. package/lib/commonjs/index.js.map +1 -1
  63. package/lib/module/index.js +13 -146
  64. package/lib/module/index.js.map +1 -1
  65. package/lib/typescript/index.d.ts +39 -1
  66. package/lib/typescript/index.d.ts.map +1 -1
  67. package/package.json +13 -10
  68. package/src/index.ts +140 -140
  69. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
  70. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -78
  71. package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
  72. package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
  73. package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
  74. package/harmony/gesture_handler/src/main/ets/GestureHandlerRegistry.ts +0 -28
  75. package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
  76. package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
  77. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
  78. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
  79. package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
  80. package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
  81. package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
  82. package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
  83. package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
  84. package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
  85. /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
  86. /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
  87. /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
  88. /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
  89. /package/harmony/gesture_handler/src/main/ets/{types.ts → rnoh/types.ts} +0 -0
@@ -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
+ }
@@ -1,11 +1,11 @@
1
1
  import { RNOHContext, RNViewBase, ComponentBuilderContext, RNComponentFactory, Tag } from "@rnoh/react-native-openharmony"
2
- import { RNGestureHandlerButton as RNC } from "./namespace/RNGestureHandlerButton"
2
+ import { RNC } from "../namespace/ts"
3
3
 
4
- export type RNGestureHandlerButtonDescriptor = RNC.Descriptor
4
+ export type RNGestureHandlerButtonDescriptor = RNC.RNGestureHandlerButton.Descriptor
5
5
 
6
6
  @Component
7
7
  export struct RNGestureHandlerButton {
8
- static readonly NAME = RNC.NAME
8
+ static readonly NAME = RNC.RNGestureHandlerButton.NAME
9
9
  public ctx!: RNOHContext
10
10
  public tag: number = -1
11
11
  @BuilderParam public buildCustomComponent: (componentBuilderContext: ComponentBuilderContext) => void
@@ -1,19 +1,15 @@
1
- import { TurboModule, TurboModuleContext, Tag } from '@rnoh/react-native-openharmony/ts';
2
- // import { TM } from "rnoh/generated/ts"
3
- import { GestureHandlerRegistry } from './GestureHandlerRegistry';
4
- import { GestureHandlerFactory } from "./GestureHandlerFactory"
5
- import { ViewRegistry } from './ViewRegistry';
6
- import { RNGHLogger, StandardRNGHLogger, FakeRNGHLogger } from './RNGHLogger';
7
- import {
8
- EventDispatcher,
9
- JSEventDispatcher,
10
- AnimatedEventDispatcher,
11
- ReanimatedEventDispatcher
12
- } from './EventDispatcher'
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'
13
8
  import { RNOHScrollLockerArkTS, RNOHScrollLockerCAPI } from "./RNOHScrollLocker"
14
- import { State } from './State';
15
9
  import { RNGHRootTouchHandlerCAPI, RawTouchEvent } from "./RNGHRootTouchHandlerCAPI"
16
10
  import { RNGHRootTouchHandlerArkTS } from './RNGHRootTouchHandlerArkTS';
11
+ import { ViewCAPI } from "./View"
12
+ import { FakeRNGestureResponder, RNOHGestureResponder } from "./RNOHGestureResponder"
17
13
 
18
14
  export enum ActionType {
19
15
  REANIMATED_WORKLET = 1,
@@ -23,20 +19,23 @@ export enum ActionType {
23
19
  }
24
20
 
25
21
 
26
- export class RNGestureHandlerModule extends TurboModule {
27
- // implements TM.RNGestureHandlerModule.Spec {
22
+ export class RNGestureHandlerModule extends TurboModule implements TM.RNGestureHandlerModule.Spec {
28
23
  static NAME = "RNGestureHandlerModule"
29
24
 
30
- private gestureHandlerRegistry = new GestureHandlerRegistry()
25
+ private gestureHandlerRegistry: GestureHandlerRegistry
31
26
  private gestureHandlerFactory: GestureHandlerFactory | undefined = undefined
32
27
  private viewRegistry: ViewRegistry | undefined = undefined
33
28
  private logger: RNGHLogger
34
29
  private touchHandlerByRootTag = new Map<Tag, RNGHRootTouchHandlerCAPI>()
30
+ private interactionManager: InteractionManager
35
31
 
36
32
  constructor(ctx: TurboModuleContext) {
37
33
  super(ctx)
38
34
  const debug = false
39
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
+
40
39
  if (this.ctx.rnInstance.getArchitecture() === "C_API") {
41
40
  this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::TOUCH_EVENT", (e: any) => {
42
41
  this.onTouch(e)
@@ -44,27 +43,61 @@ export class RNGestureHandlerModule extends TurboModule {
44
43
  this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::ROOT_CREATED", (rootTag: any) => {
45
44
  this.onGHRootCreated(rootTag)
46
45
  })
46
+ this.ctx.rnInstance.cppEventEmitter.subscribe("RNGH::CANCEL_TOUCHES", (rootTag: any) => {
47
+ const touchHandler = this.touchHandlerByRootTag.get(rootTag)
48
+ touchHandler?.cancelTouches()
49
+ })
47
50
  }
48
51
  }
49
52
 
53
+ /**
54
+ * @architecture: C-API
55
+ * Called from C++.
56
+ */
50
57
  private onGHRootCreated(rootTag: Tag) {
51
58
  this.touchHandlerByRootTag.set(rootTag, new RNGHRootTouchHandlerCAPI(this.logger, new RNGHRootTouchHandlerArkTS(rootTag, this.viewRegistry, this.gestureHandlerRegistry, this.logger)));
52
59
  }
53
60
 
61
+ /**
62
+ * @architecture: C-API
63
+ * Called from C++.
64
+ */
54
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
+ }
55
71
  const touchHandler = this.touchHandlerByRootTag.get(e.rootTag)
56
- if (touchHandler) {
57
- touchHandler.handleTouch(e);
58
- } else {
59
- this.logger.info(`Couldn't find touch handler for root tag: ${e.rootTag}`)
72
+ if (!touchHandler) {
73
+ logger.error(`Couldn't find touch handler for gesture root tag: ${e.rootTag}`)
74
+ return;
60
75
  }
61
-
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)));
62
92
  }
63
93
 
94
+ // -------------------------------------------------------------------------------------------------------------------
95
+
64
96
  public install() {
65
- this.viewRegistry = new ViewRegistry(this.ctx.descriptorRegistry, this.ctx.componentManagerRegistry)
66
- const scrollLocker = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new RNOHScrollLockerArkTS(this.ctx.rnInstance) : new RNOHScrollLockerCAPI(this.ctx.rnInstance);
67
- this.gestureHandlerFactory = new GestureHandlerFactory(this.logger, scrollLocker)
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)
68
101
  return true
69
102
  }
70
103
 
@@ -73,12 +106,15 @@ export class RNGestureHandlerModule extends TurboModule {
73
106
  handlerTag: number,
74
107
  config: Readonly<Record<string, unknown>>
75
108
  ) {
109
+ const logger = this.logger.cloneWithPrefix("createGestureHandler")
76
110
  if (!this.gestureHandlerFactory) {
77
111
  this.ctx.logger.error("Trying to create a gesture handler before creating gesture handler factory")
78
112
  return
79
113
  }
114
+ logger.debug({ handlerName, handlerTag, config })
80
115
  const gestureHandler = this.gestureHandlerFactory.create(handlerName, handlerTag)
81
116
  this.gestureHandlerRegistry.addGestureHandler(gestureHandler)
117
+ this.interactionManager.configureInteractions(gestureHandler, config);
82
118
  gestureHandler.updateGestureConfig(config)
83
119
  }
84
120
 
@@ -92,9 +128,21 @@ export class RNGestureHandlerModule extends TurboModule {
92
128
  this.ctx.logger.error("RNGH: Couldn't create EventDispatcher")
93
129
  return
94
130
  }
95
- const view = this.viewRegistry.getViewByTag(viewTag)
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
+ }
96
144
  if (!view) {
97
- this.ctx.logger.error(`RNGH: Couldn't attachGestureHandler to view ${viewTag}`)
145
+ this.ctx.logger.error("Expected view")
98
146
  return;
99
147
  }
100
148
  this.gestureHandlerRegistry.bindGestureHandlerWithView(handlerTag, view)
@@ -103,7 +151,7 @@ export class RNGestureHandlerModule extends TurboModule {
103
151
  .setEventDispatcher(eventDispatcher)
104
152
  }
105
153
 
106
- private createEventDispatcher(actionType: ActionType, viewTag: number): EventDispatcher | null {
154
+ private createEventDispatcher(actionType: ActionType, viewTag: number): OutgoingEventDispatcher | null {
107
155
  switch (actionType) {
108
156
  case ActionType.REANIMATED_WORKLET:
109
157
  return new ReanimatedEventDispatcher(this.ctx.rnInstance, this.logger.cloneWithPrefix('ReanimatedEventDispatcher'), viewTag)
@@ -120,11 +168,13 @@ export class RNGestureHandlerModule extends TurboModule {
120
168
  newConfig: Readonly<Record<string, unknown>>
121
169
  ) {
122
170
  const gestureHandler = this.gestureHandlerRegistry.getGestureHandlerByHandlerTag(handlerTag)
171
+ this.interactionManager.configureInteractions(gestureHandler, newConfig);
123
172
  gestureHandler.updateGestureConfig(newConfig)
124
173
  }
125
174
 
126
175
  public dropGestureHandler(handlerTag: number) {
127
- this.warn("dropGestureHandler is not implemented")
176
+ this.interactionManager.dropRelationsForHandlerWithTag(handlerTag)
177
+ this.gestureHandlerRegistry.removeGestureHandlerByHandlerTag(handlerTag)
128
178
  }
129
179
 
130
180
  public handleSetJSResponder(tag: number, blockNativeResponder: boolean) {
@@ -136,7 +186,7 @@ export class RNGestureHandlerModule extends TurboModule {
136
186
  }
137
187
 
138
188
  public flushOperations() {
139
- this.warn("flushOperations is not implemented")
189
+ // no-op
140
190
  }
141
191
 
142
192
  // -------------------------------------------------------------------------------------------------------------------
@@ -1,14 +1,14 @@
1
1
  import { RNOHContext, RNViewBase, ComponentBuilderContext, RNComponentFactory, Tag } from "@rnoh/react-native-openharmony"
2
- import { RNGestureHandlerRootView as RNC } from "./namespace/RNGestureHandlerRootView"
2
+ import { RNC } from "../namespace/ts"
3
3
  import { RNGHRootTouchHandlerArkTS as RNGHRootTouchHandler } from "./RNGHRootTouchHandlerArkTS"
4
4
  import { RNGestureHandlerModule } from "./RNGestureHandlerModule"
5
5
 
6
6
 
7
- export type RNGestureHandlerRootViewDescriptor = RNC.Descriptor
7
+ export type RNGestureHandlerRootViewDescriptor = RNC.RNGestureHandlerRootView.Descriptor
8
8
 
9
9
  @Component
10
10
  export struct RNGestureHandlerRootView {
11
- static readonly NAME = RNC.NAME
11
+ static readonly NAME = RNC.RNGestureHandlerRootView.NAME
12
12
  ctx!: RNOHContext
13
13
  tag: number = -1
14
14
  @BuilderParam buildCustomComponent: (componentBuilderContext: ComponentBuilderContext) => void
@@ -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
+ }
@@ -0,0 +1,134 @@
1
+ import { DescriptorRegistry, Descriptor, Tag } from '@rnoh/react-native-openharmony/ts';
2
+ import { View, Vector2D, BoundingBox } from "../core"
3
+
4
+
5
+ export type RawTouchableView = {
6
+ tag: number,
7
+ /**
8
+ * Relative to application window.
9
+ */
10
+ x: number,
11
+ /**
12
+ * Relative to application window.
13
+ */
14
+ y: number,
15
+ width: number,
16
+ height: number,
17
+ buttonRole: boolean,
18
+ }
19
+
20
+ export class ViewCAPI implements View {
21
+ private tag: number
22
+ private buttonRole: boolean
23
+ private boundingBox: BoundingBox
24
+
25
+ constructor({ tag, buttonRole, ...boundingBox }: RawTouchableView) {
26
+ this.tag = tag
27
+ this.buttonRole = buttonRole
28
+ this.boundingBox = boundingBox
29
+ }
30
+
31
+ getTag(): number {
32
+ return this.tag
33
+ }
34
+
35
+ getBoundingRect(): BoundingBox {
36
+ return { ...this.boundingBox }
37
+ }
38
+
39
+ isPositionInBounds({x, y}: {
40
+ x: number;
41
+ y: number
42
+ }): boolean {
43
+ const rect = this.getBoundingRect();
44
+ return (
45
+ x >= rect.x &&
46
+ x <= rect.x + rect.width &&
47
+ y >= rect.y &&
48
+ y <= rect.y + rect.height
49
+ );
50
+ }
51
+
52
+ updateBoundingBox(boundingBox: BoundingBox) {
53
+ this.boundingBox = boundingBox
54
+ }
55
+
56
+ setButtonRole(buttonRole: boolean) {
57
+ this.buttonRole = buttonRole
58
+ }
59
+
60
+ hasButtonRole(): boolean {
61
+ return this.buttonRole
62
+ }
63
+ }
64
+
65
+ export class ViewArkTS implements View {
66
+ constructor(
67
+ private descriptorRegistry: DescriptorRegistry,
68
+ private viewTag: number,
69
+ ) {
70
+ }
71
+
72
+
73
+ public getTag(): Tag {
74
+ return this.viewTag;
75
+ }
76
+
77
+ public isPositionInBounds({x, y}: {
78
+ x: number;
79
+ y: number
80
+ }): boolean {
81
+ const rect = this.getBoundingRect();
82
+ return (
83
+ x >= rect.x &&
84
+ x <= rect.x + rect.width &&
85
+ y >= rect.y &&
86
+ y <= rect.y + rect.height
87
+ );
88
+ }
89
+
90
+ public getBoundingRect(): BoundingBox {
91
+ const d = this.getDescriptor();
92
+ if (!d) {
93
+ return { x: 0, y: 0, width: 0, height: 0 };
94
+ }
95
+ const offsetToAbsolutePosition = this.getOffsetToAbsolutePosition();
96
+ return {
97
+ x: d.layoutMetrics.frame.origin.x - offsetToAbsolutePosition.x,
98
+ y: d.layoutMetrics.frame.origin.y - offsetToAbsolutePosition.y,
99
+ width: d.layoutMetrics.frame.size.width,
100
+ height: d.layoutMetrics.frame.size.height,
101
+ };
102
+ }
103
+
104
+ private getDescriptor() {
105
+ return this.descriptorRegistry.getDescriptor(this.viewTag);
106
+ }
107
+
108
+ private getOffsetToAbsolutePosition(): Vector2D {
109
+ const currentOffset = new Vector2D();
110
+ let parentTag = this.getDescriptor()?.parentTag;
111
+ while (parentTag !== undefined) {
112
+ const d = this.descriptorRegistry.getDescriptor(parentTag);
113
+ currentOffset.add(this.extractScrollOffsetFromDescriptor(d));
114
+ currentOffset.subtract(new Vector2D(d.layoutMetrics.frame.origin));
115
+ parentTag = d.parentTag;
116
+ }
117
+ return currentOffset;
118
+ }
119
+
120
+ private extractScrollOffsetFromDescriptor(descriptor: Descriptor<any>) {
121
+ if (descriptor.type !== 'ScrollView') {
122
+ return new Vector2D();
123
+ }
124
+ const scrollViewState: any = descriptor.state;
125
+ return new Vector2D({
126
+ x: scrollViewState.contentOffsetX,
127
+ y: scrollViewState.contentOffsetY,
128
+ });
129
+ }
130
+
131
+ public hasButtonRole(): boolean {
132
+ return false;
133
+ }
134
+ }