Skip to content

Commit

Permalink
[Image] Implement 'center' and 'repeat' resizeModes (#2581)
Browse files Browse the repository at this point in the history
* Move ImageViewManager to its own folder

* Add BorderEffect impl

* Switch from Image to Canvas

* Add ReactImageBrush (name TBD)

* wip: couple of fixes

* Add ReactImage canvas wrapper

* PR feeedback + add OnLoadEnd event to ReactImage

* Removing accidentally added files

* Fix break after merge

* PR feedback + Moved Image module to separate file
  • Loading branch information
marlenecota committed Jun 18, 2019
1 parent 721d1c6 commit f750896
Show file tree
Hide file tree
Showing 21 changed files with 1,730 additions and 508 deletions.
3 changes: 2 additions & 1 deletion vnext/ReactUWP/Base/UwpReactInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include <Views/TextViewManager.h>
#include <Views/VirtualTextViewManager.h>
#include <Views/ViewViewManager.h>
#include <Views/ImageViewManager.h>
#include <Views/Image/ImageViewManager.h>
#include <Views/WebViewManager.h>

// Polyester View Managers // TODO: Move Polyester implementations out of this library and depot
Expand All @@ -49,6 +49,7 @@
#include <Modules/ClipboardModule.h>
#include <Modules/DeviceInfoModule.h>
#include <ReactUWP/Modules/I18nModule.h>
#include <Modules/ImageViewManagerModule.h>
#include <Modules/LinkingManagerModule.h>
#include <Modules/LocationObserverModule.h>
#include <Modules/NativeUIManager.h>
Expand Down
148 changes: 148 additions & 0 deletions vnext/ReactUWP/Modules/ImageViewManagerModule.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// NYI:
// implement image cache
// implement prefetch functionality
// implement multi source (parse out most suitable image source from array of sources)
#include "pch.h"

#include "ImageViewManagerModule.h"

#include <winrt/Windows.UI.Xaml.Media.Imaging.h>

#include <cxxreact/JsArgumentHelpers.h>

#include <Views/Image/ReactImage.h>

#if _MSC_VER <= 1913
// VC 19 (2015-2017.6) cannot optimize co_await/cppwinrt usage
#pragma optimize( "", off )
#endif

namespace winrt {
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Xaml::Media::Imaging;
}

namespace react { namespace uwp {
//
// ImageViewManagerModule::ImageViewManagerModuleImpl
//
class ImageViewManagerModule::ImageViewManagerModuleImpl
{
public:
ImageViewManagerModuleImpl(ImageViewManagerModule* parent, const std::shared_ptr<facebook::react::MessageQueueThread>& defaultQueueThread)
: m_parent(parent)
, m_queueThread(defaultQueueThread)
{ }

void Disconnect()
{
m_parent = nullptr;
}

void getSize(std::string uri, Callback successCallback, Callback errorCallback);
void prefetchImage(std::string uri, Callback successCallback, Callback errorCallback);
void queryCache(const folly::dynamic& requests, Callback successCallback, Callback errorCallback);

private:
ImageViewManagerModule* m_parent;
std::shared_ptr<facebook::react::MessageQueueThread> m_queueThread;
};

winrt::fire_and_forget GetImageSizeAsync(std::string uri, facebook::xplat::module::CxxModule::Callback successCallback, facebook::xplat::module::CxxModule::Callback errorCallback)
{
bool succeeded{ false };

try
{
ImageSource source;
source.uri = uri;

winrt::InMemoryRandomAccessStream memoryStream{ co_await react::uwp::GetImageStreamAsync(source) };

winrt::BitmapImage bitmap;
if (memoryStream)
{
co_await bitmap.SetSourceAsync(memoryStream);
}

if (bitmap)
{
successCallback({ bitmap.PixelWidth(), bitmap.PixelHeight() });
succeeded = true;
}
}
catch (winrt::hresult_error const&)
{
}

if (!succeeded)
errorCallback({});

co_return;
}

void ImageViewManagerModule::ImageViewManagerModuleImpl::getSize(std::string uri, Callback successCallback, Callback errorCallback)
{
GetImageSizeAsync(uri, successCallback, errorCallback);
}

void ImageViewManagerModule::ImageViewManagerModuleImpl::prefetchImage(std::string /*uri*/, Callback successCallback, Callback /*errorCallback*/)
{
// NotYetImplemented
successCallback({});
}

void ImageViewManagerModule::ImageViewManagerModuleImpl::queryCache(const folly::dynamic& requests, Callback successCallback, Callback /*errorCallback*/)
{
// NotYetImplemented
successCallback({ folly::dynamic::object() });
}

//
// ImageViewManagerModule
//
const char* ImageViewManagerModule::name = "ImageViewManager";

ImageViewManagerModule::ImageViewManagerModule(const std::shared_ptr<facebook::react::MessageQueueThread>& defaultQueueThread)
: m_imageViewManagerModule(std::make_shared<ImageViewManagerModuleImpl>(this, defaultQueueThread))
{
}

ImageViewManagerModule::~ImageViewManagerModule()
{
}

std::string ImageViewManagerModule::getName()
{
return name;
}

std::map<std::string, folly::dynamic> ImageViewManagerModule::getConstants()
{
return { {} };
}

auto ImageViewManagerModule::getMethods() -> std::vector<Method>
{
std::shared_ptr<ImageViewManagerModuleImpl> imageViewManager(m_imageViewManagerModule);
return {
Method("getSize", [imageViewManager](folly::dynamic args, Callback successCallback, Callback errorCallback)
{
imageViewManager->getSize(facebook::xplat::jsArgAsString(args, 0), successCallback, errorCallback);
}, AsyncTag),
Method("prefetchImage", [imageViewManager](folly::dynamic args, Callback successCallback, Callback errorCallback)
{
imageViewManager->prefetchImage(facebook::xplat::jsArgAsString(args, 0), successCallback, errorCallback);
}),
Method("queryCache", [imageViewManager](folly::dynamic args, Callback successCallback, Callback errorCallback)
{
imageViewManager->queryCache(args[0], successCallback, errorCallback);
}),
};
}

} }

31 changes: 31 additions & 0 deletions vnext/ReactUWP/Modules/ImageViewManagerModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include <cxxreact/CxxModule.h>

namespace facebook {
namespace react {
class MessageQueueThread;
}
}

namespace react { namespace uwp {

class ImageViewManagerModule : public facebook::xplat::module::CxxModule
{
public:
ImageViewManagerModule(const std::shared_ptr<facebook::react::MessageQueueThread> & defaultQueueThread);
virtual ~ImageViewManagerModule();

// CxxModule
std::string getName() override;
std::map<std::string, folly::dynamic> getConstants() override;
auto getMethods()->std::vector<Method> override;

static const char* name;

private:
class ImageViewManagerModuleImpl;
std::shared_ptr<ImageViewManagerModuleImpl> m_imageViewManagerModule;
};

} } // namespace react::uwp
20 changes: 17 additions & 3 deletions vnext/ReactUWP/ReactUWP.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<AdditionalOptions>-minpdbpathlen:256</AdditionalOptions>
<AdditionalDependencies>dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Midl>
<AdditionalIncludeDirectories>$(ProjectDir)ABI\idl</AdditionalIncludeDirectories>
Expand Down Expand Up @@ -167,6 +168,7 @@
<ClInclude Include="Modules\DeviceInfoModule.h" />
<ClInclude Include="Modules\DevSupportManagerUwp.h" />
<ClInclude Include="Modules\I18nModule.h" />
<ClInclude Include="Modules\ImageViewManagerModule.h" />
<ClInclude Include="Modules\LinkingManagerModule.h" />
<ClInclude Include="Modules\LocationObserverModule.h" />
<ClInclude Include="Modules\NativeUIManager.h" />
Expand All @@ -189,15 +191,24 @@
<ClInclude Include="Utils\PropertyUtils.h" />
<ClInclude Include="Views\ActivityIndicatorViewManager.h" />
<ClInclude Include="Views\CheckboxViewManager.h" />
<ClInclude Include="Views\cppwinrt\Microsoft.UI.Composition.Effects.BorderEffect.g.h" />
<ClInclude Include="Views\cppwinrt\react.uwp.DynamicAutomationPeer.g.h" />
<ClInclude Include="Views\cppwinrt\winrt\impl\Microsoft.UI.Composition.Effects.0.h" />
<ClInclude Include="Views\cppwinrt\winrt\impl\Microsoft.UI.Composition.Effects.1.h" />
<ClInclude Include="Views\cppwinrt\winrt\impl\Microsoft.UI.Composition.Effects.2.h" />
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.0.h" />
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.1.h" />
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.2.h" />
<ClInclude Include="Views\cppwinrt\winrt\Microsoft.UI.Composition.Effects.h" />
<ClInclude Include="Views\cppwinrt\winrt\react.uwp.h" />
<ClInclude Include="Views\DatePickerViewManager.h" />
<ClInclude Include="Views\ExpressionAnimationStore.h" />
<ClInclude Include="Views\FlyoutViewManager.h" />
<ClInclude Include="Views\ImageViewManager.h" />
<ClInclude Include="Views\Image\BorderEffect.h" />
<ClInclude Include="Views\Image\Microsoft.UI.Composition.Effects_Impl.h" />
<ClInclude Include="Views\Image\ImageViewManager.h" />
<ClInclude Include="Views\Image\ReactImage.h" />
<ClInclude Include="Views\Image\ReactImageBrush.h" />
<ClInclude Include="Views\Impl\ScrollViewUWPImplementation.h" />
<ClInclude Include="Views\Impl\SnapPointManagingContentControl.h" />
<ClInclude Include="Views\PickerViewManager.h" />
Expand Down Expand Up @@ -231,7 +242,7 @@
<ClCompile Include="ABI\ReactControl_rt.cpp" />
<ClCompile Include="..\Shared\InstanceManager.cpp" />
<ClCompile Include="..\Shared\OInstance.cpp" />
<ClCompile Include="Base\ChakraJSIRuntimeHolder.cpp" Condition="'$(OSS_RN)' != 'true'"/>
<ClCompile Include="Base\ChakraJSIRuntimeHolder.cpp" Condition="'$(OSS_RN)' != 'true'" />
<ClCompile Include="Base\InstanceFactory.cpp" />
<ClCompile Include="Base\UwpReactInstance.cpp" />
<ClCompile Include="CxxReactUWP\JSBigString.cpp" />
Expand All @@ -244,6 +255,7 @@
<ClCompile Include="Modules\DeviceInfoModule.cpp" />
<ClCompile Include="Modules\DevSupportManagerUwp.cpp" />
<ClCompile Include="Modules\I18nModule.cpp" />
<ClCompile Include="Modules\ImageViewManagerModule.cpp" />
<ClCompile Include="Modules\LinkingManagerModule.cpp" />
<ClCompile Include="Modules\LocationObserverModule.cpp" />
<ClCompile Include="Modules\NativeUIManager.cpp" />
Expand Down Expand Up @@ -273,7 +285,9 @@
<ClCompile Include="Views\ExpressionAnimationStore.cpp" />
<ClCompile Include="Views\FlyoutViewManager.cpp" />
<ClCompile Include="Views\FrameworkElementViewManager.cpp" />
<ClCompile Include="Views\ImageViewManager.cpp" />
<ClCompile Include="Views\Image\ImageViewManager.cpp" />
<ClCompile Include="Views\Image\ReactImage.cpp" />
<ClCompile Include="Views\Image\ReactImageBrush.cpp" />
<ClCompile Include="Views\Impl\ScrollViewUWPImplementation.cpp" />
<ClCompile Include="Views\Impl\SnapPointManagingContentControl.cpp" />
<ClCompile Include="Views\PickerViewManager.cpp" />
Expand Down
84 changes: 66 additions & 18 deletions vnext/ReactUWP/ReactUWP.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@
<ClCompile Include="Views\FrameworkElementViewManager.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="Views\ImageViewManager.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="Views\RawTextViewManager.cpp">
<Filter>Views</Filter>
</ClCompile>
Expand Down Expand Up @@ -219,9 +216,21 @@
<ClCompile Include="Views\ScrollContentViewManager.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="Views\Image\ImageViewManager.cpp">
<Filter>Views\Image</Filter>
</ClCompile>
<ClCompile Include="Views\Image\ReactImageBrush.cpp">
<Filter>Views\Image</Filter>
</ClCompile>
<ClCompile Include="Views\Image\ReactImage.cpp">
<Filter>Views\Image</Filter>
</ClCompile>
<ClCompile Include="Views\ExpressionAnimationStore.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="Modules\ImageViewManagerModule.cpp">
<Filter>Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Modules\DeviceInfoModule.h">
Expand Down Expand Up @@ -311,9 +320,6 @@
<ClInclude Include="ABI\HStringHelper.h">
<Filter>ABI</Filter>
</ClInclude>
<ClInclude Include="Views\ImageViewManager.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="Views\RawTextViewManager.h">
<Filter>Views</Filter>
</ClInclude>
Expand Down Expand Up @@ -416,18 +422,6 @@
<ClInclude Include="Views\cppwinrt\react.uwp.DynamicAutomationPeer.g.h">
<Filter>Views\cppwinrt</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\react.uwp.h">
<Filter>Views\cppwinrt</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.0.h">
<Filter>Views\cppwinrt</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.1.h">
<Filter>Views\cppwinrt</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.2.h">
<Filter>Views\cppwinrt</Filter>
</ClInclude>
<ClInclude Include="Views\ViewControl.h">
<Filter>Views</Filter>
</ClInclude>
Expand All @@ -441,9 +435,54 @@
<ClInclude Include="Views\ScrollContentViewManager.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="Views\Image\ImageViewManager.h">
<Filter>Views\Image</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\react.uwp.h">
<Filter>Views\cppwinrt\winrt</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.0.h">
<Filter>Views\cppwinrt\winrt\impl</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.1.h">
<Filter>Views\cppwinrt\winrt\impl</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\react.uwp.2.h">
<Filter>Views\cppwinrt\winrt\impl</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\Microsoft.UI.Composition.Effects.0.h">
<Filter>Views\cppwinrt\winrt\impl</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\Microsoft.UI.Composition.Effects.1.h">
<Filter>Views\cppwinrt\winrt\impl</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\impl\Microsoft.UI.Composition.Effects.2.h">
<Filter>Views\cppwinrt\winrt\impl</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\winrt\Microsoft.UI.Composition.Effects.h">
<Filter>Views\cppwinrt\winrt</Filter>
</ClInclude>
<ClInclude Include="Views\cppwinrt\Microsoft.UI.Composition.Effects.BorderEffect.g.h">
<Filter>Views\cppwinrt</Filter>
</ClInclude>
<ClInclude Include="Views\Image\ReactImageBrush.h">
<Filter>Views\Image</Filter>
</ClInclude>
<ClInclude Include="Views\Image\ReactImage.h">
<Filter>Views\Image</Filter>
</ClInclude>
<ClInclude Include="Views\ExpressionAnimationStore.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="Modules\ImageViewManagerModule.h">
<Filter>Modules</Filter>
</ClInclude>
<ClInclude Include="Views\Image\Microsoft.UI.Composition.Effects_Impl.h">
<Filter>Views\Image</Filter>
</ClInclude>
<ClInclude Include="Views\Image\BorderEffect.h">
<Filter>Views\Image</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="EndPoints\dll\react-native-uwp.arm.def">
Expand Down Expand Up @@ -572,6 +611,15 @@
<Filter Include="Views\Impl">
<UniqueIdentifier>{101c2d4a-d343-4771-969f-29af0c9f46b2}</UniqueIdentifier>
</Filter>
<Filter Include="Views\Image">
<UniqueIdentifier>{6d877886-1c5c-45b8-8eae-2e1354cf673e}</UniqueIdentifier>
</Filter>
<Filter Include="Views\cppwinrt\winrt">
<UniqueIdentifier>{e5234a36-e9ee-4ba3-9b11-02e7bd2ca6f0}</UniqueIdentifier>
</Filter>
<Filter Include="Views\cppwinrt\winrt\impl">
<UniqueIdentifier>{24ea7245-f460-4176-82b1-3cac4cd54621}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<MidlRT Include="ABI\idl\Module.idl">
Expand Down
Loading

0 comments on commit f750896

Please sign in to comment.