react-native-windows 0.74.4 → 0.74.6

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.
Files changed (45) hide show
  1. package/Libraries/Components/TextInput/TextInput.windows.js +6 -2
  2. package/Libraries/Components/View/View.windows.js +3 -0
  3. package/Microsoft.ReactNative/ComponentView.idl +26 -0
  4. package/Microsoft.ReactNative/CompositionComponentView.idl +19 -7
  5. package/Microsoft.ReactNative/CompositionRootView.idl +1 -0
  6. package/Microsoft.ReactNative/CompositionUIService.idl +4 -0
  7. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +2 -1
  8. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +106 -19
  9. package/Microsoft.ReactNative/Fabric/AbiViewProps.h +45 -13
  10. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +83 -12
  11. package/Microsoft.ReactNative/Fabric/ComponentView.h +33 -2
  12. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +28 -64
  13. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +7 -11
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +30 -11
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +4 -0
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp +4 -0
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +12 -0
  18. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.h +4 -0
  19. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService_emptyimpl.cpp +6 -0
  20. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +60 -39
  21. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +19 -6
  22. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -0
  23. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +152 -0
  24. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +85 -0
  25. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +49 -95
  26. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +11 -15
  27. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +16 -31
  28. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +5 -8
  29. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +24 -81
  30. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +4 -13
  31. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +41 -40
  32. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -1
  33. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +53 -68
  34. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +5 -7
  35. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +38 -84
  36. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +6 -10
  37. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +59 -109
  38. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +9 -15
  39. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -0
  40. package/Microsoft.ReactNative/FocusManager.idl +22 -0
  41. package/Microsoft.ReactNative/ViewProps.idl +37 -3
  42. package/Microsoft.ReactNative.Cxx/JSValueComposition.h +4 -0
  43. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  44. package/Shared/Shared.vcxitems +6 -0
  45. package/package.json +1 -1
@@ -0,0 +1,152 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+ #include "FocusManager.h"
6
+ #include "Composition.FocusManager.g.cpp"
7
+ #include <Fabric/FabricUIManagerModule.h>
8
+
9
+ namespace winrt::Microsoft::ReactNative::implementation {
10
+
11
+ LostFocusEventArgs::LostFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource)
12
+ : m_originalSource(originalSource ? originalSource.Tag() : -1) {}
13
+ int32_t LostFocusEventArgs::OriginalSource() noexcept {
14
+ return m_originalSource;
15
+ }
16
+
17
+ GotFocusEventArgs::GotFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource)
18
+ : m_originalSource(originalSource ? originalSource.Tag() : -1) {}
19
+ int32_t GotFocusEventArgs::OriginalSource() noexcept {
20
+ return m_originalSource;
21
+ }
22
+
23
+ LosingFocusEventArgs::LosingFocusEventArgs(
24
+ const winrt::Microsoft::ReactNative::ComponentView &originalSource,
25
+ const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
26
+ const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent)
27
+ : m_originalSource(originalSource ? originalSource.Tag() : -1),
28
+ m_old(oldFocusedComponent),
29
+ m_new(newFocusedComponent) {}
30
+
31
+ int32_t LosingFocusEventArgs::OriginalSource() noexcept {
32
+ return m_originalSource;
33
+ }
34
+ winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::NewFocusedComponent() noexcept {
35
+ return m_new;
36
+ }
37
+ winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::OldFocusedComponent() noexcept {
38
+ return m_old;
39
+ }
40
+
41
+ void LosingFocusEventArgs::TryCancel() noexcept {
42
+ m_new = m_old;
43
+ }
44
+
45
+ void LosingFocusEventArgs::TrySetNewFocusedComponent(
46
+ const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept {
47
+ auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(newFocusedComponent);
48
+ if (selfView->focusable()) {
49
+ m_new = newFocusedComponent;
50
+ } else {
51
+ auto target =
52
+ winrt::Microsoft::ReactNative::Composition::FocusManager::FindFirstFocusableElement(newFocusedComponent);
53
+ if (!target)
54
+ return;
55
+ m_new = target;
56
+ }
57
+ }
58
+
59
+ GettingFocusEventArgs::GettingFocusEventArgs(
60
+ const winrt::Microsoft::ReactNative::ComponentView &originalSource,
61
+ const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
62
+ const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent)
63
+ : m_originalSource(originalSource ? originalSource.Tag() : -1),
64
+ m_old(oldFocusedComponent),
65
+ m_new(newFocusedComponent) {}
66
+
67
+ int32_t GettingFocusEventArgs::OriginalSource() noexcept {
68
+ return m_originalSource;
69
+ }
70
+ winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::NewFocusedComponent() noexcept {
71
+ return m_new;
72
+ }
73
+ winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::OldFocusedComponent() noexcept {
74
+ return m_old;
75
+ }
76
+
77
+ void GettingFocusEventArgs::TryCancel() noexcept {
78
+ m_new = m_old;
79
+ }
80
+
81
+ void GettingFocusEventArgs::TrySetNewFocusedComponent(
82
+ const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept {
83
+ auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(newFocusedComponent);
84
+ if (selfView->focusable()) {
85
+ m_new = newFocusedComponent;
86
+ } else {
87
+ auto target =
88
+ winrt::Microsoft::ReactNative::Composition::FocusManager::FindFirstFocusableElement(newFocusedComponent);
89
+ if (!target)
90
+ return;
91
+ m_new = target;
92
+ }
93
+ }
94
+
95
+ } // namespace winrt::Microsoft::ReactNative::implementation
96
+
97
+ namespace winrt::Microsoft::ReactNative::Composition::implementation {
98
+
99
+ winrt::Microsoft::ReactNative::implementation::ComponentView *NavigateFocusHelper(
100
+ winrt::Microsoft::ReactNative::implementation::ComponentView &view,
101
+ winrt::Microsoft::ReactNative::FocusNavigationReason reason) {
102
+ if (reason == winrt::Microsoft::ReactNative::FocusNavigationReason::First) {
103
+ if (view.focusable()) {
104
+ return &view;
105
+ }
106
+ }
107
+ winrt::Microsoft::ReactNative::implementation::ComponentView *toFocus = nullptr;
108
+
109
+ Mso::Functor<bool(::winrt::Microsoft::ReactNative::implementation::ComponentView & v)> fn =
110
+ [reason, &toFocus](::winrt::Microsoft::ReactNative::implementation::ComponentView &v) noexcept
111
+ -> bool { return (toFocus = NavigateFocusHelper(v, reason)); };
112
+
113
+ if (view.runOnChildren(reason == winrt::Microsoft::ReactNative::FocusNavigationReason::First, fn)) {
114
+ return toFocus;
115
+ }
116
+
117
+ if (reason == winrt::Microsoft::ReactNative::FocusNavigationReason::Last) {
118
+ if (view.focusable()) {
119
+ return &view;
120
+ }
121
+ }
122
+
123
+ return nullptr;
124
+ }
125
+
126
+ winrt::Microsoft::ReactNative::ComponentView FocusManager::FindFirstFocusableElement(
127
+ const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept {
128
+ auto selfSearchScope = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(searchScope);
129
+ auto view = NavigateFocusHelper(*selfSearchScope, winrt::Microsoft::ReactNative::FocusNavigationReason::First);
130
+ if (view) {
131
+ winrt::Microsoft::ReactNative::ComponentView component{nullptr};
132
+ winrt::check_hresult(view->QueryInterface(
133
+ winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(component)));
134
+ return *view;
135
+ }
136
+ return nullptr;
137
+ }
138
+
139
+ winrt::Microsoft::ReactNative::ComponentView FocusManager::FindLastFocusableElement(
140
+ const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept {
141
+ auto selfSearchScope = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(searchScope);
142
+ auto view = NavigateFocusHelper(*selfSearchScope, winrt::Microsoft::ReactNative::FocusNavigationReason::Last);
143
+ if (view) {
144
+ winrt::Microsoft::ReactNative::ComponentView component{nullptr};
145
+ winrt::check_hresult(view->QueryInterface(
146
+ winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(component)));
147
+ return *view;
148
+ }
149
+ return nullptr;
150
+ }
151
+
152
+ } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -0,0 +1,85 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+ #include "Composition.FocusManager.g.h"
6
+ #include "GettingFocusEventArgs.g.h"
7
+ #include "LosingFocusEventArgs.g.h"
8
+ #include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
9
+ #include <winrt/Microsoft.ReactNative.Composition.Input.h>
10
+
11
+ namespace winrt::Microsoft::ReactNative::implementation {
12
+
13
+ struct LostFocusEventArgs
14
+ : winrt::implements<LostFocusEventArgs, winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> {
15
+ LostFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource);
16
+ int32_t OriginalSource() noexcept;
17
+
18
+ private:
19
+ const int32_t m_originalSource;
20
+ };
21
+
22
+ struct GotFocusEventArgs
23
+ : winrt::implements<GotFocusEventArgs, winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> {
24
+ GotFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource);
25
+ int32_t OriginalSource() noexcept;
26
+
27
+ private:
28
+ const int32_t m_originalSource;
29
+ };
30
+
31
+ struct LosingFocusEventArgs
32
+ : winrt::Microsoft::ReactNative::implementation::LosingFocusEventArgsT<LosingFocusEventArgs> {
33
+ LosingFocusEventArgs(
34
+ const winrt::Microsoft::ReactNative::ComponentView &originalSource,
35
+ const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
36
+ const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent);
37
+ int32_t OriginalSource() noexcept;
38
+ winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() noexcept;
39
+ winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() noexcept;
40
+
41
+ void TryCancel() noexcept;
42
+ void TrySetNewFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept;
43
+
44
+ private:
45
+ const int32_t m_originalSource;
46
+ winrt::Microsoft::ReactNative::ComponentView m_old{nullptr};
47
+ winrt::Microsoft::ReactNative::ComponentView m_new{nullptr};
48
+ };
49
+
50
+ struct GettingFocusEventArgs
51
+ : winrt::Microsoft::ReactNative::implementation::GettingFocusEventArgsT<GettingFocusEventArgs> {
52
+ GettingFocusEventArgs(
53
+ const winrt::Microsoft::ReactNative::ComponentView &originalSource,
54
+ const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
55
+ const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent);
56
+ int32_t OriginalSource() noexcept;
57
+ winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() noexcept;
58
+ winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() noexcept;
59
+
60
+ void TryCancel() noexcept;
61
+ void TrySetNewFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept;
62
+
63
+ private:
64
+ const int32_t m_originalSource;
65
+ winrt::Microsoft::ReactNative::ComponentView m_old{nullptr};
66
+ winrt::Microsoft::ReactNative::ComponentView m_new{nullptr};
67
+ };
68
+ } // namespace winrt::Microsoft::ReactNative::implementation
69
+
70
+ namespace winrt::Microsoft::ReactNative::Composition::implementation {
71
+
72
+ struct FocusManager : FocusManagerT<FocusManager> {
73
+ FocusManager() = default;
74
+
75
+ static winrt::Microsoft::ReactNative::ComponentView FindFirstFocusableElement(
76
+ const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept;
77
+ static winrt::Microsoft::ReactNative::ComponentView FindLastFocusableElement(
78
+ const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept;
79
+ };
80
+
81
+ } // namespace winrt::Microsoft::ReactNative::Composition::implementation
82
+
83
+ namespace winrt::Microsoft::ReactNative::Composition::factory_implementation {
84
+ struct FocusManager : FocusManagerT<FocusManager, implementation::FocusManager> {};
85
+ } // namespace winrt::Microsoft::ReactNative::Composition::factory_implementation
@@ -14,6 +14,7 @@
14
14
  #include <react/renderer/components/image/ImageEventEmitter.h>
15
15
 
16
16
  #include <AutoDraw.h>
17
+ #include <Fabric/AbiViewProps.h>
17
18
  #include <Fabric/FabricUIManagerModule.h>
18
19
  #include <Utils/ImageUtils.h>
19
20
  #include <shcore.h>
@@ -48,19 +49,22 @@ void ImageComponentView::WindowsImageResponseObserver::didReceiveFailure() const
48
49
  m_image->didReceiveFailureFromObserver();
49
50
  }
50
51
 
52
+ facebook::react::SharedViewProps ImageComponentView::defaultProps() noexcept {
53
+ static auto const defaultProps = std::make_shared<facebook::react::ImageProps const>();
54
+ return defaultProps;
55
+ }
56
+
51
57
  ImageComponentView::ImageComponentView(
52
58
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
53
59
  facebook::react::Tag tag,
54
60
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
55
61
  : Super(
62
+ ImageComponentView::defaultProps(),
56
63
  compContext,
57
64
  tag,
58
65
  reactContext,
59
66
  ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
60
- false) {
61
- static auto const defaultProps = std::make_shared<facebook::react::ImageProps const>();
62
- m_props = defaultProps;
63
- }
67
+ false) {}
64
68
 
65
69
  void ImageComponentView::MountChildComponentView(
66
70
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
@@ -111,32 +115,24 @@ void ImageComponentView::didReceiveFailureFromObserver() noexcept {
111
115
  }
112
116
  }
113
117
 
118
+ const facebook::react::ImageProps &ImageComponentView::imageProps() const noexcept {
119
+ return *std::static_pointer_cast<const facebook::react::ImageProps>(viewProps());
120
+ }
121
+
114
122
  void ImageComponentView::updateProps(
115
123
  facebook::react::Props::Shared const &props,
116
124
  facebook::react::Props::Shared const &oldProps) noexcept {
117
- const auto &oldImageProps = *std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
125
+ const auto &oldImageProps =
126
+ *std::static_pointer_cast<const facebook::react::ImageProps>(oldProps ? oldProps : viewProps());
118
127
  const auto &newImageProps = *std::static_pointer_cast<const facebook::react::ImageProps>(props);
119
128
 
120
- ensureVisual();
121
-
122
- // update BaseComponentView props
123
- updateTransformProps(oldImageProps, newImageProps, m_visual);
124
- Super::updateProps(props, oldProps);
125
-
126
129
  if (oldImageProps.backgroundColor != newImageProps.backgroundColor ||
127
130
  oldImageProps.blurRadius != newImageProps.blurRadius || oldImageProps.tintColor != newImageProps.tintColor ||
128
131
  oldImageProps.resizeMode != newImageProps.resizeMode) {
129
132
  m_drawingSurface = nullptr; // TODO don't need to recreate the surface just to redraw...
130
133
  }
131
134
 
132
- if (oldImageProps.opacity != newImageProps.opacity) {
133
- m_visual.Opacity(newImageProps.opacity);
134
- }
135
- if (oldImageProps.testId != newImageProps.testId) {
136
- m_visual.Comment(winrt::to_hstring(newImageProps.testId));
137
- }
138
-
139
- m_props = std::static_pointer_cast<facebook::react::ImageProps const>(props);
135
+ Super::updateProps(props, oldProps);
140
136
  }
141
137
 
142
138
  void ImageComponentView::updateState(
@@ -182,19 +178,22 @@ void ImageComponentView::setStateAndResubscribeImageResponseObserver(
182
178
  }
183
179
  }
184
180
 
185
- void ImageComponentView::updateLayoutMetrics(
186
- facebook::react::LayoutMetrics const &layoutMetrics,
187
- facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
188
- // Set Position & Size Properties
181
+ winrt::Microsoft::ReactNative::ImageProps ImageComponentView::ImageProps() noexcept {
182
+ // We do not currently support custom ImageComponentView's
183
+ // If we did we would need to create a AbiImageProps and possibly return them here
184
+ assert(!m_customComponent);
185
+ return winrt::make<winrt::Microsoft::ReactNative::implementation::ImageProps>(viewProps());
186
+ }
189
187
 
190
- if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
191
- OuterVisual().IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
192
- }
188
+ winrt::Microsoft::ReactNative::ImageProps ImageComponentView::ViewProps() noexcept {
189
+ return ViewPropsInner().as<winrt::Microsoft::ReactNative::ImageProps>();
190
+ }
193
191
 
194
- Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
195
- m_visual.Size(
196
- {layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
197
- layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
192
+ winrt::Microsoft::ReactNative::ViewProps ImageComponentView::ViewPropsInner() noexcept {
193
+ // We do not currently support custom ImageComponentView's
194
+ // If we did we would need to create a AbiImageProps and possibly return them here
195
+ assert(!m_customComponent);
196
+ return winrt::make<winrt::Microsoft::ReactNative::implementation::ImageProps>(viewProps());
198
197
  }
199
198
 
200
199
  void ImageComponentView::OnRenderingDeviceLost() noexcept {
@@ -203,7 +202,7 @@ void ImageComponentView::OnRenderingDeviceLost() noexcept {
203
202
  }
204
203
 
205
204
  bool ImageComponentView::themeEffectsImage() const noexcept {
206
- return m_props->backgroundColor || isColorMeaningful(m_props->tintColor);
205
+ return viewProps()->backgroundColor || isColorMeaningful(imageProps().tintColor);
207
206
  }
208
207
 
209
208
  void ImageComponentView::onThemeChanged() noexcept {
@@ -218,7 +217,7 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
218
217
  assert(m_reactContext.UIDispatcher().HasThreadAccess());
219
218
 
220
219
  if (!m_imageResponseImage) {
221
- m_visual.Brush(nullptr);
220
+ Visual().as<Experimental::ISpriteVisual>().Brush(nullptr);
222
221
  return;
223
222
  }
224
223
 
@@ -230,18 +229,18 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
230
229
  if (!m_drawingSurface && m_imageResponseImage->m_wicbmp) {
231
230
  winrt::Windows::Foundation::Size drawingSurfaceSize{static_cast<float>(width), static_cast<float>(height)};
232
231
 
233
- const auto imageProps = std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
232
+ const auto &imgProps = imageProps();
234
233
  const auto frame{m_layoutMetrics.getContentFrame().size};
235
234
 
236
- if (imageProps->resizeMode == facebook::react::ImageResizeMode::Repeat) {
235
+ if (imgProps.resizeMode == facebook::react::ImageResizeMode::Repeat) {
237
236
  drawingSurfaceSize = {
238
237
  frame.width * m_layoutMetrics.pointScaleFactor, frame.height * m_layoutMetrics.pointScaleFactor};
239
- } else if (imageProps->blurRadius > 0) {
238
+ } else if (imgProps.blurRadius > 0) {
240
239
  // https://learn.microsoft.com/en-us/windows/win32/direct2d/gaussian-blur#output-bitmap
241
240
  // The following equation that can be used to compute the output bitmap:
242
241
  // Output bitmap growth (X and Y) = (StandardDeviation(DIPs)*3 + StandardDeviation(DIPs)*3)*((User DPI)/96)
243
242
  // Where StandardDeviation(DIPs)*3 is equivalent to the blur radius.
244
- const auto bmpGrowth{imageProps->blurRadius * 2 * m_layoutMetrics.pointScaleFactor};
243
+ const auto bmpGrowth{imgProps.blurRadius * 2 * m_layoutMetrics.pointScaleFactor};
245
244
  drawingSurfaceSize = {drawingSurfaceSize.Width + bmpGrowth, drawingSurfaceSize.Height + bmpGrowth};
246
245
  }
247
246
 
@@ -252,7 +251,7 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
252
251
 
253
252
  DrawImage();
254
253
 
255
- switch (imageProps->resizeMode) {
254
+ switch (imgProps.resizeMode) {
256
255
  case facebook::react::ImageResizeMode::Stretch:
257
256
  m_drawingSurface.Stretch(winrt::Microsoft::ReactNative::Composition::Experimental::CompositionStretch::Fill);
258
257
  break;
@@ -281,9 +280,10 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
281
280
  assert(false);
282
281
  }
283
282
 
284
- m_visual.Brush(m_drawingSurface);
283
+ Visual().as<Experimental::ISpriteVisual>().Brush(m_drawingSurface);
285
284
  } else if (m_imageResponseImage->m_brushFactory) {
286
- m_visual.Brush(m_imageResponseImage->m_brushFactory(m_reactContext.Handle(), m_compContext));
285
+ Visual().as<Experimental::ISpriteVisual>().Brush(
286
+ m_imageResponseImage->m_brushFactory(m_reactContext.Handle(), m_compContext));
287
287
  }
288
288
  }
289
289
 
@@ -310,15 +310,15 @@ void ImageComponentView::DrawImage() noexcept {
310
310
  d2dDeviceContext->CreateBitmapFromWicBitmap(m_imageResponseImage->m_wicbmp.get(), nullptr, bitmap.put()));
311
311
 
312
312
  d2dDeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f));
313
- if (m_props->backgroundColor) {
314
- d2dDeviceContext->Clear(theme()->D2DColor(*m_props->backgroundColor));
313
+ if (viewProps()->backgroundColor) {
314
+ d2dDeviceContext->Clear(theme()->D2DColor(*viewProps()->backgroundColor));
315
315
  }
316
316
 
317
- const auto imageProps = std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
317
+ const auto &imgProps = imageProps();
318
318
 
319
319
  bool useEffects{
320
- imageProps->blurRadius > 0 || isColorMeaningful(imageProps->tintColor) ||
321
- imageProps->resizeMode == facebook::react::ImageResizeMode::Repeat};
320
+ imgProps.blurRadius > 0 || isColorMeaningful(imgProps.tintColor) ||
321
+ imgProps.resizeMode == facebook::react::ImageResizeMode::Repeat};
322
322
 
323
323
  if (useEffects) {
324
324
  winrt::com_ptr<ID2D1Effect> bitmapEffects;
@@ -326,23 +326,22 @@ void ImageComponentView::DrawImage() noexcept {
326
326
  winrt::check_hresult(
327
327
  bitmapEffects->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_imageResponseImage->m_wicbmp.get()));
328
328
 
329
- if (imageProps->blurRadius > 0) {
329
+ if (imgProps.blurRadius > 0) {
330
330
  winrt::com_ptr<ID2D1Effect> gaussianBlurEffect;
331
331
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1GaussianBlur, gaussianBlurEffect.put()));
332
332
  // https://learn.microsoft.com/en-us/windows/win32/direct2d/gaussian-blur#effect-properties
333
333
  // You can compute the blur radius of the kernel by multiplying the standard deviation by 3 (radius multiplier).
334
334
  constexpr float radiusMultiplier = 3;
335
335
  winrt::check_hresult(gaussianBlurEffect->SetValue(
336
- D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, (imageProps->blurRadius) / radiusMultiplier));
336
+ D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, (imgProps.blurRadius) / radiusMultiplier));
337
337
  gaussianBlurEffect->SetInputEffect(0, bitmapEffects.get());
338
338
  bitmapEffects.copy_from(gaussianBlurEffect.get());
339
339
  }
340
340
 
341
- if (isColorMeaningful(imageProps->tintColor)) {
341
+ if (isColorMeaningful(imgProps.tintColor)) {
342
342
  winrt::com_ptr<ID2D1Effect> tintColorEffect;
343
343
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1Flood, tintColorEffect.put()));
344
- winrt::check_hresult(
345
- tintColorEffect->SetValue(D2D1_FLOOD_PROP_COLOR, theme()->D2DColor(*imageProps->tintColor)));
344
+ winrt::check_hresult(tintColorEffect->SetValue(D2D1_FLOOD_PROP_COLOR, theme()->D2DColor(*imgProps.tintColor)));
346
345
 
347
346
  winrt::com_ptr<ID2D1Effect> compositeEffect;
348
347
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1Composite, compositeEffect.put()));
@@ -353,7 +352,7 @@ void ImageComponentView::DrawImage() noexcept {
353
352
  bitmapEffects.copy_from(compositeEffect.get());
354
353
  }
355
354
 
356
- if (imageProps->resizeMode == facebook::react::ImageResizeMode::Repeat) {
355
+ if (imgProps.resizeMode == facebook::react::ImageResizeMode::Repeat) {
357
356
  winrt::com_ptr<ID2D1Effect> borderEffect;
358
357
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1Border, borderEffect.put()));
359
358
  winrt::check_hresult(borderEffect->SetValue(D2D1_BORDER_PROP_EDGE_MODE_X, D2D1_BORDER_EDGE_MODE_WRAP));
@@ -386,51 +385,6 @@ void ImageComponentView::DrawImage() noexcept {
386
385
  }
387
386
  }
388
387
 
389
- void ImageComponentView::prepareForRecycle() noexcept {}
390
-
391
- facebook::react::SharedViewProps ImageComponentView::viewProps() noexcept {
392
- return m_props;
393
- }
394
-
395
- facebook::react::Tag ImageComponentView::hitTest(
396
- facebook::react::Point pt,
397
- facebook::react::Point &localPt,
398
- bool ignorePointerEvents) const noexcept {
399
- facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
400
-
401
- facebook::react::Tag targetTag;
402
-
403
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
404
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) &&
405
- anyHitTestHelper(targetTag, ptLocal, localPt))
406
- return targetTag;
407
-
408
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
409
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
410
- ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
411
- ptLocal.y <= m_layoutMetrics.frame.size.height) {
412
- localPt = ptLocal;
413
- return Tag();
414
- }
415
-
416
- return -1;
417
- }
418
-
419
- void ImageComponentView::ensureVisual() noexcept {
420
- if (!m_visual) {
421
- m_visual = m_compContext.CreateSpriteVisual();
422
- OuterVisual().InsertAt(m_visual, 0);
423
- }
424
- }
425
-
426
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ImageComponentView::Visual() const noexcept {
427
- return m_visual;
428
- }
429
-
430
- bool ImageComponentView::focusable() const noexcept {
431
- return m_props->focusable;
432
- }
433
-
434
388
  std::string ImageComponentView::DefaultControlType() const noexcept {
435
389
  return "image";
436
390
  }
@@ -29,8 +29,8 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
29
29
 
30
30
  struct WindowsImageResponseObserver;
31
31
 
32
- struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentView> {
33
- using Super = ImageComponentViewT<ImageComponentView, ComponentView>;
32
+ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ViewComponentView> {
33
+ using Super = ImageComponentViewT<ImageComponentView, ViewComponentView>;
34
34
 
35
35
  [[nodiscard]] static winrt::Microsoft::ReactNative::ComponentView Create(
36
36
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
@@ -47,25 +47,25 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
47
47
  override;
48
48
  void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
49
49
  override;
50
- void updateLayoutMetrics(
51
- facebook::react::LayoutMetrics const &layoutMetrics,
52
- facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
53
- void prepareForRecycle() noexcept override;
54
- facebook::react::SharedViewProps viewProps() noexcept override;
55
50
  void OnRenderingDeviceLost() noexcept override;
56
51
  void onThemeChanged() noexcept override;
57
52
 
58
- facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
59
- const noexcept override;
60
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept override;
61
- bool focusable() const noexcept override;
62
53
  virtual std::string DefaultControlType() const noexcept;
54
+ static facebook::react::SharedViewProps defaultProps() noexcept;
63
55
 
64
56
  ImageComponentView(
65
57
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
66
58
  facebook::react::Tag tag,
67
59
  winrt::Microsoft::ReactNative::ReactContext const &reactContext);
68
60
 
61
+ const facebook::react::ImageProps &imageProps() const noexcept;
62
+ // TODO try to change to ViewProps
63
+ winrt::Microsoft::ReactNative::ImageProps ImageProps() noexcept;
64
+ winrt::Microsoft::ReactNative::ImageProps ViewProps() noexcept;
65
+
66
+ protected:
67
+ winrt::Microsoft::ReactNative::ViewProps ViewPropsInner() noexcept override;
68
+
69
69
  private:
70
70
  struct WindowsImageResponseObserver : facebook::react::ImageResponseObserver {
71
71
  public:
@@ -78,7 +78,6 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
78
78
  winrt::com_ptr<ImageComponentView> m_image;
79
79
  };
80
80
 
81
- void ensureVisual() noexcept;
82
81
  void ensureDrawingSurface() noexcept;
83
82
  void DrawImage() noexcept;
84
83
 
@@ -90,9 +89,6 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
90
89
  facebook::react::ImageShadowNode::ConcreteState::Shared const &state) noexcept;
91
90
  bool themeEffectsImage() const noexcept;
92
91
 
93
- std::shared_ptr<const facebook::react::ImageProps> m_props;
94
-
95
- winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_visual{nullptr};
96
92
  winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface;
97
93
  std::shared_ptr<ImageResponseImage> m_imageResponseImage;
98
94
  std::shared_ptr<WindowsImageResponseObserver> m_imageResponseObserver;