@react-native-oh-tpl/react-native-gesture-handler 2.14.1-2.14.13 → 2.14.1-2.14.14
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/harmony/gesture_handler/BuildProfile.ets +1 -1
- package/harmony/gesture_handler/index.ets +1 -2
- package/harmony/gesture_handler/oh-package-lock.json5 +1 -1
- package/harmony/gesture_handler/oh-package.json5 +1 -1
- package/harmony/gesture_handler/src/main/cpp/CMakeLists.txt +1 -1
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.h +9 -18
- package/harmony/gesture_handler/src/main/cpp/RnohReactNativeHarmonyGestureHandlerPackage.cpp +157 -0
- package/harmony/gesture_handler/src/main/cpp/RnohReactNativeHarmonyGestureHandlerPackage.h +21 -0
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerButtonComponentInstance.h +16 -16
- package/harmony/gesture_handler/src/main/cpp/componentInstances/RNGestureHandlerRootViewComponentInstance.h +202 -199
- package/harmony/gesture_handler/src/main/ets/RNOHPackage.ets +17 -0
- package/harmony/gesture_handler/src/main/ets/core/GestureHandler.ts +84 -35
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerOrchestrator.ts +20 -11
- package/harmony/gesture_handler/src/main/ets/core/GestureHandlerRegistry.ts +2 -2
- package/harmony/gesture_handler/src/main/ets/core/InteractionManager.ts +4 -4
- package/harmony/gesture_handler/src/main/ets/core/Multiset.ts +26 -0
- package/harmony/gesture_handler/src/main/ets/core/RNGHLogger.ts +7 -3
- package/harmony/gesture_handler/src/main/ets/core/ViewRegistry.ts +1 -2
- package/harmony/gesture_handler/src/main/ets/core/index.ts +2 -2
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/FlingGestureHandler.ts +12 -4
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/GestureHandlerFactory.ts +8 -5
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/LongPressGestureHandler.ts +14 -2
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/ManualGestureHandler.ts +9 -1
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/NativeViewGestureHandler.ts +13 -4
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PanGestureHandler.ts +31 -12
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/PinchGestureHandler.ts +145 -130
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/RotationGestureHandler.ts +9 -1
- package/harmony/gesture_handler/src/main/ets/gesture-handlers/TapGestureHandler.ts +15 -5
- package/harmony/gesture_handler/src/main/ets/rnoh/GestureHandlerPackage.ts +7 -4
- package/harmony/gesture_handler/src/main/ets/rnoh/Logger.ts +74 -16
- package/harmony/gesture_handler/src/main/ets/rnoh/OutgoingEventDispatchers.ts +35 -12
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootViewController.ts +182 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHView.ts +62 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/{GestureHandlerArkUIAdapter.ts → RNGHViewController.ts} +44 -22
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHViewRegistry.ts +19 -0
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerModule.ts +127 -93
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHGestureResponder.ts +0 -9
- package/harmony/gesture_handler/src/main/ets/rnoh/RNOHScrollLocker.ts +1 -8
- package/harmony/gesture_handler.har +0 -0
- package/package.json +7 -3
- package/harmony/gesture_handler/src/main/cpp/GestureHandlerPackage.cpp +0 -149
- package/harmony/gesture_handler/src/main/ets/core/ViewFinder.ts +0 -11
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerArkTS.ts +0 -98
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGHRootTouchHandlerCAPI.ts +0 -110
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerButton.ets +0 -38
- package/harmony/gesture_handler/src/main/ets/rnoh/RNGestureHandlerRootView.ets +0 -53
- package/harmony/gesture_handler/src/main/ets/rnoh/View.ts +0 -134
- package/harmony/gesture_handler/src/main/ets/rnoh/ViewRegistry.ts +0 -97
@@ -1,23 +1,71 @@
|
|
1
1
|
import { RNOHContext } from '@rnoh/react-native-openharmony/ts';
|
2
2
|
import { RNGHLogger, RNGHLoggerMessage } from "../core"
|
3
|
+
import hiTrace from "@ohos.hiTraceMeter"
|
3
4
|
|
4
|
-
|
5
|
+
class Tracer {
|
6
|
+
private activeTracesCount: number = 0
|
7
|
+
|
8
|
+
public startTrace(name: string) {
|
9
|
+
/**
|
10
|
+
* hiTrace.startTrace creates a new lane which makes the traces useless
|
11
|
+
*/
|
12
|
+
hiTrace.startTrace(name, 0)
|
13
|
+
this.activeTracesCount++
|
14
|
+
return () => {
|
15
|
+
hiTrace.finishTrace(name, 0)
|
16
|
+
this.activeTracesCount--
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
public getActiveTracesCount(): number {
|
21
|
+
return this.activeTracesCount
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
export class DevelopmentRNGHLogger implements RNGHLogger {
|
5
26
|
constructor(
|
6
|
-
|
7
|
-
|
27
|
+
protected rnohLogger: RNOHContext['logger'],
|
28
|
+
protected prefix: string,
|
29
|
+
protected tracer: Tracer = new Tracer(),
|
8
30
|
) {
|
9
31
|
}
|
10
32
|
|
11
33
|
error(msg: string) {
|
12
|
-
this.
|
34
|
+
this.log("error", msg);
|
35
|
+
}
|
36
|
+
|
37
|
+
warn(msg: string) {
|
38
|
+
this.log("warn", msg);
|
13
39
|
}
|
14
40
|
|
15
41
|
info(msg: string) {
|
16
|
-
this.
|
42
|
+
this.log("info", msg);
|
17
43
|
}
|
18
44
|
|
19
45
|
debug(msg: RNGHLoggerMessage) {
|
20
|
-
this.
|
46
|
+
this.log("debug", typeof msg === "string" ? msg : JSON.stringify(msg));
|
47
|
+
}
|
48
|
+
|
49
|
+
protected log(type: "debug" | "info" | "warn" | "error", msg: string, offset: number | undefined = undefined) {
|
50
|
+
this.rnohLogger[type](" ".repeat(offset ?? this.tracer.getActiveTracesCount() * 2),
|
51
|
+
`${this.prefix}: ${this.stringifyMsg(msg)}`)
|
52
|
+
}
|
53
|
+
|
54
|
+
startTracing(): () => void {
|
55
|
+
const startTime = Date.now()
|
56
|
+
const currentOffset = this.tracer.getActiveTracesCount() * 2
|
57
|
+
this.log("debug", "START", currentOffset)
|
58
|
+
const stopTrace = this.tracer.startTrace(this.prefix)
|
59
|
+
return () => {
|
60
|
+
stopTrace()
|
61
|
+
const stopTime = Date.now()
|
62
|
+
const durationInMs = stopTime - startTime
|
63
|
+
if (durationInMs < 16) {
|
64
|
+
this.log("debug", "STOP", currentOffset)
|
65
|
+
} else {
|
66
|
+
this.log("debug", `STOP (${durationInMs} ms)`, currentOffset)
|
67
|
+
}
|
68
|
+
}
|
21
69
|
}
|
22
70
|
|
23
71
|
private stringifyMsg(msg: RNGHLoggerMessage): string {
|
@@ -28,22 +76,32 @@ export class StandardRNGHLogger implements RNGHLogger {
|
|
28
76
|
}
|
29
77
|
}
|
30
78
|
|
31
|
-
|
32
|
-
return new
|
79
|
+
cloneAndJoinPrefix(prefix: string) {
|
80
|
+
return new DevelopmentRNGHLogger(this.rnohLogger, `${this.prefix}::${prefix}`, this.tracer);
|
33
81
|
}
|
34
82
|
}
|
35
83
|
|
36
|
-
export class
|
37
|
-
|
84
|
+
export class ProductionRNGHLogger extends DevelopmentRNGHLogger {
|
85
|
+
override debug(msg: string) {
|
86
|
+
// NOOP
|
38
87
|
}
|
39
88
|
|
40
|
-
|
89
|
+
override cloneAndJoinPrefix(prefix: string) {
|
90
|
+
return new ProductionRNGHLogger(this.rnohLogger, `${this.prefix}::${prefix}`, this.tracer);
|
41
91
|
}
|
42
92
|
|
43
|
-
|
44
|
-
|
93
|
+
override startTracing(): () => void {
|
94
|
+
const startTime = Date.now()
|
95
|
+
const currentOffset = this.tracer.getActiveTracesCount() * 2
|
45
96
|
|
46
|
-
|
47
|
-
return
|
97
|
+
const stopTrace = this.tracer.startTrace(this.prefix)
|
98
|
+
return () => {
|
99
|
+
stopTrace()
|
100
|
+
const stopTime = Date.now()
|
101
|
+
const durationInMs = stopTime - startTime
|
102
|
+
if (durationInMs > 16) {
|
103
|
+
this.log("warn", `STOP (${durationInMs} ms)`, currentOffset)
|
104
|
+
}
|
105
|
+
}
|
48
106
|
}
|
49
|
-
}
|
107
|
+
}
|
@@ -1,71 +1,94 @@
|
|
1
1
|
import { RNInstance } from '@rnoh/react-native-openharmony/ts';
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
OutgoingEventDispatcher,
|
4
|
+
GestureStateChangeEvent,
|
5
|
+
GestureUpdateEvent,
|
6
|
+
GestureTouchEvent,
|
7
|
+
RNGHLogger
|
8
|
+
} from "../core"
|
3
9
|
|
4
10
|
export class JSEventDispatcher implements OutgoingEventDispatcher {
|
5
|
-
|
11
|
+
private logger: RNGHLogger
|
12
|
+
|
13
|
+
constructor(private rnInstance: RNInstance, logger: RNGHLogger) {
|
14
|
+
this.logger = logger.cloneAndJoinPrefix("JSEventDispatcher")
|
6
15
|
}
|
7
16
|
|
8
17
|
public onGestureHandlerStateChange(event: GestureStateChangeEvent) {
|
9
|
-
this.logger.
|
18
|
+
const stopTracing = this.logger.cloneAndJoinPrefix(`onGestureHandlerStateChange`).startTracing();
|
10
19
|
this.rnInstance.emitDeviceEvent('onGestureHandlerStateChange', event);
|
20
|
+
stopTracing()
|
11
21
|
}
|
12
22
|
|
13
23
|
public onGestureHandlerEvent(
|
14
24
|
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
15
25
|
) {
|
16
|
-
this.logger.
|
26
|
+
const stopTracing = this.logger.cloneAndJoinPrefix(`onGestureHandlerEvent`).startTracing();
|
17
27
|
this.rnInstance.emitDeviceEvent('onGestureHandlerEvent', event);
|
28
|
+
stopTracing()
|
18
29
|
}
|
19
30
|
}
|
20
31
|
|
21
32
|
export class AnimatedEventDispatcher implements OutgoingEventDispatcher {
|
33
|
+
private logger: RNGHLogger
|
34
|
+
|
22
35
|
constructor(
|
23
36
|
private rnInstance: RNInstance,
|
24
|
-
|
37
|
+
logger: RNGHLogger,
|
25
38
|
private viewTag: number,
|
26
|
-
) {
|
39
|
+
) {
|
40
|
+
this.logger = logger.cloneAndJoinPrefix("AnimatedEventDispatcher")
|
41
|
+
}
|
27
42
|
|
28
43
|
public onGestureHandlerStateChange(event: GestureStateChangeEvent) {
|
29
|
-
this.logger.
|
44
|
+
const stopTracing = this.logger.cloneAndJoinPrefix(`onGestureHandlerStateChange`).startTracing()
|
30
45
|
this.rnInstance.emitDeviceEvent('onGestureHandlerStateChange', event);
|
46
|
+
stopTracing()
|
31
47
|
}
|
32
48
|
|
33
49
|
public onGestureHandlerEvent(
|
34
50
|
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
35
51
|
) {
|
36
|
-
this.logger.
|
52
|
+
const stopTracing = this.logger.cloneAndJoinPrefix(`onGestureHandlerEvent`).startTracing();
|
37
53
|
this.rnInstance.emitComponentEvent(
|
38
54
|
this.viewTag,
|
39
55
|
'onGestureHandlerEvent',
|
40
56
|
event,
|
41
57
|
);
|
58
|
+
stopTracing()
|
42
59
|
}
|
43
60
|
}
|
44
61
|
|
45
62
|
export class ReanimatedEventDispatcher implements OutgoingEventDispatcher {
|
63
|
+
private logger: RNGHLogger
|
64
|
+
|
46
65
|
constructor(
|
47
66
|
private rnInstance: RNInstance,
|
48
|
-
|
67
|
+
logger: RNGHLogger,
|
49
68
|
private viewTag: number,
|
50
|
-
) {
|
69
|
+
) {
|
70
|
+
this.logger = logger.cloneAndJoinPrefix("ReanimatedEventDispatcher")
|
71
|
+
}
|
51
72
|
|
52
73
|
public onGestureHandlerStateChange(event: GestureStateChangeEvent) {
|
53
|
-
this.logger.
|
74
|
+
const stopTracing = this.logger.cloneAndJoinPrefix(`onGestureHandlerStateChange`).startTracing();
|
54
75
|
this.rnInstance.emitComponentEvent(
|
55
76
|
this.viewTag,
|
56
77
|
'onGestureHandlerStateChange',
|
57
78
|
event,
|
58
79
|
);
|
80
|
+
stopTracing()
|
59
81
|
}
|
60
82
|
|
61
83
|
public onGestureHandlerEvent(
|
62
84
|
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
63
85
|
) {
|
64
|
-
this.logger.
|
86
|
+
const stopTracing = this.logger.cloneAndJoinPrefix(`onGestureHandlerEvent`).startTracing();
|
65
87
|
this.rnInstance.emitComponentEvent(
|
66
88
|
this.viewTag,
|
67
89
|
'onGestureHandlerEvent',
|
68
90
|
event,
|
69
91
|
);
|
92
|
+
stopTracing()
|
70
93
|
}
|
71
94
|
}
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import { TouchEvent as TouchEventArkTS, TouchType, TouchObject } from './types';
|
2
|
+
import { RNGHLogger, View, Multiset, GestureHandlerRegistry } from '../core';
|
3
|
+
import { RawTouchableView } from "./RNGHView"
|
4
|
+
import { RNGHViewController } from './RNGHViewController';
|
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 the root to the leaf which contain within their boundaries the touch point specified by `actionTouch`. */
|
19
|
+
touchableViews: RawTouchableView[]
|
20
|
+
};
|
21
|
+
|
22
|
+
|
23
|
+
const areRawTouchPointsEqual = (a: RawTouchPoint, b: RawTouchPoint) =>
|
24
|
+
a.pointerId === b.pointerId &&
|
25
|
+
a.windowX === b.windowX &&
|
26
|
+
a.windowY === b.windowY;
|
27
|
+
|
28
|
+
|
29
|
+
export class RNGHRootViewController {
|
30
|
+
private logger: RNGHLogger;
|
31
|
+
// This multiset keeps track of touchable views that were detected
|
32
|
+
// at the beginning of the gesture to ensure they aren't overridden
|
33
|
+
// during move touch events, which could prevent the gesture handler
|
34
|
+
// from updating its state correctly.
|
35
|
+
private touchableViewsMultiset: Multiset<View> = new Multiset();
|
36
|
+
private viewControllerByViewTag: Map<number, RNGHViewController> =
|
37
|
+
new Map(); // TODO: remove entry when view is removed
|
38
|
+
/**
|
39
|
+
* A view is ACTIVE, if it recently received POINTER_DOWN event
|
40
|
+
*/
|
41
|
+
private activeViewTags = new Set<number>();
|
42
|
+
|
43
|
+
constructor(
|
44
|
+
logger: RNGHLogger,
|
45
|
+
private gestureHandlerRegistry: GestureHandlerRegistry
|
46
|
+
) {
|
47
|
+
this.logger = logger.cloneAndJoinPrefix('RNGHRootTouchHandlerCAPI');
|
48
|
+
}
|
49
|
+
|
50
|
+
handleTouch(rawTouchEvent: RawTouchEvent, touchableViews: View[]) {
|
51
|
+
/**
|
52
|
+
* NOTE: TouchEventArkTS was used in ArkTS RNOH architecture. Currently only C-API architecture is supported.
|
53
|
+
*/
|
54
|
+
const touchEvent = rawTouchEventToTouchEventArkTS(rawTouchEvent);
|
55
|
+
if (touchEvent.type === TouchType.Down) {
|
56
|
+
touchableViews.forEach(view => this.touchableViewsMultiset.add(view));
|
57
|
+
}
|
58
|
+
const e = touchEvent;
|
59
|
+
if (e.type === TouchType.Down) {
|
60
|
+
this.activeViewTags.clear();
|
61
|
+
}
|
62
|
+
const views = touchableViews
|
63
|
+
for (const view of views) {
|
64
|
+
for (const handler of this.gestureHandlerRegistry.getGestureHandlersByViewTag(
|
65
|
+
view.getTag(),
|
66
|
+
)) {
|
67
|
+
this.logger.info(
|
68
|
+
`Found GestureHandler ${handler.getTag()} for view ${view.getTag()}`,
|
69
|
+
);
|
70
|
+
|
71
|
+
// create view touch handler if necessary
|
72
|
+
if (!this.viewControllerByViewTag.has(view.getTag())) {
|
73
|
+
this.viewControllerByViewTag.set(
|
74
|
+
view.getTag(),
|
75
|
+
new RNGHViewController(
|
76
|
+
view,
|
77
|
+
this.logger,
|
78
|
+
),
|
79
|
+
);
|
80
|
+
}
|
81
|
+
|
82
|
+
// attach handler (there might be multiple handlers per view)
|
83
|
+
this.viewControllerByViewTag.get(view.getTag())!.attachGestureHandler(handler) // TODO: detachGestureHandler
|
84
|
+
|
85
|
+
// register active view tag
|
86
|
+
if (e.type === TouchType.Down) {
|
87
|
+
this.activeViewTags.add(view.getTag());
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
// send touch to gesture handlers, prioritize handling touch events for child components
|
93
|
+
if (this.activeViewTags.size > 0) {
|
94
|
+
const tags = Array.from(this.activeViewTags);
|
95
|
+
for (let i = tags.length - 1; i >= 0; i--) {
|
96
|
+
const tag = tags[i];
|
97
|
+
const viewController = this.viewControllerByViewTag.get(tag);
|
98
|
+
if (viewController) {
|
99
|
+
viewController.handleTouch(e);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
if (touchEvent.type === TouchType.Up || touchEvent.type === TouchType.Cancel) {
|
106
|
+
touchableViews.forEach(view => this.touchableViewsMultiset.remove(view));
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
cancelTouches() {
|
111
|
+
for (const activeViewTag of this.activeViewTags) {
|
112
|
+
this.gestureHandlerRegistry.getGestureHandlersByViewTag(activeViewTag).forEach(gh => {
|
113
|
+
gh.cancel()
|
114
|
+
gh.reset()
|
115
|
+
})
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
const CACHED_RAW_TOUCH_POINT_BY_POINTER_ID = new Map<number, RawTouchPoint>();
|
122
|
+
let LAST_CHANGED_POINTER_ID: number | null = null;
|
123
|
+
const MAX_CACHE_SIZE = 10;
|
124
|
+
|
125
|
+
function rawTouchEventToTouchEventArkTS(raw: RawTouchEvent): TouchEventArkTS {
|
126
|
+
const touchType = touchTypeFromAction(raw.action);
|
127
|
+
const actionTouch = raw.actionTouch;
|
128
|
+
|
129
|
+
let lastChangedTouch: RawTouchPoint = actionTouch;
|
130
|
+
if (CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.has(actionTouch.pointerId)) {
|
131
|
+
if (!areRawTouchPointsEqual(actionTouch,
|
132
|
+
CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.get(actionTouch.pointerId) as RawTouchPoint)) {
|
133
|
+
LAST_CHANGED_POINTER_ID = actionTouch.pointerId;
|
134
|
+
CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.set(actionTouch.pointerId, actionTouch);
|
135
|
+
}
|
136
|
+
} else {
|
137
|
+
// remove first element if the cache is full
|
138
|
+
if (CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.size >= MAX_CACHE_SIZE) {
|
139
|
+
CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.delete(CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.keys().next().value);
|
140
|
+
}
|
141
|
+
LAST_CHANGED_POINTER_ID = actionTouch.pointerId;
|
142
|
+
CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.set(actionTouch.pointerId, actionTouch);
|
143
|
+
}
|
144
|
+
lastChangedTouch = CACHED_RAW_TOUCH_POINT_BY_POINTER_ID.get(LAST_CHANGED_POINTER_ID as number) as RawTouchPoint
|
145
|
+
return {
|
146
|
+
type: touchTypeFromAction(raw.action),
|
147
|
+
touches: raw.touchPoints.map(tp =>
|
148
|
+
touchObjectFromTouchPoint(tp, touchType),
|
149
|
+
),
|
150
|
+
changedTouches: [
|
151
|
+
touchObjectFromTouchPoint(lastChangedTouch, touchType),
|
152
|
+
],
|
153
|
+
timestamp: raw.timestamp / Math.pow(10, 6),
|
154
|
+
};
|
155
|
+
}
|
156
|
+
|
157
|
+
function touchTypeFromAction(action: number): TouchType {
|
158
|
+
switch (action) {
|
159
|
+
case 1:
|
160
|
+
return TouchType.Down;
|
161
|
+
case 2:
|
162
|
+
return TouchType.Move;
|
163
|
+
case 3:
|
164
|
+
return TouchType.Up;
|
165
|
+
default:
|
166
|
+
return TouchType.Cancel;
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
function touchObjectFromTouchPoint(
|
171
|
+
touchPoint: RawTouchPoint,
|
172
|
+
touchType: TouchType,
|
173
|
+
): TouchObject {
|
174
|
+
return {
|
175
|
+
id: touchPoint.pointerId,
|
176
|
+
windowX: touchPoint.windowX,
|
177
|
+
windowY: touchPoint.windowY,
|
178
|
+
x: touchPoint.windowX,
|
179
|
+
y: touchPoint.windowY,
|
180
|
+
type: touchType,
|
181
|
+
};
|
182
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { View, BoundingBox } from "../core"
|
2
|
+
|
3
|
+
|
4
|
+
export type RawTouchableView = {
|
5
|
+
tag: number,
|
6
|
+
/**
|
7
|
+
* Relative to application window.
|
8
|
+
*/
|
9
|
+
x: number,
|
10
|
+
/**
|
11
|
+
* Relative to application window.
|
12
|
+
*/
|
13
|
+
y: number,
|
14
|
+
width: number,
|
15
|
+
height: number,
|
16
|
+
buttonRole: boolean,
|
17
|
+
}
|
18
|
+
|
19
|
+
export class RNGHView implements View {
|
20
|
+
private tag: number
|
21
|
+
private buttonRole: boolean
|
22
|
+
private boundingBox: BoundingBox
|
23
|
+
|
24
|
+
constructor({ tag, buttonRole, ...boundingBox }: RawTouchableView) {
|
25
|
+
this.tag = tag
|
26
|
+
this.buttonRole = buttonRole
|
27
|
+
this.boundingBox = boundingBox
|
28
|
+
}
|
29
|
+
|
30
|
+
getTag(): number {
|
31
|
+
return this.tag
|
32
|
+
}
|
33
|
+
|
34
|
+
getBoundingRect(): BoundingBox {
|
35
|
+
return { ...this.boundingBox }
|
36
|
+
}
|
37
|
+
|
38
|
+
isPositionInBounds({ x, y }: {
|
39
|
+
x: number;
|
40
|
+
y: number
|
41
|
+
}): boolean {
|
42
|
+
const rect = this.getBoundingRect();
|
43
|
+
return (
|
44
|
+
x >= rect.x &&
|
45
|
+
x <= rect.x + rect.width &&
|
46
|
+
y >= rect.y &&
|
47
|
+
y <= rect.y + rect.height
|
48
|
+
);
|
49
|
+
}
|
50
|
+
|
51
|
+
updateBoundingBox(boundingBox: BoundingBox) {
|
52
|
+
this.boundingBox = boundingBox
|
53
|
+
}
|
54
|
+
|
55
|
+
setButtonRole(buttonRole: boolean) {
|
56
|
+
this.buttonRole = buttonRole
|
57
|
+
}
|
58
|
+
|
59
|
+
hasButtonRole(): boolean {
|
60
|
+
return this.buttonRole
|
61
|
+
}
|
62
|
+
}
|
@@ -11,15 +11,16 @@ import {
|
|
11
11
|
} from '../core';
|
12
12
|
import { TouchEvent, TouchType, TouchObject } from './types';
|
13
13
|
|
14
|
-
|
14
|
+
|
15
|
+
export class RNGHViewController {
|
15
16
|
private activePointerIds = new Set<number>();
|
16
|
-
private
|
17
|
+
private pointerIdsInBounds = new Set<number>();
|
17
18
|
private gestureHandlers = new Set<GestureHandler>();
|
18
19
|
private view: View;
|
19
20
|
private logger: RNGHLogger;
|
20
21
|
|
21
22
|
constructor(view: View, logger: RNGHLogger) {
|
22
|
-
this.logger = logger.
|
23
|
+
this.logger = logger.cloneAndJoinPrefix(`RNGHViewTouchHandler`)
|
23
24
|
this.view = view;
|
24
25
|
}
|
25
26
|
|
@@ -28,19 +29,23 @@ export class GestureHandlerArkUIAdapter {
|
|
28
29
|
}
|
29
30
|
|
30
31
|
handleTouch(e: TouchEvent) {
|
32
|
+
const logger = this.logger.cloneAndJoinPrefix("handleTouch")
|
31
33
|
for (const changedTouch of e.changedTouches) {
|
32
|
-
if (this.shouldSkipTouch(changedTouch))
|
33
|
-
|
34
|
+
if (this.shouldSkipTouch(changedTouch)) {
|
35
|
+
continue;
|
36
|
+
}
|
37
|
+
const wasInBounds = this.pointerIdsInBounds.has(changedTouch.id);
|
34
38
|
const isInBounds = this.isInBounds({
|
35
39
|
x: changedTouch.windowX,
|
36
40
|
y: changedTouch.windowY,
|
37
41
|
});
|
38
|
-
|
39
|
-
|
42
|
+
logger.debug(
|
43
|
+
{
|
44
|
+
viewTag: this.view.getTag(),
|
40
45
|
type: changedTouch.type,
|
41
46
|
wasInBounds,
|
42
47
|
isInBounds,
|
43
|
-
}
|
48
|
+
},
|
44
49
|
);
|
45
50
|
const adaptedEvent = this.adaptTouchEvent(e, changedTouch);
|
46
51
|
this.gestureHandlers.forEach(gh => {
|
@@ -58,9 +63,11 @@ export class GestureHandlerArkUIAdapter {
|
|
58
63
|
gh.onAdditionalPointerRemove(adaptedEvent);
|
59
64
|
break;
|
60
65
|
case EventType.MOVE:
|
61
|
-
if (!wasInBounds && !isInBounds)
|
66
|
+
if (!wasInBounds && !isInBounds) {
|
62
67
|
gh.onPointerOutOfBounds(adaptedEvent);
|
63
|
-
else
|
68
|
+
} else {
|
69
|
+
gh.onPointerMove(adaptedEvent);
|
70
|
+
}
|
64
71
|
break;
|
65
72
|
case EventType.ENTER:
|
66
73
|
gh.onPointerEnter(adaptedEvent);
|
@@ -97,9 +104,10 @@ export class GestureHandlerArkUIAdapter {
|
|
97
104
|
changedTouch.type,
|
98
105
|
this.isInBounds({ x: xAbsolute, y: yAbsolute }),
|
99
106
|
changedTouch.id,
|
100
|
-
this.
|
107
|
+
this.pointerIdsInBounds.has(changedTouch.id),
|
101
108
|
);
|
102
|
-
this.logger.
|
109
|
+
this.logger.cloneAndJoinPrefix("adaptTouchEvent")
|
110
|
+
.debug({ eventType, activePointersCount: this.activePointerIds.size })
|
103
111
|
this.updateIsInBoundsByPointerId(
|
104
112
|
changedTouch.type,
|
105
113
|
changedTouch.id,
|
@@ -133,17 +141,25 @@ export class GestureHandlerArkUIAdapter {
|
|
133
141
|
) {
|
134
142
|
switch (touchType) {
|
135
143
|
case TouchType.Down:
|
136
|
-
if (this.isInBounds({ x, y }))
|
144
|
+
if (this.isInBounds({ x, y })) {
|
145
|
+
this.pointerIdsInBounds.add(pointerId);
|
146
|
+
}
|
137
147
|
break;
|
138
148
|
case TouchType.Move:
|
139
|
-
if (this.isInBounds({
|
140
|
-
|
149
|
+
if (this.isInBounds({
|
150
|
+
x,
|
151
|
+
y
|
152
|
+
})) {
|
153
|
+
this.pointerIdsInBounds.add(pointerId);
|
154
|
+
} else {
|
155
|
+
this.pointerIdsInBounds.delete(pointerId);
|
156
|
+
}
|
141
157
|
break;
|
142
158
|
case TouchType.Up:
|
143
|
-
this.
|
159
|
+
this.pointerIdsInBounds.delete(pointerId);
|
144
160
|
break;
|
145
161
|
case TouchType.Cancel:
|
146
|
-
this.
|
162
|
+
this.pointerIdsInBounds.delete(pointerId);
|
147
163
|
break;
|
148
164
|
}
|
149
165
|
}
|
@@ -152,7 +168,7 @@ export class GestureHandlerArkUIAdapter {
|
|
152
168
|
const x = point.x;
|
153
169
|
const y = point.y;
|
154
170
|
const rect = this.view.getBoundingRect();
|
155
|
-
this.logger.
|
171
|
+
this.logger.cloneAndJoinPrefix("isInBounds").debug({ rect })
|
156
172
|
const result =
|
157
173
|
x >= rect.x &&
|
158
174
|
x <= rect.x + rect.width &&
|
@@ -204,11 +220,17 @@ export class GestureHandlerArkUIAdapter {
|
|
204
220
|
|
205
221
|
switch (touchType) {
|
206
222
|
case TouchType.Down:
|
207
|
-
if (activePointersCount > 0)
|
208
|
-
|
223
|
+
if (activePointersCount > 0) {
|
224
|
+
return EventType.ADDITIONAL_POINTER_DOWN;
|
225
|
+
} else {
|
226
|
+
return EventType.DOWN;
|
227
|
+
}
|
209
228
|
case TouchType.Up:
|
210
|
-
if (activePointersCount > 1)
|
211
|
-
|
229
|
+
if (activePointersCount > 1) {
|
230
|
+
return EventType.ADDITIONAL_POINTER_UP;
|
231
|
+
} else {
|
232
|
+
return EventType.UP;
|
233
|
+
}
|
212
234
|
case TouchType.Move:
|
213
235
|
if (isCurrentlyInBounds) {
|
214
236
|
return wasInBounds ? EventType.MOVE : EventType.ENTER;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { Tag, } from '@rnoh/react-native-openharmony/ts';
|
2
|
+
import { View, ViewRegistry } from '../core';
|
3
|
+
|
4
|
+
|
5
|
+
export class RNGHViewRegistry implements ViewRegistry {
|
6
|
+
private viewByTag = new Map<Tag, View>()
|
7
|
+
|
8
|
+
save(view: View) {
|
9
|
+
this.viewByTag.set(view.getTag(), view)
|
10
|
+
}
|
11
|
+
|
12
|
+
deleteByTag(viewTag: Tag) {
|
13
|
+
this.viewByTag.delete(viewTag)
|
14
|
+
}
|
15
|
+
|
16
|
+
getViewByTag(viewTag: Tag) {
|
17
|
+
return this.viewByTag.get(viewTag);
|
18
|
+
}
|
19
|
+
}
|