55
66#include " CircleMask.h"
77
8- namespace winrt ::NativeModuleSample::implementation
9- {
8+ namespace winrt ::NativeModuleSample::implementation {
109
1110void RegisterCircleMaskNativeComponent (
12- winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept
13- {
11+ winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept {
1412#ifdef RNW_NEW_ARCH
15- NativeModuleSampleCodegen::RegisterCircleMaskNativeComponent<CircleMaskComponentView>(packageBuilder, [](const winrt::Microsoft::ReactNative::Composition::IReactCompositionViewComponentBuilder& /* builder*/ ) {
16- // Once 0.76 includes SetViewFeatures - enable this code:
17- /*
18- // Turn off default border handling, as it overrides the Clip property of the visual
19- builder.SetViewFeatures(winrt::Microsoft::ReactNative::Composition::ComponentViewFeatures::Default & ~winrt::Microsoft::ReactNative::Composition::ComponentViewFeatures::NativeBorder);
20- */
21- });
13+ NativeModuleSampleCodegen::RegisterCircleMaskNativeComponent<CircleMaskComponentView>(
14+ packageBuilder,
15+ [](const winrt::Microsoft::ReactNative::Composition::IReactCompositionViewComponentBuilder &builder) {
16+ // Turn off default border handling, as it overrides the Clip property of the visual and doesn't render
17+ // correctly anyway This means we would have to implement drawing our own borders (which we don't do in this
18+ // example)
19+ builder.SetViewFeatures (
20+ winrt::Microsoft::ReactNative::Composition::ComponentViewFeatures::Default &
21+ ~winrt::Microsoft::ReactNative::Composition::ComponentViewFeatures::NativeBorder);
22+ });
2223#else
2324 packageBuilder.AddViewManager (L" CircleMaskViewManager" , []() { return winrt::make<CircleMaskViewManager>(); });
24- #endif
25+ #endif
2526}
2627
2728#ifdef RNW_NEW_ARCH
2829
29- winrt::Microsoft::UI::Composition::Visual CircleMaskComponentView::CreateVisual (const winrt::Microsoft::ReactNative::ComponentView &view) noexcept
30- {
30+ winrt::Microsoft::UI::Composition::Visual CircleMaskComponentView::CreateVisual (
31+ const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
3132 auto compositor = view.as <winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor ();
3233
3334 m_visual = compositor.CreateSpriteVisual ();
@@ -40,42 +41,47 @@ winrt::Microsoft::UI::Composition::Visual CircleMaskComponentView::CreateVisual(
4041 return m_visual;
4142}
4243
43- void CircleMaskComponentView::Initialize (const winrt::Microsoft::ReactNative::ComponentView &view) noexcept
44- {
45- m_layoutMetricChangedRevoker = view.LayoutMetricsChanged (
46- winrt::auto_revoke,
47- [wkThis = get_weak ()](
48- const winrt::IInspectable &/* sender*/ , const winrt::Microsoft::ReactNative::LayoutMetricsChangedArgs& args) {
49- if (auto strongThis = wkThis.get ()) {
50- // Once 0.76 includes SetViewFeatures - remove this code, since the core border code will not override our clip:
51- {
52- auto compositor = strongThis->m_visual .Compositor ();
53- auto ellipseGeometry = compositor.CreateEllipseGeometry ();
54- auto clip = compositor.CreateGeometricClip ();
55- clip.Geometry (ellipseGeometry);
56- strongThis->m_visual .Clip (clip);
57- }
58- // End of workaround for not being able to disable core clipping code
59-
60-
61- auto ellipseGeometry = strongThis->m_visual .Clip ().as <winrt::Microsoft::UI::Composition::CompositionGeometricClip>().Geometry ().as <winrt::Microsoft::UI::Composition::CompositionEllipseGeometry>();
62- winrt::Windows::Foundation::Numerics::float2 radius = {args.NewLayoutMetrics ().Frame .Width * args.NewLayoutMetrics ().PointScaleFactor / 2 , args.NewLayoutMetrics ().Frame .Height * args.NewLayoutMetrics ().PointScaleFactor / 2 };
63- ellipseGeometry.Center (radius);
64- ellipseGeometry.Radius (radius);
65- }
66- });
44+ void CircleMaskComponentView::Initialize (const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
45+ m_layoutMetricChangedRevoker = view.LayoutMetricsChanged (
46+ winrt::auto_revoke,
47+ [wkThis = get_weak ()](
48+ const winrt::IInspectable & /* sender*/ , const winrt::Microsoft::ReactNative::LayoutMetricsChangedArgs &args) {
49+ if (auto strongThis = wkThis.get ()) {
50+ auto visual = strongThis->m_visual ;
51+
52+ // Turning off default border handling has the side-effect of also stopping the visual from being positioned,
53+ // so unless that changes we have to position the visual ourselves
54+ // See https://github.com/microsoft/react-native-windows/issues/14706
55+ visual.Size (
56+ {args.NewLayoutMetrics ().Frame .Width * args.NewLayoutMetrics ().PointScaleFactor ,
57+ args.NewLayoutMetrics ().Frame .Height * args.NewLayoutMetrics ().PointScaleFactor });
58+ visual.Offset ({
59+ args.NewLayoutMetrics ().Frame .X * args.NewLayoutMetrics ().PointScaleFactor ,
60+ args.NewLayoutMetrics ().Frame .Y * args.NewLayoutMetrics ().PointScaleFactor ,
61+ 0 .0f ,
62+ });
63+
64+ auto ellipseGeometry = strongThis->m_visual .Clip ()
65+ .as <winrt::Microsoft::UI::Composition::CompositionGeometricClip>()
66+ .Geometry ()
67+ .as <winrt::Microsoft::UI::Composition::CompositionEllipseGeometry>();
68+ winrt::Windows::Foundation::Numerics::float2 radius = {
69+ args.NewLayoutMetrics ().Frame .Width * args.NewLayoutMetrics ().PointScaleFactor / 2 ,
70+ args.NewLayoutMetrics ().Frame .Height * args.NewLayoutMetrics ().PointScaleFactor / 2 };
71+ ellipseGeometry.Center (radius);
72+ ellipseGeometry.Radius (radius);
73+ }
74+ });
6775}
6876
6977#else
7078
7179// IViewManager
72- winrt::hstring CircleMaskViewManager::Name () noexcept
73- {
80+ winrt::hstring CircleMaskViewManager::Name () noexcept {
7481 return L" CircleMask" ;
7582}
7683
77- winrt::Windows::UI::Xaml::FrameworkElement CircleMaskViewManager::CreateView () noexcept
78- {
84+ winrt::Windows::UI::Xaml::FrameworkElement CircleMaskViewManager::CreateView () noexcept {
7985 auto const &view = winrt::Windows::UI::Xaml::Controls::Border ();
8086
8187 auto const &binding = winrt::Windows::UI::Xaml::Data::Binding ();
@@ -93,22 +99,21 @@ winrt::Windows::UI::Xaml::FrameworkElement CircleMaskViewManager::CreateView() n
9399void CircleMaskViewManager::AddView (
94100 winrt::Windows::UI::Xaml::FrameworkElement const &parent,
95101 winrt::Windows::UI::Xaml::UIElement const &child,
96- int64_t /* index*/ ) noexcept
97- {
102+ int64_t /* index*/ ) noexcept {
98103 if (auto const &border = parent.try_as <winrt::Windows::UI::Xaml::Controls::Border>()) {
99104 border.Child (child);
100105 }
101106}
102107
103- void CircleMaskViewManager::RemoveAllChildren (winrt::Windows::UI::Xaml::FrameworkElement const &parent) noexcept
104- {
108+ void CircleMaskViewManager::RemoveAllChildren (winrt::Windows::UI::Xaml::FrameworkElement const &parent) noexcept {
105109 if (auto const &border = parent.try_as <winrt::Windows::UI::Xaml::Controls::Border>()) {
106110 border.Child (nullptr );
107111 }
108112}
109113
110- void CircleMaskViewManager::RemoveChildAt (winrt::Windows::UI::Xaml::FrameworkElement const &parent, int64_t /* index*/ ) noexcept
111- {
114+ void CircleMaskViewManager::RemoveChildAt (
115+ winrt::Windows::UI::Xaml::FrameworkElement const &parent,
116+ int64_t /* index*/ ) noexcept {
112117 if (auto const &border = parent.try_as <winrt::Windows::UI::Xaml::Controls::Border>()) {
113118 border.Child (nullptr );
114119 }
@@ -117,8 +122,7 @@ void CircleMaskViewManager::RemoveChildAt(winrt::Windows::UI::Xaml::FrameworkEle
117122void CircleMaskViewManager::ReplaceChild (
118123 winrt::Windows::UI::Xaml::FrameworkElement const &parent,
119124 winrt::Windows::UI::Xaml::UIElement const & /* oldChild*/ ,
120- winrt::Windows::UI::Xaml::UIElement const &newChild) noexcept
121- {
125+ winrt::Windows::UI::Xaml::UIElement const &newChild) noexcept {
122126 if (auto const &border = parent.try_as <winrt::Windows::UI::Xaml::Controls::Border>()) {
123127 border.Child (newChild);
124128 }
@@ -128,8 +132,7 @@ winrt::Windows::Foundation::IInspectable HeightToCornerRadiusConverter::Convert(
128132 winrt::Windows::Foundation::IInspectable const &value,
129133 winrt::Windows::UI::Xaml::Interop::TypeName const & /* targetType*/ ,
130134 winrt::Windows::Foundation::IInspectable const & /* parameter*/ ,
131- winrt::hstring const & /* language*/ ) noexcept
132- {
135+ winrt::hstring const & /* language*/ ) noexcept {
133136 double d = winrt::unbox_value<double >(value);
134137
135138 if (isnan (d)) {
@@ -143,13 +146,11 @@ winrt::Windows::Foundation::IInspectable HeightToCornerRadiusConverter::ConvertB
143146 winrt::Windows::Foundation::IInspectable const &value,
144147 winrt::Windows::UI::Xaml::Interop::TypeName const & /* targetType*/ ,
145148 winrt::Windows::Foundation::IInspectable const & /* parameter*/ ,
146- winrt::hstring const & /* language*/ ) noexcept
147- {
149+ winrt::hstring const & /* language*/ ) noexcept {
148150 return value;
149151}
150152
151- winrt::Windows::UI::Xaml::Data::IValueConverter HeightToCornerRadiusConverter::Instance () noexcept
152- {
153+ winrt::Windows::UI::Xaml::Data::IValueConverter HeightToCornerRadiusConverter::Instance () noexcept {
153154 static auto const &instance = winrt::make<HeightToCornerRadiusConverter>();
154155 return instance;
155156};
0 commit comments