react-native-windows 0.0.0-canary.613 → 0.0.0-canary.614

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.
@@ -24,6 +24,7 @@
24
24
  #include <Fabric/Composition/ImageComponentView.h>
25
25
  #include <Fabric/Composition/ParagraphComponentView.h>
26
26
  #include <Fabric/Composition/ScrollViewComponentView.h>
27
+ #include <Fabric/Composition/SwitchComponentView.h>
27
28
  #include <Fabric/Composition/TextInput/WindowsTextInputComponentView.h>
28
29
 
29
30
  namespace Microsoft::ReactNative {
@@ -48,6 +49,8 @@ ComponentViewDescriptor const &ComponentViewRegistry::dequeueComponentViewWithCo
48
49
  view = std::make_shared<ImageComponentView>(compContext, tag, m_context);
49
50
  } else if (componentHandle == facebook::react::WindowsTextInputShadowNode::Handle()) {
50
51
  view = std::make_shared<WindowsTextInputComponentView>(compContext, tag, m_context);
52
+ } else if (componentHandle == facebook::react::SwitchShadowNode::Handle()) {
53
+ view = std::make_shared<SwitchComponentView>(compContext, tag, m_context);
51
54
  } else {
52
55
  view = std::make_shared<CompositionViewComponentView>(compContext, tag);
53
56
  }
@@ -0,0 +1,247 @@
1
+
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+
5
+ #pragma once
6
+
7
+ #include "SwitchComponentView.h"
8
+
9
+ namespace Microsoft::ReactNative {
10
+
11
+ SwitchComponentView::SwitchComponentView(
12
+ const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext,
13
+ facebook::react::Tag tag,
14
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext)
15
+ : Super(compContext, tag), m_context(reactContext) {
16
+ m_props = std::make_shared<facebook::react::SwitchProps const>();
17
+ }
18
+
19
+ std::vector<facebook::react::ComponentDescriptorProvider>
20
+ SwitchComponentView::supplementalComponentDescriptorProviders() noexcept {
21
+ return {};
22
+ }
23
+
24
+ void SwitchComponentView::mountChildComponentView(const IComponentView &childComponentView, uint32_t index) noexcept {
25
+ assert(false);
26
+ }
27
+
28
+ void SwitchComponentView::unmountChildComponentView(const IComponentView &childComponentView, uint32_t index) noexcept {
29
+ assert(false);
30
+ }
31
+
32
+ void SwitchComponentView::handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept {
33
+ if (commandName == "setValue") {
34
+ // TODO - Current implementation always aligns with JS value
35
+ // This will be needed when we move to using WinUI controls
36
+ } else {
37
+ Super::handleCommand(commandName, arg);
38
+ }
39
+ }
40
+
41
+ void SwitchComponentView::updateProps(
42
+ facebook::react::Props::Shared const &props,
43
+ facebook::react::Props::Shared const &oldProps) noexcept {
44
+ const auto &oldViewProps = *std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
45
+ const auto &newViewProps = *std::static_pointer_cast<const facebook::react::SwitchProps>(props);
46
+
47
+ ensureVisual();
48
+
49
+ if (oldViewProps.backgroundColor != newViewProps.backgroundColor ||
50
+ oldViewProps.thumbTintColor != newViewProps.thumbTintColor || oldViewProps.value != newViewProps.value ||
51
+ oldViewProps.disabled != newViewProps.disabled) {
52
+ m_drawingSurface = nullptr;
53
+ }
54
+
55
+ m_props = std::static_pointer_cast<facebook::react::ViewProps const>(props);
56
+ }
57
+
58
+ void SwitchComponentView::updateState(
59
+ facebook::react::State::Shared const &state,
60
+ facebook::react::State::Shared const &oldState) noexcept {}
61
+
62
+ void SwitchComponentView::updateLayoutMetrics(
63
+ facebook::react::LayoutMetrics const &layoutMetrics,
64
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
65
+ // Set Position & Size Properties
66
+ ensureVisual();
67
+
68
+ if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
69
+ m_visual.IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
70
+ }
71
+
72
+ m_layoutMetrics = layoutMetrics;
73
+
74
+ UpdateCenterPropertySet();
75
+ m_visual.Size(
76
+ {layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
77
+ layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
78
+ m_visual.Offset({
79
+ layoutMetrics.frame.origin.x * layoutMetrics.pointScaleFactor,
80
+ layoutMetrics.frame.origin.y * layoutMetrics.pointScaleFactor,
81
+ 0.0f,
82
+ });
83
+ }
84
+
85
+ void SwitchComponentView::finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept {
86
+ ensureDrawingSurface();
87
+ }
88
+
89
+ void SwitchComponentView::Draw() noexcept {
90
+ // Begin our update of the surface pixels. If this is our first update, we are required
91
+ // to specify the entire surface, which nullptr is shorthand for (but, as it works out,
92
+ // any time we make an update we touch the entire surface, so we always pass nullptr).
93
+ winrt::com_ptr<ID2D1DeviceContext> d2dDeviceContext;
94
+ POINT offset;
95
+
96
+ winrt::com_ptr<Composition::ICompositionDrawingSurfaceInterop> drawingSurfaceInterop;
97
+ m_drawingSurface.as(drawingSurfaceInterop);
98
+
99
+ if (CheckForDeviceRemoved(drawingSurfaceInterop->BeginDraw(d2dDeviceContext.put(), &offset))) {
100
+ const auto switchProps = std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
101
+
102
+ d2dDeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f));
103
+ if (m_props->backgroundColor) {
104
+ d2dDeviceContext->Clear(m_props->backgroundColor.AsD2DColor());
105
+ }
106
+
107
+ float offsetX = static_cast<float>(offset.x / m_layoutMetrics.pointScaleFactor);
108
+ float offsetY = static_cast<float>(offset.y / m_layoutMetrics.pointScaleFactor);
109
+
110
+ // https://github.com/microsoft/microsoft-ui-xaml/blob/main/dev/CommonStyles/ToggleSwitch_themeresources.xaml
111
+ constexpr float thumbMargin = 3.0f;
112
+ constexpr float thumbRadius = 7.0f;
113
+ constexpr float trackWidth = 40.0f;
114
+ constexpr float trackHeight = 20.0f;
115
+ constexpr float trackCornerRadius = 10.0f;
116
+
117
+ auto frame{m_layoutMetrics.frame.size};
118
+ float trackMarginX = (frame.width - trackWidth) / 2;
119
+ float trackMarginY = (frame.height - trackHeight) / 2;
120
+
121
+ D2D1_RECT_F trackRect = D2D1::RectF(
122
+ offsetX + trackMarginX,
123
+ offsetY + trackMarginY,
124
+ offsetX + trackMarginX + trackWidth,
125
+ offsetY + trackMarginY + trackHeight);
126
+
127
+ // switchProps->value = false
128
+ float thumbX = trackRect.left + thumbMargin + thumbRadius;
129
+
130
+ if (switchProps->value) {
131
+ thumbX = trackRect.right - thumbMargin - thumbRadius;
132
+ }
133
+
134
+ winrt::com_ptr<ID2D1SolidColorBrush> defaultBrush;
135
+
136
+ D2D1_COLOR_F defaultColor =
137
+ switchProps->disabled ? facebook::react::greyColor().AsD2DColor() : facebook::react::blackColor().AsD2DColor();
138
+
139
+ winrt::check_hresult(d2dDeviceContext->CreateSolidColorBrush(defaultColor, defaultBrush.put()));
140
+
141
+ winrt::com_ptr<ID2D1SolidColorBrush> thumbBrush;
142
+ if (!switchProps->disabled && switchProps->thumbTintColor) {
143
+ winrt::check_hresult(
144
+ d2dDeviceContext->CreateSolidColorBrush(switchProps->thumbTintColor.AsD2DColor(), thumbBrush.put()));
145
+ } else {
146
+ thumbBrush = defaultBrush;
147
+ }
148
+
149
+ const auto dpi = m_layoutMetrics.pointScaleFactor * 96.0f;
150
+ float oldDpiX, oldDpiY;
151
+ d2dDeviceContext->GetDpi(&oldDpiX, &oldDpiY);
152
+ d2dDeviceContext->SetDpi(dpi, dpi);
153
+
154
+ // switch thumb
155
+ D2D1_POINT_2F thumbCenter = D2D1 ::Point2F(thumbX, (trackRect.top + trackRect.bottom) / 2);
156
+ D2D1_ELLIPSE thumb = D2D1::Ellipse(thumbCenter, thumbRadius, thumbRadius);
157
+ d2dDeviceContext->FillEllipse(thumb, thumbBrush.get());
158
+
159
+ // switch track
160
+ D2D1_ROUNDED_RECT track = D2D1::RoundedRect(trackRect, trackCornerRadius, trackCornerRadius);
161
+ d2dDeviceContext->DrawRoundedRectangle(track, defaultBrush.get());
162
+
163
+ // Restore old dpi setting
164
+ d2dDeviceContext->SetDpi(oldDpiX, oldDpiY);
165
+
166
+ // Our update is done. EndDraw never indicates rendering device removed, so any
167
+ // failure here is unexpected and, therefore, fatal.
168
+ winrt::check_hresult(drawingSurfaceInterop->EndDraw());
169
+ }
170
+ }
171
+
172
+ void SwitchComponentView::prepareForRecycle() noexcept {}
173
+
174
+ facebook::react::Props::Shared SwitchComponentView::props() noexcept {
175
+ return m_props;
176
+ }
177
+
178
+ void SwitchComponentView::ensureVisual() noexcept {
179
+ if (!m_visual) {
180
+ m_visual = m_compContext.CreateSpriteVisual();
181
+ }
182
+ }
183
+
184
+ void SwitchComponentView::ensureDrawingSurface() noexcept {
185
+ if (!m_drawingSurface) {
186
+ winrt::Windows::Foundation::Size surfaceSize = {
187
+ m_layoutMetrics.frame.size.width * m_layoutMetrics.pointScaleFactor,
188
+ m_layoutMetrics.frame.size.height * m_layoutMetrics.pointScaleFactor};
189
+ m_drawingSurface = m_compContext.CreateDrawingSurface(
190
+ surfaceSize,
191
+ winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
192
+ winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
193
+
194
+ Draw();
195
+
196
+ auto surfaceBrush = m_compContext.CreateSurfaceBrush(m_drawingSurface);
197
+
198
+ m_visual.Brush(surfaceBrush);
199
+ }
200
+ }
201
+
202
+ facebook::react::Tag SwitchComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt)
203
+ const noexcept {
204
+ facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
205
+
206
+ if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
207
+ m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
208
+ ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
209
+ ptLocal.y <= m_layoutMetrics.frame.size.height) {
210
+ localPt = ptLocal;
211
+ return tag();
212
+ }
213
+
214
+ return -1;
215
+ }
216
+
217
+ facebook::react::SharedTouchEventEmitter SwitchComponentView::touchEventEmitter() noexcept {
218
+ return m_eventEmitter;
219
+ }
220
+
221
+ winrt::Microsoft::ReactNative::Composition::IVisual SwitchComponentView::Visual() const noexcept {
222
+ return m_visual;
223
+ }
224
+
225
+ int64_t SwitchComponentView::SendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept {
226
+ switch (msg) {
227
+ case WM_LBUTTONDOWN:
228
+ case WM_POINTERDOWN: {
229
+ const auto switchProps = std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
230
+
231
+ if (!switchProps->disabled && m_eventEmitter) {
232
+ auto switchEventEmitter = std::static_pointer_cast<facebook::react::SwitchEventEmitter const>(m_eventEmitter);
233
+
234
+ facebook::react::SwitchEventEmitter::OnChange args;
235
+ args.value = !(switchProps->value);
236
+ args.target = tag();
237
+
238
+ switchEventEmitter->onChange(args);
239
+ }
240
+ break;
241
+ }
242
+ }
243
+
244
+ return 0;
245
+ }
246
+
247
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,58 @@
1
+
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+
5
+ #pragma once
6
+
7
+ #include <Fabric/ComponentView.h>
8
+ #include <Microsoft.ReactNative.Cxx/ReactContext.h>
9
+
10
+ #include "CompositionViewComponentView.h"
11
+
12
+ #include <react/components/rnwcore/ShadowNodes.h>
13
+
14
+ namespace Microsoft::ReactNative {
15
+
16
+ struct SwitchComponentView;
17
+
18
+ struct SwitchComponentView : CompositionBaseComponentView {
19
+ using Super = CompositionBaseComponentView;
20
+ SwitchComponentView(
21
+ const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext,
22
+ facebook::react::Tag tag,
23
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext);
24
+
25
+ std::vector<facebook::react::ComponentDescriptorProvider> supplementalComponentDescriptorProviders() noexcept
26
+ override;
27
+ void mountChildComponentView(const IComponentView &childComponentView, uint32_t index) noexcept override;
28
+ void unmountChildComponentView(const IComponentView &childComponentView, uint32_t index) noexcept override;
29
+ void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override;
30
+ void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
31
+ override;
32
+ void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
33
+ override;
34
+ void updateLayoutMetrics(
35
+ facebook::react::LayoutMetrics const &layoutMetrics,
36
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
37
+ void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override;
38
+ void prepareForRecycle() noexcept override;
39
+ facebook::react::Props::Shared props() noexcept override;
40
+ facebook::react::SharedTouchEventEmitter touchEventEmitter() noexcept override;
41
+
42
+ facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override;
43
+ winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override;
44
+ int64_t SendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override;
45
+
46
+ private:
47
+ void ensureVisual() noexcept;
48
+ void Draw() noexcept;
49
+ void ensureDrawingSurface() noexcept;
50
+
51
+ facebook::react::Size m_contentSize;
52
+ winrt::Microsoft::ReactNative::Composition::SpriteVisual m_visual{nullptr};
53
+ winrt::Microsoft::ReactNative::ReactContext m_context;
54
+ facebook::react::SharedViewProps m_props;
55
+ winrt::Microsoft::ReactNative::Composition::ICompositionDrawingSurface m_drawingSurface;
56
+ };
57
+
58
+ } // namespace Microsoft::ReactNative
@@ -56,4 +56,9 @@ SharedColor whiteColor() {
56
56
  return color;
57
57
  }
58
58
 
59
+ SharedColor greyColor() {
60
+ static SharedColor color = colorFromComponents(ColorComponents{133, 133, 133, 1});
61
+ return color;
62
+ }
63
+
59
64
  } // namespace facebook::react
@@ -119,6 +119,7 @@ ColorComponents colorComponentsFromColor(SharedColor const &color);
119
119
  SharedColor clearColor();
120
120
  SharedColor blackColor();
121
121
  SharedColor whiteColor();
122
+ SharedColor greyColor();
122
123
 
123
124
  } // namespace react
124
125
  } // namespace facebook
@@ -10,7 +10,7 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.0.0-canary.613</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.0.0-canary.614</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>0</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
@@ -270,6 +270,7 @@
270
270
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\CompositionEventHandler.cpp" />
271
271
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\CompositionHelpers.cpp" />
272
272
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\ImageComponentView.cpp" />
273
+ <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\SwitchComponentView.cpp" />
273
274
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\ParagraphComponentView.cpp" />
274
275
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\ScrollViewComponentView.cpp" />
275
276
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Fabric\Composition\CompositionViewComponentView.cpp" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.0.0-canary.613",
3
+ "version": "0.0.0-canary.614",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",