-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Image] Implement 'center' and 'repeat' resizeModes #2581
Merged
marlenecota
merged 12 commits into
microsoft:master
from
marlenecota:image-bordereffect
Jun 18, 2019
Merged
Changes from 11 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
bdf4bcf
Move ImageViewManager to its own folder
marlenecota 55f101d
Add BorderEffect impl
marlenecota 7869db2
Switch from Image to Canvas
marlenecota ccf5a68
Add ReactImageBrush (name TBD)
marlenecota af2e505
wip: couple of fixes
marlenecota 634087e
Add ReactImage canvas wrapper
marlenecota 071564d
PR feeedback + add OnLoadEnd event to ReactImage
marlenecota 6c431d2
Merge branch 'master' into image-bordereffect
marlenecota 23e7aba
Removing accidentally added files
marlenecota 17630cf
Merge branch 'image-bordereffect' of https://github.com/marlenecota/r…
marlenecota 6727269
Fix break after merge
marlenecota ce9e014
PR feedback + Moved Image module to separate file
marlenecota File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
#pragma once | ||
#include <Views/cppwinrt/Microsoft.UI.Composition.Effects.BorderEffect.g.h> | ||
|
||
#include <wrl.h> | ||
#include <d2d1_1.h> | ||
#include <d2d1effects_2.h> | ||
#include <functional> | ||
|
||
#include <windows.graphics.effects.interop.h> | ||
#include <winrt/Windows.Foundation.h> | ||
#include <winrt/Windows.UI.h> | ||
|
||
#define CATCH_RETURN \ | ||
return S_OK; \ | ||
} catch (...) { \ | ||
auto hr = winrt::to_hresult(); \ | ||
__analysis_assume(FAILED(hr)); \ | ||
return hr; | ||
|
||
namespace abi | ||
{ | ||
using namespace ABI::Windows::Foundation; | ||
using namespace ABI::Windows::Graphics::Effects; | ||
} | ||
|
||
namespace winrt | ||
{ | ||
using namespace winrt::Microsoft::UI::Composition::Effects; | ||
using namespace winrt::Windows::Foundation; | ||
using namespace winrt::Windows::Graphics::Effects; | ||
using namespace winrt::Windows::UI; | ||
} | ||
|
||
inline winrt::IGraphicsEffectSource& to_winrt(abi::IGraphicsEffectSource*& instance) | ||
{ | ||
return reinterpret_cast<winrt::IGraphicsEffectSource&>(instance); | ||
} | ||
|
||
inline winrt::IPropertyValue& to_winrt(abi::IPropertyValue*& instance) | ||
{ | ||
return reinterpret_cast<winrt::IPropertyValue&>(instance); | ||
} | ||
|
||
namespace winrt::Microsoft::UI::Composition::Effects::implementation | ||
{ | ||
// Base class for Win2D-like effect descriptions | ||
class EffectBase : | ||
public winrt::implements< | ||
EffectBase, | ||
abi::IGraphicsEffectD2D1Interop> | ||
{ | ||
protected: | ||
// This is a header file so we can't use "using namespace", but we can do this: | ||
typedef winrt::Color UIColor; // Renamed because we use "Color" as a field name | ||
typedef winrt::PropertyValue PropertyValue; | ||
typedef abi::GRAPHICS_EFFECT_PROPERTY_MAPPING PropertyMapping; | ||
|
||
public: | ||
// IGraphicsEffect | ||
winrt::hstring Name() { return m_Name; } | ||
void Name(winrt::hstring const& value) { m_Name = value; } | ||
|
||
// IGraphicsEffectD2D1Interop | ||
IFACEMETHODIMP GetSourceCount(_Out_ UINT* count) override { *count = 0; return S_OK; } | ||
IFACEMETHODIMP GetPropertyCount(_Out_ UINT* count) override { *count = 0; return S_OK; } | ||
|
||
IFACEMETHODIMP GetSource(UINT, _Outptr_ abi::IGraphicsEffectSource**) override | ||
{ | ||
return E_INVALIDARG; | ||
} | ||
|
||
IFACEMETHODIMP GetProperty(UINT, _Outptr_ abi::IPropertyValue**) override | ||
{ | ||
return E_INVALIDARG; | ||
} | ||
|
||
IFACEMETHODIMP GetNamedPropertyMapping(LPCWSTR, _Out_ UINT*, | ||
_Out_ abi::GRAPHICS_EFFECT_PROPERTY_MAPPING*) override | ||
{ | ||
return E_INVALIDARG; | ||
} | ||
|
||
protected: | ||
// Invokes a functor with the pointer to the property factory | ||
static HRESULT UsePropertyFactory(_Outptr_ abi::IPropertyValue** value, std::function<winrt::IInspectable()> const& func) try | ||
{ | ||
auto ret = func(); | ||
auto propertyValue = ret.as<winrt::IPropertyValue>(); | ||
to_winrt(*value) = propertyValue; | ||
CATCH_RETURN; | ||
} | ||
|
||
template<UINT32 ComponentCount> | ||
static winrt::IInspectable CreateColor(UIColor color) | ||
{ | ||
static_assert(ComponentCount == 3 || ComponentCount == 4, "Unexpected color component count."); | ||
float values[] = { color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f }; | ||
return winrt::PropertyValue::CreateSingleArray(reinterpret_cast<std::array<float, ComponentCount>&>(values)); | ||
} | ||
|
||
// Helpers to implement GetNamedPropertyMapping more succintly | ||
struct NamedProperty | ||
{ | ||
const wchar_t* Name; // Compile-time constant | ||
UINT Index; // Property index | ||
abi::GRAPHICS_EFFECT_PROPERTY_MAPPING Mapping; | ||
}; | ||
|
||
HRESULT GetNamedPropertyMappingImpl( | ||
_In_count_(mappingCount) const NamedProperty* namedProperties, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should that be _In_count(namedPropertyCount)? #Resolved |
||
UINT namedPropertyCount, | ||
LPCWSTR name, | ||
_Out_ UINT* index, | ||
_Out_ abi::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) | ||
{ | ||
for (UINT i = 0; i < namedPropertyCount; ++i) | ||
{ | ||
const auto& prop = namedProperties[i]; | ||
if (_wcsicmp(name, prop.Name) == 0) | ||
{ | ||
*index = prop.Index; | ||
*mapping = prop.Mapping; | ||
return S_OK; | ||
} | ||
} | ||
return E_INVALIDARG; | ||
} | ||
|
||
// M_PI requires us to be the first to include math.h, not worth it | ||
static constexpr float k_PI = 3.14159265358979f; | ||
static constexpr float k_DegreesPerRadian = 180.0f / k_PI; | ||
|
||
public: | ||
winrt::hstring m_Name; | ||
}; | ||
|
||
//----------------------------------------------------------------------------------------------------------------- | ||
// Helper macros to make implementation more succint | ||
//----------------------------------------------------------------------------------------------------------------- | ||
|
||
#pragma push_macro("DECLARE_D2D_GUID") | ||
#undef DECLARE_D2D_GUID | ||
#define DECLARE_D2D_GUID(Guid) \ | ||
IFACEMETHODIMP GetEffectId(_Out_ GUID * id) override { *id = Guid; return S_OK; } | ||
|
||
#pragma push_macro("DECLARE_SOURCE") | ||
#undef DECLARE_SOURCE | ||
#define DECLARE_SOURCE(Name) \ | ||
winrt::IGraphicsEffectSource m_##Name; \ | ||
winrt::IGraphicsEffectSource Name() { return m_##Name; } \ | ||
void Name(winrt::IGraphicsEffectSource const& value) { m_##Name = value; } | ||
|
||
#pragma push_macro("DECLARE_SINGLE_SOURCE") | ||
#undef DECLARE_SINGLE_SOURCE | ||
#define DECLARE_SINGLE_SOURCE(Name) \ | ||
DECLARE_SOURCE(Name) \ | ||
IFACEMETHODIMP GetSourceCount(_Out_ UINT * count) override { *count = 1; return S_OK; } \ | ||
IFACEMETHODIMP GetSource(UINT index, _Outptr_ abi::IGraphicsEffectSource ** source) override try \ | ||
{ \ | ||
if (index == 0) to_winrt(*source) = m_##Name; \ | ||
else throw winrt::hresult_invalid_argument(); \ | ||
CATCH_RETURN; \ | ||
} | ||
|
||
#pragma push_macro("DECLARE_POD_PROPERTY") | ||
#undef DECLARE_POD_PROPERTY | ||
#define DECLARE_POD_PROPERTY(Name, Type, InitialValue, Condition) \ | ||
private: \ | ||
Type m_##Name = InitialValue; \ | ||
public: \ | ||
Type Name() { return m_##Name; } \ | ||
void Name(Type const& value) \ | ||
{ \ | ||
if (!(0, Condition)) { throw winrt::hresult_invalid_argument(); } \ | ||
m_##Name = value; \ | ||
} | ||
|
||
#pragma push_macro("DECLARE_NAMED_PROPERTY_MAPPING") | ||
#undef DECLARE_NAMED_PROPERTY_MAPPING | ||
#define DECLARE_NAMED_PROPERTY_MAPPING(...) \ | ||
IFACEMETHODIMP GetNamedPropertyMapping(LPCWSTR name, _Out_ UINT * index, \ | ||
_Out_ abi::GRAPHICS_EFFECT_PROPERTY_MAPPING * mapping) override \ | ||
{ \ | ||
static const NamedProperty s_Properties[] = { __VA_ARGS__ }; \ | ||
return GetNamedPropertyMappingImpl(s_Properties, _countof(s_Properties), name, index, mapping); \ | ||
} | ||
|
||
//----------------------------------------------------------------------------------------------------------------- | ||
|
||
class BorderEffect : | ||
public BorderEffectT<BorderEffect, EffectBase> | ||
{ | ||
public: | ||
DECLARE_D2D_GUID(CLSID_D2D1Border); | ||
DECLARE_SINGLE_SOURCE(Source); | ||
DECLARE_POD_PROPERTY(ExtendX, winrt::CanvasEdgeBehavior, winrt::CanvasEdgeBehavior::Clamp, true); | ||
DECLARE_POD_PROPERTY(ExtendY, winrt::CanvasEdgeBehavior, winrt::CanvasEdgeBehavior::Clamp, true); | ||
DECLARE_NAMED_PROPERTY_MAPPING( | ||
{ L"ExtendX", D2D1_BORDER_PROP_EDGE_MODE_X, PropertyMapping::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT }, | ||
{ L"ExtendY", D2D1_BORDER_PROP_EDGE_MODE_Y, PropertyMapping::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT }); | ||
|
||
public: | ||
IFACEMETHODIMP GetPropertyCount(_Out_ UINT* count) override { *count = 2; return S_OK; } | ||
|
||
IFACEMETHODIMP GetProperty(UINT index, _Outptr_ abi::IPropertyValue** value) override | ||
{ | ||
return UsePropertyFactory(value, [=]() | ||
{ | ||
switch (index) | ||
{ | ||
case D2D1_BORDER_PROP_EDGE_MODE_X: return winrt::PropertyValue::CreateUInt32((UINT32)m_ExtendX); | ||
case D2D1_BORDER_PROP_EDGE_MODE_Y: return winrt::PropertyValue::CreateUInt32((UINT32)m_ExtendY); | ||
default: throw winrt::hresult_invalid_argument(); | ||
} | ||
}); | ||
} | ||
}; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this (and probably the DECLARE macros below?) should be in a separate header. #Resolved