basalt-core 0.0.0-rc5
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/LICENSE +21 -0
- package/dist/cli/basalt.d.ts +3 -0
- package/dist/cli/basalt.d.ts.map +1 -0
- package/dist/cli/basalt.js +47 -0
- package/dist/cli/basalt.js.map +1 -0
- package/dist/cli/bundle-cli.d.ts +12 -0
- package/dist/cli/bundle-cli.d.ts.map +1 -0
- package/dist/cli/bundle-cli.js +124 -0
- package/dist/cli/bundle-cli.js.map +1 -0
- package/dist/cli/bundleWithAssets.d.ts +79 -0
- package/dist/cli/bundleWithAssets.d.ts.map +1 -0
- package/dist/cli/bundleWithAssets.js +198 -0
- package/dist/cli/bundleWithAssets.js.map +1 -0
- package/dist/cli/desktop.d.ts +339 -0
- package/dist/cli/desktop.d.ts.map +1 -0
- package/dist/cli/desktop.js +1029 -0
- package/dist/cli/desktop.js.map +1 -0
- package/dist/cli/doctor.d.ts +31 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +283 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts +77 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +442 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/metro.d.ts +49 -0
- package/dist/cli/metro.d.ts.map +1 -0
- package/dist/cli/metro.js +148 -0
- package/dist/cli/metro.js.map +1 -0
- package/dist/cli/packageApp.d.ts +102 -0
- package/dist/cli/packageApp.d.ts.map +1 -0
- package/dist/cli/packageApp.js +319 -0
- package/dist/cli/packageApp.js.map +1 -0
- package/dist/cli/steps.d.ts +34 -0
- package/dist/cli/steps.d.ts.map +1 -0
- package/dist/cli/steps.js +53 -0
- package/dist/cli/steps.js.map +1 -0
- package/dist/metro-config.d.ts +168 -0
- package/dist/metro-config.d.ts.map +1 -0
- package/dist/metro-config.js +671 -0
- package/dist/metro-config.js.map +1 -0
- package/dist/react-native.config.d.ts +7 -0
- package/dist/react-native.config.d.ts.map +1 -0
- package/dist/react-native.config.js +80 -0
- package/dist/react-native.config.js.map +1 -0
- package/dist/src/DragSource.d.ts +52 -0
- package/dist/src/DragSource.d.ts.map +1 -0
- package/dist/src/DragSource.js +97 -0
- package/dist/src/DragSource.js.map +1 -0
- package/dist/src/DropTarget.d.ts +58 -0
- package/dist/src/DropTarget.d.ts.map +1 -0
- package/dist/src/DropTarget.js +131 -0
- package/dist/src/DropTarget.js.map +1 -0
- package/dist/src/KeyHandler.d.ts +57 -0
- package/dist/src/KeyHandler.d.ts.map +1 -0
- package/dist/src/KeyHandler.js +48 -0
- package/dist/src/KeyHandler.js.map +1 -0
- package/dist/src/Menu.d.ts +72 -0
- package/dist/src/Menu.d.ts.map +1 -0
- package/dist/src/Menu.js +179 -0
- package/dist/src/Menu.js.map +1 -0
- package/dist/src/TitleBar.d.ts +75 -0
- package/dist/src/TitleBar.d.ts.map +1 -0
- package/dist/src/TitleBar.js +236 -0
- package/dist/src/TitleBar.js.map +1 -0
- package/dist/src/Window.d.ts +87 -0
- package/dist/src/Window.d.ts.map +1 -0
- package/dist/src/Window.js +248 -0
- package/dist/src/Window.js.map +1 -0
- package/dist/src/closeRequest.d.ts +55 -0
- package/dist/src/closeRequest.d.ts.map +1 -0
- package/dist/src/closeRequest.js +134 -0
- package/dist/src/closeRequest.js.map +1 -0
- package/dist/src/index.d.ts +45 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +92 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/overrides/Alert.d.ts +69 -0
- package/dist/src/overrides/Alert.d.ts.map +1 -0
- package/dist/src/overrides/Alert.js +112 -0
- package/dist/src/overrides/Alert.js.map +1 -0
- package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
- package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
- package/dist/src/overrides/BaseViewConfig.js +72 -0
- package/dist/src/overrides/BaseViewConfig.js.map +1 -0
- package/dist/src/overrides/Platform.linux.d.ts +10 -0
- package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
- package/dist/src/overrides/Platform.linux.js +15 -0
- package/dist/src/overrides/Platform.linux.js.map +1 -0
- package/dist/src/overrides/Platform.macos.d.ts +10 -0
- package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
- package/dist/src/overrides/Platform.macos.js +15 -0
- package/dist/src/overrides/Platform.macos.js.map +1 -0
- package/dist/src/overrides/Platform.windows.d.ts +10 -0
- package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
- package/dist/src/overrides/Platform.windows.js +15 -0
- package/dist/src/overrides/Platform.windows.js.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
- package/dist/src/overrides/RefreshControl.d.ts +52 -0
- package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
- package/dist/src/overrides/RefreshControl.js +92 -0
- package/dist/src/overrides/RefreshControl.js.map +1 -0
- package/dist/src/overrides/ScrollView.d.ts +39 -0
- package/dist/src/overrides/ScrollView.d.ts.map +1 -0
- package/dist/src/overrides/ScrollView.js +59 -0
- package/dist/src/overrides/ScrollView.js.map +1 -0
- package/dist/src/overrides/Share.d.ts +96 -0
- package/dist/src/overrides/Share.d.ts.map +1 -0
- package/dist/src/overrides/Share.js +97 -0
- package/dist/src/overrides/Share.js.map +1 -0
- package/dist/src/overrides/TextInput.d.ts +81 -0
- package/dist/src/overrides/TextInput.d.ts.map +1 -0
- package/dist/src/overrides/TextInput.js +213 -0
- package/dist/src/overrides/TextInput.js.map +1 -0
- package/dist/src/overrides/View.d.ts +36 -0
- package/dist/src/overrides/View.d.ts.map +1 -0
- package/dist/src/overrides/View.js +99 -0
- package/dist/src/overrides/View.js.map +1 -0
- package/dist/src/overrides/createPlatform.d.ts +32 -0
- package/dist/src/overrides/createPlatform.d.ts.map +1 -0
- package/dist/src/overrides/createPlatform.js +84 -0
- package/dist/src/overrides/createPlatform.js.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.js +84 -0
- package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
- package/dist/src/overrides/setUpXHR.d.ts +46 -0
- package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
- package/dist/src/overrides/setUpXHR.js +236 -0
- package/dist/src/overrides/setUpXHR.js.map +1 -0
- package/dist/src/quitRequest.d.ts +55 -0
- package/dist/src/quitRequest.d.ts.map +1 -0
- package/dist/src/quitRequest.js +121 -0
- package/dist/src/quitRequest.js.map +1 -0
- package/dist/src/resourcePath.d.ts +18 -0
- package/dist/src/resourcePath.d.ts.map +1 -0
- package/dist/src/resourcePath.js +31 -0
- package/dist/src/resourcePath.js.map +1 -0
- package/dist/src/responseBody.d.ts +76 -0
- package/dist/src/responseBody.d.ts.map +1 -0
- package/dist/src/responseBody.js +94 -0
- package/dist/src/responseBody.js.map +1 -0
- package/dist/src/responseHeaders.d.ts +40 -0
- package/dist/src/responseHeaders.d.ts.map +1 -0
- package/dist/src/responseHeaders.js +75 -0
- package/dist/src/responseHeaders.js.map +1 -0
- package/dist/src/titleBarState.d.ts +43 -0
- package/dist/src/titleBarState.d.ts.map +1 -0
- package/dist/src/titleBarState.js +77 -0
- package/dist/src/titleBarState.js.map +1 -0
- package/dist/src/useContextMenu.d.ts +113 -0
- package/dist/src/useContextMenu.d.ts.map +1 -0
- package/dist/src/useContextMenu.js +109 -0
- package/dist/src/useContextMenu.js.map +1 -0
- package/dist/src/useDialog.d.ts +98 -0
- package/dist/src/useDialog.d.ts.map +1 -0
- package/dist/src/useDialog.js +112 -0
- package/dist/src/useDialog.js.map +1 -0
- package/dist/src/useDisplays.d.ts +70 -0
- package/dist/src/useDisplays.d.ts.map +1 -0
- package/dist/src/useDisplays.js +118 -0
- package/dist/src/useDisplays.js.map +1 -0
- package/dist/src/useHandledKeys.d.ts +38 -0
- package/dist/src/useHandledKeys.d.ts.map +1 -0
- package/dist/src/useHandledKeys.js +70 -0
- package/dist/src/useHandledKeys.js.map +1 -0
- package/dist/src/useWindow.d.ts +140 -0
- package/dist/src/useWindow.d.ts.map +1 -0
- package/dist/src/useWindow.js +233 -0
- package/dist/src/useWindow.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/native/CMakeLists.txt +355 -0
- package/native/bootstrap.sh +613 -0
- package/native/cmake/CompilerFlags.cmake +49 -0
- package/native/cmake/Expo.cmake +125 -0
- package/native/cmake/ReactNativeCore.cmake +612 -0
- package/native/cmake/Reanimated.cmake +108 -0
- package/native/cmake/Skia.cmake +379 -0
- package/native/cmake/ThirdParty.cmake +290 -0
- package/native/cmake/Worklets.cmake +67 -0
- package/native/cmake/codegen/CMakeLists.txt +32 -0
- package/native/core/AppIdentity.cpp +85 -0
- package/native/core/AppIdentity.h +59 -0
- package/native/core/AppPaths.cpp +96 -0
- package/native/core/AppPaths.h +53 -0
- package/native/core/AppearanceModule.cpp +60 -0
- package/native/core/AppearanceModule.h +40 -0
- package/native/core/Backface.h +59 -0
- package/native/core/BlobModule.cpp +283 -0
- package/native/core/BlobModule.h +76 -0
- package/native/core/BlobRegistry.cpp +75 -0
- package/native/core/BlobRegistry.h +44 -0
- package/native/core/ColorScheme.cpp +105 -0
- package/native/core/ColorScheme.h +59 -0
- package/native/core/ComponentRegistry.h +30 -0
- package/native/core/ControlMetrics.h +37 -0
- package/native/core/CoreModules.cpp +592 -0
- package/native/core/CoreModules.h +308 -0
- package/native/core/DebuggingOverlay.cpp +106 -0
- package/native/core/DebuggingOverlay.h +65 -0
- package/native/core/DesktopControls.cpp +232 -0
- package/native/core/DesktopControls.h +170 -0
- package/native/core/DevBundle.cpp +108 -0
- package/native/core/DevBundle.h +69 -0
- package/native/core/DevMenu.cpp +99 -0
- package/native/core/DevMenu.h +75 -0
- package/native/core/DialogModule.cpp +150 -0
- package/native/core/DialogModule.h +51 -0
- package/native/core/DragAndDrop.cpp +45 -0
- package/native/core/DragAndDrop.h +225 -0
- package/native/core/ExpoImageComponent.cpp +79 -0
- package/native/core/ExpoImageComponent.h +80 -0
- package/native/core/ExpoModules.cpp +415 -0
- package/native/core/ExpoModules.h +115 -0
- package/native/core/ExpoRuntime.cpp +366 -0
- package/native/core/ExpoRuntime.h +42 -0
- package/native/core/FocusRing.h +36 -0
- package/native/core/FontRegistry.h +51 -0
- package/native/core/GestureHandlerModule.cpp +136 -0
- package/native/core/GestureHandlerModule.h +71 -0
- package/native/core/Gestures.cpp +533 -0
- package/native/core/Gestures.h +145 -0
- package/native/core/HoverTracker.cpp +69 -0
- package/native/core/HoverTracker.h +109 -0
- package/native/core/HttpClient.cpp +282 -0
- package/native/core/ImageBytes.cpp +205 -0
- package/native/core/ImageBytes.h +29 -0
- package/native/core/ImageCache.cpp +51 -0
- package/native/core/ImageCache.h +89 -0
- package/native/core/JsRuntimeAccess.cpp +70 -0
- package/native/core/JsRuntimeAccess.h +60 -0
- package/native/core/JsiPromise.h +51 -0
- package/native/core/KeyEvents.cpp +116 -0
- package/native/core/KeyEvents.h +144 -0
- package/native/core/LogBoxSurface.cpp +46 -0
- package/native/core/LogBoxSurface.h +68 -0
- package/native/core/MenuModel.h +117 -0
- package/native/core/MenuModule.cpp +209 -0
- package/native/core/MenuModule.h +66 -0
- package/native/core/MountingWalk.h +524 -0
- package/native/core/PackageModules.cpp.in +25 -0
- package/native/core/PackageModules.h +50 -0
- package/native/core/PlatformConstantsModule.cpp +63 -0
- package/native/core/PlatformConstantsModule.h +64 -0
- package/native/core/PlatformServices.h +213 -0
- package/native/core/PointerButtons.h +63 -0
- package/native/core/PullToRefresh.cpp +57 -0
- package/native/core/PullToRefresh.h +73 -0
- package/native/core/ReanimatedCompat.h +47 -0
- package/native/core/ReanimatedModule.cpp +203 -0
- package/native/core/ReanimatedModule.h +55 -0
- package/native/core/ScrollAnimation.cpp +59 -0
- package/native/core/ScrollAnimation.h +70 -0
- package/native/core/ScrollBounds.cpp +26 -0
- package/native/core/ScrollBounds.h +68 -0
- package/native/core/ScrollIndicator.cpp +50 -0
- package/native/core/ScrollIndicator.h +69 -0
- package/native/core/ScrollMomentum.cpp +71 -0
- package/native/core/ScrollMomentum.h +73 -0
- package/native/core/ScrollSnap.cpp +123 -0
- package/native/core/ScrollSnap.h +80 -0
- package/native/core/ShareFallback.cpp +101 -0
- package/native/core/ShareFallback.h +45 -0
- package/native/core/SkiaPictureViewComponent.cpp +11 -0
- package/native/core/SkiaPictureViewComponent.h +47 -0
- package/native/core/SourceCodeModule.cpp +55 -0
- package/native/core/SourceCodeModule.h +53 -0
- package/native/core/StatusBarModule.cpp +23 -0
- package/native/core/StatusBarModule.h +42 -0
- package/native/core/TestDialog.cpp +148 -0
- package/native/core/TestDialog.h +96 -0
- package/native/core/TestKeys.cpp +78 -0
- package/native/core/TestKeys.h +50 -0
- package/native/core/TestQuitFile.cpp +33 -0
- package/native/core/TestQuitFile.h +60 -0
- package/native/core/TestSettle.h +192 -0
- package/native/core/TitleBarRegions.h +31 -0
- package/native/core/TurboModuleProxy.cpp +51 -0
- package/native/core/TurboModuleProxy.h +46 -0
- package/native/core/UIManagerAccess.cpp +43 -0
- package/native/core/UIManagerAccess.h +43 -0
- package/native/core/WindowBoundsCache.cpp +319 -0
- package/native/core/WindowControl.h +235 -0
- package/native/core/WindowHost.h +158 -0
- package/native/core/WindowMethods.cpp +167 -0
- package/native/core/WindowMethods.h +84 -0
- package/native/core/WindowsModule.cpp +448 -0
- package/native/core/WindowsModule.h +133 -0
- package/native/core/WorkletsModule.cpp +199 -0
- package/native/core/WorkletsModule.h +57 -0
- package/native/core/portability_probe.cpp +210 -0
- package/native/tests/EventRecorder.h +124 -0
- package/native/tests/TestHarness.cpp +109 -0
- package/native/tests/TestHarness.h +89 -0
- package/native/tests/TreeDump.h +49 -0
- package/native/tests/test_app_identity.cpp +114 -0
- package/native/tests/test_app_paths.cpp +48 -0
- package/native/tests/test_appearance.cpp +107 -0
- package/native/tests/test_backface.cpp +79 -0
- package/native/tests/test_blobs.cpp +157 -0
- package/native/tests/test_controls.cpp +185 -0
- package/native/tests/test_devbundle.cpp +103 -0
- package/native/tests/test_drag_and_drop.cpp +143 -0
- package/native/tests/test_gestures.cpp +331 -0
- package/native/tests/test_hover.cpp +92 -0
- package/native/tests/test_image_cache.cpp +109 -0
- package/native/tests/test_js_runtime_access.cpp +137 -0
- package/native/tests/test_key_events.cpp +235 -0
- package/native/tests/test_momentum.cpp +138 -0
- package/native/tests/test_quit_file.cpp +104 -0
- package/native/tests/test_scroll_animation.cpp +120 -0
- package/native/tests/test_scroll_bounds.cpp +66 -0
- package/native/tests/test_scroll_indicator.cpp +149 -0
- package/native/tests/test_scroll_snap.cpp +112 -0
- package/native/tests/test_settle.cpp +115 -0
- package/native/tests/test_share.cpp +75 -0
- package/native/tests/test_sourcecode.cpp +62 -0
- package/native/tests/test_window_close.cpp +119 -0
- package/native/tests/test_window_limits.cpp +123 -0
- package/package.json +43 -0
- package/react-native.config.js +86 -0
- package/supported-versions.json +66 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// `RNGestureHandlerModule`, the TurboModule react-native-gesture-handler asks
|
|
2
|
+
// for by name.
|
|
3
|
+
//
|
|
4
|
+
// Hand-written rather than generated. Every other module in this project
|
|
5
|
+
// derives from one of React Native's codegenned specs, because React Native
|
|
6
|
+
// ships the specs; a third-party library's spec is generated during *its* build
|
|
7
|
+
// against *an app's* node_modules, and this project's hosts are generic
|
|
8
|
+
// binaries that are not built per app. So the eight methods are declared here
|
|
9
|
+
// against `TurboModule` directly, from the same TypeScript interface codegen
|
|
10
|
+
// would have read.
|
|
11
|
+
//
|
|
12
|
+
// It is registered unconditionally, like every other core module. An app
|
|
13
|
+
// without gesture-handler never looks the name up, and the registry behind it
|
|
14
|
+
// is empty and costs a branch.
|
|
15
|
+
//
|
|
16
|
+
// The module is a thin thing: it converts arguments, hops to the UI thread and
|
|
17
|
+
// calls core/Gestures.h. What it adds is the one piece the engine cannot have,
|
|
18
|
+
// which is a way to reach JavaScript -- RNGH listens on DeviceEventEmitter, and
|
|
19
|
+
// only a TurboModule can emit one.
|
|
20
|
+
|
|
21
|
+
#pragma once
|
|
22
|
+
|
|
23
|
+
#include <ReactCommon/TurboModule.h>
|
|
24
|
+
|
|
25
|
+
#include <folly/dynamic.h>
|
|
26
|
+
|
|
27
|
+
#include <memory>
|
|
28
|
+
#include <string>
|
|
29
|
+
|
|
30
|
+
namespace basalt {
|
|
31
|
+
|
|
32
|
+
class DesktopGestureHandlerModule : public facebook::react::TurboModule {
|
|
33
|
+
public:
|
|
34
|
+
static constexpr const char *kModuleName = "RNGestureHandlerModule";
|
|
35
|
+
|
|
36
|
+
explicit DesktopGestureHandlerModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker);
|
|
37
|
+
~DesktopGestureHandlerModule() override;
|
|
38
|
+
|
|
39
|
+
private:
|
|
40
|
+
// The method table. Each is a plain function because `MethodMetadata::invoker`
|
|
41
|
+
// is a function pointer, not a std::function -- a TurboModule's methods are
|
|
42
|
+
// meant to be static dispatch.
|
|
43
|
+
static facebook::jsi::Value createGestureHandler(facebook::jsi::Runtime &runtime,
|
|
44
|
+
facebook::react::TurboModule &module,
|
|
45
|
+
const facebook::jsi::Value *args,
|
|
46
|
+
size_t count);
|
|
47
|
+
static facebook::jsi::Value attachGestureHandler(facebook::jsi::Runtime &runtime,
|
|
48
|
+
facebook::react::TurboModule &module,
|
|
49
|
+
const facebook::jsi::Value *args,
|
|
50
|
+
size_t count);
|
|
51
|
+
static facebook::jsi::Value updateGestureHandler(facebook::jsi::Runtime &runtime,
|
|
52
|
+
facebook::react::TurboModule &module,
|
|
53
|
+
const facebook::jsi::Value *args,
|
|
54
|
+
size_t count);
|
|
55
|
+
static facebook::jsi::Value dropGestureHandler(facebook::jsi::Runtime &runtime,
|
|
56
|
+
facebook::react::TurboModule &module,
|
|
57
|
+
const facebook::jsi::Value *args,
|
|
58
|
+
size_t count);
|
|
59
|
+
static facebook::jsi::Value install(facebook::jsi::Runtime &runtime,
|
|
60
|
+
facebook::react::TurboModule &module,
|
|
61
|
+
const facebook::jsi::Value *args,
|
|
62
|
+
size_t count);
|
|
63
|
+
static facebook::jsi::Value noop(facebook::jsi::Runtime &runtime,
|
|
64
|
+
facebook::react::TurboModule &module,
|
|
65
|
+
const facebook::jsi::Value *args,
|
|
66
|
+
size_t count);
|
|
67
|
+
|
|
68
|
+
void emitGestureEvent(const std::string &eventName, folly::dynamic payload);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
} // namespace basalt
|
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
#include "Gestures.h"
|
|
2
|
+
|
|
3
|
+
#include "PlatformServices.h"
|
|
4
|
+
|
|
5
|
+
#include <glog/logging.h>
|
|
6
|
+
|
|
7
|
+
#include <algorithm>
|
|
8
|
+
#include <chrono>
|
|
9
|
+
#include <cmath>
|
|
10
|
+
|
|
11
|
+
namespace basalt {
|
|
12
|
+
|
|
13
|
+
namespace {
|
|
14
|
+
|
|
15
|
+
// RNGH's ActionType and PointerType live in its JavaScript; only the two values
|
|
16
|
+
// this side produces are named here.
|
|
17
|
+
constexpr int kPointerTypeMouse = 2;
|
|
18
|
+
|
|
19
|
+
double number(const folly::dynamic &config, const char *key, double fallback) {
|
|
20
|
+
if (!config.isObject()) {
|
|
21
|
+
return fallback;
|
|
22
|
+
}
|
|
23
|
+
const auto *value = config.get_ptr(key);
|
|
24
|
+
if (value == nullptr || !value->isNumber()) {
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
return value->asDouble();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
bool hasKey(const folly::dynamic &config, const char *key) {
|
|
31
|
+
return config.isObject() && config.get_ptr(key) != nullptr &&
|
|
32
|
+
!config.get_ptr(key)->isNull();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
std::vector<int> tagList(const folly::dynamic &config, const char *key) {
|
|
36
|
+
std::vector<int> tags;
|
|
37
|
+
if (!config.isObject()) {
|
|
38
|
+
return tags;
|
|
39
|
+
}
|
|
40
|
+
const auto *value = config.get_ptr(key);
|
|
41
|
+
if (value == nullptr || !value->isArray()) {
|
|
42
|
+
return tags;
|
|
43
|
+
}
|
|
44
|
+
for (const auto &entry : *value) {
|
|
45
|
+
if (entry.isNumber()) {
|
|
46
|
+
tags.push_back(static_cast<int>(entry.asDouble()));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return tags;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
bool contains(const std::vector<int> &tags, int tag) {
|
|
53
|
+
return std::find(tags.begin(), tags.end(), tag) != tags.end();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
} // namespace
|
|
57
|
+
|
|
58
|
+
struct GestureRegistry::Handler {
|
|
59
|
+
std::string name;
|
|
60
|
+
int tag{0};
|
|
61
|
+
int viewTag{0};
|
|
62
|
+
folly::dynamic config = folly::dynamic::object();
|
|
63
|
+
|
|
64
|
+
GestureState state{GestureState::Undetermined};
|
|
65
|
+
bool tracking{false};
|
|
66
|
+
|
|
67
|
+
// The attached view's origin in root coordinates, captured when the pointer
|
|
68
|
+
// lands: a gesture payload's `x`/`y` are relative to the view it is attached
|
|
69
|
+
// to, and `absoluteX`/`absoluteY` to the root.
|
|
70
|
+
double originX{0};
|
|
71
|
+
double originY{0};
|
|
72
|
+
|
|
73
|
+
double startX{0};
|
|
74
|
+
double startY{0};
|
|
75
|
+
double lastX{0};
|
|
76
|
+
double lastY{0};
|
|
77
|
+
double startTime{0};
|
|
78
|
+
double lastTime{0};
|
|
79
|
+
double velocityX{0};
|
|
80
|
+
double velocityY{0};
|
|
81
|
+
|
|
82
|
+
// For multi-tap. Kept between gestures, because the second tap of a double
|
|
83
|
+
// tap is a separate gesture as far as the pointer is concerned.
|
|
84
|
+
int tapCount{0};
|
|
85
|
+
double lastTapTime{0};
|
|
86
|
+
|
|
87
|
+
// Bumped on every pointer down, so a timer that fires after the gesture it
|
|
88
|
+
// belonged to can tell that it is stale. Simpler than cancelling timers, and
|
|
89
|
+
// right even when the timer has already begun running.
|
|
90
|
+
int generation{0};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
double monotonicMilliseconds() {
|
|
94
|
+
using namespace std::chrono;
|
|
95
|
+
return duration<double, std::milli>(steady_clock::now().time_since_epoch()).count();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
GestureRegistry &gestures() {
|
|
99
|
+
static GestureRegistry registry;
|
|
100
|
+
return registry;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
void GestureRegistry::setEmitter(Emitter emitter) {
|
|
104
|
+
emit_ = std::move(emitter);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
GestureRegistry::Handler *GestureRegistry::find(int handlerTag) {
|
|
108
|
+
for (auto &handler : handlers_) {
|
|
109
|
+
if (handler.tag == handlerTag) {
|
|
110
|
+
return &handler;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return nullptr;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void GestureRegistry::create(const std::string &handlerName,
|
|
117
|
+
int handlerTag,
|
|
118
|
+
folly::dynamic config) {
|
|
119
|
+
drop(handlerTag);
|
|
120
|
+
Handler handler;
|
|
121
|
+
handler.name = handlerName;
|
|
122
|
+
handler.tag = handlerTag;
|
|
123
|
+
handler.config = config.isObject() ? std::move(config) : folly::dynamic::object();
|
|
124
|
+
handlers_.push_back(std::move(handler));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
void GestureRegistry::update(int handlerTag, folly::dynamic config) {
|
|
128
|
+
Handler *handler = find(handlerTag);
|
|
129
|
+
if (handler == nullptr || !config.isObject()) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
// Merged rather than replaced: RNGH sends the properties it knows changed,
|
|
133
|
+
// and sends the relations in a second call of their own.
|
|
134
|
+
for (const auto &entry : config.items()) {
|
|
135
|
+
handler->config[entry.first] = entry.second;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
void GestureRegistry::attach(int handlerTag, int viewTag) {
|
|
140
|
+
if (Handler *handler = find(handlerTag); handler != nullptr) {
|
|
141
|
+
handler->viewTag = viewTag;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
void GestureRegistry::drop(int handlerTag) {
|
|
146
|
+
handlers_.erase(std::remove_if(handlers_.begin(),
|
|
147
|
+
handlers_.end(),
|
|
148
|
+
[handlerTag](const Handler &handler) {
|
|
149
|
+
return handler.tag == handlerTag;
|
|
150
|
+
}),
|
|
151
|
+
handlers_.end());
|
|
152
|
+
tracking_.erase(std::remove(tracking_.begin(), tracking_.end(), handlerTag), tracking_.end());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
void GestureRegistry::setStateFromWorklet(int handlerTag, int state) {
|
|
156
|
+
Handler *handler = find(handlerTag);
|
|
157
|
+
if (handler == nullptr || !handler->tracking) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const auto next = static_cast<GestureState>(state);
|
|
161
|
+
if (next == GestureState::Active) {
|
|
162
|
+
// Through the same path a recogniser takes, so that the handlers it
|
|
163
|
+
// competes with are cancelled the way they would be otherwise.
|
|
164
|
+
tryActivate(*handler, handler->lastX, handler->lastY, handler->lastTime);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
setState(*handler, next, handler->lastX, handler->lastY, handler->lastTime);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
bool GestureRegistry::empty() const {
|
|
171
|
+
return handlers_.empty();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
bool GestureRegistry::hasActiveHandler() const {
|
|
175
|
+
for (int tag : tracking_) {
|
|
176
|
+
for (const auto &handler : handlers_) {
|
|
177
|
+
if (handler.tag == tag && handler.state == GestureState::Active) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
folly::dynamic GestureRegistry::payloadFor(const Handler &handler, double x, double y) const {
|
|
186
|
+
folly::dynamic payload = folly::dynamic::object;
|
|
187
|
+
payload["handlerTag"] = handler.tag;
|
|
188
|
+
payload["numberOfPointers"] = 1;
|
|
189
|
+
payload["pointerType"] = kPointerTypeMouse;
|
|
190
|
+
payload["state"] = static_cast<int>(handler.state);
|
|
191
|
+
payload["x"] = x - handler.originX;
|
|
192
|
+
payload["y"] = y - handler.originY;
|
|
193
|
+
payload["absoluteX"] = x;
|
|
194
|
+
payload["absoluteY"] = y;
|
|
195
|
+
|
|
196
|
+
if (handler.name == "PanGestureHandler") {
|
|
197
|
+
payload["translationX"] = x - handler.startX;
|
|
198
|
+
payload["translationY"] = y - handler.startY;
|
|
199
|
+
payload["velocityX"] = handler.velocityX;
|
|
200
|
+
payload["velocityY"] = handler.velocityY;
|
|
201
|
+
} else if (handler.name == "LongPressGestureHandler") {
|
|
202
|
+
payload["duration"] = handler.lastTime - handler.startTime;
|
|
203
|
+
}
|
|
204
|
+
return payload;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void GestureRegistry::setState(Handler &handler,
|
|
208
|
+
GestureState next,
|
|
209
|
+
double x,
|
|
210
|
+
double y,
|
|
211
|
+
double timestampMs) {
|
|
212
|
+
if (handler.state == next) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const GestureState previous = handler.state;
|
|
216
|
+
handler.state = next;
|
|
217
|
+
handler.lastTime = timestampMs;
|
|
218
|
+
|
|
219
|
+
if (emit_) {
|
|
220
|
+
folly::dynamic payload = payloadFor(handler, x, y);
|
|
221
|
+
payload["oldState"] = static_cast<int>(previous);
|
|
222
|
+
emit_("onGestureHandlerStateChange", std::move(payload));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Undetermined is where a handler waits for the next gesture.
|
|
226
|
+
if (next == GestureState::End || next == GestureState::Failed ||
|
|
227
|
+
next == GestureState::Cancelled) {
|
|
228
|
+
handler.tracking = false;
|
|
229
|
+
handler.state = GestureState::Undetermined;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
void GestureRegistry::emitUpdate(const Handler &handler,
|
|
234
|
+
double x,
|
|
235
|
+
double y,
|
|
236
|
+
double /*timestampMs*/) {
|
|
237
|
+
if (!emit_) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
emit_("onGestureHandlerEvent", payloadFor(handler, x, y));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
void GestureRegistry::cancelOthers(const Handler &activated,
|
|
244
|
+
double x,
|
|
245
|
+
double y,
|
|
246
|
+
double timestampMs) {
|
|
247
|
+
const std::vector<int> simultaneous = tagList(activated.config, "simultaneousHandlers");
|
|
248
|
+
const int activatedTag = activated.tag;
|
|
249
|
+
|
|
250
|
+
for (int tag : tracking_) {
|
|
251
|
+
if (tag == activatedTag) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
Handler *other = find(tag);
|
|
255
|
+
if (other == nullptr || !other->tracking) {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (contains(simultaneous, tag) ||
|
|
259
|
+
contains(tagList(other->config, "simultaneousHandlers"), activatedTag)) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
setState(*other,
|
|
263
|
+
other->state == GestureState::Active ? GestureState::Cancelled
|
|
264
|
+
: GestureState::Failed,
|
|
265
|
+
x,
|
|
266
|
+
y,
|
|
267
|
+
timestampMs);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
bool GestureRegistry::tryActivate(Handler &handler, double x, double y, double timestampMs) {
|
|
272
|
+
// `waitFor` is RNGH's requireToFail: this handler may not activate while a
|
|
273
|
+
// handler it waits for is still undecided. Checked at the moment of
|
|
274
|
+
// activation rather than tracked as a subscription, which is enough because
|
|
275
|
+
// the next pointer event re-asks.
|
|
276
|
+
for (int tag : tagList(handler.config, "waitFor")) {
|
|
277
|
+
const Handler *other = const_cast<GestureRegistry *>(this)->find(tag);
|
|
278
|
+
if (other != nullptr && other->tracking) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
setState(handler, GestureState::Active, x, y, timestampMs);
|
|
284
|
+
cancelOthers(handler, x, y, timestampMs);
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
void GestureRegistry::beginTracking(Handler &handler,
|
|
289
|
+
const HitView &view,
|
|
290
|
+
double x,
|
|
291
|
+
double y,
|
|
292
|
+
double timestampMs) {
|
|
293
|
+
handler.tracking = true;
|
|
294
|
+
handler.originX = view.originX;
|
|
295
|
+
handler.originY = view.originY;
|
|
296
|
+
handler.startX = x;
|
|
297
|
+
handler.startY = y;
|
|
298
|
+
handler.lastX = x;
|
|
299
|
+
handler.lastY = y;
|
|
300
|
+
handler.startTime = timestampMs;
|
|
301
|
+
handler.lastTime = timestampMs;
|
|
302
|
+
handler.velocityX = 0;
|
|
303
|
+
handler.velocityY = 0;
|
|
304
|
+
handler.generation = generation_;
|
|
305
|
+
|
|
306
|
+
setState(handler, GestureState::Began, x, y, timestampMs);
|
|
307
|
+
|
|
308
|
+
if (handler.name == "LongPressGestureHandler") {
|
|
309
|
+
const double minDuration = number(handler.config, "minDurationMs", 500);
|
|
310
|
+
const int generation = handler.generation;
|
|
311
|
+
const int tag = handler.tag;
|
|
312
|
+
postDelayed(minDuration, [this, tag, generation]() {
|
|
313
|
+
Handler *held = find(tag);
|
|
314
|
+
if (held == nullptr || held->generation != generation || !held->tracking ||
|
|
315
|
+
held->state != GestureState::Began) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
tryActivate(*held, held->lastX, held->lastY, held->lastTime);
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// A native handler stands for a platform control that handles its own
|
|
323
|
+
// gesture -- RNGH's buttons, and scroll views. Nothing here wraps one, so it
|
|
324
|
+
// activates on contact, which is what those controls do.
|
|
325
|
+
if (handler.name == "NativeViewGestureHandler") {
|
|
326
|
+
tryActivate(handler, x, y, timestampMs);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
void GestureRegistry::pointerDown(const std::vector<HitView> &chain,
|
|
331
|
+
double x,
|
|
332
|
+
double y,
|
|
333
|
+
double timestampMs) {
|
|
334
|
+
generation_++;
|
|
335
|
+
pointerIsDown_ = true;
|
|
336
|
+
tracking_.clear();
|
|
337
|
+
|
|
338
|
+
// Innermost first, which is the order RNGH offers a gesture to handlers in:
|
|
339
|
+
// the closest handler to the touch gets to claim it before its ancestors.
|
|
340
|
+
for (const HitView &view : chain) {
|
|
341
|
+
for (auto &handler : handlers_) {
|
|
342
|
+
if (handler.viewTag != view.tag || handler.viewTag == 0) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
tracking_.push_back(handler.tag);
|
|
346
|
+
beginTracking(handler, view, x, y, timestampMs);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
void GestureRegistry::pointerMove(double x, double y, double timestampMs) {
|
|
352
|
+
if (!pointerIsDown_) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
for (int tag : tracking_) {
|
|
357
|
+
Handler *handler = find(tag);
|
|
358
|
+
if (handler == nullptr || !handler->tracking) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const double elapsed = timestampMs - handler->lastTime;
|
|
363
|
+
if (elapsed > 0) {
|
|
364
|
+
// Pixels per second, which is what RNGH's velocity is in.
|
|
365
|
+
handler->velocityX = (x - handler->lastX) / elapsed * 1000.0;
|
|
366
|
+
handler->velocityY = (y - handler->lastY) / elapsed * 1000.0;
|
|
367
|
+
}
|
|
368
|
+
handler->lastX = x;
|
|
369
|
+
handler->lastY = y;
|
|
370
|
+
handler->lastTime = timestampMs;
|
|
371
|
+
|
|
372
|
+
const double dx = x - handler->startX;
|
|
373
|
+
const double dy = y - handler->startY;
|
|
374
|
+
const double distance = std::sqrt(dx * dx + dy * dy);
|
|
375
|
+
|
|
376
|
+
if (handler->state == GestureState::Active) {
|
|
377
|
+
emitUpdate(*handler, x, y, timestampMs);
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
if (handler->state != GestureState::Began) {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (handler->name == "PanGestureHandler") {
|
|
385
|
+
// activeOffsetX/Y are thresholds in one direction and take precedence
|
|
386
|
+
// over minDist, which is RNGH's radial default.
|
|
387
|
+
bool activate = false;
|
|
388
|
+
if (hasKey(handler->config, "activeOffsetXStart") ||
|
|
389
|
+
hasKey(handler->config, "activeOffsetXEnd") ||
|
|
390
|
+
hasKey(handler->config, "activeOffsetYStart") ||
|
|
391
|
+
hasKey(handler->config, "activeOffsetYEnd")) {
|
|
392
|
+
activate = dx <= number(handler->config, "activeOffsetXStart", -1e9) ||
|
|
393
|
+
dx >= number(handler->config, "activeOffsetXEnd", 1e9) ||
|
|
394
|
+
dy <= number(handler->config, "activeOffsetYStart", -1e9) ||
|
|
395
|
+
dy >= number(handler->config, "activeOffsetYEnd", 1e9);
|
|
396
|
+
} else {
|
|
397
|
+
activate = distance >= number(handler->config, "minDist", 10);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const bool fail = dx <= number(handler->config, "failOffsetXStart", -1e9) ||
|
|
401
|
+
dx >= number(handler->config, "failOffsetXEnd", 1e9) ||
|
|
402
|
+
dy <= number(handler->config, "failOffsetYStart", -1e9) ||
|
|
403
|
+
dy >= number(handler->config, "failOffsetYEnd", 1e9);
|
|
404
|
+
|
|
405
|
+
if (fail) {
|
|
406
|
+
setState(*handler, GestureState::Failed, x, y, timestampMs);
|
|
407
|
+
} else if (activate && tryActivate(*handler, x, y, timestampMs)) {
|
|
408
|
+
emitUpdate(*handler, x, y, timestampMs);
|
|
409
|
+
}
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// A tap or a long press is over as soon as the pointer wanders. maxDist is
|
|
414
|
+
// RNGH's name for the slop in both.
|
|
415
|
+
if (handler->name == "TapGestureHandler" || handler->name == "LongPressGestureHandler") {
|
|
416
|
+
const double slop =
|
|
417
|
+
number(handler->config, "maxDist", handler->name == "TapGestureHandler" ? 25 : 10);
|
|
418
|
+
if (distance > slop) {
|
|
419
|
+
setState(*handler, GestureState::Failed, x, y, timestampMs);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
void GestureRegistry::pointerUp(double x, double y, double timestampMs) {
|
|
426
|
+
if (!pointerIsDown_) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
pointerIsDown_ = false;
|
|
430
|
+
|
|
431
|
+
const std::vector<int> tracking = tracking_;
|
|
432
|
+
for (int tag : tracking) {
|
|
433
|
+
Handler *handler = find(tag);
|
|
434
|
+
if (handler == nullptr || !handler->tracking) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
handler->lastTime = timestampMs;
|
|
438
|
+
|
|
439
|
+
if (handler->state == GestureState::Active) {
|
|
440
|
+
setState(*handler, GestureState::End, x, y, timestampMs);
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
if (handler->state != GestureState::Began) {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (handler->name == "TapGestureHandler") {
|
|
448
|
+
const double maxDuration = number(handler->config, "maxDurationMs", 500);
|
|
449
|
+
const double maxDelay = number(handler->config, "maxDelayMs", 500);
|
|
450
|
+
const int required = static_cast<int>(number(handler->config, "numberOfTaps", 1));
|
|
451
|
+
|
|
452
|
+
if (timestampMs - handler->startTime > maxDuration) {
|
|
453
|
+
handler->tapCount = 0;
|
|
454
|
+
setState(*handler, GestureState::Failed, x, y, timestampMs);
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
handler->tapCount++;
|
|
459
|
+
handler->lastTapTime = timestampMs;
|
|
460
|
+
|
|
461
|
+
if (handler->tapCount >= required) {
|
|
462
|
+
handler->tapCount = 0;
|
|
463
|
+
if (tryActivate(*handler, x, y, timestampMs)) {
|
|
464
|
+
setState(*handler, GestureState::End, x, y, timestampMs);
|
|
465
|
+
}
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// More taps wanted. The handler stops tracking this pointer but keeps its
|
|
470
|
+
// count, and fails if the next tap does not arrive in time.
|
|
471
|
+
handler->tracking = false;
|
|
472
|
+
handler->state = GestureState::Undetermined;
|
|
473
|
+
const int generation = handler->generation;
|
|
474
|
+
const int handlerTag = handler->tag;
|
|
475
|
+
postDelayed(maxDelay, [this, handlerTag, generation]() {
|
|
476
|
+
Handler *held = find(handlerTag);
|
|
477
|
+
if (held == nullptr || held->generation != generation || held->tapCount == 0) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
held->tapCount = 0;
|
|
481
|
+
if (emit_) {
|
|
482
|
+
folly::dynamic payload = payloadFor(*held, held->lastX, held->lastY);
|
|
483
|
+
payload["state"] = static_cast<int>(GestureState::Failed);
|
|
484
|
+
payload["oldState"] = static_cast<int>(GestureState::Began);
|
|
485
|
+
emit_("onGestureHandlerStateChange", std::move(payload));
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (handler->name == "FlingGestureHandler") {
|
|
492
|
+
const double speed =
|
|
493
|
+
std::sqrt(handler->velocityX * handler->velocityX +
|
|
494
|
+
handler->velocityY * handler->velocityY);
|
|
495
|
+
// RNGH has no configurable threshold for this; its platforms use their
|
|
496
|
+
// own recognisers. 500 px/s is the middle of what each of them treats as
|
|
497
|
+
// a flick.
|
|
498
|
+
if (speed >= 500 && tryActivate(*handler, x, y, timestampMs)) {
|
|
499
|
+
setState(*handler, GestureState::End, x, y, timestampMs);
|
|
500
|
+
} else {
|
|
501
|
+
setState(*handler, GestureState::Failed, x, y, timestampMs);
|
|
502
|
+
}
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Everything still at BEGAN when the pointer lifts did not happen: a long
|
|
507
|
+
// press that was not held, a pan that never moved, a pinch that could never
|
|
508
|
+
// have started.
|
|
509
|
+
setState(*handler, GestureState::Failed, x, y, timestampMs);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
tracking_.clear();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
void GestureRegistry::pointerCancel() {
|
|
516
|
+
const std::vector<int> tracking = tracking_;
|
|
517
|
+
for (int tag : tracking) {
|
|
518
|
+
Handler *handler = find(tag);
|
|
519
|
+
if (handler == nullptr || !handler->tracking) {
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
setState(*handler,
|
|
523
|
+
handler->state == GestureState::Active ? GestureState::Cancelled
|
|
524
|
+
: GestureState::Failed,
|
|
525
|
+
handler->lastX,
|
|
526
|
+
handler->lastY,
|
|
527
|
+
handler->lastTime);
|
|
528
|
+
}
|
|
529
|
+
tracking_.clear();
|
|
530
|
+
pointerIsDown_ = false;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
} // namespace basalt
|