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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. package/DrawerLayout/index.ts +2 -0
  2. package/Swipeable/index.ts +2 -0
  3. package/harmony/gesture_handler/BuildProfile.ets +15 -4
  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 -4
  7. package/harmony/gesture_handler/oh-package.json5 +4 -4
  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} +46 -25
  14. package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
  15. package/harmony/gesture_handler/src/main/ets/{GestureHandlerRegistry.ts → core/GestureHandlerRegistry.ts} +7 -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/index.ts +13 -0
  26. package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
  27. package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
  28. package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
  29. package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
  30. package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
  31. package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +15 -15
  32. package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
  33. package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
  34. package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
  35. package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
  36. package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
  37. package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
  38. package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
  39. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
  40. package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
  41. package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
  42. package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
  43. package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
  44. package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
  45. package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
  46. package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
  47. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +108 -0
  48. package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
  49. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
  50. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +76 -27
  51. package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
  52. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
  53. package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
  54. package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +134 -0
  55. package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -0
  56. package/harmony/gesture_handler/src/main/module.json5 +8 -6
  57. package/harmony/gesture_handler/ts.ts +2 -2
  58. package/harmony/gesture_handler.har +0 -0
  59. package/lib/commonjs/index.js +126 -141
  60. package/lib/commonjs/index.js.map +1 -1
  61. package/lib/module/index.js +13 -146
  62. package/lib/module/index.js.map +1 -1
  63. package/lib/typescript/index.d.ts +39 -1
  64. package/lib/typescript/index.d.ts.map +1 -1
  65. package/package.json +13 -10
  66. package/src/index.ts +140 -140
  67. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
  68. package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -123
  69. package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
  70. package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
  71. package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
  72. package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
  73. package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
  74. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
  75. package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
  76. package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
  77. package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
  78. package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
  79. package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
  80. package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
  81. package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
  82. /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
  83. /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
  84. /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
  85. /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
  86. /package/harmony/gesture_handler/src/main/ets/{types.ts → rnoh/types.ts} +0 -0
@@ -0,0 +1,108 @@
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, if it recently received POINTER_DOWN event
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 tag
80
+ if (e.type === TouchType.Down) {
81
+ this.activeViewTags.add(view.getTag());
82
+ }
83
+ }
84
+ }
85
+
86
+ // send touch to gesture handlers, prioritize handling touch events for child components
87
+ if (this.activeViewTags.size > 0) {
88
+ const tags = Array.from(this.activeViewTags);
89
+ for (let i = tags.length - 1; i >= 0; i--) {
90
+ const tag = tags[i];
91
+ const adapter = this.adapterByViewTag.get(tag);
92
+ if (adapter) {
93
+ adapter.handleTouch(e);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ public cancelTouches() {
101
+ for (const activeViewTag of this.activeViewTags) {
102
+ this.gestureHandlerRegistry.getGestureHandlersByViewTag(activeViewTag).forEach(gh => {
103
+ gh.cancel()
104
+ gh.reset()
105
+ })
106
+ }
107
+ }
108
+ }
@@ -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 } from '../core';
4
+ import { GestureHandlerFactory } from "../gesture-handlers"
5
+ import { ViewRegistry, 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.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,6 +168,7 @@ 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
 
@@ -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
+ }