[Fabric] Add FocusNavigationDirection and allow overriding of default command handling (#13857)

* [Fabric] Add FocusNavigationDirection and allow overriding of default command handling

* Change files

* revert packages.lock
This commit is contained in:
Andrew Coates 2024-09-13 14:03:55 -07:00 коммит произвёл GitHub
Родитель a45509e274
Коммит 67e7442be2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
28 изменённых файлов: 179 добавлений и 95 удалений

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "[Fabric] Add FocusNavigationDirection and allow overriding of default command handling",
"packageName": "@react-native-windows/codegen",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "[Fabric] Add FocusNavigationDirection and allow overriding of default command handling",
"packageName": "react-native-windows",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -334,9 +334,9 @@ export function createComponentGenerator({
}).join('\n\n') : '';
const commandHandler = hasAnyCommands ? `void HandleCommand(const winrt::Microsoft::ReactNative::ComponentView &view, winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
args;
const commandHandler = hasAnyCommands ? `void HandleCommand(const winrt::Microsoft::ReactNative::ComponentView &view, const winrt::Microsoft::ReactNative::HandleCommandArgs& args) noexcept {
auto userData = view.UserData().as<TUserData>();
auto commandName = args.CommandName();
${componentShape.commands.map(command => {
const commaSeparatedCommandArgs = command.typeAnnotation.params.map(param => param.name).join(', ');
return ` if (commandName == L"${command.name}") {
@ -344,7 +344,7 @@ ${command.typeAnnotation.params.length !== 0 ? ` ${command.typeAnnotation.p
const commandArgType = translateCommandParamType(param.typeAnnotation, commandAliases, `${componentName}_${command.name}`, cppCodegenOptions);
return `${(param.optional && !commandArgType.alreadySupportsOptionalOrHasDefault) ? `std::optional<${commandArgType.type}>` : commandArgType.type} ${param.name};`;
}).join('\n')}
winrt::Microsoft::ReactNative::ReadArgs(args, ${commaSeparatedCommandArgs});` : ''}
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), ${commaSeparatedCommandArgs});` : ''}
userData->Handle${capitalizeFirstLetter(command.name)}Command(${commaSeparatedCommandArgs});
return;
}`
@ -352,10 +352,9 @@ ${command.typeAnnotation.params.length !== 0 ? ` ${command.typeAnnotation.p
}` : '';
const registerCommandHandler = hasAnyCommands ? ` builder.SetCustomCommandHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
const winrt::Microsoft::ReactNative::HandleCommandArgs& args) noexcept {
auto userData = view.UserData().as<TUserData>();
userData->HandleCommand(view, commandName, args);
userData->HandleCommand(view, args);
});` : '';
const baseType = baseStructTemplate

Просмотреть файл

@ -115,12 +115,12 @@ struct BaseMovingLight {
// You must provide an implementation of this method to handle the "setLightOn" command
virtual void HandleSetLightOnCommand(bool value) noexcept = 0;
void HandleCommand(const winrt::Microsoft::ReactNative::ComponentView &view, winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
args;
void HandleCommand(const winrt::Microsoft::ReactNative::ComponentView &view, const winrt::Microsoft::ReactNative::HandleCommandArgs& args) noexcept {
auto userData = view.UserData().as<TUserData>();
auto commandName = args.CommandName();
if (commandName == L"setLightOn") {
bool value;
winrt::Microsoft::ReactNative::ReadArgs(args, value);
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), value);
userData->HandleSetLightOnCommand(value);
return;
}
@ -175,10 +175,9 @@ void RegisterMovingLightNativeComponent(
}
builder.SetCustomCommandHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
const winrt::Microsoft::ReactNative::HandleCommandArgs& args) noexcept {
auto userData = view.UserData().as<TUserData>();
userData->HandleCommand(view, commandName, args);
userData->HandleCommand(view, args);
});
if constexpr (&TUserData::MountChildComponentView != &BaseMovingLight<TUserData>::MountChildComponentView) {

Просмотреть файл

@ -34,6 +34,15 @@ namespace Microsoft.ReactNative
All = 0x0000000F,
};
enum FocusNavigationDirection
{
None,
Next,
Previous,
First,
Last,
};
[webhosthidden]
[experimental]
interface IComponentState
@ -46,6 +55,7 @@ namespace Microsoft.ReactNative
[experimental]
[webhosthidden]
runtimeclass LosingFocusEventArgs : Microsoft.ReactNative.Composition.Input.RoutedEventArgs {
FocusNavigationDirection Direction { get; };
Microsoft.ReactNative.ComponentView NewFocusedComponent { get; };
Microsoft.ReactNative.ComponentView OldFocusedComponent { get; };
@ -56,6 +66,7 @@ namespace Microsoft.ReactNative
[experimental]
[webhosthidden]
runtimeclass GettingFocusEventArgs : Microsoft.ReactNative.Composition.Input.RoutedEventArgs {
FocusNavigationDirection Direction { get; };
Microsoft.ReactNative.ComponentView NewFocusedComponent { get; };
Microsoft.ReactNative.ComponentView OldFocusedComponent { get; };

Просмотреть файл

@ -256,11 +256,9 @@ void ComponentView::CustomCommandHandler(const HandleCommandDelegate &handler) n
m_customCommandHandler = handler;
}
void ComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
if (m_customCommandHandler) {
m_customCommandHandler(*this, commandName, args);
m_customCommandHandler(*this, args);
}
}
@ -285,7 +283,7 @@ void ComponentView::parent(const winrt::Microsoft::ReactNative::ComponentView &p
m_parent = parent;
if (!parent) {
if (oldRootView && oldRootView->GetFocusedComponent() == *this) {
oldRootView->TrySetFocusedComponent(oldParent);
oldRootView->TrySetFocusedComponent(oldParent, winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
}
}
if (parent) {
@ -424,7 +422,7 @@ void ComponentView::GotFocus(winrt::event_token const &token) noexcept {
bool ComponentView::TryFocus() noexcept {
if (auto root = rootComponentView()) {
return root->TrySetFocusedComponent(*get_strong());
return root->TrySetFocusedComponent(*get_strong(), winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
}
return false;

Просмотреть файл

@ -228,9 +228,7 @@ struct ComponentView : public ComponentViewT<ComponentView> {
virtual void UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept;
virtual void HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept;
virtual void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept;
virtual void FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept;
virtual void OnPointerEntered(
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept;

Просмотреть файл

@ -248,23 +248,26 @@ void ComponentView::updateEventEmitter(facebook::react::EventEmitter::Shared con
base_type::updateEventEmitter(eventEmitter);
}
void ComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
base_type::HandleCommand(args);
if (args.Handled())
return;
auto commandName = args.CommandName();
if (commandName == L"focus") {
if (auto root = rootComponentView()) {
root->TrySetFocusedComponent(*get_strong());
root->TrySetFocusedComponent(*get_strong(), winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
}
return;
}
if (commandName == L"blur") {
if (auto root = rootComponentView()) {
root->TrySetFocusedComponent(nullptr); // Todo store this component as previously focused element
root->TrySetFocusedComponent(
nullptr, winrt::Microsoft::ReactNative::FocusNavigationDirection::None); // Todo store this component as
// previously focused element
}
return;
}
base_type::HandleCommand(commandName, args);
}
bool ComponentView::CapturePointer(const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer) noexcept {

Просмотреть файл

@ -38,8 +38,7 @@ struct ComponentView : public ComponentViewT<
virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual OuterVisual() const noexcept;
void updateEventEmitter(facebook::react::EventEmitter::Shared const &eventEmitter) noexcept override;
const facebook::react::SharedViewEventEmitter &GetEventEmitter() const noexcept;
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
facebook::react::Props::Shared props() noexcept override;
virtual const facebook::react::SharedViewProps &viewProps() const noexcept {
static facebook::react::SharedViewProps emptyProps;

Просмотреть файл

@ -67,17 +67,21 @@ struct TraceUpdate {
};
void DebuggingOverlayComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
base_type::HandleCommand(args);
if (args.Handled())
return;
auto commandName = args.CommandName();
if (commandName == L"highlightTraceUpdates") {
std::vector<TraceUpdate> updates;
winrt::Microsoft::ReactNative::ReadArgs(args, updates);
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), updates);
// TODO should create visuals that get removed after 2 seconds
return;
}
if (commandName == L"highlightElements") {
std::vector<ElementRectangle> elements;
winrt::Microsoft::ReactNative::ReadArgs(args, elements);
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), elements);
if (auto root = rootComponentView()) {
auto rootVisual = root->OuterVisual();
@ -106,8 +110,6 @@ void DebuggingOverlayComponentView::HandleCommand(
}
return;
}
base_type::HandleCommand(commandName, args);
}
} // namespace winrt::Microsoft::ReactNative::Composition::implementation

Просмотреть файл

@ -29,8 +29,7 @@ struct DebuggingOverlayComponentView
facebook::react::Tag tag,
winrt::Microsoft::ReactNative::ReactContext const &reactContext);
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
private:
uint32_t m_activeOverlays{0};

Просмотреть файл

@ -22,19 +22,26 @@ int32_t GotFocusEventArgs::OriginalSource() noexcept {
LosingFocusEventArgs::LosingFocusEventArgs(
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent)
: m_originalSource(originalSource ? originalSource.Tag() : -1),
m_direction(direction),
m_old(oldFocusedComponent),
m_new(newFocusedComponent) {}
int32_t LosingFocusEventArgs::OriginalSource() noexcept {
int32_t LosingFocusEventArgs::OriginalSource() const noexcept {
return m_originalSource;
}
winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::NewFocusedComponent() noexcept {
winrt::Microsoft::ReactNative::FocusNavigationDirection LosingFocusEventArgs::Direction() const noexcept {
return m_direction;
}
winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::NewFocusedComponent() const noexcept {
return m_new;
}
winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::OldFocusedComponent() noexcept {
winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::OldFocusedComponent() const noexcept {
return m_old;
}
@ -58,19 +65,26 @@ void LosingFocusEventArgs::TrySetNewFocusedComponent(
GettingFocusEventArgs::GettingFocusEventArgs(
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent)
: m_originalSource(originalSource ? originalSource.Tag() : -1),
m_direction(direction),
m_old(oldFocusedComponent),
m_new(newFocusedComponent) {}
int32_t GettingFocusEventArgs::OriginalSource() noexcept {
int32_t GettingFocusEventArgs::OriginalSource() const noexcept {
return m_originalSource;
}
winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::NewFocusedComponent() noexcept {
winrt::Microsoft::ReactNative::FocusNavigationDirection GettingFocusEventArgs::Direction() const noexcept {
return m_direction;
}
winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::NewFocusedComponent() const noexcept {
return m_new;
}
winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::OldFocusedComponent() noexcept {
winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::OldFocusedComponent() const noexcept {
return m_old;
}

Просмотреть файл

@ -32,17 +32,21 @@ struct LosingFocusEventArgs
: winrt::Microsoft::ReactNative::implementation::LosingFocusEventArgsT<LosingFocusEventArgs> {
LosingFocusEventArgs(
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent);
int32_t OriginalSource() noexcept;
winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() noexcept;
winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() noexcept;
int32_t OriginalSource() const noexcept;
winrt::Microsoft::ReactNative::FocusNavigationDirection Direction() const noexcept;
winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() const noexcept;
winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() const noexcept;
void TryCancel() noexcept;
void TrySetNewFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept;
private:
const int32_t m_originalSource;
const winrt::Microsoft::ReactNative::FocusNavigationDirection m_direction;
winrt::Microsoft::ReactNative::ComponentView m_old{nullptr};
winrt::Microsoft::ReactNative::ComponentView m_new{nullptr};
};
@ -51,17 +55,20 @@ struct GettingFocusEventArgs
: winrt::Microsoft::ReactNative::implementation::GettingFocusEventArgsT<GettingFocusEventArgs> {
GettingFocusEventArgs(
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent);
int32_t OriginalSource() noexcept;
winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() noexcept;
winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() noexcept;
int32_t OriginalSource() const noexcept;
winrt::Microsoft::ReactNative::FocusNavigationDirection Direction() const noexcept;
winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() const noexcept;
winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() const noexcept;
void TryCancel() noexcept;
void TrySetNewFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept;
private:
const int32_t m_originalSource;
const winrt::Microsoft::ReactNative::FocusNavigationDirection m_direction;
winrt::Microsoft::ReactNative::ComponentView m_old{nullptr};
winrt::Microsoft::ReactNative::ComponentView m_new{nullptr};
};

Просмотреть файл

@ -191,9 +191,8 @@ void WindowsModalHostComponentView::UnmountChildComponentView(
}
void WindowsModalHostComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
Super::HandleCommand(commandName, args);
const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
Super::HandleCommand(args);
}
void WindowsModalHostComponentView::updateProps(

Просмотреть файл

@ -28,8 +28,7 @@ struct WindowsModalHostComponentView
void UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept override;
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
override;

Просмотреть файл

@ -91,12 +91,18 @@ bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::Focus
? FocusManager::FindFirstFocusableElement(*this)
: FocusManager::FindLastFocusableElement(*this);
if (view) {
TrySetFocusedComponent(view);
TrySetFocusedComponent(
view,
request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::First
? winrt::Microsoft::ReactNative::FocusNavigationDirection::First
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Last);
}
return view != nullptr;
}
bool RootComponentView::TrySetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
bool RootComponentView::TrySetFocusedComponent(
const winrt::Microsoft::ReactNative::ComponentView &view,
winrt::Microsoft::ReactNative::FocusNavigationDirection direction) noexcept {
auto target = view;
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
if (selfView && !selfView->focusable()) {
@ -110,7 +116,7 @@ bool RootComponentView::TrySetFocusedComponent(const winrt::Microsoft::ReactNati
return false;
auto losingFocusArgs = winrt::make<winrt::Microsoft::ReactNative::implementation::LosingFocusEventArgs>(
target, m_focusedComponent, target);
target, direction, m_focusedComponent, target);
if (m_focusedComponent) {
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_focusedComponent)
->onLosingFocus(losingFocusArgs);
@ -118,7 +124,7 @@ bool RootComponentView::TrySetFocusedComponent(const winrt::Microsoft::ReactNati
if (losingFocusArgs.NewFocusedComponent()) {
auto gettingFocusArgs = winrt::make<winrt::Microsoft::ReactNative::implementation::GettingFocusEventArgs>(
target, m_focusedComponent, losingFocusArgs.NewFocusedComponent());
target, direction, m_focusedComponent, losingFocusArgs.NewFocusedComponent());
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(losingFocusArgs.NewFocusedComponent())
->onGettingFocus(gettingFocusArgs);
@ -138,13 +144,16 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
}
Mso::Functor<bool(const winrt::Microsoft::ReactNative::ComponentView &)> fn =
[currentlyFocused = m_focusedComponent](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
[currentlyFocused = m_focusedComponent, next](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
if (view == currentlyFocused)
return false;
return winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view)
->rootComponentView()
->TrySetFocusedComponent(view);
->TrySetFocusedComponent(
view,
next ? winrt::Microsoft::ReactNative::FocusNavigationDirection::Next
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous);
};
return winrt::Microsoft::ReactNative::implementation::walkTree(m_focusedComponent, next, fn);

Просмотреть файл

@ -28,7 +28,9 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
winrt::Microsoft::ReactNative::ComponentView GetFocusedComponent() noexcept;
void SetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &value) noexcept;
bool TrySetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
bool TrySetFocusedComponent(
const winrt::Microsoft::ReactNative::ComponentView &view,
winrt::Microsoft::ReactNative::FocusNavigationDirection direction) noexcept;
bool NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept;

Просмотреть файл

@ -1055,13 +1055,16 @@ bool ScrollViewComponentView::scrollRight(float delta, bool animate) noexcept {
return true;
}
void ScrollViewComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
void ScrollViewComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
Super::HandleCommand(args);
if (args.Handled())
return;
auto commandName = args.CommandName();
if (commandName == L"scrollTo") {
double x, y;
bool animate;
winrt::Microsoft::ReactNative::ReadArgs(args, x, y, animate);
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), x, y, animate);
scrollTo(
{static_cast<float>(x) * m_layoutMetrics.pointScaleFactor,
static_cast<float>(y) * m_layoutMetrics.pointScaleFactor,
@ -1071,12 +1074,10 @@ void ScrollViewComponentView::HandleCommand(
// No-op for now
} else if (commandName == L"scrollToEnd") {
bool animate;
winrt::Microsoft::ReactNative::ReadArgs(args, animate);
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), animate);
scrollToEnd(animate);
} else if (commandName == L"zoomToRect") {
// No-op for now
} else {
Super::HandleCommand(commandName, args);
}
}

Просмотреть файл

@ -74,8 +74,7 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
void prepareForRecycle() noexcept override;
void OnKeyDown(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
const noexcept override;
facebook::react::Point getClientOffset() const noexcept override;

Просмотреть файл

@ -56,14 +56,14 @@ void SwitchComponentView::UnmountChildComponentView(
base_type::UnmountChildComponentView(childComponentView, index);
}
void SwitchComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
void SwitchComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
Super::HandleCommand(args);
if (args.Handled())
return;
auto commandName = args.CommandName();
if (commandName == L"setValue") {
// TODO - Current implementation always aligns with JS value
// This will be needed when we move to using WinUI controls
} else {
Super::HandleCommand(commandName, args);
}
}
@ -261,7 +261,7 @@ void SwitchComponentView::OnPointerPressed(
m_supressAnimationForNextFrame = true;
if (auto root = rootComponentView()) {
root->TrySetFocusedComponent(*get_strong());
root->TrySetFocusedComponent(*get_strong(), winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
}
updateVisuals();

Просмотреть файл

@ -27,8 +27,7 @@ struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, ViewCompo
void UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept override;
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
override;
void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept

Просмотреть файл

@ -225,7 +225,8 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
winrt::Microsoft::ReactNative::ComponentView view{nullptr};
winrt::check_hresult(
m_outer->QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
m_outer->rootComponentView()->TrySetFocusedComponent(view);
m_outer->rootComponentView()->TrySetFocusedComponent(
view, winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
// assert(false);
// TODO focus
}
@ -522,13 +523,17 @@ WindowsTextInputComponentView::WindowsTextInputComponentView(
}
void WindowsTextInputComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
Super::HandleCommand(args);
if (args.Handled())
return;
auto commandName = args.CommandName();
if (commandName == L"setTextAndSelection") {
int eventCount, begin, end;
winrt::hstring text;
winrt::Microsoft::ReactNative::ReadArgs(args, eventCount, text, begin, end);
winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), eventCount, text, begin, end);
if (eventCount >= m_nativeEventCount) {
m_comingFromJS = true;
UpdateText(winrt::to_string(text));
@ -549,8 +554,6 @@ void WindowsTextInputComponentView::HandleCommand(
m_comingFromJS = false;
}
} else {
Super::HandleCommand(commandName, args);
}
}

Просмотреть файл

@ -46,8 +46,7 @@ struct WindowsTextInputComponentView
void FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept override;
static facebook::react::SharedViewProps defaultProps() noexcept;
const facebook::react::WindowsTextInputProps &windowsTextInputProps() const noexcept;
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
void OnRenderingDeviceLost() noexcept override;
void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;

Просмотреть файл

@ -122,7 +122,9 @@ HRESULT UiaSetFocusHelper(::Microsoft::ReactNative::ReactTaggedView &view) noexc
if (rootCV == nullptr)
return UIA_E_ELEMENTNOTAVAILABLE;
return rootCV->TrySetFocusedComponent(strongView) ? S_OK : E_FAIL;
return rootCV->TrySetFocusedComponent(strongView, winrt::Microsoft::ReactNative::FocusNavigationDirection::None)
? S_OK
: E_FAIL;
}
bool WasUiaPropertyAdvised(winrt::com_ptr<IRawElementProviderSimple> &providerSimple, PROPERTYID propId) noexcept {

Просмотреть файл

@ -37,8 +37,7 @@ winrt::Microsoft::ReactNative::ComponentView UnimplementedNativeViewComponentVie
}
void UnimplementedNativeViewComponentView::HandleCommand(
winrt::hstring commandName,
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
// Do not call base to avoid unknown command asserts
}

Просмотреть файл

@ -25,8 +25,7 @@ struct UnimplementedNativeViewComponentView
facebook::react::LayoutMetrics const &layoutMetrics,
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
override;
void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
UnimplementedNativeViewComponentView(
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,

Просмотреть файл

@ -2,6 +2,8 @@
// Licensed under the MIT License.
#include "pch.h"
#include "HandleCommandArgs.g.cpp"
#include "HandleCommandArgs.g.h"
#include <AsynchronousEventBeat.h>
#include <DynamicReader.h>
#include <DynamicWriter.h>
@ -368,6 +370,28 @@ void FabricUIManager::schedulerDidRequestPreliminaryViewAllocation(const faceboo
*/
}
struct HandleCommandArgs : public winrt::Microsoft::ReactNative::implementation::HandleCommandArgsT<HandleCommandArgs> {
HandleCommandArgs(winrt::hstring commandName, folly::dynamic const &arg) : m_commandName(commandName), m_args(arg) {}
winrt::hstring CommandName() const noexcept {
return m_commandName;
}
winrt::Microsoft::ReactNative::IJSValueReader CommandArgs() const noexcept {
return winrt::make<winrt::Microsoft::ReactNative::DynamicReader>(m_args);
}
bool Handled() const noexcept {
return m_handled;
}
void Handled(bool value) noexcept {
m_handled = value;
}
private:
folly::dynamic const &m_args;
const winrt::hstring m_commandName;
bool m_handled{false};
};
void FabricUIManager::schedulerDidDispatchCommand(
facebook::react::ShadowView const &shadowView,
std::string const &commandName,
@ -375,7 +399,7 @@ void FabricUIManager::schedulerDidDispatchCommand(
if (m_context.UIDispatcher().HasThreadAccess()) {
auto descriptor = m_registry.componentViewDescriptorWithTag(shadowView.tag);
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(descriptor.view)
->HandleCommand(winrt::to_hstring(commandName), winrt::make<winrt::Microsoft::ReactNative::DynamicReader>(arg));
->HandleCommand(winrt::make<HandleCommandArgs>(winrt::to_hstring(commandName), arg));
} else {
m_context.UIDispatcher().Post(
[wkThis = weak_from_this(), commandName, tag = shadowView.tag, args = folly::dynamic(arg)]() {
@ -383,7 +407,7 @@ void FabricUIManager::schedulerDidDispatchCommand(
auto view = pThis->m_registry.findComponentViewWithTag(tag);
if (view) {
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view)->HandleCommand(
winrt::to_hstring(commandName), winrt::make<winrt::Microsoft::ReactNative::DynamicReader>(args));
winrt::make<HandleCommandArgs>(winrt::to_hstring(commandName), args));
}
}
});

Просмотреть файл

@ -47,6 +47,13 @@ namespace Microsoft.ReactNative
UInt32 Index { get; };
};
[experimental]
runtimeclass HandleCommandArgs {
String CommandName { get; };
IJSValueReader CommandArgs { get; };
Boolean Handled;
};
[experimental]
DOC_STRING("A delegate that creates a @IComponentProps object for an instance of @ViewProps. See @IReactViewComponentBuilder.SetCreateProps")
delegate IComponentProps ViewPropsFactory(ViewProps props);
@ -71,7 +78,7 @@ namespace Microsoft.ReactNative
delegate void ComponentViewInitializer(ComponentView view);
[experimental]
delegate void HandleCommandDelegate(ComponentView source, String commandName, IJSValueReader args);
delegate void HandleCommandDelegate(ComponentView source, HandleCommandArgs args);
[experimental]
delegate void UpdateFinalizerDelegate(ComponentView source, ComponentViewUpdateMask updateMask);