From 132f89ac04b59641db332f7bb279fd11ba81a9dc Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Mon, 15 Feb 2021 17:25:19 -0800 Subject: [PATCH] not static --- .../windows/ReactNativeXaml/XamlMetadata.cpp | 53 +++++++++++++------ .../windows/ReactNativeXaml/XamlMetadata.h | 12 +++-- .../ReactNativeXaml/XamlViewManager.cpp | 30 ++--------- .../windows/ReactNativeXaml/XamlViewManager.h | 2 + 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/package/windows/ReactNativeXaml/XamlMetadata.cpp b/package/windows/ReactNativeXaml/XamlMetadata.cpp index 69ba935..3232f8b 100644 --- a/package/windows/ReactNativeXaml/XamlMetadata.cpp +++ b/package/windows/ReactNativeXaml/XamlMetadata.cpp @@ -6,7 +6,7 @@ using namespace winrt::Microsoft::ReactNative; #define MAKE_GET_DP(type, prop) IsType, []() { return type::prop(); } - //ctx.DispatchEvent(sender.as(), L"top" L#evtName, [](auto const& evtDataWriter) noexcept {}); \ +//ctx.DispatchEvent(sender.as(), L"top" L#evtName, [](auto const& evtDataWriter) noexcept {}); \ #define MAKE_EVENT(evtName, xamlType) \ { #evtName, { [](IInspectable o, IReactContext reactContext) { \ @@ -17,7 +17,11 @@ using namespace winrt::Microsoft::ReactNative; } \ } } } - const std::map > XamlMetadata::xamlEventMap = { +#define CREATE_TYPE(T) [](){return T();} + + +XamlMetadata::XamlMetadata() { + xamlEventMap = { MAKE_EVENT(Click, xaml::Controls::Primitives::ButtonBase), // { "Click", { [](IInspectable o, IReactContext context) { // if (auto c = o.try_as()) { @@ -26,7 +30,7 @@ using namespace winrt::Microsoft::ReactNative; //}} } } }; - const std::multimap XamlMetadata::xamlPropertyMap = { + xamlPropertyMap = { { "width", { MAKE_GET_DP(FrameworkElement, WidthProperty), FromJSType::Double, XamlPropType::Double }}, { "height", { MAKE_GET_DP(FrameworkElement, HeightProperty), FromJSType::Double, XamlPropType::Double }}, { "text", { MAKE_GET_DP(ContentControl, ContentProperty), FromJSType::String, XamlPropType::Object }}, @@ -36,19 +40,34 @@ using namespace winrt::Microsoft::ReactNative; { "backgroundColor", { MAKE_GET_DP(Control, BackgroundProperty), FromJSType::SolidColorBrush, XamlPropType::Object }}, }; - const PropInfo* XamlMetadata::GetProp(const std::string& propertyName, const IInspectable& obj) { - auto propRange = xamlPropertyMap.equal_range(propertyName); - for (auto prop = propRange.first; prop != propRange.second; ++prop) - { - if (prop->second.isType(obj)) { return &(prop->second); } - } - return nullptr; - } - -#define CREATE_TYPE(T) [](){return T();} - - const std::map> XamlMetadata::xamlTypeCreatorMap = { - { "hyperlinkButton", CREATE_TYPE(HyperlinkButton)}, - { "textblock", CREATE_TYPE(TextBlock)}, + xamlTypeCreatorMap = { + { "hyperlinkButton", CREATE_TYPE(HyperlinkButton)}, + { "textblock", CREATE_TYPE(TextBlock)}, }; +} +winrt::Windows::Foundation::IInspectable XamlMetadata::Create(const std::string& typeName, const winrt::Microsoft::ReactNative::IReactContext& context) { + if (xamlTypeCreatorMap.count(typeName) != 0) { + auto creator = xamlTypeCreatorMap.at(typeName); + auto e = creator(); + // Register events + std::for_each(xamlEventMap.begin(), xamlEventMap.end(), [e, context](const auto& entry) {entry.second(e, context); }); + return e; + } + else { + assert(false && "xaml type not found"); + throw std::invalid_argument("xaml type not found"); + } + +} + + +const PropInfo* XamlMetadata::GetProp(const std::string& propertyName, const IInspectable& obj) { + auto propRange = xamlPropertyMap.equal_range(propertyName); + for (auto prop = propRange.first; prop != propRange.second; ++prop) + { + if (prop->second.isType(obj)) { return &(prop->second); } + } + return nullptr; +} + diff --git a/package/windows/ReactNativeXaml/XamlMetadata.h b/package/windows/ReactNativeXaml/XamlMetadata.h index 86fe910..ff64096 100644 --- a/package/windows/ReactNativeXaml/XamlMetadata.h +++ b/package/windows/ReactNativeXaml/XamlMetadata.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -107,8 +108,11 @@ private: }; struct XamlMetadata { - static const std::map> xamlTypeCreatorMap; - static const std::multimap xamlPropertyMap; - static const std::map > xamlEventMap; - static const PropInfo* GetProp(const std::string& propertyName, const IInspectable& obj); + winrt::Windows::Foundation::IInspectable Create(const std::string& typeName, const winrt::Microsoft::ReactNative::IReactContext& context); + XamlMetadata(); + const PropInfo* GetProp(const std::string& propertyName, const IInspectable& obj); + + std::map> xamlTypeCreatorMap; + std::multimap xamlPropertyMap; + std::map > xamlEventMap; }; \ No newline at end of file diff --git a/package/windows/ReactNativeXaml/XamlViewManager.cpp b/package/windows/ReactNativeXaml/XamlViewManager.cpp index 23d79c0..d93fc88 100644 --- a/package/windows/ReactNativeXaml/XamlViewManager.cpp +++ b/package/windows/ReactNativeXaml/XamlViewManager.cpp @@ -39,19 +39,7 @@ namespace winrt::ReactNativeXaml { winrt::IInspectable XamlViewManager::CreateViewWithProperties(winrt::Microsoft::ReactNative::IJSValueReader const& propertyMapReader) noexcept { const JSValueObject& propertyMap = JSValue::ReadObjectFrom(propertyMapReader); auto typeName = propertyMap["type"].AsString(); - if (XamlMetadata::xamlTypeCreatorMap.count(typeName) != 0) { - auto creator = XamlMetadata::xamlTypeCreatorMap.at(typeName); - auto e = creator(); - //e.as().Tag(delegating.Tag()); // event dispatching needs to have the xaml event sender have a tag - // Register events - std::for_each(XamlMetadata::xamlEventMap.begin(), XamlMetadata::xamlEventMap.end(), [e, context = this->m_reactContext](const auto& entry) {entry.second(e, context); }); - return e; - } - else { - assert(false && "xaml type not found"); - VerifyElseCrash(false); - } - + return xamlMetadata.Create(typeName, m_reactContext); } // IViewManagerWithNativeProperties @@ -79,17 +67,9 @@ namespace winrt::ReactNativeXaml { if (!e) { if (propertyMap.count("type") != 0) { const auto typeName = propertyMap["type"].AsString(); - if (XamlMetadata::xamlTypeCreatorMap.count(typeName) != 0) { - auto creator = XamlMetadata::xamlTypeCreatorMap.at(typeName); - e = creator(); - e.as().Tag(delegating.Tag()); // event dispatching needs to have the xaml event sender have a tag - // Register events - std::for_each(XamlMetadata::xamlEventMap.begin(), XamlMetadata::xamlEventMap.end(), [e, context = ReactContext()](const auto& entry) {entry.second(e, context); }); - delegating.Content(e); - } - else { - assert(false && "xaml type not found"); - } + e = xamlMetadata.Create(typeName, m_reactContext); + e.as().Tag(delegating.Tag()); // event dispatching needs to have the xaml event sender have a tag + delegating.Content(e); } else { assert(false && "xaml type not specified"); @@ -102,7 +82,7 @@ namespace winrt::ReactNativeXaml { auto const& propertyName = pair.first; auto const& propertyValue = pair.second; - if (auto prop = XamlMetadata::GetProp(propertyName, control)) { + if (auto prop = xamlMetadata.GetProp(propertyName, control)) { prop->SetValue(control, propertyValue); } else if (propertyName == "type") {} diff --git a/package/windows/ReactNativeXaml/XamlViewManager.h b/package/windows/ReactNativeXaml/XamlViewManager.h index 752cfb0..887d25a 100644 --- a/package/windows/ReactNativeXaml/XamlViewManager.h +++ b/package/windows/ReactNativeXaml/XamlViewManager.h @@ -3,6 +3,7 @@ #include "pch.h" #include "CppWinRTIncludes.h" #include "winrt/Microsoft.ReactNative.h" +#include "XamlMetadata.h" // Required to avoid creating unnecessary ContentControls to hold dynamically-typed ui elements // https://github.com/microsoft/react-native-windows/pull/7137 @@ -63,6 +64,7 @@ namespace winrt::ReactNativeXaml { bool RequiresNativeLayout() noexcept { return true; } private: winrt::Microsoft::ReactNative::IReactContext m_reactContext{ nullptr }; + XamlMetadata xamlMetadata; }; }