react-native-windows 0.76.2 → 0.77.0-preview.1
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/.flowconfig +5 -1
- package/Libraries/ActionSheetIOS/ActionSheetIOS.d.ts +1 -0
- package/Libraries/ActionSheetIOS/ActionSheetIOS.js +13 -0
- package/Libraries/Animated/AnimatedEvent.js +1 -1
- package/Libraries/Animated/AnimatedImplementation.js +2 -2
- package/Libraries/Animated/NativeAnimatedAllowlist.js +20 -9
- package/Libraries/Animated/NativeAnimatedAllowlist.windows.js +122 -0
- package/Libraries/Animated/animations/Animation.js +60 -25
- package/Libraries/Animated/animations/DecayAnimation.js +26 -38
- package/Libraries/Animated/animations/SpringAnimation.js +33 -39
- package/Libraries/Animated/animations/TimingAnimation.js +34 -42
- package/Libraries/Animated/components/AnimatedFlatList.js +1 -1
- package/Libraries/Animated/components/AnimatedSectionList.js +3 -1
- package/Libraries/Animated/createAnimatedComponent.js +60 -33
- package/Libraries/Animated/nodes/AnimatedColor.js +1 -1
- package/Libraries/Animated/nodes/AnimatedInterpolation.js +1 -1
- package/Libraries/Animated/nodes/AnimatedNode.js +39 -45
- package/Libraries/Animated/nodes/AnimatedObject.js +13 -3
- package/Libraries/Animated/nodes/AnimatedProps.js +96 -46
- package/Libraries/Animated/nodes/AnimatedProps.windows.js +281 -0
- package/Libraries/Animated/nodes/AnimatedStyle.js +108 -39
- package/Libraries/Animated/nodes/AnimatedStyle.windows.js +251 -0
- package/Libraries/Animated/nodes/AnimatedTransform.js +56 -23
- package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
- package/Libraries/Animated/nodes/AnimatedWithChildren.js +1 -3
- package/Libraries/Animated/useAnimatedProps.js +41 -35
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts +19 -3
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +77 -5
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js +82 -5
- package/Libraries/Components/ActivityIndicator/ActivityIndicator.js +4 -4
- package/Libraries/Components/Button.js +9 -4
- package/Libraries/Components/Button.windows.js +19 -5
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js +3 -1
- package/Libraries/Components/Glyph/Glyph.js +2 -1
- package/Libraries/Components/Keyboard/KeyboardAvoidingView.js +7 -0
- package/Libraries/Components/Popup/PopupNativeComponent.js +0 -1
- package/Libraries/Components/Pressable/Pressable.js +4 -4
- package/Libraries/Components/Pressable/Pressable.windows.js +10 -4
- package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +13 -7
- package/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +3 -2
- package/Libraries/Components/SafeAreaView/SafeAreaView.js +4 -4
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +0 -1
- package/Libraries/Components/ScrollView/ScrollView.js +49 -88
- package/Libraries/Components/ScrollView/ScrollViewCommands.js +1 -1
- package/Libraries/Components/ScrollView/ScrollViewContext.js +2 -0
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +0 -2
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.windows.js +0 -5
- package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +8 -9
- package/Libraries/Components/Switch/Switch.js +8 -6
- package/Libraries/Components/Switch/Switch.windows.js +8 -6
- package/Libraries/Components/TextInput/InputAccessoryView.js +1 -1
- package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +4 -4
- package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +6 -4
- package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +2 -1
- package/Libraries/Components/TextInput/TextInput.d.ts +27 -4
- package/Libraries/Components/TextInput/TextInput.flow.js +36 -19
- package/Libraries/Components/TextInput/TextInput.js +37 -13
- package/Libraries/Components/TextInput/TextInput.windows.js +47 -16
- package/Libraries/Components/TextInput/TextInputState.js +11 -13
- package/Libraries/Components/TextInput/TextInputState.windows.js +11 -13
- package/Libraries/Components/Touchable/BoundingDimensions.js +11 -3
- package/Libraries/Components/Touchable/Position.js +7 -2
- package/Libraries/Components/Touchable/Touchable.js +4 -0
- package/Libraries/Components/Touchable/Touchable.windows.js +4 -0
- package/Libraries/Components/Touchable/TouchableBounce.js +6 -2
- package/Libraries/Components/Touchable/TouchableBounce.windows.js +227 -0
- package/Libraries/Components/Touchable/TouchableHighlight.js +5 -5
- package/Libraries/Components/Touchable/TouchableHighlight.windows.js +5 -5
- package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +371 -0
- package/Libraries/Components/Touchable/TouchableOpacity.js +6 -5
- package/Libraries/Components/Touchable/TouchableOpacity.windows.js +11 -5
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +1 -2
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +9 -3
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -1
- package/Libraries/Components/View/View.js +4 -4
- package/Libraries/Components/View/View.windows.js +88 -57
- package/Libraries/Components/View/ViewAccessibility.d.ts +10 -0
- package/Libraries/Components/View/ViewAccessibility.windows.js +2 -0
- package/Libraries/Components/View/ViewNativeComponent.js +6 -98
- package/Libraries/Components/View/ViewPropTypes.d.ts +7 -0
- package/Libraries/Components/View/ViewPropTypes.js +0 -3
- package/Libraries/Components/View/ViewPropTypes.windows.js +2 -3
- package/Libraries/Core/ExceptionsManager.js +50 -29
- package/Libraries/Core/ReactNativeVersion.js +3 -3
- package/Libraries/Core/__mocks__/NativeExceptionsManager.js +0 -1
- package/Libraries/Core/setUpBatchedBridge.js +1 -10
- package/Libraries/Core/setUpDeveloperTools.js +1 -5
- package/Libraries/Core/setUpErrorHandling.js +20 -18
- package/Libraries/Core/setUpReactDevTools.js +107 -8
- package/Libraries/Core/setUpSegmentFetcher.js +1 -0
- package/Libraries/Core/setUpTimers.js +21 -18
- package/Libraries/Debugging/DebuggingOverlay.js +4 -5
- package/Libraries/Image/AssetSourceResolver.js +12 -1
- package/Libraries/Image/AssetSourceResolver.windows.js +12 -1
- package/Libraries/Image/Image.android.js +1 -5
- package/Libraries/Image/Image.d.ts +20 -29
- package/Libraries/Image/Image.ios.js +0 -2
- package/Libraries/Image/Image.windows.js +5 -1
- package/Libraries/Image/ImageBackground.js +2 -5
- package/Libraries/Image/ImageProps.js +7 -6
- package/Libraries/Image/ImageResizeMode.d.ts +8 -1
- package/Libraries/Image/ImageResizeMode.js +4 -1
- package/Libraries/Image/ImageSource.d.ts +0 -2
- package/Libraries/Image/ImageSource.js +0 -2
- package/Libraries/Image/ImageTypes.flow.js +11 -9
- package/Libraries/Image/ImageUtils.js +6 -3
- package/Libraries/Image/ImageViewNativeComponent.js +5 -3
- package/Libraries/Inspector/Inspector.js +1 -0
- package/Libraries/Inspector/NetworkOverlay.js +4 -0
- package/Libraries/Inspector/ReactDevToolsOverlay.js +8 -14
- package/Libraries/Inspector/getInspectorDataForViewAtPoint.js +3 -5
- package/Libraries/Interaction/InteractionManager.js +6 -1
- package/Libraries/Interaction/InteractionManagerStub.js +176 -0
- package/Libraries/Interaction/TouchHistoryMath.js +22 -19
- package/Libraries/JSInspector/NetworkAgent.js +1 -1
- package/Libraries/Lists/FlatList.d.ts +1 -2
- package/Libraries/Lists/FlatList.js +2 -2
- package/Libraries/Lists/SectionListModern.js +7 -7
- package/Libraries/Lists/__flowtests__/FlatList-flowtest.js +2 -2
- package/Libraries/Lists/__flowtests__/SectionList-flowtest.js +1 -1
- package/Libraries/LogBox/Data/LogBoxData.js +3 -3
- package/Libraries/LogBox/LogBox.js +18 -5
- package/Libraries/LogBox/LogBoxInspectorContainer.js +1 -1
- package/Libraries/LogBox/LogBoxNotificationContainer.js +2 -2
- package/Libraries/LogBox/UI/AnsiHighlight.js +26 -17
- package/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js +6 -1
- package/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.windows.js +6 -1
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +1 -1
- package/Libraries/LogBox/UI/LogBoxInspectorHeader.windows.js +1 -1
- package/Libraries/LogBox/UI/LogBoxInspectorStackFrames.js +1 -1
- package/Libraries/LogBox/UI/LogBoxMessage.js +2 -2
- package/Libraries/Modal/Modal.d.ts +12 -0
- package/Libraries/Modal/Modal.js +31 -4
- package/Libraries/Modal/Modal.windows.js +370 -0
- package/Libraries/NativeComponent/BaseViewConfig.android.js +72 -1
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +2 -1
- package/Libraries/NativeComponent/BaseViewConfig.windows.js +3 -11
- package/Libraries/NativeComponent/NativeComponentRegistry.js +3 -3
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -1
- package/Libraries/Network/XHRInterceptor.js +63 -14
- package/Libraries/Network/XMLHttpRequest.js +26 -1
- package/Libraries/NewAppScreen/components/HermesBadge.js +1 -1
- package/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts +49 -2
- package/Libraries/PermissionsAndroid/PermissionsAndroid.js +4 -4
- package/Libraries/Pressability/HoverState.js +2 -0
- package/Libraries/Pressability/Pressability.js +2 -3
- package/Libraries/Pressability/Pressability.windows.js +2 -3
- package/Libraries/Pressability/usePressability.js +4 -1
- package/Libraries/ReactNative/AppContainer.js +1 -1
- package/Libraries/ReactNative/AppRegistry.js +1 -11
- package/Libraries/ReactNative/DisplayMode.js +1 -1
- package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +2 -3
- package/Libraries/ReactNative/RendererImplementation.js +18 -17
- package/Libraries/ReactNative/getCachedComponentWithDebugName.js +1 -3
- package/Libraries/ReactNative/renderApplication.js +9 -8
- package/Libraries/ReactNative/requireNativeComponent.js +5 -2
- package/Libraries/Renderer/shims/ReactFabric.js +3 -3
- package/Libraries/Renderer/shims/ReactFeatureFlags.js +2 -2
- package/Libraries/Renderer/shims/ReactNative.js +3 -3
- package/Libraries/Renderer/shims/ReactNativeTypes.js +22 -35
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +5 -6
- package/Libraries/Renderer/shims/createReactNativeComponentClass.js +2 -2
- package/Libraries/StyleSheet/StyleSheet.js +7 -1
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +13 -2
- package/Libraries/StyleSheet/StyleSheetTypes.js +24 -6
- package/Libraries/StyleSheet/processBackgroundImage.js +87 -110
- package/Libraries/StyleSheet/processTransform.js +3 -34
- package/Libraries/Text/Text.js +248 -249
- package/Libraries/Text/Text.windows.js +298 -292
- package/Libraries/Text/TextNativeComponent.js +0 -1
- package/Libraries/Text/TextProps.windows.js +2 -0
- package/Libraries/TurboModule/TurboModuleRegistry.js +5 -5
- package/Libraries/Types/CoreEventTypes.d.ts +3 -10
- package/Libraries/Types/CoreEventTypes.js +4 -6
- package/Libraries/Types/CoreEventTypes.windows.js +4 -6
- package/Libraries/Utilities/Appearance.js +3 -1
- package/Libraries/Utilities/BackHandler.android.js +6 -18
- package/Libraries/Utilities/BackHandler.d.ts +0 -4
- package/Libraries/Utilities/BackHandler.ios.js +0 -7
- package/Libraries/Utilities/BackHandler.windows.js +6 -18
- package/Libraries/Utilities/HMRClient.js +3 -4
- package/Libraries/Utilities/Platform.flow.js +2 -2
- package/Libraries/Utilities/Platform.flow.windows.js +3 -2
- package/Libraries/Utilities/__mocks__/BackHandler.js +3 -8
- package/Libraries/Utilities/codegenNativeComponent.js +1 -1
- package/Libraries/Utilities/useMergeRefs.js +26 -7
- package/Libraries/WebSocket/WebSocketEvent.js +4 -1
- package/Libraries/WebSocket/WebSocketInterceptor.js +31 -13
- package/Libraries/__flowtests__/ReactNativeTypes-flowtest.js +6 -5
- package/Libraries/promiseRejectionTrackingOptions.js +1 -1
- package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +9 -8
- package/Microsoft.ReactNative/AsynchronousEventBeat.h +5 -5
- package/Microsoft.ReactNative/CompositionComponentView.idl +2 -1
- package/Microsoft.ReactNative/FBReactNativeSpec/FBReactNativeSpecJSI.h +5 -0
- package/Microsoft.ReactNative/Fabric/AbiComponentDescriptor.cpp +6 -3
- package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +7 -0
- package/Microsoft.ReactNative/Fabric/AbiViewProps.h +2 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +45 -50
- package/Microsoft.ReactNative/Fabric/ComponentView.h +14 -22
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +943 -0
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +80 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +223 -21
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +19 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +187 -6
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +10 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +8 -32
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +349 -929
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +32 -29
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +9 -2
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +181 -123
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +16 -8
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +99 -37
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +25 -3
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +64 -3
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +51 -3
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +18 -8
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +6 -8
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +56 -7
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +9 -3
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +35 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +7 -0
- package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +12 -12
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +4 -4
- package/Microsoft.ReactNative/Fabric/ImageRequest.cpp +4 -8
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +16 -15
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +1 -5
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +26 -0
- package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +1 -1
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +15 -0
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.h +9 -0
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +20 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +11 -6
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
- package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -2
- package/Microsoft.ReactNative/SynchronousEventBeat.cpp +14 -4
- package/Microsoft.ReactNative/SynchronousEventBeat.h +4 -2
- package/Microsoft.ReactNative/ViewProps.idl +2 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +78 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.h +51 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +48 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.cpp +41 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.h +127 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.inc +125 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +16 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_win.cpp +23 -0
- package/Microsoft.ReactNative.Cxx/ComponentView.Experimental.interop.h +14 -0
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +834 -0
- package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +117 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +366 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +560 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +1611 -0
- package/Microsoft.ReactNative.Cxx/JSI/threadsafe.h +79 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +7 -11
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +1 -1
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +2878 -0
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +36 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/CallInvoker.h +64 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/SchedulerPriority.h +22 -0
- package/{ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core → Microsoft.ReactNative.Cxx}/ReactCommon/TurboModule.cpp +63 -63
- package/Microsoft.ReactNative.Cxx/ReactCommon/TurboModule.h +165 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/TurboModuleUtils.cpp +105 -0
- package/{ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core → Microsoft.ReactNative.Cxx}/ReactCommon/TurboModuleUtils.h +57 -58
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/AString.h +42 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Array.h +151 -0
- package/{ReactCommon/TEMP_UntilReactCommonUpdate → Microsoft.ReactNative.Cxx/ReactCommon}/react/bridging/Base.h +177 -154
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Bool.h +25 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Bridging.h +21 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/CallbackWrapper.h +67 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Class.h +90 -0
- package/{ReactCommon/TEMP_UntilReactCommonUpdate → Microsoft.ReactNative.Cxx/ReactCommon}/react/bridging/Convert.h +170 -172
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Error.h +51 -0
- package/{ReactCommon/TEMP_UntilReactCommonUpdate → Microsoft.ReactNative.Cxx/ReactCommon}/react/bridging/EventEmitter.h +134 -136
- package/{ReactCommon/TEMP_UntilReactCommonUpdate → Microsoft.ReactNative.Cxx/ReactCommon}/react/bridging/Function.h +283 -283
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/LongLivedObject.cpp +63 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/LongLivedObject.h +61 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Object.h +93 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Promise.h +104 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/bridging/Value.h +107 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/debug/flags.h +22 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/react/debug/react_native_assert.h +72 -0
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +553 -0
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +167 -0
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +186 -0
- package/Microsoft.ReactNative.Cxx/stubs/glog/logging.h +82 -0
- package/PropertySheets/Bundle.Common.targets +1 -1
- package/PropertySheets/Bundle.props +3 -0
- package/PropertySheets/Generated/PackageVersion.g.props +4 -4
- package/PropertySheets/ManagedCodeGen/Microsoft.ReactNative.Managed.CodeGen.targets +1 -1
- package/PropertySheets/OutputMSBuildProperties.targets +3 -1
- package/ReactCommon/ReactCommon.vcxproj +5 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +2 -3
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +61 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +26 -23
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +150 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +252 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +795 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/runtimescheduler/SchedulerPriorityUtils.h +59 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +188 -39
- package/Scripts/Microsoft.ReactNative.Managed.CodeGen.targets +1 -1
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +97 -62
- package/Shared/InspectorPackagerConnection.cpp +3 -6
- package/Shared/InspectorPackagerConnection.h +2 -2
- package/Shared/InstanceManager.h +1 -1
- package/Shared/OInstance.h +1 -1
- package/Shared/Shared.vcxitems +20 -2
- package/Shared/Shared.vcxitems.filters +4 -1
- package/Shared/TurboModuleManager.cpp +29 -4
- package/codegen/NativeAccessibilityInfoSpec.g.h +28 -9
- package/codegen/NativeAccessibilityManagerSpec.g.h +20 -13
- package/codegen/NativeActionSheetManagerSpec.g.h +5 -0
- package/codegen/NativeAlertManagerSpec.g.h +1 -0
- package/codegen/NativeAnimatedModuleSpec.g.h +1 -0
- package/codegen/NativeAnimatedTurboModuleSpec.g.h +1 -0
- package/codegen/NativeAppStateSpec.g.h +1 -0
- package/codegen/NativeAppThemeSpec.g.h +1 -0
- package/codegen/NativeAppearanceSpec.g.h +1 -0
- package/codegen/NativeBlobModuleSpec.g.h +1 -0
- package/codegen/NativeBugReportingSpec.g.h +1 -0
- package/codegen/NativeClipboardSpec.g.h +1 -0
- package/codegen/NativeDOMSpec.g.h +1 -0
- package/codegen/NativeDevLoadingViewSpec.g.h +1 -0
- package/codegen/NativeDevMenuSpec.g.h +1 -0
- package/codegen/NativeDevSettingsSpec.g.h +1 -0
- package/codegen/NativeDeviceEventManagerSpec.g.h +1 -0
- package/codegen/NativeDeviceInfoSpec.g.h +1 -0
- package/codegen/NativeDialogManagerAndroidSpec.g.h +1 -0
- package/codegen/NativeDialogManagerWindowsSpec.g.h +1 -0
- package/codegen/NativeExceptionsManagerSpec.g.h +2 -7
- package/codegen/NativeFileReaderModuleSpec.g.h +1 -0
- package/codegen/NativeFrameRateLoggerSpec.g.h +1 -0
- package/codegen/NativeHeadlessJsTaskSupportSpec.g.h +1 -0
- package/codegen/NativeI18nManagerSpec.g.h +1 -0
- package/codegen/NativeIdleCallbacksSpec.g.h +1 -0
- package/codegen/NativeImageEditorSpec.g.h +1 -0
- package/codegen/NativeImageLoaderAndroidSpec.g.h +1 -0
- package/codegen/NativeImageLoaderIOSSpec.g.h +1 -0
- package/codegen/NativeImageStoreAndroidSpec.g.h +1 -0
- package/codegen/NativeImageStoreIOSSpec.g.h +1 -0
- package/codegen/NativeIntentAndroidSpec.g.h +1 -0
- package/codegen/NativeIntersectionObserverSpec.g.h +3 -0
- package/codegen/NativeJSCHeapCaptureSpec.g.h +1 -0
- package/codegen/NativeJSCSamplingProfilerSpec.g.h +1 -0
- package/codegen/NativeKeyboardObserverSpec.g.h +1 -0
- package/codegen/NativeLinkingManagerSpec.g.h +1 -0
- package/codegen/NativeLogBoxSpec.g.h +1 -0
- package/codegen/NativeMicrotasksSpec.g.h +1 -0
- package/codegen/NativeModalManagerSpec.g.h +1 -0
- package/codegen/NativeMutationObserverSpec.g.h +1 -0
- package/codegen/NativeNetworkingAndroidSpec.g.h +1 -0
- package/codegen/NativeNetworkingIOSSpec.g.h +1 -0
- package/codegen/NativePerformanceSpec.g.h +128 -3
- package/codegen/NativePermissionsAndroidSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsAndroidSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsIOSSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsWindowsSpec.g.h +1 -0
- package/codegen/NativePushNotificationManagerIOSSpec.g.h +1 -0
- package/codegen/NativeReactDevToolsRuntimeSettingsModuleSpec.g.h +67 -0
- package/codegen/NativeReactDevToolsSettingsManagerSpec.g.h +41 -0
- package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +126 -137
- package/codegen/NativeRedBoxSpec.g.h +1 -0
- package/codegen/NativeSampleTurboModuleSpec.g.h +1 -0
- package/codegen/NativeSegmentFetcherSpec.g.h +1 -0
- package/codegen/NativeSettingsManagerSpec.g.h +1 -0
- package/codegen/NativeShareModuleSpec.g.h +1 -0
- package/codegen/NativeSoundManagerSpec.g.h +1 -0
- package/codegen/NativeSourceCodeSpec.g.h +1 -0
- package/codegen/NativeStatusBarManagerAndroidSpec.g.h +1 -0
- package/codegen/NativeStatusBarManagerIOSSpec.g.h +1 -0
- package/codegen/NativeTimingSpec.g.h +1 -0
- package/codegen/NativeToastAndroidSpec.g.h +1 -0
- package/codegen/NativeUIManagerSpec.g.h +1 -0
- package/codegen/NativeVibrationSpec.g.h +1 -0
- package/codegen/NativeWebSocketModuleSpec.g.h +1 -0
- package/codegen/react/components/rnwcore/ComponentDescriptors.h +0 -1
- package/codegen/react/components/rnwcore/Props.cpp +1 -0
- package/codegen/react/components/rnwcore/Props.h +1 -0
- package/codegen/react/components/rnwcore/ShadowNodes.cpp +0 -1
- package/codegen/react/components/rnwcore/ShadowNodes.h +0 -11
- package/codegen/react/components/rnwcore/States.h +0 -12
- package/codegen/rnwcoreJSI-generated.cpp +219 -186
- package/codegen/rnwcoreJSI.h +942 -511
- package/index.js +10 -3
- package/index.windows.js +10 -3
- package/jest/setup.js +36 -1
- package/just-task.js +15 -0
- package/package.json +22 -22
- package/src/private/animated/NativeAnimatedHelper.js +18 -16
- package/src/private/animated/useAnimatedPropsMemo.js +348 -0
- package/src/private/animated/useAnimatedPropsMemo.windows.js +356 -0
- package/src/private/components/HScrollViewNativeComponents.js +1 -27
- package/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +11 -8
- package/src/private/components/VScrollViewNativeComponents.js +2 -25
- package/src/private/debugging/ReactDevToolsSettingsManager.android.js +20 -0
- package/src/private/debugging/ReactDevToolsSettingsManager.ios.js +30 -0
- package/src/private/debugging/ReactDevToolsSettingsManager.windows.js +20 -0
- package/src/private/{fusebox → debugging}/setUpFuseboxReactDevToolsDispatcher.js +6 -0
- package/src/private/devmenu/DevMenu.d.ts +20 -0
- package/src/private/devmenu/DevMenu.js +31 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +95 -86
- package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +8 -2
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +17 -19
- package/src/private/fusebox/specs/NativeReactDevToolsRuntimeSettingsModule.js +34 -0
- package/src/private/setup/setUpDOM.js +14 -6
- package/src/private/setup/setUpMutationObserver.js +5 -0
- package/src/private/specs/components/AndroidHorizontalScrollContentViewNativeComponent.js +1 -0
- package/src/private/specs/components/RCTModalHostViewNativeComponent.js +8 -0
- package/src/private/specs/modules/NativeAccessibilityInfo.js +9 -0
- package/src/private/specs/modules/NativeAccessibilityManager.js +4 -0
- package/src/private/specs/modules/NativeActionSheetManager.js +2 -0
- package/src/private/specs/modules/NativeAppearance.js +4 -10
- package/src/private/specs/modules/NativeExceptionsManager.js +0 -12
- package/src/private/specs/modules/{NativeDevToolsSettingsManager.js → NativeReactDevToolsSettingsManager.js} +3 -5
- package/src/private/webapis/dom/geometry/DOMRect.js +2 -2
- package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +2 -2
- package/src/private/webapis/dom/nodes/ReactNativeElement.js +2 -3
- package/src/private/webapis/intersectionobserver/IntersectionObserver.js +102 -11
- package/src/private/webapis/intersectionobserver/IntersectionObserverEntry.js +26 -0
- package/src/private/webapis/intersectionobserver/IntersectionObserverManager.js +1 -0
- package/src/private/webapis/intersectionobserver/specs/NativeIntersectionObserver.js +1 -0
- package/src/private/webapis/intersectionobserver/specs/__mocks__/NativeIntersectionObserver.js +9 -0
- package/src/private/webapis/performance/EventTiming.js +13 -8
- package/src/private/webapis/performance/Performance.js +66 -73
- package/src/private/webapis/performance/PerformanceEntry.js +2 -5
- package/src/private/webapis/performance/PerformanceObserver.js +65 -164
- package/src/private/webapis/performance/RawPerformanceEntry.js +1 -1
- package/src/private/webapis/performance/UserTiming.js +11 -7
- package/src/private/webapis/performance/Utilities.js +18 -0
- package/src/private/webapis/performance/specs/NativePerformance.js +71 -2
- package/src/private/webapis/performance/specs/__mocks__/NativePerformanceMock.js +267 -0
- package/templates/cpp-lib/template.config.js +13 -7
- package/templates/templateUtils.js +10 -0
- package/types/index.d.ts +1 -1
- package/types/public/ReactNativeTypes.d.ts +4 -8
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.android.js +0 -35
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.d.ts +0 -20
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.ios.js +0 -49
- package/Libraries/DevToolsSettings/DevToolsSettingsManager.windows.js +0 -35
- package/Libraries/DevToolsSettings/NativeDevToolsSettingsManager.js +0 -13
- package/Libraries/ReactNative/ReactFabricInternals.js +0 -17
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/CallbackWrapper.h +0 -101
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/scrollview/ScrollViewProps.cpp +0 -569
- package/codegen/NativeDevToolsSettingsManagerSpec.g.h +0 -52
- package/codegen/NativePerformanceObserverSpec.g.h +0 -130
- package/src/private/components/useSyncOnScroll.js +0 -48
- package/src/private/webapis/performance/specs/NativePerformanceObserver.js +0 -61
- package/src/private/webapis/performance/specs/__mocks__/NativePerformance.js +0 -67
- package/src/private/webapis/performance/specs/__mocks__/NativePerformanceObserver.js +0 -127
- package/types/experimental.d.ts +0 -59
- /package/src/private/{fusebox → debugging}/FuseboxSessionObserver.js +0 -0
|
@@ -32,16 +32,32 @@
|
|
|
32
32
|
|
|
33
33
|
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
34
34
|
|
|
35
|
+
constexpr float FOCUS_VISUAL_WIDTH = 2.0f;
|
|
36
|
+
|
|
37
|
+
// m_outerVisual
|
|
38
|
+
// |
|
|
39
|
+
// |
|
|
40
|
+
// ----- m_visual <-- Background / clip - Can be a custom visual depending on Component type
|
|
41
|
+
// |
|
|
42
|
+
// ----- Border Visuals x N (BorderPrimitive attached to m_visual)
|
|
43
|
+
// ------Focus Visual Container (created when hosting focus visuals)
|
|
44
|
+
// |
|
|
45
|
+
// |------Inner Focus Visual
|
|
46
|
+
// |
|
|
47
|
+
// ------ Border Visuals x N (BorderPrimitive)
|
|
48
|
+
// |------Outer Focus Visual
|
|
49
|
+
// |
|
|
50
|
+
// ------ Border Visuals x N (BorderPrimitive)
|
|
51
|
+
|
|
35
52
|
ComponentView::ComponentView(
|
|
36
53
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
37
54
|
facebook::react::Tag tag,
|
|
38
55
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
39
|
-
ComponentViewFeatures flags
|
|
40
|
-
|
|
56
|
+
ComponentViewFeatures flags,
|
|
57
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
|
|
58
|
+
: base_type(tag, reactContext, builder), m_compContext(compContext), m_flags(flags) {
|
|
41
59
|
m_outerVisual = compContext.CreateSpriteVisual(); // TODO could be a raw ContainerVisual if we had a
|
|
42
60
|
// CreateContainerVisual in ICompositionContext
|
|
43
|
-
m_focusVisual = compContext.CreateFocusVisual();
|
|
44
|
-
m_outerVisual.InsertAt(m_focusVisual.InnerVisual(), 0);
|
|
45
61
|
}
|
|
46
62
|
|
|
47
63
|
ComponentView::~ComponentView() {
|
|
@@ -68,9 +84,21 @@ void ComponentView::onThemeChanged() noexcept {
|
|
|
68
84
|
}
|
|
69
85
|
}
|
|
70
86
|
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
if (m_borderPrimitive) {
|
|
88
|
+
m_borderPrimitive->onThemeChanged(
|
|
89
|
+
m_layoutMetrics, BorderPrimitive::resolveAndAlignBorderMetrics(m_layoutMetrics, *viewProps()));
|
|
90
|
+
}
|
|
91
|
+
if (m_componentHostingFocusVisual) {
|
|
92
|
+
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive) {
|
|
93
|
+
auto innerFocusMetrics = focusLayoutMetrics(true /*inner*/);
|
|
94
|
+
m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive->onThemeChanged(
|
|
95
|
+
innerFocusMetrics, focusBorderMetrics(true /*inner*/, innerFocusMetrics));
|
|
96
|
+
}
|
|
97
|
+
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusOuterPrimitive) {
|
|
98
|
+
auto outerFocusMetrics = focusLayoutMetrics(true /*inner*/);
|
|
99
|
+
m_componentHostingFocusVisual->m_focusPrimitive->m_focusOuterPrimitive->onThemeChanged(
|
|
100
|
+
outerFocusMetrics, focusBorderMetrics(false /*inner*/, outerFocusMetrics));
|
|
101
|
+
}
|
|
74
102
|
}
|
|
75
103
|
|
|
76
104
|
if ((m_flags & ComponentViewFeatures::ShadowProps) == ComponentViewFeatures::ShadowProps) {
|
|
@@ -131,13 +159,25 @@ void ComponentView::updateProps(
|
|
|
131
159
|
}
|
|
132
160
|
}
|
|
133
161
|
|
|
134
|
-
if (
|
|
135
|
-
|
|
162
|
+
if (m_borderPrimitive) {
|
|
163
|
+
m_borderPrimitive->updateProps(oldViewProps, newViewProps);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (m_componentHostingFocusVisual) {
|
|
167
|
+
if (!newViewProps.enableFocusRing) {
|
|
168
|
+
m_componentHostingFocusVisual->hostFocusVisual(false, get_strong());
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive) {
|
|
172
|
+
m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive->updateProps(oldViewProps, newViewProps);
|
|
173
|
+
}
|
|
174
|
+
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusOuterPrimitive) {
|
|
175
|
+
m_componentHostingFocusVisual->m_focusPrimitive->m_focusOuterPrimitive->updateProps(oldViewProps, newViewProps);
|
|
176
|
+
}
|
|
136
177
|
}
|
|
137
178
|
if ((m_flags & ComponentViewFeatures::ShadowProps) == ComponentViewFeatures::ShadowProps) {
|
|
138
179
|
updateShadowProps(oldViewProps, newViewProps);
|
|
139
180
|
}
|
|
140
|
-
|
|
141
181
|
if (oldViewProps.tooltip != newViewProps.tooltip) {
|
|
142
182
|
if (!m_tooltipTracked && newViewProps.tooltip) {
|
|
143
183
|
TooltipService::GetCurrent(m_reactContext.Properties())->StartTracking(*this);
|
|
@@ -155,13 +195,84 @@ void ComponentView::updateLayoutMetrics(
|
|
|
155
195
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
156
196
|
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
|
|
157
197
|
if ((m_flags & ComponentViewFeatures::NativeBorder) == ComponentViewFeatures::NativeBorder) {
|
|
158
|
-
|
|
198
|
+
updateClippingPath(layoutMetrics, *viewProps());
|
|
199
|
+
OuterVisual().Size(
|
|
200
|
+
{layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
|
|
201
|
+
layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
|
|
202
|
+
OuterVisual().Offset({
|
|
203
|
+
layoutMetrics.frame.origin.x * layoutMetrics.pointScaleFactor,
|
|
204
|
+
layoutMetrics.frame.origin.y * layoutMetrics.pointScaleFactor,
|
|
205
|
+
0.0f,
|
|
206
|
+
});
|
|
159
207
|
}
|
|
160
208
|
|
|
161
209
|
base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
|
|
210
|
+
|
|
211
|
+
if (layoutMetrics != oldLayoutMetrics) {
|
|
212
|
+
if (m_borderPrimitive) {
|
|
213
|
+
m_borderPrimitive->markNeedsUpdate();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (m_componentHostingFocusVisual) {
|
|
217
|
+
m_componentHostingFocusVisual->updateFocusLayoutMetrics();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
162
221
|
UpdateCenterPropertySet();
|
|
163
222
|
}
|
|
164
223
|
|
|
224
|
+
void ComponentView::updateFocusLayoutMetrics() noexcept {
|
|
225
|
+
facebook::react::RectangleEdges<bool> nudgeEdges;
|
|
226
|
+
auto scaleFactor = m_focusPrimitive->m_focusVisualComponent->m_layoutMetrics.pointScaleFactor;
|
|
227
|
+
if (m_focusPrimitive) {
|
|
228
|
+
if (m_focusPrimitive->m_focusOuterPrimitive) {
|
|
229
|
+
auto outerFocusMetrics = m_focusPrimitive->m_focusVisualComponent->focusLayoutMetrics(false /*inner*/);
|
|
230
|
+
|
|
231
|
+
if (outerFocusMetrics.frame.origin.x < 0) {
|
|
232
|
+
nudgeEdges.left = true;
|
|
233
|
+
}
|
|
234
|
+
if (outerFocusMetrics.frame.origin.y < 0) {
|
|
235
|
+
nudgeEdges.top = true;
|
|
236
|
+
}
|
|
237
|
+
if (outerFocusMetrics.frame.getMaxX() > m_layoutMetrics.frame.getMaxX()) {
|
|
238
|
+
nudgeEdges.right = true;
|
|
239
|
+
}
|
|
240
|
+
if (outerFocusMetrics.frame.getMaxY() > m_layoutMetrics.frame.getMaxY()) {
|
|
241
|
+
nudgeEdges.bottom = true;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
m_focusPrimitive->m_focusOuterPrimitive->RootVisual().Size(
|
|
245
|
+
{outerFocusMetrics.frame.size.width * scaleFactor -
|
|
246
|
+
(nudgeEdges.left ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0) -
|
|
247
|
+
(nudgeEdges.right ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0),
|
|
248
|
+
outerFocusMetrics.frame.size.height * scaleFactor -
|
|
249
|
+
(nudgeEdges.top ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0) -
|
|
250
|
+
(nudgeEdges.bottom ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0)});
|
|
251
|
+
m_focusPrimitive->m_focusOuterPrimitive->RootVisual().Offset(
|
|
252
|
+
{nudgeEdges.left ? 0 : -(FOCUS_VISUAL_WIDTH * 2 * scaleFactor),
|
|
253
|
+
nudgeEdges.top ? 0 : -(FOCUS_VISUAL_WIDTH * 2 * scaleFactor),
|
|
254
|
+
0.0f});
|
|
255
|
+
m_focusPrimitive->m_focusOuterPrimitive->markNeedsUpdate();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (m_focusPrimitive->m_focusInnerPrimitive) {
|
|
259
|
+
auto innerFocusMetrics = m_focusPrimitive->m_focusVisualComponent->focusLayoutMetrics(true /*inner*/);
|
|
260
|
+
m_focusPrimitive->m_focusInnerPrimitive->RootVisual().Size(
|
|
261
|
+
{innerFocusMetrics.frame.size.width * scaleFactor -
|
|
262
|
+
(nudgeEdges.left ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0) -
|
|
263
|
+
(nudgeEdges.right ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0),
|
|
264
|
+
innerFocusMetrics.frame.size.height * scaleFactor -
|
|
265
|
+
(nudgeEdges.top ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0) -
|
|
266
|
+
(nudgeEdges.bottom ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0)});
|
|
267
|
+
m_focusPrimitive->m_focusInnerPrimitive->RootVisual().Offset(
|
|
268
|
+
{nudgeEdges.left ? 0 : -FOCUS_VISUAL_WIDTH * scaleFactor,
|
|
269
|
+
nudgeEdges.top ? 0 : -FOCUS_VISUAL_WIDTH * scaleFactor,
|
|
270
|
+
0.0f});
|
|
271
|
+
m_focusPrimitive->m_focusInnerPrimitive->markNeedsUpdate();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
165
276
|
const facebook::react::LayoutMetrics &ComponentView::layoutMetrics() const noexcept {
|
|
166
277
|
return m_layoutMetrics;
|
|
167
278
|
}
|
|
@@ -199,7 +310,27 @@ void ComponentView::FinalizeTransform(
|
|
|
199
310
|
|
|
200
311
|
void ComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept {
|
|
201
312
|
if ((m_flags & ComponentViewFeatures::NativeBorder) == ComponentViewFeatures::NativeBorder) {
|
|
202
|
-
|
|
313
|
+
auto borderMetrics = BorderPrimitive::resolveAndAlignBorderMetrics(m_layoutMetrics, *viewProps());
|
|
314
|
+
if (!m_borderPrimitive && BorderPrimitive::requiresBorder(borderMetrics, theme())) {
|
|
315
|
+
m_borderPrimitive = std::make_shared<BorderPrimitive>(*this, Visual());
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (m_borderPrimitive) {
|
|
319
|
+
m_borderPrimitive->finalize(m_layoutMetrics, borderMetrics);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (m_componentHostingFocusVisual) {
|
|
324
|
+
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive) {
|
|
325
|
+
auto innerFocusMetrics = focusLayoutMetrics(true /*inner*/);
|
|
326
|
+
m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive->finalize(
|
|
327
|
+
innerFocusMetrics, focusBorderMetrics(true /*inner*/, innerFocusMetrics));
|
|
328
|
+
}
|
|
329
|
+
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusOuterPrimitive) {
|
|
330
|
+
auto outerFocusMetrics = focusLayoutMetrics(false /*inner*/);
|
|
331
|
+
m_componentHostingFocusVisual->m_focusPrimitive->m_focusOuterPrimitive->finalize(
|
|
332
|
+
outerFocusMetrics, focusBorderMetrics(false /*inner*/, outerFocusMetrics));
|
|
333
|
+
}
|
|
203
334
|
}
|
|
204
335
|
|
|
205
336
|
if (m_FinalizeTransform) {
|
|
@@ -213,7 +344,12 @@ void ComponentView::onLostFocus(
|
|
|
213
344
|
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
214
345
|
if (args.OriginalSource() == Tag()) {
|
|
215
346
|
m_eventEmitter->onBlur();
|
|
216
|
-
|
|
347
|
+
|
|
348
|
+
if (m_componentHostingFocusVisual) {
|
|
349
|
+
auto s = get_strong();
|
|
350
|
+
|
|
351
|
+
m_componentHostingFocusVisual->hostFocusVisual(false, get_strong());
|
|
352
|
+
}
|
|
217
353
|
if (m_uiaProvider) {
|
|
218
354
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
219
355
|
m_uiaProvider, UIA_HasKeyboardFocusPropertyId, true, false);
|
|
@@ -222,12 +358,47 @@ void ComponentView::onLostFocus(
|
|
|
222
358
|
base_type::onLostFocus(args);
|
|
223
359
|
}
|
|
224
360
|
|
|
361
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ComponentView::visualToHostFocus() noexcept {
|
|
362
|
+
return OuterVisual();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// We want to host focus visuals as close to the focused component as possible. However since the focus visuals extend
|
|
366
|
+
// past the bounds of the component, in cases where additional components are positioned directly next to this one, we'd
|
|
367
|
+
// get zorder issues causing most of the focus rect to be obscured. So we go up the tree until we find a component who's
|
|
368
|
+
// bounds will fix the entire focus rect.
|
|
369
|
+
winrt::com_ptr<ComponentView> ComponentView::focusVisualRoot(const facebook::react::Rect &focusRect) noexcept {
|
|
370
|
+
auto compVisual =
|
|
371
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(OuterVisual());
|
|
372
|
+
if (!compVisual) {
|
|
373
|
+
return get_strong();
|
|
374
|
+
// When not using lifted composition, force the focus visual to host within its own component, as we do not support
|
|
375
|
+
// ParentForTransform
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (facebook::react::Rect::intersect(focusRect, m_layoutMetrics.frame) == focusRect) {
|
|
379
|
+
return get_strong();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (!m_parent) {
|
|
383
|
+
return get_strong();
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return m_parent.as<ComponentView>()->focusVisualRoot(
|
|
387
|
+
{{focusRect.origin.x + m_layoutMetrics.frame.origin.x, focusRect.origin.y + m_layoutMetrics.frame.origin.y},
|
|
388
|
+
focusRect.size});
|
|
389
|
+
}
|
|
390
|
+
|
|
225
391
|
void ComponentView::onGotFocus(
|
|
226
392
|
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
227
393
|
if (args.OriginalSource() == Tag()) {
|
|
228
394
|
m_eventEmitter->onFocus();
|
|
229
|
-
if (
|
|
230
|
-
|
|
395
|
+
if (viewProps()->enableFocusRing) {
|
|
396
|
+
facebook::react::Rect focusRect = m_layoutMetrics.frame;
|
|
397
|
+
focusRect.origin.x -= (FOCUS_VISUAL_WIDTH * 2);
|
|
398
|
+
focusRect.origin.y -= (FOCUS_VISUAL_WIDTH * 2);
|
|
399
|
+
focusRect.size.width += (FOCUS_VISUAL_WIDTH * 2);
|
|
400
|
+
focusRect.size.height += (FOCUS_VISUAL_WIDTH * 2);
|
|
401
|
+
focusVisualRoot(focusRect)->hostFocusVisual(true, get_strong());
|
|
231
402
|
}
|
|
232
403
|
if (m_uiaProvider) {
|
|
233
404
|
auto spProviderSimple = m_uiaProvider.try_as<IRawElementProviderSimple>();
|
|
@@ -325,6 +496,10 @@ void ComponentView::ReleasePointerCapture(
|
|
|
325
496
|
->ReleasePointerCapture(pointer, static_cast<facebook::react::Tag>(Tag()));
|
|
326
497
|
}
|
|
327
498
|
|
|
499
|
+
void ComponentView::SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept {
|
|
500
|
+
m_flags = viewFeatures;
|
|
501
|
+
}
|
|
502
|
+
|
|
328
503
|
RECT ComponentView::getClientRect() const noexcept {
|
|
329
504
|
RECT rc{0};
|
|
330
505
|
facebook::react::Point parentOffset{0};
|
|
@@ -356,907 +531,146 @@ const facebook::react::SharedViewEventEmitter &ComponentView::GetEventEmitter()
|
|
|
356
531
|
return m_eventEmitter;
|
|
357
532
|
}
|
|
358
533
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
ComponentView::SpecialBorderLayerCount>
|
|
362
|
-
ComponentView::FindSpecialBorderLayers() const noexcept {
|
|
363
|
-
std::array<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual, SpecialBorderLayerCount> layers{
|
|
364
|
-
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
|
365
|
-
|
|
366
|
-
if (m_numBorderVisuals) {
|
|
367
|
-
for (uint8_t i = 0; i < m_numBorderVisuals; i++) {
|
|
368
|
-
auto visual = Visual().GetAt(i);
|
|
369
|
-
layers[i] = visual.as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>();
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return layers;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
struct RoundedPathParameters {
|
|
377
|
-
float topLeftRadiusX = 0;
|
|
378
|
-
float topLeftRadiusY = 0;
|
|
379
|
-
float topRightRadiusX = 0;
|
|
380
|
-
float topRightRadiusY = 0;
|
|
381
|
-
float bottomRightRadiusX = 0;
|
|
382
|
-
float bottomRightRadiusY = 0;
|
|
383
|
-
float bottomLeftRadiusX = 0;
|
|
384
|
-
float bottomLeftRadiusY = 0;
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
/*
|
|
388
|
-
* Creates and returns a PathGeometry object used to clip the visuals of an element when a BorderRadius is set.
|
|
389
|
-
* Can also be used as part of a GeometryGroup for drawing a rounded border / innerstroke when called from
|
|
390
|
-
* GetGeometryForRoundedBorder. "params" defines the radii (horizontal and vertical) for each corner (top left, top
|
|
391
|
-
* right, bottom right, bottom left). "rectPathGeometry" defines the bounding box of the generated shape.
|
|
392
|
-
*/
|
|
393
|
-
static winrt::com_ptr<ID2D1PathGeometry> GenerateRoundedRectPathGeometry(
|
|
394
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
395
|
-
const RoundedPathParameters ¶ms,
|
|
396
|
-
const facebook::react::RectangleEdges<float> &rectPathGeometry) noexcept {
|
|
397
|
-
winrt::com_ptr<ID2D1PathGeometry> pathGeometry;
|
|
398
|
-
winrt::com_ptr<ID2D1Factory1> spD2dFactory;
|
|
399
|
-
compContext.as<::Microsoft::ReactNative::Composition::Experimental::ICompositionContextInterop>()->D2DFactory(
|
|
400
|
-
spD2dFactory.put());
|
|
401
|
-
|
|
402
|
-
// Create a path geometry.
|
|
403
|
-
HRESULT hr = spD2dFactory->CreatePathGeometry(pathGeometry.put());
|
|
404
|
-
if (FAILED(hr)) {
|
|
405
|
-
assert(false);
|
|
406
|
-
return nullptr;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// Write to the path geometry using the geometry sink.
|
|
410
|
-
winrt::com_ptr<ID2D1GeometrySink> spSink = nullptr;
|
|
411
|
-
hr = pathGeometry->Open(spSink.put());
|
|
412
|
-
|
|
413
|
-
if (FAILED(hr)) {
|
|
414
|
-
assert(false);
|
|
415
|
-
return nullptr;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
float left = rectPathGeometry.left;
|
|
419
|
-
float right = rectPathGeometry.right;
|
|
420
|
-
float top = rectPathGeometry.top;
|
|
421
|
-
float bottom = rectPathGeometry.bottom;
|
|
422
|
-
|
|
423
|
-
// This function uses Cubic Beziers to approximate Arc segments, even though D2D supports arcs.
|
|
424
|
-
// This is INTENTIONAL. D2D Arc Segments are eventually converted into cubic beziers, but this
|
|
425
|
-
// is done in such a way that we don't have control over how many bezier curve segments are used
|
|
426
|
-
// for each arc. We need to ensure that we always use the same number of control points so that
|
|
427
|
-
// our paths can be used in a PathKeyFrameAnimation.
|
|
428
|
-
// Value for control point scale factor derived from methods described in:
|
|
429
|
-
// https://web.archive.org/web/20200322075504/http://itc.ktu.lt/index.php/ITC/article/download/11812/6479
|
|
430
|
-
constexpr float controlPointScaleFactor = 0.44771528244f; // 1 - (4 * (sqrtf(2.0f) - 1) / 3.0f);
|
|
431
|
-
|
|
432
|
-
#ifdef DEBUG
|
|
433
|
-
// std::sqrtf is not constexpr, so we precalculated this and wrote it in a constexpr form above.
|
|
434
|
-
// On debug, we should still check that the values are equivalent, though.
|
|
435
|
-
static float calculatedScaleFactor = 1 - (4 * (sqrtf(2.0f) - 1) / 3.0f);
|
|
436
|
-
assert(controlPointScaleFactor == calculatedScaleFactor);
|
|
437
|
-
#endif // DEBUG
|
|
438
|
-
|
|
439
|
-
bool needsConsistentNumberOfControlPoints = true; // VisualVersion::IsUseWinCompClippingRegionEnabled();
|
|
440
|
-
|
|
441
|
-
if (needsConsistentNumberOfControlPoints || (params.topLeftRadiusX != 0.0 && params.topLeftRadiusY != 0.0)) {
|
|
442
|
-
spSink->BeginFigure(D2D1::Point2F(left + params.topLeftRadiusX, top), D2D1_FIGURE_BEGIN_FILLED);
|
|
443
|
-
} else {
|
|
444
|
-
spSink->BeginFigure(D2D1::Point2F(left, top), D2D1_FIGURE_BEGIN_FILLED);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Move to the top right corner
|
|
448
|
-
spSink->AddLine(D2D1::Point2F(right - params.topRightRadiusX, top));
|
|
449
|
-
if (needsConsistentNumberOfControlPoints) {
|
|
450
|
-
D2D1_BEZIER_SEGMENT arcSegmentTopRight = {
|
|
451
|
-
D2D1::Point2F(right - controlPointScaleFactor * params.topRightRadiusX, top),
|
|
452
|
-
D2D1::Point2F(right, top + controlPointScaleFactor * params.topRightRadiusY),
|
|
453
|
-
D2D1::Point2F(right, top + params.topRightRadiusY)};
|
|
454
|
-
|
|
455
|
-
spSink->AddBezier(&arcSegmentTopRight);
|
|
456
|
-
} else if (params.topRightRadiusX != 0.0 && params.topRightRadiusY != 0.0) {
|
|
457
|
-
D2D1_ARC_SEGMENT arcSegmentTopRight = {
|
|
458
|
-
D2D1::Point2F(right, top + params.topRightRadiusY),
|
|
459
|
-
D2D1::SizeF(params.topRightRadiusX, params.topRightRadiusY),
|
|
460
|
-
0.0f,
|
|
461
|
-
D2D1_SWEEP_DIRECTION_CLOCKWISE,
|
|
462
|
-
D2D1_ARC_SIZE_SMALL};
|
|
463
|
-
|
|
464
|
-
spSink->AddArc(&arcSegmentTopRight);
|
|
465
|
-
} else {
|
|
466
|
-
spSink->AddLine(D2D1::Point2F(right, top));
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
// Move to the bottom right corner
|
|
470
|
-
spSink->AddLine(D2D1::Point2F(right, bottom - params.bottomRightRadiusY));
|
|
471
|
-
if (needsConsistentNumberOfControlPoints) {
|
|
472
|
-
D2D1_BEZIER_SEGMENT arcSegmentBottomRight = {
|
|
473
|
-
D2D1::Point2F(right, bottom - controlPointScaleFactor * params.bottomRightRadiusY),
|
|
474
|
-
D2D1::Point2F(right - controlPointScaleFactor * params.bottomRightRadiusX, bottom),
|
|
475
|
-
D2D1::Point2F(right - params.bottomRightRadiusX, bottom)};
|
|
476
|
-
|
|
477
|
-
spSink->AddBezier(&arcSegmentBottomRight);
|
|
478
|
-
} else if (params.bottomRightRadiusX != 0.0 && params.bottomRightRadiusY != 0.0) {
|
|
479
|
-
D2D1_ARC_SEGMENT arcSegmentBottomRight = {
|
|
480
|
-
D2D1::Point2F(right - params.bottomRightRadiusX, bottom),
|
|
481
|
-
D2D1::SizeF(params.bottomRightRadiusX, params.bottomRightRadiusY),
|
|
482
|
-
0.0f,
|
|
483
|
-
D2D1_SWEEP_DIRECTION_CLOCKWISE,
|
|
484
|
-
D2D1_ARC_SIZE_SMALL};
|
|
485
|
-
|
|
486
|
-
spSink->AddArc(&arcSegmentBottomRight);
|
|
487
|
-
} else {
|
|
488
|
-
spSink->AddLine(D2D1::Point2F(right, bottom));
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// Move to the bottom left corner
|
|
492
|
-
spSink->AddLine(D2D1::Point2F(left + params.bottomLeftRadiusX, bottom));
|
|
493
|
-
if (needsConsistentNumberOfControlPoints) {
|
|
494
|
-
D2D1_BEZIER_SEGMENT arcSegmentBottomLeft = {
|
|
495
|
-
D2D1::Point2F(left + controlPointScaleFactor * params.bottomLeftRadiusX, bottom),
|
|
496
|
-
D2D1::Point2F(left, bottom - controlPointScaleFactor * params.bottomLeftRadiusY),
|
|
497
|
-
D2D1::Point2F(left, bottom - params.bottomLeftRadiusY)};
|
|
498
|
-
|
|
499
|
-
spSink->AddBezier(&arcSegmentBottomLeft);
|
|
500
|
-
} else if (params.bottomLeftRadiusX != 0.0 && params.bottomLeftRadiusY != 0.0) {
|
|
501
|
-
D2D1_ARC_SEGMENT arcSegmentBottomLeft = {
|
|
502
|
-
D2D1::Point2F(left, bottom - params.bottomLeftRadiusY),
|
|
503
|
-
D2D1::SizeF(params.bottomLeftRadiusX, params.bottomLeftRadiusY),
|
|
504
|
-
0.0f,
|
|
505
|
-
D2D1_SWEEP_DIRECTION_CLOCKWISE,
|
|
506
|
-
D2D1_ARC_SIZE_SMALL};
|
|
507
|
-
|
|
508
|
-
spSink->AddArc(&arcSegmentBottomLeft);
|
|
509
|
-
} else {
|
|
510
|
-
spSink->AddLine(D2D1::Point2F(left, bottom));
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Move to the top left corner
|
|
514
|
-
spSink->AddLine(D2D1::Point2F(left, top + params.topLeftRadiusY));
|
|
515
|
-
if (needsConsistentNumberOfControlPoints) {
|
|
516
|
-
D2D1_BEZIER_SEGMENT arcSegmentTopLeft = {
|
|
517
|
-
D2D1::Point2F(left, top + controlPointScaleFactor * params.topLeftRadiusY),
|
|
518
|
-
D2D1::Point2F(left + controlPointScaleFactor * params.topLeftRadiusX, top),
|
|
519
|
-
D2D1::Point2F(left + params.topLeftRadiusX, top)};
|
|
520
|
-
|
|
521
|
-
spSink->AddBezier(&arcSegmentTopLeft);
|
|
522
|
-
} else if (params.topLeftRadiusX != 0.0 && params.topLeftRadiusY != 0.0) {
|
|
523
|
-
D2D1_ARC_SEGMENT arcSegmentTopLeft = {
|
|
524
|
-
D2D1::Point2F(left + params.topLeftRadiusX, top),
|
|
525
|
-
D2D1::SizeF(params.topLeftRadiusX, params.topLeftRadiusY),
|
|
526
|
-
0.0f,
|
|
527
|
-
D2D1_SWEEP_DIRECTION_CLOCKWISE,
|
|
528
|
-
D2D1_ARC_SIZE_SMALL};
|
|
529
|
-
|
|
530
|
-
spSink->AddArc(&arcSegmentTopLeft);
|
|
531
|
-
} else {
|
|
532
|
-
spSink->AddLine(D2D1::Point2F(left, top));
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
spSink->EndFigure(D2D1_FIGURE_END_CLOSED);
|
|
536
|
-
spSink->Close();
|
|
537
|
-
|
|
538
|
-
return pathGeometry;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
RoundedPathParameters GenerateRoundedPathParameters(
|
|
542
|
-
const facebook::react::RectangleCorners<facebook::react::CornerRadii> &baseRadius,
|
|
543
|
-
const facebook::react::RectangleEdges<float> &inset,
|
|
544
|
-
const facebook::react::Size &pathSize) noexcept {
|
|
545
|
-
RoundedPathParameters result;
|
|
546
|
-
|
|
547
|
-
if (pathSize.width == 0 || pathSize.height == 0) {
|
|
548
|
-
return result;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
float totalTopRadius = baseRadius.topLeft.horizontal + baseRadius.topRight.horizontal;
|
|
552
|
-
float totalRightRadius = baseRadius.topRight.vertical + baseRadius.bottomRight.vertical;
|
|
553
|
-
float totalBottomRadius = baseRadius.bottomRight.horizontal + baseRadius.bottomLeft.horizontal;
|
|
554
|
-
float totalLeftRadius = baseRadius.bottomLeft.vertical + baseRadius.topLeft.vertical;
|
|
555
|
-
|
|
556
|
-
float maxHorizontalRadius = std::max(totalTopRadius, totalBottomRadius);
|
|
557
|
-
float maxVerticalRadius = std::max(totalLeftRadius, totalRightRadius);
|
|
558
|
-
|
|
559
|
-
double totalWidth = inset.left + inset.right + pathSize.width;
|
|
560
|
-
double totalHeight = inset.top + inset.bottom + pathSize.height;
|
|
561
|
-
|
|
562
|
-
float scaleHoriz = static_cast<float>(maxHorizontalRadius / totalWidth);
|
|
563
|
-
float scaleVert = static_cast<float>(maxVerticalRadius / totalHeight);
|
|
564
|
-
|
|
565
|
-
float maxScale = std::max(1.0f, std::max(scaleHoriz, scaleVert));
|
|
566
|
-
|
|
567
|
-
result.topLeftRadiusX = std::max(0.0f, baseRadius.topLeft.horizontal / maxScale - inset.left);
|
|
568
|
-
result.topLeftRadiusY = std::max(0.0f, baseRadius.topLeft.vertical / maxScale - inset.top);
|
|
569
|
-
result.topRightRadiusX = std::max(0.0f, baseRadius.topRight.horizontal / maxScale - inset.right);
|
|
570
|
-
result.topRightRadiusY = std::max(0.0f, baseRadius.topRight.vertical / maxScale - inset.top);
|
|
571
|
-
result.bottomRightRadiusX = std::max(0.0f, baseRadius.bottomRight.horizontal / maxScale - inset.right);
|
|
572
|
-
result.bottomRightRadiusY = std::max(0.0f, baseRadius.bottomRight.vertical / maxScale - inset.bottom);
|
|
573
|
-
result.bottomLeftRadiusX = std::max(0.0f, baseRadius.bottomLeft.horizontal / maxScale - inset.left);
|
|
574
|
-
result.bottomLeftRadiusY = std::max(0.0f, baseRadius.bottomLeft.vertical / maxScale - inset.bottom);
|
|
575
|
-
|
|
576
|
-
return result;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
static winrt::com_ptr<ID2D1PathGeometry> GenerateRoundedRectPathGeometry(
|
|
580
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
581
|
-
const facebook::react::RectangleCorners<facebook::react::CornerRadii> &baseRadius,
|
|
582
|
-
const facebook::react::RectangleEdges<float> &inset,
|
|
583
|
-
const facebook::react::RectangleEdges<float> &rectPathGeometry) noexcept {
|
|
584
|
-
RoundedPathParameters params = GenerateRoundedPathParameters(
|
|
585
|
-
baseRadius,
|
|
586
|
-
inset,
|
|
587
|
-
{rectPathGeometry.right - rectPathGeometry.left, rectPathGeometry.bottom - rectPathGeometry.top});
|
|
588
|
-
|
|
589
|
-
return GenerateRoundedRectPathGeometry(compContext, params, rectPathGeometry);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
void DrawShape(
|
|
593
|
-
ID2D1RenderTarget *pRT,
|
|
594
|
-
const D2D1_RECT_F &rect,
|
|
595
|
-
ID2D1Brush *brush,
|
|
596
|
-
FLOAT strokeWidth,
|
|
597
|
-
ID2D1StrokeStyle *strokeStyle) {
|
|
598
|
-
pRT->DrawRectangle(rect, brush, strokeWidth, strokeStyle);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
void DrawShape(ID2D1RenderTarget *pRT, ID2D1GeometryGroup &geometry, ID2D1Brush *brush, FLOAT, ID2D1StrokeStyle *) {
|
|
602
|
-
pRT->FillGeometry(&geometry, brush);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
void DrawShape(
|
|
606
|
-
ID2D1RenderTarget *pRT,
|
|
607
|
-
ID2D1PathGeometry &geometry,
|
|
608
|
-
ID2D1Brush *brush,
|
|
609
|
-
FLOAT strokeWidth,
|
|
610
|
-
ID2D1StrokeStyle *strokeStyle) {
|
|
611
|
-
pRT->DrawGeometry(&geometry, brush, strokeWidth, strokeStyle);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
template <typename TShape>
|
|
615
|
-
void SetBorderLayerPropertiesCommon(
|
|
616
|
-
winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme,
|
|
617
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
618
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual &layer,
|
|
619
|
-
TShape &shape,
|
|
620
|
-
winrt::com_ptr<::Microsoft::ReactNative::Composition::Experimental::ICompositionDrawingSurfaceInterop>
|
|
621
|
-
&borderTexture,
|
|
622
|
-
const D2D1_RECT_F &textureRect,
|
|
623
|
-
facebook::react::Point anchorPoint,
|
|
624
|
-
facebook::react::Point anchorOffset,
|
|
625
|
-
winrt::Windows::Foundation::Numerics::float2 size,
|
|
626
|
-
winrt::Windows::Foundation::Numerics::float2 relativeSizeAdjustment,
|
|
627
|
-
FLOAT strokeWidth,
|
|
628
|
-
const facebook::react::SharedColor &borderColor,
|
|
629
|
-
facebook::react::BorderStyle borderStyle) {
|
|
630
|
-
layer.Offset({anchorOffset.x, anchorOffset.y, 0}, {anchorPoint.x, anchorPoint.y, 0});
|
|
631
|
-
layer.RelativeSizeWithOffset(size, relativeSizeAdjustment);
|
|
632
|
-
layer.as<::Microsoft::ReactNative::Composition::Experimental::IVisualInterop>()->SetClippingPath(nullptr);
|
|
633
|
-
|
|
634
|
-
if ((textureRect.right - textureRect.left) <= 0 || (textureRect.bottom - textureRect.top) <= 0)
|
|
635
|
-
return;
|
|
636
|
-
|
|
637
|
-
auto surface = compContext.CreateDrawingSurfaceBrush(
|
|
638
|
-
{(textureRect.right - textureRect.left), (textureRect.bottom - textureRect.top)},
|
|
639
|
-
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
|
|
640
|
-
winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
|
|
641
|
-
surface.as(borderTexture);
|
|
642
|
-
|
|
643
|
-
layer.Brush(surface);
|
|
644
|
-
|
|
645
|
-
POINT offset;
|
|
646
|
-
::Microsoft::ReactNative::Composition::AutoDrawDrawingSurface autoDraw(
|
|
647
|
-
surface, 1.0f /* We have already done the dpi scaling */, &offset);
|
|
648
|
-
if (auto pRT = autoDraw.GetRenderTarget()) {
|
|
649
|
-
// Clear with transparency
|
|
650
|
-
pRT->Clear();
|
|
651
|
-
|
|
652
|
-
if (!facebook::react::isColorMeaningful(borderColor)) {
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
winrt::com_ptr<ID2D1Factory> spFactory;
|
|
657
|
-
pRT->GetFactory(spFactory.put());
|
|
658
|
-
assert(spFactory);
|
|
659
|
-
if (spFactory == nullptr)
|
|
660
|
-
return;
|
|
661
|
-
|
|
662
|
-
winrt::com_ptr<ID2D1SolidColorBrush> spBorderBrush;
|
|
663
|
-
pRT->CreateSolidColorBrush(theme->D2DColor(*borderColor), spBorderBrush.put());
|
|
664
|
-
assert(spBorderBrush);
|
|
665
|
-
if (spBorderBrush == nullptr)
|
|
666
|
-
return;
|
|
667
|
-
|
|
668
|
-
winrt::com_ptr<ID2D1StrokeStyle> spStrokeStyle;
|
|
669
|
-
|
|
670
|
-
enum class BorderStyle { Solid, Dotted, Dashed };
|
|
671
|
-
|
|
672
|
-
if (borderStyle == facebook::react::BorderStyle::Dotted || borderStyle == facebook::react::BorderStyle::Dashed) {
|
|
673
|
-
const auto capStyle =
|
|
674
|
-
borderStyle == facebook::react::BorderStyle::Dashed ? D2D1_CAP_STYLE_FLAT : D2D1_CAP_STYLE_ROUND;
|
|
675
|
-
const auto strokeStyleProps = D2D1::StrokeStyleProperties(
|
|
676
|
-
capStyle,
|
|
677
|
-
capStyle,
|
|
678
|
-
capStyle,
|
|
679
|
-
D2D1_LINE_JOIN_MITER,
|
|
680
|
-
10.0f,
|
|
681
|
-
borderStyle == facebook::react::BorderStyle::Dashed ? D2D1_DASH_STYLE_DASH : D2D1_DASH_STYLE_DOT,
|
|
682
|
-
0.0f);
|
|
683
|
-
spFactory->CreateStrokeStyle(&strokeStyleProps, nullptr, 0, spStrokeStyle.put());
|
|
684
|
-
}
|
|
685
|
-
D2D1::Matrix3x2F originalTransform;
|
|
686
|
-
D2D1::Matrix3x2F translationTransform =
|
|
687
|
-
D2D1::Matrix3x2F::Translation(-textureRect.left + offset.x, -textureRect.top + offset.y);
|
|
688
|
-
|
|
689
|
-
pRT->GetTransform(&originalTransform);
|
|
690
|
-
translationTransform = originalTransform * translationTransform;
|
|
691
|
-
|
|
692
|
-
pRT->SetTransform(translationTransform);
|
|
693
|
-
|
|
694
|
-
DrawShape(pRT, shape, spBorderBrush.get(), strokeWidth, spStrokeStyle.get());
|
|
695
|
-
|
|
696
|
-
pRT->SetTransform(originalTransform);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
template <typename TShape>
|
|
701
|
-
void SetBorderLayerProperties(
|
|
702
|
-
winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme,
|
|
703
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
704
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual &layer,
|
|
705
|
-
TShape &shape,
|
|
706
|
-
winrt::com_ptr<::Microsoft::ReactNative::Composition::Experimental::ICompositionDrawingSurfaceInterop>
|
|
707
|
-
&borderTexture,
|
|
708
|
-
const D2D1_RECT_F &textureRect,
|
|
709
|
-
facebook::react::Point anchorPoint,
|
|
710
|
-
facebook::react::Point anchorOffset,
|
|
711
|
-
winrt::Windows::Foundation::Numerics::float2 size,
|
|
712
|
-
winrt::Windows::Foundation::Numerics::float2 relativeSizeAdjustment,
|
|
713
|
-
FLOAT strokeWidth,
|
|
714
|
-
const facebook::react::SharedColor &borderColor,
|
|
715
|
-
facebook::react::BorderStyle borderStyle) {
|
|
716
|
-
if constexpr (!std::is_base_of_v<ID2D1GeometryGroup, TShape>) {
|
|
717
|
-
SetBorderLayerPropertiesCommon(
|
|
718
|
-
theme,
|
|
719
|
-
compContext,
|
|
720
|
-
layer,
|
|
721
|
-
shape,
|
|
722
|
-
borderTexture,
|
|
723
|
-
textureRect,
|
|
724
|
-
anchorPoint,
|
|
725
|
-
anchorOffset,
|
|
726
|
-
size,
|
|
727
|
-
relativeSizeAdjustment,
|
|
728
|
-
strokeWidth,
|
|
729
|
-
borderColor,
|
|
730
|
-
borderStyle);
|
|
731
|
-
} else {
|
|
732
|
-
// if (VisualVersion::IsUseWinCompClippingRegionEnabled())
|
|
733
|
-
{
|
|
734
|
-
layer.Offset({anchorOffset.x, anchorOffset.y, 0}, {anchorPoint.x, anchorPoint.y, 0});
|
|
735
|
-
layer.RelativeSizeWithOffset(
|
|
736
|
-
{textureRect.right - textureRect.left, textureRect.bottom - textureRect.top}, {0.0f, 0.0f});
|
|
737
|
-
|
|
738
|
-
layer.Brush(theme->Brush(*borderColor));
|
|
739
|
-
|
|
740
|
-
winrt::com_ptr<ID2D1Factory1> spD2dFactory;
|
|
741
|
-
compContext.as<::Microsoft::ReactNative::Composition::Experimental::ICompositionContextInterop>()->D2DFactory(
|
|
742
|
-
spD2dFactory.put());
|
|
743
|
-
|
|
744
|
-
winrt::com_ptr<ID2D1TransformedGeometry> transformedShape;
|
|
745
|
-
D2D1::Matrix3x2F translationTransform = D2D1::Matrix3x2F::Translation(-textureRect.left, -textureRect.top);
|
|
746
|
-
winrt::check_hresult(
|
|
747
|
-
spD2dFactory->CreateTransformedGeometry(&shape, &translationTransform, transformedShape.put()));
|
|
748
|
-
|
|
749
|
-
layer.as<::Microsoft::ReactNative::Composition::Experimental::IVisualInterop>()->SetClippingPath(
|
|
750
|
-
transformedShape.get());
|
|
751
|
-
}
|
|
752
|
-
/*
|
|
753
|
-
else
|
|
754
|
-
{
|
|
755
|
-
SetBorderLayerPropertiesCommon(theme, comContext, layer, shape, borderTexture, textureRect,
|
|
756
|
-
anchorPoint, anchorOffset, strokeWidth, borderColor, borderStyle);
|
|
757
|
-
}
|
|
758
|
-
*/
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
namespace AnchorPosition {
|
|
763
|
-
const float Left = 0.0;
|
|
764
|
-
const float Center = 0.5;
|
|
765
|
-
const float Right = 1.0;
|
|
766
|
-
const float Top = 0.0;
|
|
767
|
-
const float Bottom = 1.0;
|
|
768
|
-
} // namespace AnchorPosition
|
|
769
|
-
|
|
770
|
-
template <typename TShape>
|
|
771
|
-
void DrawAllBorderLayers(
|
|
772
|
-
winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme,
|
|
773
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
774
|
-
std::array<
|
|
775
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual,
|
|
776
|
-
ComponentView::SpecialBorderLayerCount> &spBorderLayers,
|
|
777
|
-
TShape &shape,
|
|
778
|
-
const facebook::react::BorderWidths &borderWidths,
|
|
779
|
-
const facebook::react::BorderRadii &borderRadii,
|
|
780
|
-
float textureWidth,
|
|
781
|
-
float textureHeight,
|
|
782
|
-
const facebook::react::BorderColors &borderColors,
|
|
783
|
-
facebook::react::BorderStyle borderStyle) {
|
|
784
|
-
// Now that we've drawn our nice border in one layer, split it into its component layers
|
|
785
|
-
winrt::com_ptr<::Microsoft::ReactNative::Composition::Experimental::ICompositionDrawingSurfaceInterop>
|
|
786
|
-
spTextures[ComponentView::SpecialBorderLayerCount];
|
|
787
|
-
|
|
788
|
-
// Set component border properties
|
|
789
|
-
// Top Left Corner
|
|
790
|
-
SetBorderLayerProperties(
|
|
791
|
-
theme,
|
|
792
|
-
compContext,
|
|
793
|
-
spBorderLayers[0],
|
|
794
|
-
shape,
|
|
795
|
-
spTextures[0], // Target Layer, Source Texture, Target Texture
|
|
796
|
-
{0,
|
|
797
|
-
0,
|
|
798
|
-
borderRadii.topLeft.vertical + borderWidths.left,
|
|
799
|
-
borderRadii.topLeft.horizontal + borderWidths.top}, // Texture Left, Top, Width, Height
|
|
800
|
-
{AnchorPosition::Left, AnchorPosition::Top}, // Layer Anchor Point
|
|
801
|
-
{0, 0}, // Layer Anchor Offset
|
|
802
|
-
{borderRadii.topLeft.vertical + borderWidths.left, borderRadii.topLeft.horizontal + borderWidths.top}, // size
|
|
803
|
-
{0.0f, 0.0f}, // relativeSize
|
|
804
|
-
std::max(borderWidths.left, borderWidths.top),
|
|
805
|
-
borderColors.left ? borderColors.left : borderColors.top,
|
|
806
|
-
borderStyle);
|
|
807
|
-
|
|
808
|
-
// Top Edge Border
|
|
809
|
-
SetBorderLayerProperties(
|
|
810
|
-
theme,
|
|
811
|
-
compContext,
|
|
812
|
-
spBorderLayers[1],
|
|
813
|
-
shape,
|
|
814
|
-
spTextures[1],
|
|
815
|
-
{borderRadii.topLeft.vertical + borderWidths.left,
|
|
816
|
-
0,
|
|
817
|
-
textureWidth - (borderRadii.topRight.vertical + borderWidths.right),
|
|
818
|
-
borderWidths.top},
|
|
819
|
-
{AnchorPosition::Left, AnchorPosition::Top},
|
|
820
|
-
{borderRadii.topLeft.vertical + borderWidths.left, 0},
|
|
821
|
-
{-(borderRadii.topLeft.vertical + borderWidths.left + borderRadii.topRight.vertical + borderWidths.right),
|
|
822
|
-
borderWidths.top}, // size
|
|
823
|
-
{1.0f, 0.0f}, // relativeSize
|
|
824
|
-
borderWidths.top,
|
|
825
|
-
borderColors.top,
|
|
826
|
-
borderStyle);
|
|
827
|
-
|
|
828
|
-
// Top Right Corner Border
|
|
829
|
-
SetBorderLayerProperties(
|
|
830
|
-
theme,
|
|
831
|
-
compContext,
|
|
832
|
-
spBorderLayers[2],
|
|
833
|
-
shape,
|
|
834
|
-
spTextures[2],
|
|
835
|
-
{textureWidth - (borderRadii.topRight.vertical + borderWidths.right),
|
|
836
|
-
0,
|
|
837
|
-
textureWidth,
|
|
838
|
-
borderRadii.topRight.horizontal + borderWidths.top},
|
|
839
|
-
{AnchorPosition::Right, AnchorPosition::Top},
|
|
840
|
-
{-(borderRadii.topRight.vertical + borderWidths.right), 0},
|
|
841
|
-
{borderRadii.topRight.vertical + borderWidths.right, borderRadii.topRight.horizontal + borderWidths.top},
|
|
842
|
-
{0.0f, 0.0f},
|
|
843
|
-
std::max(borderWidths.right, borderWidths.top),
|
|
844
|
-
borderColors.right ? borderColors.right : borderColors.top,
|
|
845
|
-
borderStyle);
|
|
846
|
-
|
|
847
|
-
// Right Edge Border
|
|
848
|
-
SetBorderLayerProperties(
|
|
849
|
-
theme,
|
|
850
|
-
compContext,
|
|
851
|
-
spBorderLayers[3],
|
|
852
|
-
shape,
|
|
853
|
-
spTextures[3],
|
|
854
|
-
{textureWidth - borderWidths.right,
|
|
855
|
-
borderWidths.top + borderRadii.topRight.horizontal,
|
|
856
|
-
textureWidth,
|
|
857
|
-
textureHeight - (borderWidths.bottom + borderRadii.bottomRight.horizontal)},
|
|
858
|
-
{AnchorPosition::Right, AnchorPosition::Top},
|
|
859
|
-
{-borderWidths.right, borderWidths.top + borderRadii.topRight.horizontal},
|
|
860
|
-
{borderWidths.right,
|
|
861
|
-
-(borderWidths.top + borderRadii.topRight.horizontal + borderWidths.bottom +
|
|
862
|
-
borderRadii.bottomRight.horizontal)}, // size
|
|
863
|
-
{0.0f, 1.0f},
|
|
864
|
-
borderWidths.right,
|
|
865
|
-
borderColors.right,
|
|
866
|
-
borderStyle);
|
|
867
|
-
|
|
868
|
-
// Bottom Right Corner Border
|
|
869
|
-
SetBorderLayerProperties(
|
|
870
|
-
theme,
|
|
871
|
-
compContext,
|
|
872
|
-
spBorderLayers[4],
|
|
873
|
-
shape,
|
|
874
|
-
spTextures[4],
|
|
875
|
-
{textureWidth - (borderWidths.right + borderRadii.bottomRight.vertical),
|
|
876
|
-
textureHeight - (borderWidths.bottom + borderRadii.bottomRight.horizontal),
|
|
877
|
-
textureWidth,
|
|
878
|
-
textureHeight},
|
|
879
|
-
{AnchorPosition::Right, AnchorPosition::Bottom},
|
|
880
|
-
{-(borderWidths.right + borderRadii.bottomRight.vertical),
|
|
881
|
-
-(borderWidths.bottom + borderRadii.bottomRight.horizontal)},
|
|
882
|
-
{borderWidths.right + borderRadii.bottomRight.vertical, borderWidths.bottom + borderRadii.bottomRight.horizontal},
|
|
883
|
-
{0, 0},
|
|
884
|
-
std::max(borderWidths.right, borderWidths.bottom),
|
|
885
|
-
borderColors.right ? borderColors.right : borderColors.bottom,
|
|
886
|
-
borderStyle);
|
|
887
|
-
|
|
888
|
-
// Bottom Edge Border
|
|
889
|
-
SetBorderLayerProperties(
|
|
890
|
-
theme,
|
|
891
|
-
compContext,
|
|
892
|
-
spBorderLayers[5],
|
|
893
|
-
shape,
|
|
894
|
-
spTextures[5],
|
|
895
|
-
{borderWidths.left + borderRadii.bottomLeft.vertical,
|
|
896
|
-
textureHeight - borderWidths.bottom,
|
|
897
|
-
textureWidth - (borderWidths.right + borderRadii.bottomRight.vertical),
|
|
898
|
-
textureHeight},
|
|
899
|
-
{AnchorPosition::Left, AnchorPosition::Bottom},
|
|
900
|
-
{borderWidths.left + borderRadii.bottomLeft.vertical, -borderWidths.bottom},
|
|
901
|
-
{-(borderWidths.right + borderRadii.bottomLeft.vertical + borderWidths.left + borderRadii.bottomRight.vertical),
|
|
902
|
-
borderWidths.bottom},
|
|
903
|
-
{1.0f, 0.0f},
|
|
904
|
-
borderWidths.bottom,
|
|
905
|
-
borderColors.bottom,
|
|
906
|
-
borderStyle);
|
|
907
|
-
|
|
908
|
-
// Bottom Left Corner Border
|
|
909
|
-
SetBorderLayerProperties(
|
|
910
|
-
theme,
|
|
911
|
-
compContext,
|
|
912
|
-
spBorderLayers[6],
|
|
913
|
-
shape,
|
|
914
|
-
spTextures[6],
|
|
915
|
-
{0,
|
|
916
|
-
textureHeight - (borderWidths.bottom + borderRadii.bottomLeft.horizontal),
|
|
917
|
-
borderWidths.left + borderRadii.bottomLeft.vertical,
|
|
918
|
-
textureHeight},
|
|
919
|
-
{AnchorPosition::Left, AnchorPosition::Bottom},
|
|
920
|
-
{0, -(borderWidths.bottom + borderRadii.bottomLeft.horizontal)},
|
|
921
|
-
{borderWidths.left + borderRadii.bottomLeft.vertical, borderWidths.bottom + borderRadii.bottomLeft.horizontal},
|
|
922
|
-
{0, 0},
|
|
923
|
-
std::max(borderWidths.left, borderWidths.bottom),
|
|
924
|
-
borderColors.left ? borderColors.left : borderColors.bottom,
|
|
925
|
-
borderStyle);
|
|
926
|
-
|
|
927
|
-
// Left Edge Border
|
|
928
|
-
SetBorderLayerProperties(
|
|
929
|
-
theme,
|
|
930
|
-
compContext,
|
|
931
|
-
spBorderLayers[7],
|
|
932
|
-
shape,
|
|
933
|
-
spTextures[7],
|
|
934
|
-
{0,
|
|
935
|
-
borderWidths.top + borderRadii.topLeft.horizontal,
|
|
936
|
-
borderWidths.left,
|
|
937
|
-
textureHeight - (borderWidths.bottom + borderRadii.bottomLeft.horizontal)},
|
|
938
|
-
{AnchorPosition::Left, AnchorPosition::Top},
|
|
939
|
-
{0, borderWidths.top + borderRadii.topLeft.horizontal},
|
|
940
|
-
{borderWidths.left,
|
|
941
|
-
-(borderWidths.top + borderRadii.topLeft.horizontal + borderWidths.bottom + borderRadii.bottomLeft.horizontal)},
|
|
942
|
-
{0, 1},
|
|
943
|
-
borderWidths.left,
|
|
944
|
-
borderColors.left,
|
|
945
|
-
borderStyle);
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
winrt::com_ptr<ID2D1GeometryGroup> GetGeometryForRoundedBorder(
|
|
949
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
950
|
-
const facebook::react::RectangleCorners<facebook::react::CornerRadii> &radius,
|
|
951
|
-
const facebook::react::RectangleEdges<float> &inset,
|
|
952
|
-
const facebook::react::RectangleEdges<float> &thickness,
|
|
953
|
-
const facebook::react::RectangleEdges<float> &rectPathGeometry) noexcept {
|
|
954
|
-
winrt::com_ptr<ID2D1PathGeometry> outerPathGeometry =
|
|
955
|
-
GenerateRoundedRectPathGeometry(compContext, radius, inset, rectPathGeometry);
|
|
956
|
-
|
|
957
|
-
if (outerPathGeometry == nullptr) {
|
|
958
|
-
assert(false);
|
|
959
|
-
return nullptr;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
facebook::react::RectangleEdges<float> rectInnerPathGeometry = {
|
|
963
|
-
rectPathGeometry.left + thickness.left,
|
|
964
|
-
rectPathGeometry.top + thickness.top,
|
|
965
|
-
rectPathGeometry.right - thickness.right,
|
|
966
|
-
rectPathGeometry.bottom - thickness.bottom};
|
|
967
|
-
|
|
968
|
-
// Total thickness is larger than original element size.
|
|
969
|
-
// Clamp inner rect to have a width/height of 0, but placed such that the ratio of side-thicknesses is respected.
|
|
970
|
-
// We need to respect this ratio so that any animations work properly.
|
|
971
|
-
|
|
972
|
-
if (rectInnerPathGeometry.left > rectInnerPathGeometry.right) {
|
|
973
|
-
float leftRatio = thickness.left / (thickness.left + thickness.right);
|
|
974
|
-
auto x = std::floor(rectPathGeometry.left + ((rectPathGeometry.right - rectPathGeometry.left) * leftRatio));
|
|
975
|
-
rectInnerPathGeometry.left = x;
|
|
976
|
-
rectInnerPathGeometry.right = x;
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
if (rectInnerPathGeometry.top > rectInnerPathGeometry.bottom) {
|
|
980
|
-
float topRatio = thickness.top / (thickness.top + thickness.bottom);
|
|
981
|
-
auto y = rectPathGeometry.top + std::floor((rectPathGeometry.top - rectPathGeometry.bottom) * topRatio);
|
|
982
|
-
rectInnerPathGeometry.top = y;
|
|
983
|
-
rectInnerPathGeometry.bottom = y;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
facebook::react::RectangleEdges<float> innerInset = {
|
|
987
|
-
inset.left + thickness.left,
|
|
988
|
-
inset.top + thickness.top,
|
|
989
|
-
inset.right + thickness.right,
|
|
990
|
-
inset.bottom + thickness.bottom};
|
|
991
|
-
|
|
992
|
-
winrt::com_ptr<ID2D1PathGeometry> innerPathGeometry =
|
|
993
|
-
GenerateRoundedRectPathGeometry(compContext, radius, innerInset, rectInnerPathGeometry);
|
|
994
|
-
|
|
995
|
-
if (innerPathGeometry == nullptr) {
|
|
996
|
-
assert(false); // Failed to create inner pathGeometry for rounded border
|
|
997
|
-
return nullptr;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
ID2D1Geometry *ppGeometries[] = {outerPathGeometry.get(), innerPathGeometry.get()};
|
|
1001
|
-
winrt::com_ptr<ID2D1Factory1> spD2dFactory;
|
|
1002
|
-
compContext.as<::Microsoft::ReactNative::Composition::Experimental::ICompositionContextInterop>()->D2DFactory(
|
|
1003
|
-
spD2dFactory.put());
|
|
1004
|
-
|
|
1005
|
-
winrt::com_ptr<ID2D1GeometryGroup> geometryGroup = nullptr;
|
|
1006
|
-
// Create a geometry group.
|
|
1007
|
-
HRESULT hr = spD2dFactory->CreateGeometryGroup(
|
|
1008
|
-
D2D1_FILL_MODE_ALTERNATE, ppGeometries, ARRAYSIZE(ppGeometries), geometryGroup.put());
|
|
1009
|
-
|
|
1010
|
-
if (SUCCEEDED(hr)) {
|
|
1011
|
-
return geometryGroup;
|
|
1012
|
-
}
|
|
1013
|
-
return nullptr;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
// We don't want half pixel borders, or border radii - they lead to blurry borders
|
|
1017
|
-
// Also apply scale factor to the radii at this point
|
|
1018
|
-
void pixelRoundBorderRadii(facebook::react::BorderRadii &borderRadii, float scaleFactor) noexcept {
|
|
1019
|
-
// Always round radii down to avoid spikey circles
|
|
1020
|
-
borderRadii.topLeft = {
|
|
1021
|
-
std::floor(borderRadii.topLeft.horizontal * scaleFactor), std::floor(borderRadii.topLeft.vertical * scaleFactor)};
|
|
1022
|
-
borderRadii.topRight = {
|
|
1023
|
-
std::floor(borderRadii.topRight.horizontal * scaleFactor),
|
|
1024
|
-
std::floor(borderRadii.topRight.vertical * scaleFactor)};
|
|
1025
|
-
borderRadii.bottomLeft = {
|
|
1026
|
-
std::floor(borderRadii.bottomLeft.horizontal * scaleFactor),
|
|
1027
|
-
std::floor(borderRadii.bottomLeft.vertical * scaleFactor)};
|
|
1028
|
-
borderRadii.bottomRight = {
|
|
1029
|
-
std::floor(borderRadii.bottomRight.horizontal * scaleFactor),
|
|
1030
|
-
std::floor(borderRadii.bottomRight.vertical * scaleFactor)};
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
void scaleAndPixelRoundBorderWidths(
|
|
1034
|
-
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
1035
|
-
facebook::react::BorderMetrics &borderMetrics,
|
|
1036
|
-
float scaleFactor) noexcept {
|
|
1037
|
-
borderMetrics.borderWidths.left = (borderMetrics.borderWidths.left == 0)
|
|
1038
|
-
? 0.f
|
|
1039
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.left * scaleFactor));
|
|
1040
|
-
borderMetrics.borderWidths.top = (borderMetrics.borderWidths.top == 0)
|
|
1041
|
-
? 0.f
|
|
1042
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.top * scaleFactor));
|
|
1043
|
-
borderMetrics.borderWidths.right = (borderMetrics.borderWidths.right == 0)
|
|
1044
|
-
? 0.f
|
|
1045
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.right * scaleFactor));
|
|
1046
|
-
borderMetrics.borderWidths.bottom = (borderMetrics.borderWidths.bottom == 0)
|
|
1047
|
-
? 0.f
|
|
1048
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.bottom * scaleFactor));
|
|
1049
|
-
|
|
1050
|
-
// If we rounded both sides of the borderWidths up, we may have made the borderWidths larger than the total
|
|
1051
|
-
if (layoutMetrics.frame.size.width * scaleFactor <
|
|
1052
|
-
(borderMetrics.borderWidths.left + borderMetrics.borderWidths.right)) {
|
|
1053
|
-
borderMetrics.borderWidths.right--;
|
|
1054
|
-
}
|
|
1055
|
-
if (layoutMetrics.frame.size.height * scaleFactor <
|
|
1056
|
-
(borderMetrics.borderWidths.top + borderMetrics.borderWidths.bottom)) {
|
|
1057
|
-
borderMetrics.borderWidths.bottom--;
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
// react-native uses black as a default color when none is specified.
|
|
1062
|
-
void assignDefaultBlackBorders(facebook::react::BorderMetrics &borderMetrics) noexcept {
|
|
1063
|
-
if (!borderMetrics.borderColors.left) {
|
|
1064
|
-
borderMetrics.borderColors.left = facebook::react::blackColor();
|
|
1065
|
-
}
|
|
1066
|
-
if (!borderMetrics.borderColors.top) {
|
|
1067
|
-
borderMetrics.borderColors.top = facebook::react::blackColor();
|
|
1068
|
-
}
|
|
1069
|
-
if (!borderMetrics.borderColors.right) {
|
|
1070
|
-
borderMetrics.borderColors.right = facebook::react::blackColor();
|
|
1071
|
-
}
|
|
1072
|
-
if (!borderMetrics.borderColors.bottom) {
|
|
1073
|
-
borderMetrics.borderColors.bottom = facebook::react::blackColor();
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
facebook::react::BorderMetrics resolveAndAlignBorderMetrics(
|
|
1078
|
-
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
1079
|
-
const facebook::react::ViewProps &viewProps) noexcept {
|
|
1080
|
-
auto borderMetrics = viewProps.resolveBorderMetrics(layoutMetrics);
|
|
1081
|
-
|
|
1082
|
-
pixelRoundBorderRadii(borderMetrics.borderRadii, layoutMetrics.pointScaleFactor);
|
|
1083
|
-
scaleAndPixelRoundBorderWidths(layoutMetrics, borderMetrics, layoutMetrics.pointScaleFactor);
|
|
1084
|
-
assignDefaultBlackBorders(borderMetrics);
|
|
1085
|
-
return borderMetrics;
|
|
534
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ComponentView::OuterVisual() const noexcept {
|
|
535
|
+
return m_outerVisual ? m_outerVisual : Visual();
|
|
1086
536
|
}
|
|
1087
537
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
if (
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
if (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
538
|
+
facebook::react::LayoutMetrics ComponentView::focusLayoutMetrics(bool inner) const noexcept {
|
|
539
|
+
facebook::react::LayoutMetrics layoutMetrics = m_layoutMetrics;
|
|
540
|
+
layoutMetrics.frame.origin.x -= FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
541
|
+
layoutMetrics.frame.origin.y -= FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
542
|
+
layoutMetrics.frame.size.height += FOCUS_VISUAL_WIDTH * (inner ? 2 : 4);
|
|
543
|
+
layoutMetrics.frame.size.width += FOCUS_VISUAL_WIDTH * (inner ? 2 : 4);
|
|
544
|
+
return layoutMetrics;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
facebook::react::BorderMetrics ComponentView::focusBorderMetrics(
|
|
548
|
+
bool inner,
|
|
549
|
+
const facebook::react::LayoutMetrics &layoutMetrics) const noexcept {
|
|
550
|
+
facebook::react::BorderMetrics metrics = BorderPrimitive::resolveAndAlignBorderMetrics(layoutMetrics, *viewProps());
|
|
551
|
+
facebook::react::Color innerColor;
|
|
552
|
+
innerColor.m_color = {1, 0, 0, 0};
|
|
553
|
+
innerColor.m_platformColor.push_back(inner ? "FocusVisualSecondary" : "FocusVisualPrimary");
|
|
554
|
+
metrics.borderColors.bottom = metrics.borderColors.left = metrics.borderColors.right = metrics.borderColors.top =
|
|
555
|
+
innerColor;
|
|
556
|
+
if (metrics.borderRadii.bottomLeft.horizontal != 0)
|
|
557
|
+
metrics.borderRadii.bottomLeft.horizontal += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
558
|
+
if (metrics.borderRadii.bottomLeft.vertical != 0)
|
|
559
|
+
metrics.borderRadii.bottomLeft.vertical += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
560
|
+
if (metrics.borderRadii.bottomRight.horizontal != 0)
|
|
561
|
+
metrics.borderRadii.bottomRight.horizontal += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
562
|
+
if (metrics.borderRadii.bottomRight.vertical != 0)
|
|
563
|
+
metrics.borderRadii.bottomRight.vertical += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
564
|
+
if (metrics.borderRadii.topLeft.horizontal != 0)
|
|
565
|
+
metrics.borderRadii.topLeft.horizontal += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
566
|
+
if (metrics.borderRadii.topLeft.vertical != 0)
|
|
567
|
+
metrics.borderRadii.topLeft.vertical += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
568
|
+
if (metrics.borderRadii.topRight.horizontal != 0)
|
|
569
|
+
metrics.borderRadii.topRight.horizontal += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
570
|
+
if (metrics.borderRadii.topRight.vertical != 0)
|
|
571
|
+
metrics.borderRadii.topRight.vertical += FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
572
|
+
|
|
573
|
+
metrics.borderStyles.bottom = metrics.borderStyles.left = metrics.borderStyles.right = metrics.borderStyles.top =
|
|
574
|
+
facebook::react::BorderStyle::Solid;
|
|
575
|
+
metrics.borderWidths.bottom = metrics.borderWidths.left = metrics.borderWidths.right = metrics.borderWidths.top =
|
|
576
|
+
FOCUS_VISUAL_WIDTH * layoutMetrics.pointScaleFactor;
|
|
577
|
+
return metrics;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
void ComponentView::hostFocusVisual(bool show, winrt::com_ptr<ComponentView> view) noexcept {
|
|
581
|
+
if ((view->m_flags & ComponentViewFeatures::FocusVisual) == ComponentViewFeatures::FocusVisual) {
|
|
582
|
+
// Any previous view showing focus visuals should have removed them before another shows it
|
|
583
|
+
assert(
|
|
584
|
+
!m_focusPrimitive || !m_focusPrimitive->m_focusVisualComponent ||
|
|
585
|
+
m_focusPrimitive->m_focusVisualComponent == view);
|
|
586
|
+
assert(
|
|
587
|
+
!m_focusPrimitive || !m_focusPrimitive->m_focusVisualComponent ||
|
|
588
|
+
view->m_componentHostingFocusVisual.get() == this);
|
|
589
|
+
if (show && !view->m_componentHostingFocusVisual) {
|
|
590
|
+
view->m_componentHostingFocusVisual = get_strong();
|
|
591
|
+
|
|
592
|
+
if (!m_focusPrimitive) {
|
|
593
|
+
m_focusPrimitive = std::make_unique<FocusPrimitive>();
|
|
594
|
+
}
|
|
595
|
+
m_focusPrimitive->m_focusVisualComponent = view;
|
|
596
|
+
|
|
597
|
+
if (!m_focusPrimitive->m_focusVisual) {
|
|
598
|
+
m_focusPrimitive->m_focusVisual = m_compContext.CreateSpriteVisual();
|
|
599
|
+
auto hostingVisual =
|
|
600
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(
|
|
601
|
+
visualToHostFocus())
|
|
602
|
+
.as<winrt::Microsoft::UI::Composition::ContainerVisual>();
|
|
603
|
+
if (hostingVisual) {
|
|
604
|
+
hostingVisual.Children().InsertAtTop(
|
|
605
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(
|
|
606
|
+
m_focusPrimitive->m_focusVisual));
|
|
607
|
+
} else {
|
|
608
|
+
assert(
|
|
609
|
+
view.get() ==
|
|
610
|
+
this); // When not using lifted comp, focus visuals should always host within their own component
|
|
611
|
+
OuterVisual().InsertAt(m_focusPrimitive->m_focusVisual, 1);
|
|
612
|
+
}
|
|
1148
613
|
}
|
|
1149
|
-
} else {
|
|
1150
|
-
facebook::react::RectangleEdges<float> rectPathGeometry = {0, 0, extentWidth, extentHeight};
|
|
1151
|
-
|
|
1152
|
-
winrt::com_ptr<ID2D1GeometryGroup> pathGeometry = GetGeometryForRoundedBorder(
|
|
1153
|
-
m_compContext,
|
|
1154
|
-
borderMetrics.borderRadii,
|
|
1155
|
-
{0, 0, 0, 0}, // inset
|
|
1156
|
-
borderMetrics.borderWidths,
|
|
1157
|
-
rectPathGeometry);
|
|
1158
|
-
|
|
1159
|
-
DrawAllBorderLayers(
|
|
1160
|
-
theme,
|
|
1161
|
-
m_compContext,
|
|
1162
|
-
spBorderVisuals,
|
|
1163
|
-
*pathGeometry,
|
|
1164
|
-
borderMetrics.borderWidths,
|
|
1165
|
-
borderMetrics.borderRadii,
|
|
1166
|
-
extentWidth,
|
|
1167
|
-
extentHeight,
|
|
1168
|
-
borderMetrics.borderColors,
|
|
1169
|
-
borderStyle);
|
|
1170
|
-
}
|
|
1171
|
-
} else {
|
|
1172
|
-
// Because in DirectX geometry starts at the center of the stroke, we need to deflate rectangle by half the stroke
|
|
1173
|
-
// width / height to render correctly.
|
|
1174
|
-
D2D1_RECT_F rectShape{
|
|
1175
|
-
borderMetrics.borderWidths.left / 2.0f,
|
|
1176
|
-
borderMetrics.borderWidths.top / 2.0f,
|
|
1177
|
-
extentWidth - (borderMetrics.borderWidths.right / 2.0f),
|
|
1178
|
-
extentHeight - (borderMetrics.borderWidths.bottom / 2.0f)};
|
|
1179
|
-
DrawAllBorderLayers(
|
|
1180
|
-
theme,
|
|
1181
|
-
m_compContext,
|
|
1182
|
-
spBorderVisuals,
|
|
1183
|
-
rectShape,
|
|
1184
|
-
borderMetrics.borderWidths,
|
|
1185
|
-
borderMetrics.borderRadii,
|
|
1186
|
-
extentWidth,
|
|
1187
|
-
extentHeight,
|
|
1188
|
-
borderMetrics.borderColors,
|
|
1189
|
-
borderStyle);
|
|
1190
|
-
}
|
|
1191
|
-
return true;
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
void ComponentView::finalizeBorderUpdates(
|
|
1195
|
-
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
1196
|
-
const facebook::react::ViewProps &viewProps) noexcept {
|
|
1197
|
-
if (!m_needsBorderUpdate || theme()->IsEmpty()) {
|
|
1198
|
-
return;
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
m_needsBorderUpdate = false;
|
|
1202
|
-
auto spBorderLayers = FindSpecialBorderLayers();
|
|
1203
614
|
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
if (
|
|
1207
|
-
|
|
615
|
+
m_focusPrimitive->m_focusVisual.IsVisible(true);
|
|
616
|
+
assert(view->viewProps()->enableFocusRing);
|
|
617
|
+
if (!m_focusPrimitive->m_focusInnerPrimitive) {
|
|
618
|
+
m_focusPrimitive->m_focusInnerPrimitive = std::make_shared<BorderPrimitive>(*this);
|
|
619
|
+
m_focusPrimitive->m_focusVisual.InsertAt(m_focusPrimitive->m_focusInnerPrimitive->RootVisual(), 0);
|
|
620
|
+
}
|
|
621
|
+
if (!m_focusPrimitive->m_focusOuterPrimitive) {
|
|
622
|
+
m_focusPrimitive->m_focusOuterPrimitive = std::make_shared<BorderPrimitive>(*this);
|
|
623
|
+
m_focusPrimitive->m_focusVisual.InsertAt(m_focusPrimitive->m_focusOuterPrimitive->RootVisual(), 0);
|
|
624
|
+
}
|
|
625
|
+
if (auto focusVisual =
|
|
626
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(
|
|
627
|
+
m_focusPrimitive->m_focusVisual)) {
|
|
628
|
+
auto outerVisual =
|
|
629
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(
|
|
630
|
+
view->OuterVisual());
|
|
631
|
+
focusVisual.ParentForTransform(outerVisual);
|
|
1208
632
|
}
|
|
633
|
+
updateFocusLayoutMetrics();
|
|
634
|
+
auto innerFocusMetrics = view->focusLayoutMetrics(true /*inner*/);
|
|
635
|
+
m_focusPrimitive->m_focusInnerPrimitive->finalize(
|
|
636
|
+
innerFocusMetrics, view->focusBorderMetrics(true /*inner*/, innerFocusMetrics));
|
|
637
|
+
auto outerFocusMetrics = view->focusLayoutMetrics(false /*inner*/);
|
|
638
|
+
m_focusPrimitive->m_focusOuterPrimitive->finalize(
|
|
639
|
+
outerFocusMetrics, view->focusBorderMetrics(false /*inner*/, outerFocusMetrics));
|
|
640
|
+
} else if (!show && view->m_componentHostingFocusVisual && m_focusPrimitive) {
|
|
641
|
+
m_focusPrimitive->m_focusVisualComponent = nullptr;
|
|
642
|
+
m_focusPrimitive->m_focusVisual.IsVisible(false);
|
|
643
|
+
view->m_componentHostingFocusVisual = nullptr;
|
|
1209
644
|
}
|
|
1210
645
|
}
|
|
1211
646
|
}
|
|
1212
647
|
|
|
1213
|
-
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ComponentView::OuterVisual() const noexcept {
|
|
1214
|
-
return m_outerVisual ? m_outerVisual : Visual();
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
void ComponentView::showFocusVisual(bool show) noexcept {
|
|
1218
|
-
if (show) {
|
|
1219
|
-
assert(m_enableFocusVisual);
|
|
1220
|
-
m_focusVisual.IsFocused(true);
|
|
1221
|
-
} else {
|
|
1222
|
-
m_focusVisual.IsFocused(false);
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
void ComponentView::updateBorderProps(
|
|
1227
|
-
const facebook::react::ViewProps &oldViewProps,
|
|
1228
|
-
const facebook::react::ViewProps &newViewProps) noexcept {
|
|
1229
|
-
if (oldViewProps.borderColors != newViewProps.borderColors || oldViewProps.borderRadii != newViewProps.borderRadii ||
|
|
1230
|
-
!(oldViewProps.yogaStyle.border(facebook::yoga::Edge::All) ==
|
|
1231
|
-
newViewProps.yogaStyle.border(facebook::yoga::Edge::All)) ||
|
|
1232
|
-
oldViewProps.borderStyles != newViewProps.borderStyles) {
|
|
1233
|
-
m_needsBorderUpdate = true;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
m_enableFocusVisual = newViewProps.enableFocusRing;
|
|
1237
|
-
if (!m_enableFocusVisual) {
|
|
1238
|
-
showFocusVisual(false);
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
648
|
void ComponentView::updateShadowProps(
|
|
1243
649
|
const facebook::react::ViewProps &oldViewProps,
|
|
1244
650
|
const facebook::react::ViewProps &newViewProps) noexcept {
|
|
1245
651
|
// Shadow Properties
|
|
1246
652
|
if (oldViewProps.shadowOffset != newViewProps.shadowOffset || oldViewProps.shadowColor != newViewProps.shadowColor ||
|
|
1247
653
|
oldViewProps.shadowOpacity != newViewProps.shadowOpacity ||
|
|
1248
|
-
oldViewProps.shadowRadius != newViewProps.shadowRadius) {
|
|
654
|
+
oldViewProps.shadowRadius != newViewProps.shadowRadius || oldViewProps.boxShadow != newViewProps.boxShadow) {
|
|
1249
655
|
applyShadowProps(newViewProps);
|
|
1250
656
|
}
|
|
1251
657
|
}
|
|
1252
658
|
|
|
1253
659
|
void ComponentView::applyShadowProps(const facebook::react::ViewProps &viewProps) noexcept {
|
|
1254
660
|
auto shadow = m_compContext.CreateDropShadow();
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
shadow.Color(theme()->Color(*viewProps.
|
|
661
|
+
if (!viewProps.boxShadow.empty()) {
|
|
662
|
+
shadow.Offset({viewProps.boxShadow[0].offsetX, viewProps.boxShadow[0].offsetY, 0});
|
|
663
|
+
shadow.Opacity(1);
|
|
664
|
+
shadow.BlurRadius(viewProps.boxShadow[0].blurRadius);
|
|
665
|
+
shadow.Color(theme()->Color(*viewProps.boxShadow[0].color));
|
|
666
|
+
} else {
|
|
667
|
+
shadow.Offset({viewProps.shadowOffset.width, viewProps.shadowOffset.height, 0});
|
|
668
|
+
shadow.Opacity(viewProps.shadowOpacity);
|
|
669
|
+
shadow.BlurRadius(viewProps.shadowRadius);
|
|
670
|
+
if (viewProps.shadowColor)
|
|
671
|
+
shadow.Color(theme()->Color(*viewProps.shadowColor));
|
|
672
|
+
}
|
|
673
|
+
|
|
1260
674
|
Visual().as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>().Shadow(shadow);
|
|
1261
675
|
}
|
|
1262
676
|
|
|
@@ -1347,6 +761,19 @@ void ComponentView::updateAccessibilityProps(
|
|
|
1347
761
|
UIA_LiveSettingPropertyId,
|
|
1348
762
|
oldViewProps.accessibilityLiveRegion,
|
|
1349
763
|
newViewProps.accessibilityLiveRegion);
|
|
764
|
+
|
|
765
|
+
if ((oldViewProps.accessibilityState.has_value() && oldViewProps.accessibilityState->selected.has_value()) !=
|
|
766
|
+
((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value()))) {
|
|
767
|
+
auto compProvider =
|
|
768
|
+
m_uiaProvider.try_as<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>();
|
|
769
|
+
if (compProvider) {
|
|
770
|
+
if ((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value())) {
|
|
771
|
+
winrt::Microsoft::ReactNative::implementation::AddSelectionItemsToContainer(compProvider.get());
|
|
772
|
+
} else {
|
|
773
|
+
winrt::Microsoft::ReactNative::implementation::RemoveSelectionItemsFromContainer(compProvider.get());
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
1350
777
|
}
|
|
1351
778
|
|
|
1352
779
|
std::optional<std::string> ComponentView::getAccessiblityValue() noexcept {
|
|
@@ -1370,10 +797,10 @@ void ComponentView::Toggle() noexcept {
|
|
|
1370
797
|
// no-op
|
|
1371
798
|
}
|
|
1372
799
|
|
|
1373
|
-
void ComponentView::
|
|
800
|
+
void ComponentView::updateClippingPath(
|
|
1374
801
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
1375
802
|
const facebook::react::ViewProps &viewProps) noexcept {
|
|
1376
|
-
auto borderMetrics = resolveAndAlignBorderMetrics(layoutMetrics, viewProps);
|
|
803
|
+
auto borderMetrics = BorderPrimitive::resolveAndAlignBorderMetrics(layoutMetrics, viewProps);
|
|
1377
804
|
|
|
1378
805
|
if (borderMetrics.borderRadii.topLeft.horizontal == 0 && borderMetrics.borderRadii.topRight.horizontal == 0 &&
|
|
1379
806
|
borderMetrics.borderRadii.bottomLeft.horizontal == 0 && borderMetrics.borderRadii.bottomRight.horizontal == 0 &&
|
|
@@ -1381,7 +808,7 @@ void ComponentView::updateBorderLayoutMetrics(
|
|
|
1381
808
|
borderMetrics.borderRadii.bottomLeft.vertical == 0 && borderMetrics.borderRadii.bottomRight.vertical == 0) {
|
|
1382
809
|
Visual().as<::Microsoft::ReactNative::Composition::Experimental::IVisualInterop>()->SetClippingPath(nullptr);
|
|
1383
810
|
} else {
|
|
1384
|
-
winrt::com_ptr<ID2D1PathGeometry> pathGeometry = GenerateRoundedRectPathGeometry(
|
|
811
|
+
winrt::com_ptr<ID2D1PathGeometry> pathGeometry = BorderPrimitive::GenerateRoundedRectPathGeometry(
|
|
1385
812
|
m_compContext,
|
|
1386
813
|
borderMetrics.borderRadii,
|
|
1387
814
|
{0, 0, 0, 0},
|
|
@@ -1393,24 +820,16 @@ void ComponentView::updateBorderLayoutMetrics(
|
|
|
1393
820
|
Visual().as<::Microsoft::ReactNative::Composition::Experimental::IVisualInterop>()->SetClippingPath(
|
|
1394
821
|
pathGeometry.get());
|
|
1395
822
|
}
|
|
823
|
+
}
|
|
1396
824
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
m_focusVisual.ScaleFactor(layoutMetrics.pointScaleFactor);
|
|
1402
|
-
OuterVisual().Size(
|
|
1403
|
-
{layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
|
|
1404
|
-
layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
|
|
1405
|
-
OuterVisual().Offset({
|
|
1406
|
-
layoutMetrics.frame.origin.x * layoutMetrics.pointScaleFactor,
|
|
1407
|
-
layoutMetrics.frame.origin.y * layoutMetrics.pointScaleFactor,
|
|
1408
|
-
0.0f,
|
|
1409
|
-
});
|
|
825
|
+
std::pair<facebook::react::Cursor, HCURSOR> ComponentView::cursor() const noexcept {
|
|
826
|
+
return {viewProps()->cursor, nullptr};
|
|
1410
827
|
}
|
|
1411
828
|
|
|
1412
829
|
void ComponentView::indexOffsetForBorder(uint32_t &index) const noexcept {
|
|
1413
|
-
|
|
830
|
+
if (m_borderPrimitive) {
|
|
831
|
+
index += m_borderPrimitive->numberOfVisuals();
|
|
832
|
+
}
|
|
1414
833
|
}
|
|
1415
834
|
|
|
1416
835
|
void ComponentView::OnRenderingDeviceLost() noexcept {}
|
|
@@ -1528,24 +947,15 @@ ViewComponentView::ViewComponentView(
|
|
|
1528
947
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
1529
948
|
facebook::react::Tag tag,
|
|
1530
949
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
1531
|
-
ComponentViewFeatures flags
|
|
1532
|
-
|
|
950
|
+
ComponentViewFeatures flags,
|
|
951
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
|
|
952
|
+
: base_type(compContext, tag, reactContext, flags, builder),
|
|
1533
953
|
m_props(defaultProps ? defaultProps : ViewComponentView::defaultProps()) {}
|
|
1534
954
|
|
|
1535
955
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ViewComponentView::createVisual() noexcept {
|
|
1536
956
|
return m_compContext.CreateSpriteVisual();
|
|
1537
957
|
}
|
|
1538
958
|
|
|
1539
|
-
void ViewComponentView::CreateVisualHandler(
|
|
1540
|
-
const winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate &handler) {
|
|
1541
|
-
m_createVisualHandler = handler;
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
|
-
winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate ViewComponentView::CreateVisualHandler()
|
|
1545
|
-
const noexcept {
|
|
1546
|
-
return m_createVisualHandler;
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
959
|
void ViewComponentView::CreateInternalVisualHandler(
|
|
1550
960
|
const winrt::Microsoft::ReactNative::Composition::Experimental::CreateInternalVisualDelegate &handler) {
|
|
1551
961
|
m_createInternalVisualHandler = handler;
|
|
@@ -1560,10 +970,10 @@ void ViewComponentView::ensureVisual() noexcept {
|
|
|
1560
970
|
if (!m_visual) {
|
|
1561
971
|
if (m_createInternalVisualHandler) {
|
|
1562
972
|
m_visual = m_createInternalVisualHandler(*this);
|
|
1563
|
-
} else if (
|
|
973
|
+
} else if (m_builder && m_builder->CreateVisualHandler()) {
|
|
1564
974
|
m_visual =
|
|
1565
975
|
winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::CreateVisual(
|
|
1566
|
-
|
|
976
|
+
m_builder->CreateVisualHandler()(*this));
|
|
1567
977
|
} else {
|
|
1568
978
|
m_visual = createVisual();
|
|
1569
979
|
}
|
|
@@ -1579,6 +989,13 @@ winrt::Microsoft::ReactNative::ComponentView ViewComponentView::Create(
|
|
|
1579
989
|
ViewComponentView::defaultProps(), compContext, tag, reactContext, ComponentViewFeatures::Default);
|
|
1580
990
|
}
|
|
1581
991
|
|
|
992
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual
|
|
993
|
+
ViewComponentView::VisualToMountChildrenInto() noexcept {
|
|
994
|
+
if (m_builder && m_builder->VisualToMountChildrenIntoHandler())
|
|
995
|
+
return m_builder->VisualToMountChildrenIntoHandler()(*this);
|
|
996
|
+
return Visual();
|
|
997
|
+
}
|
|
998
|
+
|
|
1582
999
|
void ViewComponentView::MountChildComponentView(
|
|
1583
1000
|
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
|
|
1584
1001
|
uint32_t index) noexcept {
|
|
@@ -1598,7 +1015,7 @@ void ViewComponentView::MountChildComponentView(
|
|
|
1598
1015
|
}
|
|
1599
1016
|
}
|
|
1600
1017
|
}
|
|
1601
|
-
|
|
1018
|
+
VisualToMountChildrenInto().InsertAt(compositionChild->OuterVisual(), visualIndex);
|
|
1602
1019
|
} else {
|
|
1603
1020
|
m_hasNonVisualChildren = true;
|
|
1604
1021
|
}
|
|
@@ -1611,7 +1028,7 @@ void ViewComponentView::UnmountChildComponentView(
|
|
|
1611
1028
|
|
|
1612
1029
|
indexOffsetForBorder(index);
|
|
1613
1030
|
if (auto compositionChild = childComponentView.try_as<ComponentView>()) {
|
|
1614
|
-
|
|
1031
|
+
VisualToMountChildrenInto().Remove(compositionChild->OuterVisual());
|
|
1615
1032
|
}
|
|
1616
1033
|
}
|
|
1617
1034
|
|
|
@@ -1823,7 +1240,7 @@ winrt::Microsoft::ReactNative::ViewProps ViewComponentView::ViewProps() noexcept
|
|
|
1823
1240
|
|
|
1824
1241
|
winrt::Microsoft::ReactNative::ViewProps ViewComponentView::ViewPropsInner() noexcept {
|
|
1825
1242
|
// If we have AbiViewProps, then we dont need to new up a props wrapper
|
|
1826
|
-
if (
|
|
1243
|
+
if (m_builder) {
|
|
1827
1244
|
const auto &abiViewProps = *std::static_pointer_cast<const ::Microsoft::ReactNative::AbiViewProps>(m_props);
|
|
1828
1245
|
return abiViewProps.ViewProps();
|
|
1829
1246
|
}
|
|
@@ -1913,6 +1330,9 @@ winrt::Microsoft::ReactNative::ComponentView lastDeepChild(
|
|
|
1913
1330
|
return current;
|
|
1914
1331
|
}
|
|
1915
1332
|
|
|
1333
|
+
// Walks the tree calling the function fn on each node.
|
|
1334
|
+
// If fn returns true, then walkTree stops itterating over the tree, and returns true.
|
|
1335
|
+
// If the tree walk completes without fn returning true, then walkTree returns false.
|
|
1916
1336
|
bool walkTree(
|
|
1917
1337
|
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
1918
1338
|
bool forward,
|