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