@react-native-oh-tpl/react-native-gesture-handler 2.12.9 → 2.14.1-2.14.9
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.
- package/DrawerLayout/index.ts +2 -0
- package/Swipeable/index.ts +2 -0
- package/harmony/gesture_handler/BuildProfile.ets +15 -3
- package/harmony/gesture_handler/hvigorfile.ts +1 -1
- package/harmony/gesture_handler/index.ets +2 -2
- package/harmony/gesture_handler/oh-package-lock.json5 +4 -3
- package/harmony/gesture_handler/oh-package.json5 +4 -4
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +63 -17
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +3 -3
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewJSIBinder.h +2 -2
- package/harmony/gesture_handler/src/main/cpp/{RNGestureHandlerButtonComponentInstance.h → componentInstances/RNGestureHandlerButtonComponentInstance.h} +2 -2
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +234 -0
- package/harmony/gesture_handler/src/main/ets/{GestureHandler.ts → core/GestureHandler.ts} +46 -25
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerOrchestrator.ts → core/GestureHandlerOrchestrator.ts} +122 -67
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerRegistry.ts → core/GestureHandlerRegistry.ts} +7 -0
- package/harmony/gesture_handler/src/main/ets/{Event.ts → core/IncomingEvent.ts} +30 -20
- package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +144 -0
- package/harmony/gesture_handler/src/main/ets/{OutgoingEvent.ts → core/OutgoingEvent.ts} +1 -1
- package/harmony/gesture_handler/src/main/ets/core/OutgoingEventDispatcher.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/{PointerTracker.ts → core/PointerTracker.ts} +4 -4
- package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +12 -0
- package/harmony/gesture_handler/src/main/ets/core/Vector2D.ts +80 -0
- package/harmony/gesture_handler/src/main/ets/{VelocityTracker.ts → core/VelocityTracker.ts} +13 -5
- package/harmony/gesture_handler/src/main/ets/core/View.ts +19 -0
- package/harmony/gesture_handler/src/main/ets/core/index.ts +13 -0
- package/harmony/gesture_handler/src/main/ets/detectors/ScaleGestureDetector.ts +169 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +211 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +64 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +127 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +42 -0
- package/harmony/gesture_handler/src/main/ets/{NativeViewGestureHandler.ts → gesture-handlers/NativeViewGestureHandler.ts} +10 -12
- package/harmony/gesture_handler/src/main/ets/{PanGestureHandler.ts → gesture-handlers/PanGestureHandler.ts} +27 -13
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +159 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +164 -0
- package/harmony/gesture_handler/src/main/ets/{TapGestureHandler.ts → gesture-handlers/TapGestureHandler.ts} +11 -11
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/detectors/RotationGestureDetector.ts +167 -0
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/index.ts +1 -0
- package/harmony/gesture_handler/src/main/ets/namespace/RNGestureHandlerModule.ts +8 -9
- package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerButton.ts → components/RNGestureHandlerButton.ts} +35 -36
- package/harmony/gesture_handler/src/main/ets/namespace/{RNGestureHandlerRootView.ts → components/RNGestureHandlerRootView.ts} +23 -23
- package/harmony/gesture_handler/src/main/ets/namespace/components/ts.ts +2 -0
- package/harmony/gesture_handler/src/main/ets/namespace/ts.ts +2 -3
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerArkUIAdapter.ts +240 -0
- package/harmony/gesture_handler/src/main/ets/{GestureHandlerPackage.ts → rnoh/GestureHandlerPackage.ts} +4 -4
- package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +49 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +71 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +104 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +110 -0
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerButton.ets → rnoh/RNGestureHandlerButton.ets} +3 -3
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerModule.ts → rnoh/RNGestureHandlerModule.ts} +74 -27
- package/harmony/gesture_handler/src/main/ets/{RNGestureHandlerRootView.ets → rnoh/RNGestureHandlerRootView.ets} +3 -3
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +24 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +32 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +119 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +95 -0
- package/harmony/gesture_handler/src/main/module.json5 +8 -6
- package/harmony/gesture_handler/ts.ts +2 -2
- package/harmony/gesture_handler.har +0 -0
- package/lib/commonjs/index.js +98 -138
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +9 -142
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +35 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +13 -10
- package/src/index.ts +136 -136
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerPackage.h +0 -72
- package/harmony/gesture_handler/src/main/cpp/RNGestureHandlerRootViewComponentInstance.h +0 -78
- package/harmony/gesture_handler/src/main/ets/EventDispatcher.ts +0 -53
- package/harmony/gesture_handler/src/main/ets/GestureHandlerArkUIAdapter.ts +0 -203
- package/harmony/gesture_handler/src/main/ets/GestureHandlerFactory.ts +0 -45
- package/harmony/gesture_handler/src/main/ets/InteractionManager.ts +0 -109
- package/harmony/gesture_handler/src/main/ets/RNGHLogger.ts +0 -48
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerArkTS.ts +0 -60
- package/harmony/gesture_handler/src/main/ets/RNGHRootTouchHandlerCAPI.ts +0 -87
- package/harmony/gesture_handler/src/main/ets/RNOHScrollLocker.ts +0 -23
- package/harmony/gesture_handler/src/main/ets/Vector2D.ts +0 -36
- package/harmony/gesture_handler/src/main/ets/View.ts +0 -71
- package/harmony/gesture_handler/src/main/ets/ViewRegistry.ts +0 -43
- package/harmony/gesture_handler/src/main/ets/pages/Index.ets +0 -17
- package/harmony/gesture_handler/src/main/ets/webviewability/WebviewAbility.ts +0 -41
- /package/harmony/gesture_handler/src/main/ets/{CircularBuffer.ts → core/CircularBuffer.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{LeastSquareSolver.ts → core/LeastSquareSolver.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{RNGHError.ts → core/RNGHError.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{State.ts → core/State.ts} +0 -0
- /package/harmony/gesture_handler/src/main/ets/{types.ts → rnoh/types.ts} +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Tag } from '@rnoh/react-native-openharmony/ts';
|
|
2
|
+
import { GestureHandlerArkUIAdapter } from './GestureHandlerArkUIAdapter';
|
|
3
|
+
import { RNGHLogger, GestureHandlerRegistry, View } from '../core';
|
|
4
|
+
import { TouchEvent, TouchType } from './types';
|
|
5
|
+
|
|
6
|
+
export interface ViewFinder {
|
|
7
|
+
getTouchableViewsAt(
|
|
8
|
+
pointRelativeToRoot: {
|
|
9
|
+
x: number,
|
|
10
|
+
y: number
|
|
11
|
+
},
|
|
12
|
+
rootTag: Tag
|
|
13
|
+
): View[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class RNGHRootTouchHandlerArkTS {
|
|
17
|
+
private adapterByViewTag: Map<number, GestureHandlerArkUIAdapter> = new Map(); // TODO: remove adapter when view is removed
|
|
18
|
+
/**
|
|
19
|
+
* A view is ACTIVE in a window defined by two POINTER_DOWN events
|
|
20
|
+
*/
|
|
21
|
+
private activeViewTags = new Set<number>();
|
|
22
|
+
private viewFinder: ViewFinder;
|
|
23
|
+
private gestureHandlerRegistry: GestureHandlerRegistry;
|
|
24
|
+
private logger: RNGHLogger;
|
|
25
|
+
private rootTag: Tag;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
rootTag: Tag,
|
|
29
|
+
viewFinder: ViewFinder,
|
|
30
|
+
gestureHandlerRegistry: GestureHandlerRegistry,
|
|
31
|
+
logger: RNGHLogger,
|
|
32
|
+
) {
|
|
33
|
+
this.rootTag = rootTag;
|
|
34
|
+
this.viewFinder = viewFinder;
|
|
35
|
+
this.gestureHandlerRegistry = gestureHandlerRegistry;
|
|
36
|
+
this.logger = logger;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param touchEvent - TouchEvent. The type is any to allow providing the type in ets file (any and unknowns aren't allowed in ets files).
|
|
42
|
+
* @param touchableViews - Optional. List of views that can have gesture handler attached for given touch. If not provided, viewFinder will be used.
|
|
43
|
+
*/
|
|
44
|
+
public handleTouch(touchEvent: any, touchableViews: View[] | null = null) {
|
|
45
|
+
const e = touchEvent as TouchEvent;
|
|
46
|
+
if (e.type === TouchType.Down) {
|
|
47
|
+
this.activeViewTags.clear();
|
|
48
|
+
}
|
|
49
|
+
for (const changedTouch of e.changedTouches) {
|
|
50
|
+
const views = touchableViews ?? this.viewFinder.getTouchableViewsAt(
|
|
51
|
+
{
|
|
52
|
+
x: changedTouch.windowX,
|
|
53
|
+
y: changedTouch.windowY,
|
|
54
|
+
},
|
|
55
|
+
this.rootTag,
|
|
56
|
+
);
|
|
57
|
+
for (const view of views) {
|
|
58
|
+
for (const handler of this.gestureHandlerRegistry.getGestureHandlersByViewTag(
|
|
59
|
+
view.getTag(),
|
|
60
|
+
)) {
|
|
61
|
+
this.logger.info(
|
|
62
|
+
`Found GestureHandler ${handler.getTag()} for view ${view.getTag()}`,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// create adapter if necessary
|
|
66
|
+
if (!this.adapterByViewTag.has(view.getTag())) {
|
|
67
|
+
this.adapterByViewTag.set(
|
|
68
|
+
view.getTag(),
|
|
69
|
+
new GestureHandlerArkUIAdapter(
|
|
70
|
+
view,
|
|
71
|
+
this.logger,
|
|
72
|
+
),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// attach handler (there might be multiple handlers per view)
|
|
77
|
+
this.adapterByViewTag.get(view.getTag())!.attachGestureHandler(handler) // TODO: detachGestureHandler
|
|
78
|
+
|
|
79
|
+
// register active view tags
|
|
80
|
+
if (e.type === TouchType.Down) {
|
|
81
|
+
this.activeViewTags.add(view.getTag());
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// send touch to gesture handlers
|
|
87
|
+
for (const viewTag of this.activeViewTags) {
|
|
88
|
+
const adapter = this.adapterByViewTag.get(viewTag);
|
|
89
|
+
if (adapter) {
|
|
90
|
+
adapter.handleTouch(e);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public cancelTouches() {
|
|
97
|
+
for (const activeViewTag of this.activeViewTags) {
|
|
98
|
+
this.gestureHandlerRegistry.getGestureHandlersByViewTag(activeViewTag).forEach(gh => {
|
|
99
|
+
gh.cancel()
|
|
100
|
+
gh.reset()
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { RNGHRootTouchHandlerArkTS } from './RNGHRootTouchHandlerArkTS';
|
|
2
|
+
import { TouchEvent as TouchEventArkTS, TouchType, TouchObject } from './types';
|
|
3
|
+
import { RNGHLogger, View } from '../core';
|
|
4
|
+
import { RawTouchableView } from "./View"
|
|
5
|
+
|
|
6
|
+
type RawTouchPoint = {
|
|
7
|
+
pointerId: number;
|
|
8
|
+
windowX: number;
|
|
9
|
+
windowY: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type RawTouchEvent = {
|
|
13
|
+
action: number;
|
|
14
|
+
actionTouch: RawTouchPoint;
|
|
15
|
+
touchPoints: RawTouchPoint[];
|
|
16
|
+
sourceType: number;
|
|
17
|
+
timestamp: number;
|
|
18
|
+
/** TouchableViews is a list of views from root to leaf which contain the touch point specified by `actionTouch` in their boundary boxes. */
|
|
19
|
+
touchableViews: RawTouchableView[]
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const CACHED_TOUCHES_MAP = new Map<number, RawTouchPoint>();
|
|
23
|
+
let lastChangedPointerId: number | null = null;
|
|
24
|
+
const MAX_SIZE = 10;
|
|
25
|
+
const areRawTouchPointsEqual = (a: RawTouchPoint, b: RawTouchPoint) =>
|
|
26
|
+
a.pointerId === b.pointerId &&
|
|
27
|
+
a.windowX === b.windowX &&
|
|
28
|
+
a.windowY === b.windowY;
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
export class RNGHRootTouchHandlerCAPI {
|
|
32
|
+
private logger: RNGHLogger;
|
|
33
|
+
|
|
34
|
+
constructor(
|
|
35
|
+
logger: RNGHLogger,
|
|
36
|
+
private touchHandlerArkTS: RNGHRootTouchHandlerArkTS,
|
|
37
|
+
) {
|
|
38
|
+
this.logger = logger.cloneWithPrefix('RNGHRootTouchHandlerCAPI');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
handleTouch(rawTouchEvent: RawTouchEvent, touchableViews: View[]) {
|
|
42
|
+
this.touchHandlerArkTS.handleTouch(
|
|
43
|
+
touchEventArkTSFromRawTouchEvent(rawTouchEvent), touchableViews
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
cancelTouches() {
|
|
48
|
+
this.touchHandlerArkTS.cancelTouches()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function touchEventArkTSFromRawTouchEvent(raw: RawTouchEvent): TouchEventArkTS {
|
|
53
|
+
const touchType = touchTypeFromAction(raw.action);
|
|
54
|
+
const actionTouch = raw.actionTouch;
|
|
55
|
+
let hasTouchChanged = true;
|
|
56
|
+
let lastChangedTouch: RawTouchPoint = actionTouch;
|
|
57
|
+
if (CACHED_TOUCHES_MAP.has(actionTouch.pointerId)) {
|
|
58
|
+
if (areRawTouchPointsEqual(actionTouch, CACHED_TOUCHES_MAP.get(actionTouch.pointerId) as RawTouchPoint)) {
|
|
59
|
+
hasTouchChanged = false;
|
|
60
|
+
} else {
|
|
61
|
+
lastChangedPointerId = actionTouch.pointerId;
|
|
62
|
+
CACHED_TOUCHES_MAP.set(actionTouch.pointerId, actionTouch);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
// remove first element if the cache is full
|
|
66
|
+
if (CACHED_TOUCHES_MAP.size >= MAX_SIZE) {
|
|
67
|
+
CACHED_TOUCHES_MAP.delete(CACHED_TOUCHES_MAP.keys().next().value);
|
|
68
|
+
}
|
|
69
|
+
lastChangedPointerId = actionTouch.pointerId;
|
|
70
|
+
CACHED_TOUCHES_MAP.set(actionTouch.pointerId, actionTouch);
|
|
71
|
+
}
|
|
72
|
+
lastChangedTouch = CACHED_TOUCHES_MAP.get(lastChangedPointerId as number) as RawTouchPoint
|
|
73
|
+
return {
|
|
74
|
+
type: touchTypeFromAction(raw.action),
|
|
75
|
+
touches: raw.touchPoints.map(tp =>
|
|
76
|
+
touchObjectFromTouchPoint(tp, touchType),
|
|
77
|
+
),
|
|
78
|
+
changedTouches: [
|
|
79
|
+
touchObjectFromTouchPoint(lastChangedTouch, touchType),
|
|
80
|
+
],
|
|
81
|
+
timestamp: raw.timestamp / Math.pow(10, 6),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function touchTypeFromAction(action: number): TouchType {
|
|
86
|
+
switch (action) {
|
|
87
|
+
case 1:
|
|
88
|
+
return TouchType.Down;
|
|
89
|
+
case 2:
|
|
90
|
+
return TouchType.Move;
|
|
91
|
+
case 3:
|
|
92
|
+
return TouchType.Up;
|
|
93
|
+
default:
|
|
94
|
+
return TouchType.Cancel;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function touchObjectFromTouchPoint(
|
|
99
|
+
touchPoint: RawTouchPoint,
|
|
100
|
+
touchType: TouchType,
|
|
101
|
+
): TouchObject {
|
|
102
|
+
return {
|
|
103
|
+
id: touchPoint.pointerId,
|
|
104
|
+
windowX: touchPoint.windowX,
|
|
105
|
+
windowY: touchPoint.windowY,
|
|
106
|
+
x: touchPoint.windowX,
|
|
107
|
+
y: touchPoint.windowY,
|
|
108
|
+
type: touchType,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { RNOHContext, RNViewBase, ComponentBuilderContext, RNComponentFactory, Tag } from "@rnoh/react-native-openharmony"
|
|
2
|
-
import {
|
|
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
|
|
2
|
-
|
|
3
|
-
import { GestureHandlerRegistry } from '
|
|
4
|
-
import { GestureHandlerFactory } from "
|
|
5
|
-
import { ViewRegistry } from './ViewRegistry';
|
|
6
|
-
import {
|
|
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
|
|
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,60 @@ 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
|
-
|
|
58
|
-
|
|
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
|
+
} else {
|
|
86
|
+
this.viewRegistry.save(new ViewCAPI(touchableView))
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
// relay touch
|
|
90
|
+
touchHandler.handleTouch(e, e.touchableViews.map(({tag}) => this.viewRegistry.getViewByTag(tag)));
|
|
62
91
|
}
|
|
63
92
|
|
|
93
|
+
// -------------------------------------------------------------------------------------------------------------------
|
|
94
|
+
|
|
64
95
|
public install() {
|
|
65
|
-
this.viewRegistry =
|
|
66
|
-
const scrollLocker = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new RNOHScrollLockerArkTS(this.ctx.rnInstance) : new RNOHScrollLockerCAPI(this.ctx.rnInstance);
|
|
67
|
-
this.
|
|
96
|
+
this.viewRegistry = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new ViewRegistryArkTS(this.ctx.descriptorRegistry) : new ViewRegistryCAPI()
|
|
97
|
+
const scrollLocker = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new RNOHScrollLockerArkTS(this.ctx.rnInstance) : new RNOHScrollLockerCAPI(this.ctx.rnInstance, this.logger);
|
|
98
|
+
const rnGestureResponder = this.ctx.rnInstance.getArchitecture() === "ARK_TS" ? new FakeRNGestureResponder() : new RNOHGestureResponder(this.ctx.rnInstance)
|
|
99
|
+
this.gestureHandlerFactory = new GestureHandlerFactory(this.logger, scrollLocker, this.interactionManager, rnGestureResponder)
|
|
68
100
|
return true
|
|
69
101
|
}
|
|
70
102
|
|
|
@@ -73,12 +105,15 @@ export class RNGestureHandlerModule extends TurboModule {
|
|
|
73
105
|
handlerTag: number,
|
|
74
106
|
config: Readonly<Record<string, unknown>>
|
|
75
107
|
) {
|
|
108
|
+
const logger = this.logger.cloneWithPrefix("createGestureHandler")
|
|
76
109
|
if (!this.gestureHandlerFactory) {
|
|
77
110
|
this.ctx.logger.error("Trying to create a gesture handler before creating gesture handler factory")
|
|
78
111
|
return
|
|
79
112
|
}
|
|
113
|
+
logger.debug({ handlerName, handlerTag, config })
|
|
80
114
|
const gestureHandler = this.gestureHandlerFactory.create(handlerName, handlerTag)
|
|
81
115
|
this.gestureHandlerRegistry.addGestureHandler(gestureHandler)
|
|
116
|
+
this.interactionManager.configureInteractions(gestureHandler, config);
|
|
82
117
|
gestureHandler.updateGestureConfig(config)
|
|
83
118
|
}
|
|
84
119
|
|
|
@@ -92,9 +127,20 @@ export class RNGestureHandlerModule extends TurboModule {
|
|
|
92
127
|
this.ctx.logger.error("RNGH: Couldn't create EventDispatcher")
|
|
93
128
|
return
|
|
94
129
|
}
|
|
95
|
-
const
|
|
130
|
+
const viewRegistry = this.viewRegistry
|
|
131
|
+
let view = this.viewRegistry.getViewByTag(viewTag)
|
|
132
|
+
if (!view && viewRegistry instanceof ViewRegistryCAPI) {
|
|
133
|
+
view = new ViewCAPI({
|
|
134
|
+
tag: viewTag,
|
|
135
|
+
x: 0,
|
|
136
|
+
y: 0,
|
|
137
|
+
width: 0,
|
|
138
|
+
height: 0
|
|
139
|
+
})
|
|
140
|
+
viewRegistry.save(view)
|
|
141
|
+
}
|
|
96
142
|
if (!view) {
|
|
97
|
-
this.ctx.logger.error(
|
|
143
|
+
this.ctx.logger.error("Expected view")
|
|
98
144
|
return;
|
|
99
145
|
}
|
|
100
146
|
this.gestureHandlerRegistry.bindGestureHandlerWithView(handlerTag, view)
|
|
@@ -103,7 +149,7 @@ export class RNGestureHandlerModule extends TurboModule {
|
|
|
103
149
|
.setEventDispatcher(eventDispatcher)
|
|
104
150
|
}
|
|
105
151
|
|
|
106
|
-
private createEventDispatcher(actionType: ActionType, viewTag: number):
|
|
152
|
+
private createEventDispatcher(actionType: ActionType, viewTag: number): OutgoingEventDispatcher | null {
|
|
107
153
|
switch (actionType) {
|
|
108
154
|
case ActionType.REANIMATED_WORKLET:
|
|
109
155
|
return new ReanimatedEventDispatcher(this.ctx.rnInstance, this.logger.cloneWithPrefix('ReanimatedEventDispatcher'), viewTag)
|
|
@@ -120,6 +166,7 @@ export class RNGestureHandlerModule extends TurboModule {
|
|
|
120
166
|
newConfig: Readonly<Record<string, unknown>>
|
|
121
167
|
) {
|
|
122
168
|
const gestureHandler = this.gestureHandlerRegistry.getGestureHandlerByHandlerTag(handlerTag)
|
|
169
|
+
this.interactionManager.configureInteractions(gestureHandler, newConfig);
|
|
123
170
|
gestureHandler.updateGestureConfig(newConfig)
|
|
124
171
|
}
|
|
125
172
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { RNOHContext, RNViewBase, ComponentBuilderContext, RNComponentFactory, Tag } from "@rnoh/react-native-openharmony"
|
|
2
|
-
import {
|
|
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,119 @@
|
|
|
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
|
+
}
|
|
18
|
+
|
|
19
|
+
export class ViewCAPI implements View {
|
|
20
|
+
private tag: number
|
|
21
|
+
private boundingBox: BoundingBox
|
|
22
|
+
|
|
23
|
+
constructor({ tag, ...boundingBox }: RawTouchableView) {
|
|
24
|
+
this.tag = tag
|
|
25
|
+
this.boundingBox = boundingBox
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getTag(): number {
|
|
29
|
+
return this.tag
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getBoundingRect(): BoundingBox {
|
|
33
|
+
return { ...this.boundingBox }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
isPositionInBounds({x, y}: {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number
|
|
39
|
+
}): boolean {
|
|
40
|
+
const rect = this.getBoundingRect();
|
|
41
|
+
return (
|
|
42
|
+
x >= rect.x &&
|
|
43
|
+
x <= rect.x + rect.width &&
|
|
44
|
+
y >= rect.y &&
|
|
45
|
+
y <= rect.y + rect.height
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
updateBoundingBox(boundingBox: BoundingBox) {
|
|
50
|
+
this.boundingBox = boundingBox
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class ViewArkTS implements View {
|
|
55
|
+
constructor(
|
|
56
|
+
private descriptorRegistry: DescriptorRegistry,
|
|
57
|
+
private viewTag: number,
|
|
58
|
+
) {
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
public getTag(): Tag {
|
|
63
|
+
return this.viewTag;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public isPositionInBounds({x, y}: {
|
|
67
|
+
x: number;
|
|
68
|
+
y: number
|
|
69
|
+
}): boolean {
|
|
70
|
+
const rect = this.getBoundingRect();
|
|
71
|
+
return (
|
|
72
|
+
x >= rect.x &&
|
|
73
|
+
x <= rect.x + rect.width &&
|
|
74
|
+
y >= rect.y &&
|
|
75
|
+
y <= rect.y + rect.height
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public getBoundingRect(): BoundingBox {
|
|
80
|
+
const d = this.getDescriptor();
|
|
81
|
+
if (!d) {
|
|
82
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
83
|
+
}
|
|
84
|
+
const offsetToAbsolutePosition = this.getOffsetToAbsolutePosition();
|
|
85
|
+
return {
|
|
86
|
+
x: d.layoutMetrics.frame.origin.x - offsetToAbsolutePosition.x,
|
|
87
|
+
y: d.layoutMetrics.frame.origin.y - offsetToAbsolutePosition.y,
|
|
88
|
+
width: d.layoutMetrics.frame.size.width,
|
|
89
|
+
height: d.layoutMetrics.frame.size.height,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private getDescriptor() {
|
|
94
|
+
return this.descriptorRegistry.getDescriptor(this.viewTag);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private getOffsetToAbsolutePosition(): Vector2D {
|
|
98
|
+
const currentOffset = new Vector2D();
|
|
99
|
+
let parentTag = this.getDescriptor()?.parentTag;
|
|
100
|
+
while (parentTag !== undefined) {
|
|
101
|
+
const d = this.descriptorRegistry.getDescriptor(parentTag);
|
|
102
|
+
currentOffset.add(this.extractScrollOffsetFromDescriptor(d));
|
|
103
|
+
currentOffset.subtract(new Vector2D(d.layoutMetrics.frame.origin));
|
|
104
|
+
parentTag = d.parentTag;
|
|
105
|
+
}
|
|
106
|
+
return currentOffset;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private extractScrollOffsetFromDescriptor(descriptor: Descriptor<any>) {
|
|
110
|
+
if (descriptor.type !== 'ScrollView') {
|
|
111
|
+
return new Vector2D();
|
|
112
|
+
}
|
|
113
|
+
const scrollViewState: any = descriptor.state;
|
|
114
|
+
return new Vector2D({
|
|
115
|
+
x: scrollViewState.contentOffsetX,
|
|
116
|
+
y: scrollViewState.contentOffsetY,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|