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

Sign up to get free protection for your applications and to get access to all the features.
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
+ }