From d0da31e5c2bc21e68f85af9cb87f8b1cbd52318b Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Tue, 11 Jun 2024 17:00:40 -0700 Subject: [PATCH 01/34] save state --- .../WindowsModalHostViewComponentView.cpp | 53 ++++++++++++------- .../Modal/WindowsModalHostViewComponentView.h | 1 + 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp index d4fa0493b79..577c66fbe19 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp @@ -39,7 +39,7 @@ winrt::Microsoft::ReactNative::ComponentView WindowsModalHostComponentView::Crea return winrt::make(compContext, tag, reactContext); } -// constants for creating a new windows (code mostly taken from LogBox) +// constants for creating a new windows constexpr PCWSTR c_modalWindowClassName = L"MS_REACTNATIVE_MODAL"; constexpr auto CompHostProperty = L"CompHost"; const int MODAL_DEFAULT_WIDTH = 500; @@ -47,26 +47,27 @@ const int MODAL_DEFAULT_HEIGHT = 500; // creates a new modal window void WindowsModalHostComponentView::EnsureModalCreated() { - auto host = - winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_context.Properties()); + auto host = winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_context.Properties()); + // return if hwnd already exists if (!host || m_hwnd) { return; } RegisterWndClass(); // creates and register a windows class - auto CompositionHwndHost = winrt::Microsoft::ReactNative::CompositionHwndHost(); + m_compositionHwndHost = winrt::Microsoft::ReactNative::CompositionHwndHost(); // creates a new RNW hwndHost winrt::Microsoft::ReactNative::ReactViewOptions viewOptions; - viewOptions.ComponentName(L"Modal"); - CompositionHwndHost.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions)); + // this is the name of the component registered in Javascript via AppRegistry.registerComponent('ModuleName', () => ModuleName); + // IE, Bootstrap is the app name registered, do we need to do the same for Modal in javascript? How do we do that? + viewOptions.ComponentName(L"Bootstrap"); + m_compositionHwndHost.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions)); // creates a new ReactViewHost. What is the difference between CompositionHwndHost and ViewHost? HINSTANCE hInstance = GetModuleHandle(NULL); winrt::impl::abi::type *pHost{nullptr}; winrt::com_ptr<::IUnknown> spunk; - CompositionHwndHost.as(spunk); + m_compositionHwndHost.as(spunk); // get the root hwnd - auto roothwnd = reinterpret_cast( - winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_context.Properties().Handle())); + auto roothwnd = reinterpret_cast(winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_context.Properties().Handle())); m_hwnd = CreateWindow( c_modalWindowClassName, @@ -86,6 +87,8 @@ void WindowsModalHostComponentView::EnsureModalCreated() { throw std::exception("Failed to create new hwnd for Modal: " + GetLastError()); } + winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(host.InstanceSettings().Properties(), reinterpret_cast(m_hwnd)); + spunk.detach(); } @@ -99,7 +102,9 @@ void WindowsModalHostComponentView::ShowOnUIThread() { void WindowsModalHostComponentView::HideOnUIThread() noexcept { if (m_hwnd) { - ::ShowWindow(m_hwnd, SW_HIDE); + LPARAM lParam = 0; + WPARAM wParam = 0; + SendMessage(m_hwnd, WM_CLOSE, wParam, lParam); } } @@ -129,7 +134,7 @@ LRESULT CALLBACK ModalBoxWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM break; } case WM_CREATE: { // recieves after window is created but before visible - // host.Initialize((uint64_t)hwnd); cause Modal to throw a not registered error + host.Initialize((uint64_t)hwnd); break; } case WM_CLOSE: { @@ -175,20 +180,31 @@ void WindowsModalHostComponentView::RegisterWndClass() noexcept { registered = true; } +// childComponentView - reference to the child component view +// index - the position in which the childComponentView should be mounted void WindowsModalHostComponentView::MountChildComponentView( const winrt::Microsoft::ReactNative::ComponentView &childComponentView, uint32_t index) noexcept { - // Disabled due to partial Modal implementation. Tracking re-enablement with task list here: - // https://github.com/microsoft/react-native-windows/issues/11157 assert(false); - base_type::MountChildComponentView(childComponentView, index); + EnsureModalCreated(); + // TODO: these are getting added to the roothwnd but we want them in the modal hwnd? What is the best way to do this? + m_children.InsertAt(index, childComponentView); // insert childComponent into m_children + // Set parent: This line sets the parent of the childComponentView to *this (the current instance of WindowsModalHostComponentView). The get_self function is used to obtain the implementation object from the WinRT projection object. + winrt::get_self(childComponentView)->parent(*this); + // Adjust index for borders: This line calls the indexOffsetForBorder method with the index parameter. This method likely adjusts the index to account for any special border handling or offsets required when inserting the child. + indexOffsetForBorder(index); + // Ensure visual setup: This line calls the ensureVisual method. This method probably ensures that the visual tree for the component view is properly set up and initialized. + ensureVisual(); + // This ensures that the subsequent code only runs if the childComponentView can be treated as a ComponentView + if (auto compositionChild = childComponentView.try_as()) { + Visual().InsertAt(compositionChild->OuterVisual(), index); + } } void WindowsModalHostComponentView::UnmountChildComponentView( const winrt::Microsoft::ReactNative::ComponentView &childComponentView, uint32_t index) noexcept { - // Disabled due to partial Modal implementation.Tracking re-enablement with task list here : https : // - // github.com/microsoft/react-native-windows/issues/11157 assert(false); base_type::UnmountChildComponentView(childComponentView, index); + HideOnUIThread(); } void WindowsModalHostComponentView::HandleCommand( @@ -204,7 +220,6 @@ void WindowsModalHostComponentView::updateProps( *std::static_pointer_cast(oldProps ? oldProps : viewProps()); const auto &newModalProps = *std::static_pointer_cast(props); - // currently Modal only gets Destroyed by closing the window if (newModalProps.visible) { EnsureModalCreated(); ShowOnUIThread(); @@ -218,7 +233,7 @@ void WindowsModalHostComponentView::updateLayoutMetrics( facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept { Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics); - // Temporary placeholder for Modal, draws on main hwnd +// Temporary placeholder for Modal, draws on main hwnd if (m_layoutMetrics.frame.size != layoutMetrics.frame.size || m_layoutMetrics.pointScaleFactor != layoutMetrics.pointScaleFactor || m_layoutMetrics.frame.size.width == 0) { // Always make visual a min size, so that even if its laid out at zero size, its clear an unimplemented view was @@ -254,7 +269,7 @@ void WindowsModalHostComponentView::updateLayoutMetrics( float offsetX = static_cast(offset.x / m_layoutMetrics.pointScaleFactor); float offsetY = static_cast(offset.y / m_layoutMetrics.pointScaleFactor); - + winrt::com_ptr spTextFormat; winrt::check_hresult(::Microsoft::ReactNative::DWriteFactory()->CreateTextFormat( L"Segoe UI", diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h index 6bf56707180..71c886cba06 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h @@ -58,6 +58,7 @@ struct WindowsModalHostComponentView private: HWND m_hwnd{nullptr}; + winrt::Microsoft::ReactNative::CompositionHwndHost m_compositionHwndHost; winrt::Microsoft::ReactNative::ReactContext m_context; }; From e3f75ed00bd4aa6cc75af68af997184b7d1ffecb Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Wed, 12 Jun 2024 11:37:19 -0700 Subject: [PATCH 02/34] add example --- packages/playground/Samples/simple.tsx | 38 +++++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/playground/Samples/simple.tsx b/packages/playground/Samples/simple.tsx index 71349398ce4..74fd2c7c2ab 100644 --- a/packages/playground/Samples/simple.tsx +++ b/packages/playground/Samples/simple.tsx @@ -4,18 +4,36 @@ * @format */ import React from 'react'; -import {AppRegistry, View} from 'react-native'; - -export default class Bootstrap extends React.Component { - render() { - return ( +import { + AppRegistry, + View, + Button, + SafeAreaView, + Modal, + Text, +} from 'react-native'; +const Bootstrap = () => { + const [modalVisible, setModalVisible] = React.useState(false); + return ( + +