Skip to content

Commit 21e551f

Browse files
authored
Adds simple animated fabric activityIndicator (#11537)
* get files building * try to add something to screen * restore build state * link to managerModule * get a basic circle on the page * circles are responsive to color * add static loading circles * clean up code * restore vscode settings * fix * Change files * address feedback * get a circle moving around a ring * create simple animated activityIndicator * add color * clean up code * fix merge * format * remove unneccesary code * remove drawingSurface and update updateProps * switch from ShapeVisual
1 parent c973765 commit 21e551f

9 files changed

+403
-4
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "add default static activityIndicator",
4+
"packageName": "react-native-windows",
5+
"email": "tatianakapos@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

vnext/Microsoft.ReactNative/CompositionSwitcher.idl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ namespace Microsoft.ReactNative.Composition
9292
void TryUpdatePosition(Windows.Foundation.Numerics.Vector3 position, Boolean animate);
9393
}
9494

95+
[webhosthidden]
96+
[experimental]
97+
runtimeclass ActivityVisual : IVisual
98+
{
99+
void updateColor(Windows.UI.Color color);
100+
}
101+
95102
[webhosthidden]
96103
[uuid("a74bfffc-7f2d-432f-8291-654782ab0d52")] // uuid needed for empty interfaces
97104
[version(1)]
@@ -129,6 +136,7 @@ namespace Microsoft.ReactNative.Composition
129136

130137
SpriteVisual CreateSpriteVisual();
131138
ScrollVisual CreateScrollerVisual();
139+
ActivityVisual CreateActivityVisual();
132140
ICaretVisual CreateCaretVisual();
133141
IFocusVisual CreateFocusVisual();
134142
IDropShadow CreateDropShadow();
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include "ActivityIndicatorComponentView.h"
7+
#include "CompositionDynamicAutomationProvider.h"
8+
9+
#include <Windows.UI.Composition.h>
10+
#include <Windows.h>
11+
#include "CompositionContextHelper.h"
12+
13+
namespace Microsoft::ReactNative {
14+
15+
std::shared_ptr<ActivityIndicatorComponentView> ActivityIndicatorComponentView::Create(
16+
const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext,
17+
facebook::react::Tag tag,
18+
winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept {
19+
return std::shared_ptr<ActivityIndicatorComponentView>(
20+
new ActivityIndicatorComponentView(compContext, tag, reactContext));
21+
}
22+
23+
ActivityIndicatorComponentView::ActivityIndicatorComponentView(
24+
const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext,
25+
facebook::react::Tag tag,
26+
winrt::Microsoft::ReactNative::ReactContext const &reactContext)
27+
: Super(compContext, tag), m_context(reactContext) {
28+
m_props = std::make_shared<facebook::react::ActivityIndicatorViewProps const>();
29+
}
30+
31+
void ActivityIndicatorComponentView::mountChildComponentView(
32+
IComponentView &childComponentView,
33+
uint32_t index) noexcept {
34+
assert(false);
35+
}
36+
37+
void ActivityIndicatorComponentView::unmountChildComponentView(
38+
IComponentView &childComponentView,
39+
uint32_t index) noexcept {
40+
assert(false);
41+
}
42+
43+
void ActivityIndicatorComponentView::handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept {
44+
Super::handleCommand(commandName, arg);
45+
}
46+
47+
void ActivityIndicatorComponentView::updateProps(
48+
facebook::react::Props::Shared const &props,
49+
facebook::react::Props::Shared const &oldProps) noexcept {
50+
const auto oldViewProps = std::static_pointer_cast<const facebook::react::ActivityIndicatorViewProps>(m_props);
51+
const auto newViewProps = std::static_pointer_cast<const facebook::react::ActivityIndicatorViewProps>(props);
52+
53+
ensureVisual();
54+
55+
// update color if needed
56+
if (newViewProps->color && (!oldProps || newViewProps->color != oldViewProps->color)) {
57+
m_ActivityIndicatorVisual.updateColor(newViewProps->color.AsWindowsColor());
58+
}
59+
60+
updateBorderProps(*oldViewProps, *newViewProps);
61+
m_props = std::static_pointer_cast<facebook::react::ViewProps const>(props);
62+
}
63+
64+
void ActivityIndicatorComponentView::updateState(
65+
facebook::react::State::Shared const &state,
66+
facebook::react::State::Shared const &oldState) noexcept {}
67+
68+
void ActivityIndicatorComponentView::updateLayoutMetrics(
69+
facebook::react::LayoutMetrics const &layoutMetrics,
70+
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
71+
// Set Position & Size Properties
72+
ensureVisual();
73+
74+
if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
75+
OuterVisual().IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
76+
}
77+
78+
updateBorderLayoutMetrics(layoutMetrics, *m_props);
79+
m_layoutMetrics = layoutMetrics;
80+
81+
UpdateCenterPropertySet();
82+
m_visual.Size(
83+
{layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
84+
layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
85+
}
86+
87+
void ActivityIndicatorComponentView::finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept {}
88+
89+
void ActivityIndicatorComponentView::prepareForRecycle() noexcept {}
90+
91+
facebook::react::Props::Shared ActivityIndicatorComponentView::props() noexcept {
92+
return m_props;
93+
}
94+
95+
void ActivityIndicatorComponentView::ensureVisual() noexcept {
96+
if (!m_visual) {
97+
m_visual = m_compContext.CreateSpriteVisual();
98+
m_ActivityIndicatorVisual = m_compContext.CreateActivityVisual(); // creates COM control
99+
100+
OuterVisual().InsertAt(m_ActivityIndicatorVisual, 0);
101+
OuterVisual().InsertAt(m_visual, 0);
102+
}
103+
}
104+
105+
facebook::react::Tag ActivityIndicatorComponentView::hitTest(
106+
facebook::react::Point pt,
107+
facebook::react::Point &localPt,
108+
bool ignorePointerEvents) const noexcept {
109+
facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
110+
111+
if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
112+
m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
113+
ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
114+
ptLocal.y <= m_layoutMetrics.frame.size.height) {
115+
localPt = ptLocal;
116+
return tag();
117+
}
118+
return -1;
119+
}
120+
121+
winrt::Microsoft::ReactNative::Composition::IVisual ActivityIndicatorComponentView::Visual() const noexcept {
122+
return m_visual;
123+
}
124+
125+
bool ActivityIndicatorComponentView::focusable() const noexcept {
126+
return false;
127+
}
128+
129+
} // namespace Microsoft::ReactNative
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include <Fabric/ComponentView.h>
7+
#include <Microsoft.ReactNative.Cxx/ReactContext.h>
8+
9+
#include "CompositionViewComponentView.h"
10+
11+
#include <react/components/rnwcore/ShadowNodes.h>
12+
13+
namespace Microsoft::ReactNative {
14+
15+
struct ActivityIndicatorComponentView;
16+
17+
struct ActivityIndicatorComponentView : CompositionBaseComponentView {
18+
using Super = CompositionBaseComponentView;
19+
20+
[[nodiscard]] static std::shared_ptr<ActivityIndicatorComponentView> Create(
21+
const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext,
22+
facebook::react::Tag tag,
23+
winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
24+
25+
void mountChildComponentView(IComponentView &childComponentView, uint32_t index) noexcept override;
26+
void unmountChildComponentView(IComponentView &childComponentView, uint32_t index) noexcept override;
27+
void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override;
28+
void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
29+
override;
30+
void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
31+
override;
32+
void updateLayoutMetrics(
33+
facebook::react::LayoutMetrics const &layoutMetrics,
34+
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
35+
void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override;
36+
void prepareForRecycle() noexcept override;
37+
facebook::react::Props::Shared props() noexcept override;
38+
bool focusable() const noexcept override;
39+
40+
facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
41+
const noexcept override;
42+
winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override;
43+
44+
private:
45+
ActivityIndicatorComponentView(
46+
const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext,
47+
facebook::react::Tag tag,
48+
winrt::Microsoft::ReactNative::ReactContext const &reactContext);
49+
50+
void ensureVisual() noexcept;
51+
52+
winrt::Microsoft::ReactNative::Composition::SpriteVisual m_visual{nullptr};
53+
winrt::Microsoft::ReactNative::Composition::ActivityVisual m_ActivityIndicatorVisual{nullptr};
54+
winrt::Microsoft::ReactNative::ReactContext m_context;
55+
facebook::react::SharedViewProps m_props;
56+
};
57+
58+
} // namespace Microsoft::ReactNative

vnext/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <react/renderer/components/view/ViewShadowNode.h>
2121

2222
#include <Fabric/Composition/AbiCompositionViewComponentView.h>
23+
#include <Fabric/Composition/ActivityIndicatorComponentView.h>
2324
#include <Fabric/Composition/CompositionHelpers.h>
2425
#include <Fabric/Composition/CompositionViewComponentView.h>
2526
#include <Fabric/Composition/ImageComponentView.h>
@@ -57,6 +58,8 @@ ComponentViewDescriptor const &ComponentViewRegistry::dequeueComponentViewWithCo
5758
view = WindowsTextInputComponentView::Create(compContext, tag, m_context);
5859
} else if (componentHandle == facebook::react::SwitchShadowNode::Handle()) {
5960
view = SwitchComponentView::Create(compContext, tag, m_context);
61+
} else if (componentHandle == facebook::react::ActivityIndicatorViewShadowNode::Handle()) {
62+
view = ActivityIndicatorComponentView::Create(compContext, tag, m_context);
6063
} else if (componentHandle == facebook::react::RootShadowNode::Handle()) {
6164
view = RootComponentView::Create(compContext, tag, m_context);
6265
} else if (

0 commit comments

Comments
 (0)