diff --git a/src/components/ScreenContentWrapper.windows.tsx b/src/components/ScreenContentWrapper.windows.tsx new file mode 100644 index 0000000000..4e01239169 --- /dev/null +++ b/src/components/ScreenContentWrapper.windows.tsx @@ -0,0 +1,5 @@ +import { View } from 'react-native'; + +const ScreenContentWrapper = View; + +export default ScreenContentWrapper; diff --git a/src/components/ScreenFooter.windows.tsx b/src/components/ScreenFooter.windows.tsx new file mode 100644 index 0000000000..14d935da91 --- /dev/null +++ b/src/components/ScreenFooter.windows.tsx @@ -0,0 +1,7 @@ +import { View } from 'react-native'; + +const ScreenFooter = View; +const FooterComponent = View; + +export default ScreenFooter; +export { FooterComponent }; diff --git a/windows/RNScreens/ModalScreenViewManager.cpp b/windows/RNScreens/ModalScreenViewManager.cpp new file mode 100644 index 0000000000..13da81cd2f --- /dev/null +++ b/windows/RNScreens/ModalScreenViewManager.cpp @@ -0,0 +1,22 @@ +#include "pch.h" +#include "ModalScreenViewManager.h" +#include "JSValueXaml.h" +#include "NativeModules.h" + +namespace winrt { +using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +} // namespace winrt + +namespace winrt::RNScreens::implementation { +// IViewManager +winrt::hstring ModalScreenViewManager::Name() noexcept { + return L"RNSModalScreen"; +} + + +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ModalScreenViewManager.h b/windows/RNScreens/ModalScreenViewManager.h new file mode 100644 index 0000000000..fbc0dc9efc --- /dev/null +++ b/windows/RNScreens/ModalScreenViewManager.h @@ -0,0 +1,13 @@ +#pragma once +#include "NativeModules.h" +#include "winrt/Microsoft.ReactNative.h" +#include "ScreenViewManager.h" + +namespace winrt::RNScreens::implementation { + +class ModalScreenViewManager : public ScreenViewManager { + public: + ModalScreenViewManager() = default; + winrt::hstring Name() noexcept; +}; +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/RNScreens.vcxproj b/windows/RNScreens/RNScreens.vcxproj index 0d7b49dc7f..3c7b03beff 100644 --- a/windows/RNScreens/RNScreens.vcxproj +++ b/windows/RNScreens/RNScreens.vcxproj @@ -20,7 +20,7 @@ 10.0.18362.0 - 10.0.16299.0 + 10.0.17763.0 @@ -122,6 +122,9 @@ + + + RNScreens.idl @@ -133,6 +136,8 @@ RNScreens.idl + + @@ -144,12 +149,17 @@ + + + ReactPackageProvider.idl + + diff --git a/windows/RNScreens/RNScreens.vcxproj.filters b/windows/RNScreens/RNScreens.vcxproj.filters index da5011e6f0..c9dcbe269b 100644 --- a/windows/RNScreens/RNScreens.vcxproj.filters +++ b/windows/RNScreens/RNScreens.vcxproj.filters @@ -17,8 +17,13 @@ + + + + + @@ -31,8 +36,13 @@ + + + + + diff --git a/windows/RNScreens/ReactPackageProvider.cpp b/windows/RNScreens/ReactPackageProvider.cpp index 64bd82d34b..e271dfa601 100644 --- a/windows/RNScreens/ReactPackageProvider.cpp +++ b/windows/RNScreens/ReactPackageProvider.cpp @@ -8,6 +8,9 @@ #include "ScreenStackHeaderConfigViewManager.h" #include "ScreenStackViewManager.h" #include "ScreenViewManager.h" +#include "ScreenStackHeaderSubviewViewManager.h" +#include "ModalScreenViewManager.h" +#include "SearchBarViewManager.h" using namespace winrt::Microsoft::ReactNative; @@ -17,14 +20,29 @@ void ReactPackageProvider::CreatePackage( packageBuilder.AddViewManager(L"RNScreensViewManager", []() { return winrt::make(); }); + packageBuilder.AddViewManager(L"RNScreensStackHeaderConfigViewManager", []() { return winrt::make(); }); + packageBuilder.AddViewManager(L"RNSScreenStackViewManager", []() { return winrt::make(); }); + packageBuilder.AddViewManager(L"RNSScreenContainerViewManager", []() { return winrt::make(); }); + + packageBuilder.AddViewManager(L"RNSScreenStackHeaderSubviewViewManager", [] () { + return winrt::make(); + }); + + packageBuilder.AddViewManager(L"RNSModalScreenViewManager", [] () { + return winrt::make(); + }); + + packageBuilder.AddViewManager(L"RNSSearchBar", [] () { + return winrt::make(); + }); } } // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/Screen.cpp b/windows/RNScreens/Screen.cpp index e5ede3c009..e29f1235bb 100644 --- a/windows/RNScreens/Screen.cpp +++ b/windows/RNScreens/Screen.cpp @@ -1,122 +1,128 @@ -#include "pch.h" -#include "Screen.h" -#include "JSValueXaml.h" -#include "NativeModules.h" - - -namespace winrt { -using namespace Microsoft::ReactNative; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::UI; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Controls; -} // namespace winrt - -namespace winrt::RNScreens::implementation { -Screen::Screen(winrt::Microsoft::ReactNative::IReactContext reactContext) - : m_reactContext(reactContext) { - onLoadingRevoker = Loading({this, &Screen::onLoading}); - onLoadedRevoker = Loaded({this, &Screen::onLoaded}); - onUnloadedRevoker = Unloaded({this, &Screen::onUnloaded}); -} - -Screen::~Screen() { - Loading(onLoadingRevoker); - Loaded(onLoadedRevoker); - Unloaded(onUnloadedRevoker); -} - -void Screen::addView(winrt::Windows::UI::Xaml::UIElement element) { - Children().Append(element); -} - -void Screen::removeAllChildren() { - Children().Clear(); -} - -void Screen::removeChildAt(int64_t index) { - Children().RemoveAt(static_cast(index)); -} - -void Screen::replaceChild( - winrt::Windows::UI::Xaml::UIElement oldChild, - winrt::Windows::UI::Xaml::UIElement newChild) { - uint32_t index; - if (!Children().IndexOf(oldChild, index)) - return; - - Children().SetAt(index, newChild); -} - -void Screen::onLoading( - winrt::Windows::UI::Xaml::FrameworkElement const &sender, - winrt::Windows::Foundation::IInspectable const &) { - auto screen = sender.try_as(); - if (!screen) - return; - - screen->dispatchOnWillAppear(); -} - -void Screen::onLoaded( - winrt::Windows::Foundation::IInspectable const &sender, - winrt::Windows::UI::Xaml::RoutedEventArgs const &) { - auto screen = sender.try_as(); - if (!screen) - return; - - screen->dispatchOnAppear(); -} - -void Screen::onUnloaded( - winrt::Windows::Foundation::IInspectable const &sender, - winrt::Windows::UI::Xaml::RoutedEventArgs const &) { - auto screen = sender.try_as(); - if (!screen) - return; - - screen->dispatchOnWillDisappear(); - screen->dispatchOnDisappear(); -} - -void Screen::dispatchOnWillAppear() { - m_reactContext.DispatchEvent( - *this, - L"topWillAppear", - [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { - eventDataWriter.WriteObjectBegin(); - eventDataWriter.WriteObjectEnd(); - }); -} - -void Screen::dispatchOnWillDisappear() { - m_reactContext.DispatchEvent( - *this, - L"topWillDisappear", - [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { - eventDataWriter.WriteObjectBegin(); - eventDataWriter.WriteObjectEnd(); - }); -} - -void Screen::dispatchOnAppear() { - m_reactContext.DispatchEvent( - *this, - L"topAppear", - [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { - eventDataWriter.WriteObjectBegin(); - eventDataWriter.WriteObjectEnd(); - }); -} - -void Screen::dispatchOnDisappear() { - m_reactContext.DispatchEvent( - *this, - L"topDisappear", - [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { - eventDataWriter.WriteObjectBegin(); - eventDataWriter.WriteObjectEnd(); - }); -} -} // namespace winrt::RNScreens::implementation +#include "pch.h" +#include "Screen.h" +#include "JSValueXaml.h" +#include "NativeModules.h" + + +namespace winrt { +using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +} // namespace winrt + +namespace winrt::RNScreens::implementation { +Screen::Screen(winrt::Microsoft::ReactNative::IReactContext reactContext) + : m_reactContext(reactContext) { + onLoadingRevoker = Loading({this, &Screen::onLoading}); + onLoadedRevoker = Loaded({this, &Screen::onLoaded}); + onUnloadedRevoker = Unloaded({this, &Screen::onUnloaded}); +} + +Screen::~Screen() { + Loading(onLoadingRevoker); + Loaded(onLoadedRevoker); + Unloaded(onUnloadedRevoker); +} + +void Screen::addView(winrt::Windows::UI::Xaml::UIElement element) { + Children().Append(element); +} + +void Screen::removeAllChildren() { + Children().Clear(); +} + +void Screen::removeChildAt(int64_t index) { + Children().RemoveAt(static_cast(index)); +} + +void Screen::replaceChild( + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild) { + uint32_t index; + if (!Children().IndexOf(oldChild, index)) + return; + + Children().SetAt(index, newChild); +} + +void Screen::onLoading( + winrt::Windows::UI::Xaml::FrameworkElement const &sender, + winrt::Windows::Foundation::IInspectable const &) { + auto screen = sender.try_as(); + if (!screen) + return; + + screen->dispatchOnWillAppear(); +} + +void Screen::onLoaded( + winrt::Windows::Foundation::IInspectable const &sender, + winrt::Windows::UI::Xaml::RoutedEventArgs const &) { + auto screen = sender.try_as(); + if (!screen) + return; + + screen->dispatchOnAppear(); +} + +void Screen::onUnloaded( + winrt::Windows::Foundation::IInspectable const &sender, + winrt::Windows::UI::Xaml::RoutedEventArgs const &) { + auto screen = sender.try_as(); + if (!screen) + return; + + screen->dispatchOnWillDisappear(); + screen->dispatchOnDisappear(); +} + +void Screen::dispatchOnWillAppear() { + m_reactContext.DispatchEvent( + *this, + L"topWillAppear", + [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { + eventDataWriter.WriteObjectBegin(); + eventDataWriter.WriteObjectEnd(); + }); +} + +void Screen::dispatchOnWillDisappear() { + m_reactContext.DispatchEvent( + *this, + L"topWillDisappear", + [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { + eventDataWriter.WriteObjectBegin(); + eventDataWriter.WriteObjectEnd(); + }); +} + +void Screen::dispatchOnAppear() { + m_reactContext.DispatchEvent( + *this, + L"topAppear", + [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { + eventDataWriter.WriteObjectBegin(); + eventDataWriter.WriteObjectEnd(); + }); +} + +void Screen::dispatchOnDisappear() { + m_reactContext.DispatchEvent( + *this, + L"topDisappear", + [&](winrt::IJSValueWriter const &eventDataWriter) noexcept { + eventDataWriter.WriteObjectBegin(); + eventDataWriter.WriteObjectEnd(); + }); +} +StackAnimation Screen::GetStackAnimation() const { + return stackAnimation; +} +void Screen::SetStackAnimation(StackAnimation const& animation) { + stackAnimation = animation; +} +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/Screen.h b/windows/RNScreens/Screen.h index 7abf42672c..f2617a461f 100644 --- a/windows/RNScreens/Screen.h +++ b/windows/RNScreens/Screen.h @@ -2,15 +2,16 @@ namespace winrt::RNScreens::implementation { -enum class StackPresentation { PUSH, MODAL, TRANSPARENT_MODAL }; +enum class StackPresentation { PUSH, MODAL, TRANSPARENT_MODAL, FORM_SHEET }; enum class StackAnimation { DEFAULT, NONE, FADE, - SIMPLE_FROM_BOTTOM, + SLIDE_FROM_BOTTOM, SLIDE_FROM_RIGHT, SLIDE_FROM_LEFT, + FADE_FROM_BOTTOM, IOS_FROM_RIGHT, IOS_FROM_LEFT }; @@ -59,8 +60,11 @@ class Screen : public winrt::Windows::UI::Xaml::Controls::StackPanelT { void dispatchOnDisappear(); void dispatchOnWillAppear(); void dispatchOnWillDisappear(); + StackAnimation GetStackAnimation() const; + void SetStackAnimation(StackAnimation const& animation); private: winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; + StackAnimation stackAnimation; }; } // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenStackHeaderConfig.cpp b/windows/RNScreens/ScreenStackHeaderConfig.cpp index 989f22d71b..03514e4082 100644 --- a/windows/RNScreens/ScreenStackHeaderConfig.cpp +++ b/windows/RNScreens/ScreenStackHeaderConfig.cpp @@ -15,5 +15,29 @@ using namespace Windows::UI::Xaml::Controls; namespace winrt::RNScreens::implementation { ScreenStackHeaderConfig::ScreenStackHeaderConfig( winrt::Microsoft::ReactNative::IReactContext reactContext) - : m_reactContext(reactContext) {} + : m_reactContext(reactContext), + m_children( + {winrt::single_threaded_vector()}) {} + +void ScreenStackHeaderConfig::addView(winrt::Windows::UI::Xaml::UIElement element) { + Children().Append(element); +} + +void ScreenStackHeaderConfig::removeAllChildren() { + Children().Clear(); +} + +void ScreenStackHeaderConfig::removeChildAt(int64_t index) { + Children().RemoveAt(static_cast(index)); +} + +void ScreenStackHeaderConfig::replaceChild( + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild) { + uint32_t index; + if (!Children().IndexOf(oldChild, index)) + return; + + Children().SetAt(index, newChild); +} } // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenStackHeaderConfig.h b/windows/RNScreens/ScreenStackHeaderConfig.h index 39fab151ce..53c8b6fe53 100644 --- a/windows/RNScreens/ScreenStackHeaderConfig.h +++ b/windows/RNScreens/ScreenStackHeaderConfig.h @@ -6,8 +6,17 @@ class ScreenStackHeaderConfig ScreenStackHeaderConfig> { public: ScreenStackHeaderConfig( - winrt::Microsoft::ReactNative::IReactContext m_reactContext); + winrt::Microsoft::ReactNative::IReactContext reactContext); + void addView(winrt::Windows::UI::Xaml::UIElement element); + void removeAllChildren(); + void removeChildAt(int64_t index); + void replaceChild( + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild); + + winrt::Windows::Foundation::Collections::IVector + m_children; private: winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; }; diff --git a/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp b/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp index d26378934b..f15180512f 100644 --- a/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp +++ b/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp @@ -26,7 +26,48 @@ ScreenStackHeaderConfigViewManager::CreateView() noexcept { // IViewManagerRequiresNativeLayout bool ScreenStackHeaderConfigViewManager::RequiresNativeLayout() { - return true; + return false; +} + +// IViewManagerWithChildren +void ScreenStackHeaderConfigViewManager::AddView( + FrameworkElement parent, + UIElement child, + int64_t index) { + auto screenStackHeaderConfig = parent.as(); + if (!screenStackHeaderConfig) + return; + + screenStackHeaderConfig->addView(child); +} + +void ScreenStackHeaderConfigViewManager::RemoveAllChildren(FrameworkElement parent) { + auto screenStackHeaderConfig = parent.as(); + if (!screenStackHeaderConfig) + return; + + screenStackHeaderConfig->removeAllChildren(); +} + +void ScreenStackHeaderConfigViewManager::RemoveChildAt( + FrameworkElement parent, + int64_t index) { + auto screenStackHeaderConfig = parent.as(); + if (!screenStackHeaderConfig) + return; + + screenStackHeaderConfig->removeChildAt(index); +} + +void ScreenStackHeaderConfigViewManager::ReplaceChild( + FrameworkElement parent, + UIElement oldChild, + UIElement newChild) { + auto screenStackHeaderConfig = parent.as(); + if (!screenStackHeaderConfig) + return; + + screenStackHeaderConfig->replaceChild(oldChild, newChild); } // IViewManagerWithReactContext diff --git a/windows/RNScreens/ScreenStackHeaderConfigViewManager.h b/windows/RNScreens/ScreenStackHeaderConfigViewManager.h index ed37a80b93..99c6d8ddb5 100644 --- a/windows/RNScreens/ScreenStackHeaderConfigViewManager.h +++ b/windows/RNScreens/ScreenStackHeaderConfigViewManager.h @@ -10,6 +10,7 @@ class ScreenStackHeaderConfigViewManager winrt::Microsoft::ReactNative::IViewManager, winrt::Microsoft::ReactNative::IViewManagerRequiresNativeLayout, winrt::Microsoft::ReactNative::IViewManagerWithReactContext, + winrt::Microsoft::ReactNative::IViewManagerWithChildren, winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties, winrt::Microsoft::ReactNative:: IViewManagerWithExportedEventTypeConstants, @@ -24,6 +25,20 @@ class ScreenStackHeaderConfigViewManager // IViewManagerRequiresNativeLayout bool RequiresNativeLayout(); + // IViewManagerWithChildren + void AddView( + winrt::Windows::UI::Xaml::FrameworkElement parent, + winrt::Windows::UI::Xaml::UIElement child, + int64_t index); + void RemoveAllChildren(winrt::Windows::UI::Xaml::FrameworkElement parent); + void RemoveChildAt( + winrt::Windows::UI::Xaml::FrameworkElement parent, + int64_t index); + void ReplaceChild( + winrt::Windows::UI::Xaml::FrameworkElement parent, + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild); + // IViewManagerWithReactContext winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept; void ReactContext( diff --git a/windows/RNScreens/ScreenStackHeaderSubview.cpp b/windows/RNScreens/ScreenStackHeaderSubview.cpp new file mode 100644 index 0000000000..0df07f3e93 --- /dev/null +++ b/windows/RNScreens/ScreenStackHeaderSubview.cpp @@ -0,0 +1,43 @@ +#include "pch.h" +#include "ScreenStackHeaderSubview.h" +#include "JSValueXaml.h" +#include "NativeModules.h" + +namespace winrt { +using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +} // namespace winrt + +namespace winrt::RNScreens::implementation { +ScreenStackHeaderSubview::ScreenStackHeaderSubview( + winrt::Microsoft::ReactNative::IReactContext reactContext) + : m_reactContext(reactContext), + m_children( + {winrt::single_threaded_vector()}) {} + +void ScreenStackHeaderSubview::addView(winrt::Windows::UI::Xaml::UIElement element) { + Children().Append(element); +} + +void ScreenStackHeaderSubview::removeAllChildren() { + Children().Clear(); +} + +void ScreenStackHeaderSubview::removeChildAt(int64_t index) { + Children().RemoveAt(static_cast(index)); +} + +void ScreenStackHeaderSubview::replaceChild( + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild) { + uint32_t index; + if (!Children().IndexOf(oldChild, index)) + return; + + Children().SetAt(index, newChild); +} +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenStackHeaderSubview.h b/windows/RNScreens/ScreenStackHeaderSubview.h new file mode 100644 index 0000000000..8a3d6a278e --- /dev/null +++ b/windows/RNScreens/ScreenStackHeaderSubview.h @@ -0,0 +1,24 @@ +#pragma once + +namespace winrt::RNScreens::implementation { +class ScreenStackHeaderSubview + : public winrt::Windows::UI::Xaml::Controls::StackPanelT< + ScreenStackHeaderSubview> { + public: + ScreenStackHeaderSubview( + winrt::Microsoft::ReactNative::IReactContext reactContext); + + void addView(winrt::Windows::UI::Xaml::UIElement element); + void removeAllChildren(); + void removeChildAt(int64_t index); + void replaceChild( + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild); + + winrt::Windows::Foundation::Collections::IVector + m_children; + + private: + winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; +}; +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenStackHeaderSubviewViewManager.cpp b/windows/RNScreens/ScreenStackHeaderSubviewViewManager.cpp new file mode 100644 index 0000000000..077a0004b7 --- /dev/null +++ b/windows/RNScreens/ScreenStackHeaderSubviewViewManager.cpp @@ -0,0 +1,129 @@ +#include "pch.h" +#include "ScreenStackHeaderSubviewViewManager.h" +#include "ScreenStackHeaderSubview.h" +#include "JSValueXaml.h" +#include "NativeModules.h" + +namespace winrt { +using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +} // namespace winrt + +namespace winrt::RNScreens::implementation { +// IViewManager +winrt::hstring ScreenStackHeaderSubviewViewManager::Name() noexcept { + return L"RNSScreenStackHeaderSubview"; +} + +winrt::FrameworkElement ScreenStackHeaderSubviewViewManager::CreateView() noexcept { + return winrt::make(m_reactContext); +} + +// IViewManagerRequiresNativeLayout +bool ScreenStackHeaderSubviewViewManager::RequiresNativeLayout() { + return false; +} + +// IViewManagerWithChildren +void ScreenStackHeaderSubviewViewManager::AddView( + FrameworkElement parent, + UIElement child, + int64_t index) { + auto screenStackHeaderSubview = parent.as(); + if (!screenStackHeaderSubview) + return; + + screenStackHeaderSubview->addView(child); +} + +void ScreenStackHeaderSubviewViewManager::RemoveAllChildren(FrameworkElement parent) { + auto screenStackHeaderSubview = parent.as(); + if (!screenStackHeaderSubview) + return; + + screenStackHeaderSubview->removeAllChildren(); +} + +void ScreenStackHeaderSubviewViewManager::RemoveChildAt( + FrameworkElement parent, + int64_t index) { + auto screenStackHeaderSubview = parent.as(); + if (!screenStackHeaderSubview) + return; + + screenStackHeaderSubview->removeChildAt(index); +} + +void ScreenStackHeaderSubviewViewManager::ReplaceChild( + FrameworkElement parent, + UIElement oldChild, + UIElement newChild) { + auto screenStackHeaderSubview = parent.as(); + if (!screenStackHeaderSubview) + return; + + screenStackHeaderSubview->replaceChild(oldChild, newChild); +} + +// IViewManagerWithNativeProperties +IMapView +ScreenStackHeaderSubviewViewManager::NativeProps() noexcept { + auto nativeProps = + winrt::single_threaded_map(); + return nativeProps.GetView(); +} + +void ScreenStackHeaderSubviewViewManager::UpdateProperties( + FrameworkElement const &view, + IJSValueReader const &propertyMapReader) noexcept { + (void)view; + const JSValueObject &propertyMap = JSValue::ReadObjectFrom(propertyMapReader); + for (auto const &pair : propertyMap) { + auto const &propertyName = pair.first; + auto const &propertyValue = pair.second; + (void)propertyName; + (void)propertyValue; + } +} + +// IViewManagerWithCommands +IVectorView ScreenStackHeaderSubviewViewManager::Commands() noexcept { + auto commands = winrt::single_threaded_vector(); + return commands.GetView(); +} + +void ScreenStackHeaderSubviewViewManager::DispatchCommand( + FrameworkElement const &view, + winrt::hstring const &commandId, + winrt::IJSValueReader const &commandArgsReader) noexcept { + (void)view; + (void)commandId; + (void)commandArgsReader; +} + + +// IViewManagerWithExportedEventTypeConstants +ConstantProviderDelegate ScreenStackHeaderSubviewViewManager:: + ExportedCustomBubblingEventTypeConstants() noexcept { + return nullptr; +} + +ConstantProviderDelegate ScreenStackHeaderSubviewViewManager:: + ExportedCustomDirectEventTypeConstants() noexcept { + return nullptr; +} + +// IViewManagerWithReactContext +winrt::IReactContext ScreenStackHeaderSubviewViewManager::ReactContext() noexcept { + return m_reactContext; +} + +void ScreenStackHeaderSubviewViewManager::ReactContext(IReactContext reactContext) noexcept { + m_reactContext = reactContext; +} + +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenStackHeaderSubviewViewManager.h b/windows/RNScreens/ScreenStackHeaderSubviewViewManager.h new file mode 100644 index 0000000000..1378e3ce47 --- /dev/null +++ b/windows/RNScreens/ScreenStackHeaderSubviewViewManager.h @@ -0,0 +1,77 @@ +#pragma once + +#include "NativeModules.h" +#include "winrt/Microsoft.ReactNative.h" + +namespace winrt::RNScreens::implementation { +class ScreenStackHeaderSubviewViewManager + : public winrt::implements< + ScreenStackHeaderSubviewViewManager, + winrt::Microsoft::ReactNative::IViewManager, + winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties, + winrt::Microsoft::ReactNative::IViewManagerWithCommands, + winrt::Microsoft::ReactNative::IViewManagerWithChildren, + winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants, + winrt::Microsoft::ReactNative::IViewManagerRequiresNativeLayout, + winrt::Microsoft::ReactNative::IViewManagerWithReactContext> { + public: + ScreenStackHeaderSubviewViewManager() = default; + + // IViewManager + winrt::hstring Name() noexcept; + winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept; + + // IViewManagerRequiresNativeLayout + bool RequiresNativeLayout(); + + // IViewManagerWithChildren + void AddView( + winrt::Windows::UI::Xaml::FrameworkElement parent, + winrt::Windows::UI::Xaml::UIElement child, + int64_t index); + void RemoveAllChildren(winrt::Windows::UI::Xaml::FrameworkElement parent); + void RemoveChildAt( + winrt::Windows::UI::Xaml::FrameworkElement parent, + int64_t index); + void ReplaceChild( + winrt::Windows::UI::Xaml::FrameworkElement parent, + winrt::Windows::UI::Xaml::UIElement oldChild, + winrt::Windows::UI::Xaml::UIElement newChild); + + // IViewManagerWithNativeProperties + winrt::Windows::Foundation::Collections::IMapView< + winrt::hstring, + winrt::Microsoft::ReactNative::ViewManagerPropertyType> + NativeProps() noexcept; + + void UpdateProperties( + winrt::Windows::UI::Xaml::FrameworkElement const &view, + winrt::Microsoft::ReactNative::IJSValueReader const + &propertyMapReader) noexcept; + + // IViewManagerWithExportedEventTypeConstants + winrt::Microsoft::ReactNative::ConstantProviderDelegate + ExportedCustomBubblingEventTypeConstants() noexcept; + winrt::Microsoft::ReactNative::ConstantProviderDelegate + ExportedCustomDirectEventTypeConstants() noexcept; + + + // IViewManagerWithCommands + winrt::Windows::Foundation::Collections::IVectorView + Commands() noexcept; + + void DispatchCommand( + winrt::Windows::UI::Xaml::FrameworkElement const &view, + winrt::hstring const &commandId, + winrt::Microsoft::ReactNative::IJSValueReader const + &commandArgsReader) noexcept; + + // IViewManagerWithReactContext + winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept; + void ReactContext( + winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept; + + private: + winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; +}; +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenViewManager.cpp b/windows/RNScreens/ScreenViewManager.cpp index c25b82d554..0298453807 100644 --- a/windows/RNScreens/ScreenViewManager.cpp +++ b/windows/RNScreens/ScreenViewManager.cpp @@ -98,22 +98,51 @@ ScreenViewManager::NativeProps() noexcept { void ScreenViewManager::UpdateProperties( FrameworkElement const &view, IJSValueReader const &propertyMapReader) noexcept { - (void)view; - const JSValueObject &propertyMap = JSValue::ReadObjectFrom(propertyMapReader); - for (auto const &pair : propertyMap) { - auto const &propertyName = pair.first; - auto const &propertyValue = pair.second; - if (propertyValue != nullptr) { - if (propertyName == "replaceAnimation") { - auto const &value = propertyValue.AsString(); - // TODO: Implement this for Windows - (void)value; - } else if (propertyName == "stackPresentation") { - auto const &value = propertyValue.AsString(); - // TODO: Implement this for Windows - (void)value; - } else { - OutputDebugStringA("Unknown property in ScreenViewManager\n"); + if (auto screen = view.try_as()) { + const JSValueObject &propertyMap = JSValue::ReadObjectFrom(propertyMapReader); + for (auto const &pair : propertyMap) { + auto const &propertyName = pair.first; + auto const &propertyValue = pair.second; + if (propertyName == "stackAnimation") { + if (propertyValue.IsNull() || + propertyValue.AsString() == "default" || + propertyValue.AsString() == "flip" || + propertyValue.AsString() == "simple_push") { + screen->SetStackAnimation(winrt::RNScreens::implementation::StackAnimation::DEFAULT); + } else if (propertyValue.AsString() == "none") { + screen->SetStackAnimation(StackAnimation::NONE); + } else if (propertyValue.AsString() == "fade") { + screen->SetStackAnimation(StackAnimation::FADE); + } else if (propertyValue.AsString() == "slide_from_right") { + screen->SetStackAnimation(StackAnimation::SLIDE_FROM_RIGHT); + } else if (propertyValue.AsString() == "slide_from_left") { + screen->SetStackAnimation(StackAnimation::SLIDE_FROM_LEFT); + } else if (propertyValue.AsString() == "slide_from_bottom") { + screen->SetStackAnimation(StackAnimation::SLIDE_FROM_BOTTOM); + } else if (propertyValue.AsString() == "fade_from_bottom") { + screen->SetStackAnimation(StackAnimation::FADE_FROM_BOTTOM); + } else if (propertyValue.AsString() == "ios_from_right") { + screen->SetStackAnimation(StackAnimation::IOS_FROM_RIGHT); + } else if (propertyValue.AsString() == "ios_from_left") { + screen->SetStackAnimation(StackAnimation::IOS_FROM_LEFT); + } else { + std::string error = "Unknown animation type: "; + error += propertyValue.AsString(); + throw std::runtime_error(error); + } + } + if (propertyValue != nullptr) { + if (propertyName == "replaceAnimation") { + auto const &value = propertyValue.AsString(); + // TODO: Implement this for Windows + (void)value; + } else if (propertyName == "stackPresentation") { + auto const &value = propertyValue.AsString(); + // TODO: Implement this for Windows + (void)value; + } else { + OutputDebugStringA("Unknown property in ScreenViewManager\n"); + } } } } diff --git a/windows/RNScreens/ScreenViewManager.h b/windows/RNScreens/ScreenViewManager.h index 17cb8e1bf9..420df7f715 100644 --- a/windows/RNScreens/ScreenViewManager.h +++ b/windows/RNScreens/ScreenViewManager.h @@ -20,7 +20,7 @@ class ScreenViewManager ScreenViewManager() = default; // IViewManager - winrt::hstring Name() noexcept; + virtual winrt::hstring Name() noexcept; winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept; // IViewManagerRequiresNativeLayout diff --git a/windows/RNScreens/SearchBar.cpp b/windows/RNScreens/SearchBar.cpp new file mode 100644 index 0000000000..94170385ea --- /dev/null +++ b/windows/RNScreens/SearchBar.cpp @@ -0,0 +1,19 @@ +#include "pch.h" +#include "SearchBar.h" +#include "JSValueXaml.h" +#include "NativeModules.h" + +namespace winrt { +using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +} // namespace winrt + +namespace winrt::RNScreens::implementation { +SearchBar::SearchBar( + winrt::Microsoft::ReactNative::IReactContext reactContext) + : m_reactContext(reactContext) {} +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/SearchBar.h b/windows/RNScreens/SearchBar.h new file mode 100644 index 0000000000..9bad637421 --- /dev/null +++ b/windows/RNScreens/SearchBar.h @@ -0,0 +1,14 @@ +#pragma once + +namespace winrt::RNScreens::implementation { +class SearchBar + : public winrt::Windows::UI::Xaml::Controls::StackPanelT< + SearchBar> { + public: + SearchBar( + winrt::Microsoft::ReactNative::IReactContext reactContext); + + private: + winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; +}; +} // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/SearchBarViewManager.cpp b/windows/RNScreens/SearchBarViewManager.cpp new file mode 100644 index 0000000000..f58ddd2011 --- /dev/null +++ b/windows/RNScreens/SearchBarViewManager.cpp @@ -0,0 +1,88 @@ +#include "pch.h" +#include "SearchBarViewManager.h" +#include "SearchBar.h" +#include "JSValueXaml.h" +#include "NativeModules.h" + +namespace winrt { +using namespace Microsoft::ReactNative; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +} // namespace winrt + +namespace winrt::RNScreens::implementation { +// IViewManager +winrt::hstring SearchBarViewManager::Name() noexcept { + return L"RNSSearchBar"; +} + +winrt::FrameworkElement SearchBarViewManager::CreateView() noexcept { + return winrt::make(m_reactContext); +} + +// IViewManagerRequiresNativeLayout +bool SearchBarViewManager::RequiresNativeLayout() { + return false; +} + +// IViewManagerWithNativeProperties +IMapView +SearchBarViewManager::NativeProps() noexcept { + auto nativeProps = + winrt::single_threaded_map(); + return nativeProps.GetView(); +} + +void SearchBarViewManager::UpdateProperties( + FrameworkElement const &view, + IJSValueReader const &propertyMapReader) noexcept { + (void)view; + const JSValueObject &propertyMap = JSValue::ReadObjectFrom(propertyMapReader); + for (auto const &pair : propertyMap) { + auto const &propertyName = pair.first; + auto const &propertyValue = pair.second; + (void)propertyName; + (void)propertyValue; + } +} + +// IViewManagerWithCommands +IVectorView SearchBarViewManager::Commands() noexcept { + auto commands = winrt::single_threaded_vector(); + return commands.GetView(); +} + +void SearchBarViewManager::DispatchCommand( + FrameworkElement const &view, + winrt::hstring const &commandId, + winrt::IJSValueReader const &commandArgsReader) noexcept { + (void)view; + (void)commandId; + (void)commandArgsReader; +} + + +// IViewManagerWithExportedEventTypeConstants +ConstantProviderDelegate SearchBarViewManager:: + ExportedCustomBubblingEventTypeConstants() noexcept { + return nullptr; +} + +ConstantProviderDelegate SearchBarViewManager:: + ExportedCustomDirectEventTypeConstants() noexcept { + return nullptr; +} + +// IViewManagerWithReactContext +winrt::IReactContext SearchBarViewManager::ReactContext() noexcept { + return m_reactContext; +} + +void SearchBarViewManager::ReactContext(IReactContext reactContext) noexcept { + m_reactContext = reactContext; +} + +} // namespace winrt::RNScreens::implementation \ No newline at end of file diff --git a/windows/RNScreens/SearchBarViewManager.h b/windows/RNScreens/SearchBarViewManager.h new file mode 100644 index 0000000000..4b75802777 --- /dev/null +++ b/windows/RNScreens/SearchBarViewManager.h @@ -0,0 +1,62 @@ +#pragma once + +#include "NativeModules.h" +#include "winrt/Microsoft.ReactNative.h" + +namespace winrt::RNScreens::implementation { +class SearchBarViewManager + : public winrt::implements< + SearchBarViewManager, + winrt::Microsoft::ReactNative::IViewManager, + winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties, + winrt::Microsoft::ReactNative::IViewManagerWithCommands, + winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants, + winrt::Microsoft::ReactNative::IViewManagerRequiresNativeLayout, + winrt::Microsoft::ReactNative::IViewManagerWithReactContext> { + public: + SearchBarViewManager() = default; + + // IViewManager + winrt::hstring Name() noexcept; + winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept; + + // IViewManagerRequiresNativeLayout + bool RequiresNativeLayout(); + + // IViewManagerWithNativeProperties + winrt::Windows::Foundation::Collections::IMapView< + winrt::hstring, + winrt::Microsoft::ReactNative::ViewManagerPropertyType> + NativeProps() noexcept; + + void UpdateProperties( + winrt::Windows::UI::Xaml::FrameworkElement const &view, + winrt::Microsoft::ReactNative::IJSValueReader const + &propertyMapReader) noexcept; + + // IViewManagerWithExportedEventTypeConstants + winrt::Microsoft::ReactNative::ConstantProviderDelegate + ExportedCustomBubblingEventTypeConstants() noexcept; + winrt::Microsoft::ReactNative::ConstantProviderDelegate + ExportedCustomDirectEventTypeConstants() noexcept; + + + // IViewManagerWithCommands + winrt::Windows::Foundation::Collections::IVectorView + Commands() noexcept; + + void DispatchCommand( + winrt::Windows::UI::Xaml::FrameworkElement const &view, + winrt::hstring const &commandId, + winrt::Microsoft::ReactNative::IJSValueReader const + &commandArgsReader) noexcept; + + // IViewManagerWithReactContext + winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept; + void ReactContext( + winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept; + + private: + winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; +}; +} // namespace winrt::RNScreens::implementation