-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Keyboard #3541
Keyboard #3541
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"type": "prerelease", | ||
"comment": "Support Keyboard events", | ||
"packageName": "react-native-windows", | ||
"email": "[email protected]", | ||
"commit": "45a2fb84e8cbe53ad7ea190efab3919124ffb90b", | ||
"date": "2019-10-28T17:44:55.590Z", | ||
"file": "D:\\react2\\react-native-windows\\change\\react-native-windows-2019-10-28-10-44-55-keyboard.json" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#include "pch.h" | ||
|
||
#include <Utils/RectUtils.h> | ||
|
||
namespace winrt { | ||
using namespace Windows::Foundation; | ||
} // namespace winrt | ||
|
||
namespace react { | ||
namespace uwp { | ||
|
||
// Represents positive infinity. | ||
const float PositiveInfinity = std::numeric_limits<float>::infinity(); | ||
|
||
// Represents negative infinity. | ||
const float NegativeInfinity = -std::numeric_limits<float>::infinity(); | ||
|
||
bool IsPositiveInfinity(float value) { | ||
return value == PositiveInfinity; | ||
} | ||
|
||
bool IsNegativeInfinity(float value) { | ||
return value == NegativeInfinity; | ||
} | ||
|
||
// This is a read-only alias for X. If this is the empty rectangle, | ||
// the value will be positive infinity. | ||
float GetLeft(_In_ winrt::Rect rect) { | ||
return rect.X; | ||
} | ||
|
||
// This is a read-only alias for Y. If this is the empty rectangle, | ||
// the value will be positive infinity. | ||
float GetTop(_In_ winrt::Rect rect) { | ||
return rect.Y; | ||
} | ||
|
||
// This is a read-only alias for X + Width. If this is the empty | ||
// rectangle, the value will be negative infinity. | ||
float GetRight(_In_ winrt::Rect rect) { | ||
return (IsEmptyRect(rect) ? NegativeInfinity : rect.X + rect.Width); | ||
} | ||
|
||
// This is a read-only alias for Y + Height. If this is the empty | ||
// rectangle, the value will be negative infinity. | ||
float GetBottom(_In_ winrt::Rect rect) { | ||
return (IsEmptyRect(rect) ? NegativeInfinity : rect.Y + rect.Height); | ||
} | ||
|
||
REACTWINDOWS_API_(bool) IsEmptyRect(winrt::Rect rect) { | ||
return rect.Width < 0; | ||
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.
<= ? 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. In fact consider reusing user32's IsRectEmpty instead In reply to: 339777475 [](ancestors = 339777475) |
||
} | ||
|
||
REACTWINDOWS_API_(winrt::Rect) CreateEmptyRect() { | ||
winrt::Rect result; | ||
result.X = std::numeric_limits<float>::infinity(); | ||
result.Y = std::numeric_limits<float>::infinity(); | ||
result.Width = -std::numeric_limits<float>::infinity(); | ||
result.Height = -std::numeric_limits<float>::infinity(); | ||
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 set these to 0? #Resolved |
||
return result; | ||
} | ||
|
||
// Update this rectangle to be the union of this and rect. | ||
REACTWINDOWS_API_(winrt::Rect) UnionRect(winrt::Rect rect1, _In_ winrt::Rect rect2) { | ||
winrt::Rect result = rect1; | ||
if (IsEmptyRect(rect1)) { | ||
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. can you just call the user32 UnionRect? |
||
result.X = rect2.X; | ||
result.Y = rect2.Y; | ||
result.Width = rect2.Width; | ||
result.Height = rect2.Height; | ||
} else { | ||
if (IsEmptyRect(rect2)) { | ||
float left = 0.0f; | ||
float top = 0.0f; | ||
|
||
left = std::min(rect1.X, rect2.X); | ||
top = std::min(rect1.Y, rect2.Y); | ||
|
||
// We need this check so that the math does not result in NaN | ||
if (IsPositiveInfinity(rect2.Width) || IsPositiveInfinity(rect1.Width)) { | ||
result.Width = std::numeric_limits<float>::infinity(); | ||
} else { | ||
float right1 = GetRight(rect1); | ||
float right2 = GetRight(rect2); | ||
float maxRight = 0.0f; | ||
|
||
maxRight = std::max(right1, right1); | ||
result.Width = std::max(maxRight - left, 0.0f); | ||
} | ||
|
||
// We need this check so that the math does not result in NaN | ||
if (IsPositiveInfinity(rect2.Height) || IsPositiveInfinity(rect1.Height)) { | ||
result.Height = PositiveInfinity; | ||
} else { | ||
float bottom1 = GetBottom(rect1); | ||
float bottom2 = GetBottom(rect2); | ||
float maxBottom = 0.0f; | ||
|
||
// Max with 0 to prevent double weirdness from causing us to be | ||
// (-epsilon..0) | ||
maxBottom = std::max(bottom1, bottom2); | ||
result.Height = std::max(maxBottom - top, 0.0f); | ||
} | ||
|
||
result.X = static_cast<FLOAT>(left); | ||
result.Y = static_cast<FLOAT>(top); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
} // namespace uwp | ||
} // namespace react |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#include <pch.h> | ||
|
||
#include "SIPEventHandler.h" | ||
|
||
#include <Modules/NativeUIManager.h> | ||
#include <Utils/RectUtils.h> | ||
|
||
#include <winrt/Windows.ApplicationModel.Core.h> | ||
#include <winrt/Windows.Devices.Input.h> | ||
#include <winrt/Windows.Foundation.h> | ||
#include <winrt/Windows.UI.Core.h> | ||
#include <winrt/Windows.UI.Input.h> | ||
#include <winrt/Windows.UI.Xaml.Controls.h> | ||
#include <winrt/Windows.UI.Xaml.Input.h> | ||
#include <winrt/Windows.UI.Xaml.Media.h> | ||
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. Remove. #Resolved |
||
#include <winrt/Windows.UI.Xaml.h> | ||
|
||
namespace winrt { | ||
using namespace Windows::UI; | ||
using namespace Windows::Foundation; | ||
using namespace Windows::Foundation::Collections; | ||
using namespace Windows::UI::ViewManagement::Core; | ||
} // namespace winrt | ||
namespace react { | ||
namespace uwp { | ||
|
||
SIPEventHandler::SIPEventHandler(const std::weak_ptr<IReactInstance> &reactInstance) | ||
: m_wkReactInstance(reactInstance) { | ||
auto coreInputView = winrt::CoreInputView::GetForCurrentView(); | ||
if (coreInputView) { | ||
m_occlusionsChnaged_revoker = coreInputView.OcclusionsChanged( | ||
winrt::auto_revoke, [=](auto &&, const winrt::CoreInputViewOcclusionsChangedEventArgs &e) { | ||
if (!e.Handled()) { | ||
winrt::Rect finalRect = CreateEmptyRect(); | ||
winrt::IVectorView<winrt::CoreInputViewOcclusion> occlusions = e.Occlusions(); | ||
for (uint32_t i = 0; i < occlusions.Size(); i++) { | ||
winrt::CoreInputViewOcclusion occlusion = occlusions.GetAt(i); | ||
if (occlusion.OcclusionKind() == winrt::CoreInputViewOcclusionKind::Docked) { | ||
finalRect = UnionRect(finalRect, occlusion.OccludingRect()); | ||
} | ||
} | ||
|
||
if (IsEmptyRect(finalRect)) { | ||
folly::dynamic params = folly::dynamic::object("screenY", 0)("screenX", 0)("width", 0)("height", 0); | ||
SendEvent("keyboardDidHide", std::move(params)); | ||
} else { | ||
folly::dynamic params = folly::dynamic::object( | ||
"endCoordinates", | ||
folly::dynamic::object("screenY", finalRect.Y)("screenX", finalRect.X)("width", finalRect.Width)( | ||
"height", finalRect.Height)); | ||
SendEvent("keyboardDidShow", std::move(params)); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
SIPEventHandler::~SIPEventHandler() { | ||
m_occlusionsChnaged_revoker = {}; | ||
} | ||
|
||
void SIPEventHandler::SendEvent(std::string &&eventName, folly::dynamic &¶meters) { | ||
if (auto instance = m_wkReactInstance.lock()) { | ||
instance->CallJsFunction( | ||
"RCTDeviceEventEmitter", "emit", folly::dynamic::array(std::move(eventName), std::move(parameters))); | ||
} | ||
} | ||
} // namespace uwp | ||
} // namespace react |
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. | ||
|
||
#pragma once | ||
#include <folly/dynamic.h> | ||
|
||
#include <IReactInstance.h> | ||
#include <winrt/Windows.UI.ViewManagement.Core.h> | ||
|
||
namespace winrt { | ||
using namespace Windows::UI; | ||
using namespace Windows::Foundation; | ||
using namespace Windows::UI::ViewManagement::Core; | ||
} // namespace winrt | ||
|
||
namespace react { | ||
namespace uwp { | ||
|
||
class SIPEventHandler { | ||
public: | ||
SIPEventHandler(const std::weak_ptr<IReactInstance> &reactInstance); | ||
virtual ~SIPEventHandler(); | ||
|
||
private: | ||
void SendEvent(std::string &&eventName, folly::dynamic &¶meters); | ||
std::weak_ptr<IReactInstance> m_wkReactInstance; | ||
winrt::CoreInputView::OcclusionsChanged_revoker m_occlusionsChnaged_revoker; | ||
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.
fix typo: Ch n aged #Resolved |
||
}; | ||
|
||
} // namespace uwp | ||
} // namespace react |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#pragma once | ||
|
||
#include <ReactWindowsCore/ReactWindowsAPI.h> | ||
#include <winrt/Windows.Foundation.h> | ||
|
||
namespace react { | ||
namespace uwp { | ||
|
||
REACTWINDOWS_API_(bool) IsEmptyRect(winrt::Windows::Foundation::Rect rect); | ||
REACTWINDOWS_API_(winrt::Windows::Foundation::Rect) CreateEmptyRect(); | ||
REACTWINDOWS_API_(winrt::Windows::Foundation::Rect) | ||
UnionRect(winrt::Windows::Foundation::Rect rect1, _In_ winrt::Windows::Foundation::Rect rect2); | ||
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. when passing Rect pass instead const Rect& #Resolved 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. There is already RectHelper class I can use, will remove . #Resolved |
||
|
||
} // namespace uwp | ||
} // namespace react |
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.
not used, remove? #Resolved