[Fabric] Eliminate forks needed for onMouseEnter/Leave (#12161)
* [Fabric] Eliminate forks needed for onMouseEnter/Leave We previously forked TouchEventEmitter and BaseViewProps to detect onMouseEnter/onMouseLeave events. Now that there are host platform extension points for ViewEventEmitter and ViewProps, we can move 100% of the enter/leave event handling to host platform logic. * Change files
This commit is contained in:
Родитель
bb94c7d276
Коммит
c62e76f330
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "prerelease",
|
||||
"comment": "[Fabric] Eliminate forks needed for onMouseEnter/Leave",
|
||||
"packageName": "react-native-windows",
|
||||
"email": "erozell@outlook.com",
|
||||
"dependentChangeType": "patch"
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
#include <functional/functor.h>
|
||||
#include <inspectable.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
|
||||
#include <react/renderer/components/view/TouchEventEmitter.h>
|
||||
#include <react/renderer/components/view/ViewEventEmitter.h>
|
||||
#include <react/renderer/components/view/ViewProps.h>
|
||||
#include <react/renderer/core/LayoutMetrics.h>
|
||||
|
||||
|
@ -68,8 +68,8 @@ struct IComponentView {
|
|||
virtual void onFocusLost() noexcept = 0;
|
||||
virtual void onFocusGained() noexcept = 0;
|
||||
virtual bool focusable() const noexcept = 0;
|
||||
virtual facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept = 0;
|
||||
virtual facebook::react::SharedTouchEventEmitter touchEventEmitter() noexcept = 0;
|
||||
virtual facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept = 0;
|
||||
virtual facebook::react::SharedViewEventEmitter eventEmitter() noexcept = 0;
|
||||
virtual facebook::react::Tag tag() const noexcept = 0;
|
||||
// By default, hitTests according the pointerEvents prop on the Component.
|
||||
// If ignorePointerEvents = true, all Components are treated as valid targets
|
||||
|
|
|
@ -31,6 +31,14 @@ bool IsViewListeningToEvent(IComponentView *view, facebook::react::ViewEvents::O
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IsViewListeningToEvent(IComponentView *view, facebook::react::WindowsViewEvents::Offset eventType) {
|
||||
if (view) {
|
||||
auto const &viewProps = *std::static_pointer_cast<facebook::react::ViewProps const>(view->props());
|
||||
return viewProps.windowsEvents[eventType];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsAnyViewInPathListeningToEvent(
|
||||
std::vector<IComponentView *> &path,
|
||||
facebook::react::ViewEvents::Offset eventType) {
|
||||
|
@ -44,7 +52,7 @@ bool IsAnyViewInPathListeningToEvent(
|
|||
|
||||
IComponentView *FindClosestFabricManagedTouchableView(IComponentView *componentView) {
|
||||
while (componentView) {
|
||||
if (componentView->touchEventEmitter()) {
|
||||
if (componentView->eventEmitter()) {
|
||||
return componentView;
|
||||
}
|
||||
componentView = componentView->parent();
|
||||
|
@ -211,7 +219,7 @@ int64_t CompositionEventHandler::SendMessage(uint32_t msg, uint64_t wParam, int6
|
|||
std::vector<IComponentView *> GetTouchableViewsInPathToRoot(IComponentView *view) {
|
||||
std::vector<IComponentView *> results;
|
||||
while (view) {
|
||||
if (view->touchEventEmitter()) {
|
||||
if (view->eventEmitter()) {
|
||||
results.push_back(view);
|
||||
}
|
||||
view = view->parent();
|
||||
|
@ -254,7 +262,7 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|||
if (targetView != nullptr && previousTargetTag != targetView->tag()) {
|
||||
bool shouldEmitOverEvent =
|
||||
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerOver);
|
||||
facebook::react::SharedTouchEventEmitter eventEmitter = targetView->touchEventEmitterAtPoint(event.offsetPoint);
|
||||
const auto eventEmitter = targetView->eventEmitterAtPoint(event.offsetPoint);
|
||||
if (shouldEmitOverEvent && eventEmitter != nullptr) {
|
||||
eventEmitter->onPointerOver(event);
|
||||
}
|
||||
|
@ -276,12 +284,12 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|||
bool shouldEmitEvent = componentView != nullptr &&
|
||||
(hasParentEnterListener ||
|
||||
IsViewListeningToEvent(componentView, facebook::react::ViewEvents::Offset::PointerEnter) ||
|
||||
IsViewListeningToEvent(componentView, facebook::react::ViewEvents::Offset::MouseEnter));
|
||||
IsViewListeningToEvent(componentView, facebook::react::WindowsViewEvents::Offset::MouseEnter));
|
||||
|
||||
if (shouldEmitEvent &&
|
||||
std::find(currentlyHoveredViews.begin(), currentlyHoveredViews.end(), componentView) ==
|
||||
currentlyHoveredViews.end()) {
|
||||
facebook::react::SharedTouchEventEmitter eventEmitter = componentView->touchEventEmitter();
|
||||
const auto eventEmitter = componentView->eventEmitter();
|
||||
if (eventEmitter) {
|
||||
eventEmitter->onPointerEnter(event);
|
||||
if (IsMousePointerEvent(event)) {
|
||||
|
@ -302,7 +310,7 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|||
if (previousTargetTag != -1 && previousTargetTag != (targetView ? targetView->tag() : -1)) {
|
||||
bool shouldEmitOutEvent =
|
||||
IsAnyViewInPathListeningToEvent(currentlyHoveredViews, facebook::react::ViewEvents::Offset::PointerOut);
|
||||
facebook::react::SharedTouchEventEmitter eventEmitter = prevTargetView->touchEventEmitter();
|
||||
const auto eventEmitter = prevTargetView->eventEmitter();
|
||||
if (shouldEmitOutEvent && eventEmitter != nullptr) {
|
||||
eventEmitter->onPointerOut(event);
|
||||
}
|
||||
|
@ -327,7 +335,7 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|||
bool shouldEmitEvent = componentView != nullptr &&
|
||||
(hasParentLeaveListener ||
|
||||
IsViewListeningToEvent(componentView, facebook::react::ViewEvents::Offset::PointerLeave) ||
|
||||
IsViewListeningToEvent(componentView, facebook::react::ViewEvents::Offset::MouseLeave));
|
||||
IsViewListeningToEvent(componentView, facebook::react::WindowsViewEvents::Offset::MouseLeave));
|
||||
|
||||
if (shouldEmitEvent &&
|
||||
std::find(eventPathViews.begin(), eventPathViews.end(), componentView) == eventPathViews.end()) {
|
||||
|
@ -343,7 +351,7 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|||
itComponentView++) { // for (UIView *componentView in [viewsToEmitLeaveEventsTo reverseObjectEnumerator]) {
|
||||
auto componentView = *itComponentView;
|
||||
|
||||
facebook::react::SharedTouchEventEmitter eventEmitter = componentView->touchEventEmitter();
|
||||
const auto eventEmitter = componentView->eventEmitter();
|
||||
if (eventEmitter) {
|
||||
eventEmitter->onPointerLeave(event);
|
||||
if (IsMousePointerEvent(event)) {
|
||||
|
@ -440,8 +448,7 @@ void CompositionEventHandler::MouseMove(uint32_t msg, uint64_t wParam, int64_t l
|
|||
facebook::react::PointerEvent pointerEvent = CreatePointerEventFromIncompleteHoverData(ptScaled, ptLocal);
|
||||
|
||||
auto handler = [targetView, &pointerEvent](std::vector<IComponentView *> &eventPathViews) {
|
||||
facebook::react::SharedTouchEventEmitter eventEmitter =
|
||||
targetView ? targetView->touchEventEmitterAtPoint(pointerEvent.offsetPoint) : nullptr;
|
||||
const auto eventEmitter = targetView ? targetView->eventEmitterAtPoint(pointerEvent.offsetPoint) : nullptr;
|
||||
bool hasMoveEventListeners =
|
||||
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerMove) ||
|
||||
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerMoveCapture);
|
||||
|
@ -506,7 +513,7 @@ void CompositionEventHandler::PointerPressed(uint32_t msg, uint64_t wParam, int6
|
|||
|
||||
auto componentView = targetComponentView;
|
||||
while (componentView) {
|
||||
if (auto eventEmitter = componentView->touchEventEmitter()) {
|
||||
if (auto eventEmitter = componentView->eventEmitter()) {
|
||||
activeTouch.eventEmitter = eventEmitter;
|
||||
activeTouch.touch.target = componentView->tag();
|
||||
// activeTouch.componentView = componentView;
|
||||
|
@ -570,7 +577,7 @@ void CompositionEventHandler::ButtonDown(uint32_t msg, uint64_t wParam, int64_t
|
|||
|
||||
auto componentView = targetComponentView;
|
||||
while (componentView) {
|
||||
if (auto eventEmitter = componentView->touchEventEmitterAtPoint(ptLocal)) {
|
||||
if (auto eventEmitter = componentView->eventEmitterAtPoint(ptLocal)) {
|
||||
activeTouch.eventEmitter = eventEmitter;
|
||||
activeTouch.touch.target = componentView->tag();
|
||||
// activeTouch.componentView = componentView;
|
||||
|
|
|
@ -1275,11 +1275,11 @@ void CompositionBaseComponentView::EnsureTransformMatrixFacade() noexcept {
|
|||
.StartAnimation(L"TransformMatrix", expression);
|
||||
}
|
||||
|
||||
facebook::react::SharedTouchEventEmitter CompositionBaseComponentView::touchEventEmitter() noexcept {
|
||||
facebook::react::SharedViewEventEmitter CompositionBaseComponentView::eventEmitter() noexcept {
|
||||
return m_eventEmitter;
|
||||
}
|
||||
|
||||
facebook::react::SharedTouchEventEmitter CompositionBaseComponentView::touchEventEmitterAtPoint(
|
||||
facebook::react::SharedViewEventEmitter CompositionBaseComponentView::eventEmitterAtPoint(
|
||||
facebook::react::Point /*pt*/) noexcept {
|
||||
return m_eventEmitter;
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ struct CompositionBaseComponentView : public IComponentView,
|
|||
bool focusable() const noexcept override;
|
||||
std::vector<facebook::react::ComponentDescriptorProvider> supplementalComponentDescriptorProviders() noexcept
|
||||
override;
|
||||
facebook::react::SharedTouchEventEmitter touchEventEmitter() noexcept override;
|
||||
facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept override;
|
||||
facebook::react::SharedViewEventEmitter eventEmitter() noexcept override;
|
||||
facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept override;
|
||||
facebook::react::Tag tag() const noexcept override;
|
||||
int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override;
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ facebook::react::Tag ParagraphComponentView::hitTest(
|
|||
return -1;
|
||||
}
|
||||
|
||||
facebook::react::SharedTouchEventEmitter ParagraphComponentView::touchEventEmitterAtPoint(
|
||||
facebook::react::SharedViewEventEmitter ParagraphComponentView::eventEmitterAtPoint(
|
||||
facebook::react::Point pt) noexcept {
|
||||
if (m_attributedStringBox.getValue().getFragments().size()) {
|
||||
BOOL isTrailingHit = false;
|
||||
|
@ -145,7 +145,7 @@ facebook::react::SharedTouchEventEmitter ParagraphComponentView::touchEventEmitt
|
|||
|
||||
for (auto fragment : m_attributedStringBox.getValue().getFragments()) {
|
||||
if (textPosition < fragment.string.length()) {
|
||||
return std::static_pointer_cast<const facebook::react::TouchEventEmitter>(
|
||||
return std::static_pointer_cast<const facebook::react::ViewEventEmitter>(
|
||||
fragment.parentShadowView.eventEmitter);
|
||||
}
|
||||
textPosition -= static_cast<uint32_t>(fragment.string.length());
|
||||
|
|
|
@ -39,7 +39,7 @@ struct ParagraphComponentView : CompositionBaseComponentView {
|
|||
facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
|
||||
const noexcept override;
|
||||
void OnRenderingDeviceLost() noexcept override;
|
||||
facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept override;
|
||||
facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept override;
|
||||
|
||||
winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override;
|
||||
virtual std::string DefaultControlType() const noexcept override;
|
||||
|
|
|
@ -36,6 +36,24 @@ void HostPlatformViewEventEmitter::onBlur() const {
|
|||
dispatchEvent("blur");
|
||||
}
|
||||
|
||||
#pragma mark - Mouse Events
|
||||
|
||||
void HostPlatformViewEventEmitter::onMouseEnter(PointerEvent const &pointerEvent) const {
|
||||
dispatchEvent(
|
||||
"mouseEnter",
|
||||
std::make_shared<PointerEvent>(pointerEvent),
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void HostPlatformViewEventEmitter::onMouseLeave(PointerEvent const &pointerEvent) const {
|
||||
dispatchEvent(
|
||||
"mouseLeave",
|
||||
std::make_shared<PointerEvent>(pointerEvent),
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
// @generated SignedSource<<a6f36c63efa0edf80beb29b0187deb77>>
|
||||
|
|
|
@ -21,6 +21,11 @@ class HostPlatformViewEventEmitter : public BaseViewEventEmitter {
|
|||
|
||||
void onFocus() const;
|
||||
void onBlur() const;
|
||||
|
||||
#pragma mark - Mouse Events
|
||||
|
||||
void onMouseEnter(PointerEvent const &pointerEvent) const;
|
||||
void onMouseLeave(PointerEvent const &pointerEvent) const;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
|
|
@ -1,368 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "BaseViewProps.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <react/renderer/components/view/conversions.h>
|
||||
#include <react/renderer/components/view/propsConversions.h>
|
||||
#include <react/renderer/core/graphicsConversions.h>
|
||||
#include <react/renderer/core/propsConversions.h>
|
||||
#include <react/renderer/debug/debugStringConvertibleUtils.h>
|
||||
#include <react/utils/CoreFeatures.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
BaseViewProps::BaseViewProps(
|
||||
const PropsParserContext &context,
|
||||
BaseViewProps const &sourceProps,
|
||||
RawProps const &rawProps,
|
||||
bool shouldSetRawProps)
|
||||
: YogaStylableProps(context, sourceProps, rawProps, shouldSetRawProps),
|
||||
AccessibilityProps(context, sourceProps, rawProps),
|
||||
opacity(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.opacity
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"opacity",
|
||||
sourceProps.opacity,
|
||||
(Float)1.0)),
|
||||
backgroundColor(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.backgroundColor
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"backgroundColor",
|
||||
sourceProps.backgroundColor,
|
||||
{})),
|
||||
borderRadii(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.borderRadii
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"border",
|
||||
"Radius",
|
||||
sourceProps.borderRadii,
|
||||
{})),
|
||||
borderColors(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.borderColors
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"border",
|
||||
"Color",
|
||||
sourceProps.borderColors,
|
||||
{})),
|
||||
borderCurves(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.borderCurves
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"border",
|
||||
"Curve",
|
||||
sourceProps.borderCurves,
|
||||
{})),
|
||||
borderStyles(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.borderStyles
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"border",
|
||||
"Style",
|
||||
sourceProps.borderStyles,
|
||||
{})),
|
||||
shadowColor(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowColor
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"shadowColor",
|
||||
sourceProps.shadowColor,
|
||||
{})),
|
||||
shadowOffset(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowOffset
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"shadowOffset",
|
||||
sourceProps.shadowOffset,
|
||||
{})),
|
||||
shadowOpacity(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.shadowOpacity
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"shadowOpacity",
|
||||
sourceProps.shadowOpacity,
|
||||
{})),
|
||||
shadowRadius(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowRadius
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"shadowRadius",
|
||||
sourceProps.shadowRadius,
|
||||
{})),
|
||||
transform(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.transform
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"transform",
|
||||
sourceProps.transform,
|
||||
{})),
|
||||
backfaceVisibility(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.backfaceVisibility
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"backfaceVisibility",
|
||||
sourceProps.backfaceVisibility,
|
||||
{})),
|
||||
shouldRasterize(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.shouldRasterize
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"shouldRasterize",
|
||||
sourceProps.shouldRasterize,
|
||||
{})),
|
||||
zIndex(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.zIndex
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"zIndex",
|
||||
sourceProps.zIndex,
|
||||
{})),
|
||||
pointerEvents(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.pointerEvents
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"pointerEvents",
|
||||
sourceProps.pointerEvents,
|
||||
{})),
|
||||
hitSlop(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.hitSlop
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"hitSlop",
|
||||
sourceProps.hitSlop,
|
||||
{})),
|
||||
onLayout(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.onLayout
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"onLayout",
|
||||
sourceProps.onLayout,
|
||||
{})),
|
||||
events(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.events
|
||||
: convertRawProp(context, rawProps, sourceProps.events, {})),
|
||||
collapsable(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.collapsable
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"collapsable",
|
||||
sourceProps.collapsable,
|
||||
true)),
|
||||
removeClippedSubviews(
|
||||
CoreFeatures::enablePropIteratorSetter
|
||||
? sourceProps.removeClippedSubviews
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"removeClippedSubviews",
|
||||
sourceProps.removeClippedSubviews,
|
||||
false)){}
|
||||
|
||||
#define VIEW_EVENT_CASE(eventType) \
|
||||
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
|
||||
const auto offset = ViewEvents::Offset::eventType; \
|
||||
ViewEvents defaultViewEvents{}; \
|
||||
bool res = defaultViewEvents[offset]; \
|
||||
if (value.hasValue()) { \
|
||||
fromRawValue(context, value, res); \
|
||||
} \
|
||||
events[offset] = res; \
|
||||
return; \
|
||||
}
|
||||
|
||||
void BaseViewProps::setProp(
|
||||
const PropsParserContext &context,
|
||||
RawPropsPropNameHash hash,
|
||||
const char *propName,
|
||||
RawValue const &value) {
|
||||
// All Props structs setProp methods must always, unconditionally,
|
||||
// call all super::setProp methods, since multiple structs may
|
||||
// reuse the same values.
|
||||
YogaStylableProps::setProp(context, hash, propName, value);
|
||||
AccessibilityProps::setProp(context, hash, propName, value);
|
||||
|
||||
static auto defaults = BaseViewProps{};
|
||||
|
||||
switch (hash) {
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(opacity);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(backgroundColor);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowColor);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowOffset);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowOpacity);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowRadius);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(transform);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(backfaceVisibility);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(shouldRasterize);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(zIndex);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(pointerEvents);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(hitSlop);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(onLayout);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
|
||||
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
|
||||
// events field
|
||||
VIEW_EVENT_CASE(PointerEnter);
|
||||
VIEW_EVENT_CASE(PointerEnterCapture);
|
||||
VIEW_EVENT_CASE(PointerMove);
|
||||
VIEW_EVENT_CASE(PointerMoveCapture);
|
||||
VIEW_EVENT_CASE(PointerLeave);
|
||||
VIEW_EVENT_CASE(PointerLeaveCapture);
|
||||
VIEW_EVENT_CASE(PointerOver);
|
||||
VIEW_EVENT_CASE(PointerOut);
|
||||
VIEW_EVENT_CASE(MoveShouldSetResponder);
|
||||
VIEW_EVENT_CASE(MoveShouldSetResponderCapture);
|
||||
VIEW_EVENT_CASE(StartShouldSetResponder);
|
||||
VIEW_EVENT_CASE(StartShouldSetResponderCapture);
|
||||
VIEW_EVENT_CASE(ResponderGrant);
|
||||
VIEW_EVENT_CASE(ResponderReject);
|
||||
VIEW_EVENT_CASE(ResponderStart);
|
||||
VIEW_EVENT_CASE(ResponderEnd);
|
||||
VIEW_EVENT_CASE(ResponderRelease);
|
||||
VIEW_EVENT_CASE(ResponderMove);
|
||||
VIEW_EVENT_CASE(ResponderTerminate);
|
||||
VIEW_EVENT_CASE(ResponderTerminationRequest);
|
||||
VIEW_EVENT_CASE(ShouldBlockNativeResponder);
|
||||
VIEW_EVENT_CASE(TouchStart);
|
||||
VIEW_EVENT_CASE(TouchMove);
|
||||
VIEW_EVENT_CASE(TouchEnd);
|
||||
VIEW_EVENT_CASE(TouchCancel);
|
||||
VIEW_EVENT_CASE(MouseEnter); // [Windows]
|
||||
VIEW_EVENT_CASE(MouseLeave); // [Windows]
|
||||
|
||||
// BorderRadii
|
||||
SET_CASCADED_RECTANGLE_CORNERS(borderRadii, "border", "Radius", value);
|
||||
SET_CASCADED_RECTANGLE_EDGES(borderColors, "border", "Color", value);
|
||||
SET_CASCADED_RECTANGLE_EDGES(borderStyles, "border", "Style", value);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Convenience Methods
|
||||
|
||||
static BorderRadii ensureNoOverlap(BorderRadii const &radii, Size const &size) {
|
||||
// "Corner curves must not overlap: When the sum of any two adjacent border
|
||||
// radii exceeds the size of the border box, UAs must proportionally reduce
|
||||
// the used values of all border radii until none of them overlap."
|
||||
// Source: https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
|
||||
|
||||
auto insets = EdgeInsets{
|
||||
/* .left = */ radii.topLeft + radii.bottomLeft,
|
||||
/* .top = */ radii.topLeft + radii.topRight,
|
||||
/* .right = */ radii.topRight + radii.bottomRight,
|
||||
/* .bottom = */ radii.bottomLeft + radii.bottomRight,
|
||||
};
|
||||
|
||||
auto insetsScale = EdgeInsets{
|
||||
/* .left = */
|
||||
insets.left > 0 ? std::min((Float)1.0, size.height / insets.left) : 0,
|
||||
/* .top = */
|
||||
insets.top > 0 ? std::min((Float)1.0, size.width / insets.top) : 0,
|
||||
/* .right = */
|
||||
insets.right > 0 ? std::min((Float)1.0, size.height / insets.right) : 0,
|
||||
/* .bottom = */
|
||||
insets.bottom > 0 ? std::min((Float)1.0, size.width / insets.bottom) : 0,
|
||||
};
|
||||
|
||||
return BorderRadii{
|
||||
/* topLeft = */
|
||||
radii.topLeft * std::min(insetsScale.top, insetsScale.left),
|
||||
/* topRight = */
|
||||
radii.topRight * std::min(insetsScale.top, insetsScale.right),
|
||||
/* bottomLeft = */
|
||||
radii.bottomLeft * std::min(insetsScale.bottom, insetsScale.left),
|
||||
/* bottomRight = */
|
||||
radii.bottomRight * std::min(insetsScale.bottom, insetsScale.right),
|
||||
};
|
||||
}
|
||||
|
||||
BorderMetrics BaseViewProps::resolveBorderMetrics(
|
||||
LayoutMetrics const &layoutMetrics) const {
|
||||
auto isRTL =
|
||||
bool{layoutMetrics.layoutDirection == LayoutDirection::RightToLeft};
|
||||
|
||||
auto borderWidths = CascadedBorderWidths{
|
||||
/* .left = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeLeft]),
|
||||
/* .top = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeTop]),
|
||||
/* .right = */
|
||||
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeRight]),
|
||||
/* .bottom = */
|
||||
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeBottom]),
|
||||
/* .start = */
|
||||
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeStart]),
|
||||
/* .end = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeEnd]),
|
||||
/* .horizontal = */
|
||||
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeHorizontal]),
|
||||
/* .vertical = */
|
||||
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeVertical]),
|
||||
/* .all = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeAll]),
|
||||
};
|
||||
|
||||
return {
|
||||
/* .borderColors = */ borderColors.resolve(isRTL, {}),
|
||||
/* .borderWidths = */ borderWidths.resolve(isRTL, 0),
|
||||
/* .borderRadii = */
|
||||
ensureNoOverlap(borderRadii.resolve(isRTL, 0), layoutMetrics.frame.size),
|
||||
/* .borderCurves = */ borderCurves.resolve(isRTL, BorderCurve::Circular),
|
||||
/* .borderStyles = */ borderStyles.resolve(isRTL, BorderStyle::Solid),
|
||||
};
|
||||
}
|
||||
|
||||
bool BaseViewProps::getClipsContentToBounds() const {
|
||||
return yogaStyle.overflow() != YGOverflowVisible;
|
||||
}
|
||||
|
||||
#pragma mark - DebugStringConvertible
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
SharedDebugStringConvertibleList BaseViewProps::getDebugProps() const {
|
||||
const auto &defaultBaseViewProps = BaseViewProps();
|
||||
|
||||
return AccessibilityProps::getDebugProps() +
|
||||
YogaStylableProps::getDebugProps() +
|
||||
SharedDebugStringConvertibleList{
|
||||
debugStringConvertibleItem(
|
||||
"opacity", opacity, defaultBaseViewProps.opacity),
|
||||
debugStringConvertibleItem(
|
||||
"backgroundColor",
|
||||
backgroundColor,
|
||||
defaultBaseViewProps.backgroundColor),
|
||||
debugStringConvertibleItem(
|
||||
"zIndex", zIndex, defaultBaseViewProps.zIndex.value_or(0)),
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace facebook::react
|
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "TouchEventEmitter.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
#pragma mark - Touches
|
||||
|
||||
static jsi::Value touchesPayload(
|
||||
jsi::Runtime &runtime,
|
||||
Touches const &touches) {
|
||||
auto array = jsi::Array(runtime, touches.size());
|
||||
int i = 0;
|
||||
for (auto const &touch : touches) {
|
||||
auto object = jsi::Object(runtime);
|
||||
setTouchPayloadOnObject(object, runtime, touch);
|
||||
array.setValueAtIndex(runtime, i++, object);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static jsi::Value touchEventPayload(
|
||||
jsi::Runtime &runtime,
|
||||
TouchEvent const &event) {
|
||||
auto object = jsi::Object(runtime);
|
||||
object.setProperty(
|
||||
runtime, "touches", touchesPayload(runtime, event.touches));
|
||||
object.setProperty(
|
||||
runtime, "changedTouches", touchesPayload(runtime, event.changedTouches));
|
||||
object.setProperty(
|
||||
runtime, "targetTouches", touchesPayload(runtime, event.targetTouches));
|
||||
|
||||
if (!event.changedTouches.empty()) {
|
||||
auto const &firstChangedTouch = *event.changedTouches.begin();
|
||||
setTouchPayloadOnObject(object, runtime, firstChangedTouch);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
void TouchEventEmitter::dispatchTouchEvent(
|
||||
std::string type,
|
||||
TouchEvent const &event,
|
||||
EventPriority priority,
|
||||
RawEvent::Category category) const {
|
||||
dispatchEvent(
|
||||
std::move(type),
|
||||
[event](jsi::Runtime &runtime) {
|
||||
return touchEventPayload(runtime, event);
|
||||
},
|
||||
priority,
|
||||
category);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::dispatchPointerEvent(
|
||||
std::string type,
|
||||
PointerEvent const &event,
|
||||
EventPriority priority,
|
||||
RawEvent::Category category) const {
|
||||
dispatchEvent(
|
||||
std::move(type),
|
||||
std::make_shared<PointerEvent>(event),
|
||||
priority,
|
||||
category);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onTouchStart(TouchEvent const &event) const {
|
||||
dispatchTouchEvent(
|
||||
"touchStart",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onTouchMove(TouchEvent const &event) const {
|
||||
dispatchUniqueEvent("touchMove", [event](jsi::Runtime &runtime) {
|
||||
return touchEventPayload(runtime, event);
|
||||
});
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onTouchEnd(TouchEvent const &event) const {
|
||||
dispatchTouchEvent(
|
||||
"touchEnd",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousEnd);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onTouchCancel(TouchEvent const &event) const {
|
||||
dispatchTouchEvent(
|
||||
"touchCancel",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousEnd);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onClick(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"click",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::Discrete);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerCancel(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerCancel",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousEnd);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerDown(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerDown",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerMove(const PointerEvent &event) const {
|
||||
dispatchUniqueEvent("pointerMove", std::make_shared<PointerEvent>(event));
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerUp(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerUp",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousEnd);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerEnter(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerEnter",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerLeave(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerLeave",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousEnd);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerOver(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerOver",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onPointerOut(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"pointerOut",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onGotPointerCapture(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"gotPointerCapture",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onLostPointerCapture(const PointerEvent &event) const {
|
||||
dispatchPointerEvent(
|
||||
"lostPointerCapture",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousEnd);
|
||||
}
|
||||
|
||||
// [Windows
|
||||
void TouchEventEmitter::onMouseEnter(PointerEvent const &event) const {
|
||||
dispatchPointerEvent(
|
||||
"mouseEnter",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
|
||||
void TouchEventEmitter::onMouseLeave(PointerEvent const &event) const {
|
||||
dispatchPointerEvent(
|
||||
"mouseLeave",
|
||||
event,
|
||||
EventPriority::AsynchronousBatched,
|
||||
RawEvent::Category::ContinuousStart);
|
||||
}
|
||||
// Windows]
|
||||
|
||||
|
||||
} // namespace facebook::react
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/components/view/PointerEvent.h>
|
||||
#include <react/renderer/components/view/TouchEvent.h>
|
||||
#include <react/renderer/core/EventEmitter.h>
|
||||
#include <react/renderer/core/LayoutMetrics.h>
|
||||
#include <react/renderer/core/ReactPrimitives.h>
|
||||
#include <react/renderer/debug/DebugStringConvertible.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class TouchEventEmitter;
|
||||
|
||||
using SharedTouchEventEmitter = std::shared_ptr<TouchEventEmitter const>;
|
||||
|
||||
class TouchEventEmitter : public EventEmitter {
|
||||
public:
|
||||
using EventEmitter::EventEmitter;
|
||||
|
||||
void onTouchStart(TouchEvent const &event) const;
|
||||
void onTouchMove(TouchEvent const &event) const;
|
||||
void onTouchEnd(TouchEvent const &event) const;
|
||||
void onTouchCancel(TouchEvent const &event) const;
|
||||
|
||||
void onClick(PointerEvent const &event) const;
|
||||
void onPointerCancel(PointerEvent const &event) const;
|
||||
void onPointerDown(PointerEvent const &event) const;
|
||||
void onPointerMove(PointerEvent const &event) const;
|
||||
void onPointerUp(PointerEvent const &event) const;
|
||||
void onPointerEnter(PointerEvent const &event) const;
|
||||
void onPointerLeave(PointerEvent const &event) const;
|
||||
void onPointerOver(PointerEvent const &event) const;
|
||||
void onPointerOut(PointerEvent const &event) const;
|
||||
void onGotPointerCapture(PointerEvent const &event) const;
|
||||
void onLostPointerCapture(PointerEvent const &event) const;
|
||||
|
||||
void onMouseEnter(PointerEvent const &event) const; // [Windows]
|
||||
void onMouseLeave(PointerEvent const &event) const; // [Windows]
|
||||
|
||||
private:
|
||||
void dispatchTouchEvent(
|
||||
std::string type,
|
||||
TouchEvent const &event,
|
||||
EventPriority priority,
|
||||
RawEvent::Category category) const;
|
||||
void dispatchPointerEvent(
|
||||
std::string type,
|
||||
PointerEvent const &event,
|
||||
EventPriority priority,
|
||||
RawEvent::Category category) const;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
|
@ -1,290 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/graphics/Color.h>
|
||||
#include <react/renderer/graphics/RectangleCorners.h>
|
||||
#include <react/renderer/graphics/RectangleEdges.h>
|
||||
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
enum class PointerEventsMode : uint8_t { Auto, None, BoxNone, BoxOnly };
|
||||
|
||||
struct ViewEvents {
|
||||
std::bitset<64> bits{};
|
||||
|
||||
enum class Offset : std::size_t {
|
||||
// Pointer events
|
||||
PointerEnter = 0,
|
||||
PointerMove = 1,
|
||||
PointerLeave = 2,
|
||||
|
||||
// PanResponder callbacks
|
||||
MoveShouldSetResponder = 3,
|
||||
MoveShouldSetResponderCapture = 4,
|
||||
StartShouldSetResponder = 5,
|
||||
StartShouldSetResponderCapture = 6,
|
||||
ResponderGrant = 7,
|
||||
ResponderReject = 8,
|
||||
ResponderStart = 9,
|
||||
ResponderEnd = 10,
|
||||
ResponderRelease = 11,
|
||||
ResponderMove = 12,
|
||||
ResponderTerminate = 13,
|
||||
ResponderTerminationRequest = 14,
|
||||
ShouldBlockNativeResponder = 15,
|
||||
|
||||
// Touch events
|
||||
TouchStart = 16,
|
||||
TouchMove = 17,
|
||||
TouchEnd = 18,
|
||||
TouchCancel = 19,
|
||||
|
||||
// W3C Pointer Events
|
||||
PointerEnterCapture = 23,
|
||||
PointerLeaveCapture = 24,
|
||||
PointerMoveCapture = 25,
|
||||
PointerOver = 26,
|
||||
PointerOut = 27,
|
||||
PointerOverCapture = 28,
|
||||
PointerOutCapture = 29,
|
||||
Click = 30,
|
||||
ClickCapture = 31,
|
||||
GotPointerCapture = 32,
|
||||
LostPointerCapture = 33,
|
||||
PointerDown = 34,
|
||||
PointerDownCapture = 35,
|
||||
PointerUp = 36,
|
||||
PointerUpCapture = 37,
|
||||
MouseEnter = 30, // Windows
|
||||
MouseLeave = 31, // Windows
|
||||
|
||||
};
|
||||
|
||||
constexpr bool operator[](const Offset offset) const {
|
||||
return bits[static_cast<std::size_t>(offset)];
|
||||
}
|
||||
|
||||
std::bitset<64>::reference operator[](const Offset offset) {
|
||||
return bits[static_cast<std::size_t>(offset)];
|
||||
}
|
||||
};
|
||||
|
||||
inline static bool operator==(ViewEvents const &lhs, ViewEvents const &rhs) {
|
||||
return lhs.bits == rhs.bits;
|
||||
}
|
||||
|
||||
inline static bool operator!=(ViewEvents const &lhs, ViewEvents const &rhs) {
|
||||
return lhs.bits != rhs.bits;
|
||||
}
|
||||
|
||||
enum class BackfaceVisibility : uint8_t { Auto, Visible, Hidden };
|
||||
|
||||
enum class BorderCurve : uint8_t { Circular, Continuous };
|
||||
|
||||
enum class BorderStyle : uint8_t { Solid, Dotted, Dashed };
|
||||
|
||||
enum class LayoutConformance : uint8_t { Undefined, Classic, Strict };
|
||||
|
||||
template <typename T>
|
||||
struct CascadedRectangleEdges {
|
||||
using Counterpart = RectangleEdges<T>;
|
||||
using OptionalT = std::optional<T>;
|
||||
|
||||
OptionalT left{};
|
||||
OptionalT top{};
|
||||
OptionalT right{};
|
||||
OptionalT bottom{};
|
||||
OptionalT start{};
|
||||
OptionalT end{};
|
||||
OptionalT horizontal{};
|
||||
OptionalT vertical{};
|
||||
OptionalT all{};
|
||||
OptionalT block{};
|
||||
OptionalT blockStart{};
|
||||
OptionalT blockEnd{};
|
||||
|
||||
Counterpart resolve(bool isRTL, T defaults) const {
|
||||
const auto leadingEdge = isRTL ? end : start;
|
||||
const auto trailingEdge = isRTL ? start : end;
|
||||
const auto horizontalOrAllOrDefault =
|
||||
horizontal.value_or(all.value_or(defaults));
|
||||
const auto verticalOrAllOrDefault =
|
||||
vertical.value_or(all.value_or(defaults));
|
||||
|
||||
return {
|
||||
/* .left = */
|
||||
left.value_or(leadingEdge.value_or(horizontalOrAllOrDefault)),
|
||||
/* .top = */
|
||||
blockStart.value_or(
|
||||
block.value_or(top.value_or(verticalOrAllOrDefault))),
|
||||
/* .right = */
|
||||
right.value_or(trailingEdge.value_or(horizontalOrAllOrDefault)),
|
||||
/* .bottom = */
|
||||
blockEnd.value_or(
|
||||
block.value_or(bottom.value_or(verticalOrAllOrDefault))),
|
||||
};
|
||||
}
|
||||
|
||||
bool operator==(const CascadedRectangleEdges<T> &rhs) const {
|
||||
return std::tie(
|
||||
this->left,
|
||||
this->top,
|
||||
this->right,
|
||||
this->bottom,
|
||||
this->start,
|
||||
this->end,
|
||||
this->horizontal,
|
||||
this->vertical,
|
||||
this->all,
|
||||
this->block,
|
||||
this->blockStart,
|
||||
this->blockEnd) ==
|
||||
std::tie(
|
||||
rhs.left,
|
||||
rhs.top,
|
||||
rhs.right,
|
||||
rhs.bottom,
|
||||
rhs.start,
|
||||
rhs.end,
|
||||
rhs.horizontal,
|
||||
rhs.vertical,
|
||||
rhs.all,
|
||||
rhs.block,
|
||||
rhs.blockStart,
|
||||
rhs.blockEnd);
|
||||
}
|
||||
|
||||
bool operator!=(const CascadedRectangleEdges<T> &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct CascadedRectangleCorners {
|
||||
using Counterpart = RectangleCorners<T>;
|
||||
using OptionalT = std::optional<T>;
|
||||
|
||||
OptionalT topLeft{};
|
||||
OptionalT topRight{};
|
||||
OptionalT bottomLeft{};
|
||||
OptionalT bottomRight{};
|
||||
OptionalT topStart{};
|
||||
OptionalT topEnd{};
|
||||
OptionalT bottomStart{};
|
||||
OptionalT bottomEnd{};
|
||||
OptionalT all{};
|
||||
OptionalT endEnd{};
|
||||
OptionalT endStart{};
|
||||
OptionalT startEnd{};
|
||||
OptionalT startStart{};
|
||||
|
||||
Counterpart resolve(bool isRTL, T defaults) const {
|
||||
const auto logicalTopStart = topStart ? topStart : startStart;
|
||||
const auto logicalTopEnd = topEnd ? topEnd : startEnd;
|
||||
const auto logicalBottomStart = bottomStart ? bottomStart : endStart;
|
||||
const auto logicalBottomEnd = bottomEnd ? bottomEnd : endEnd;
|
||||
|
||||
const auto topLeading = isRTL ? logicalTopEnd : logicalTopStart;
|
||||
const auto topTrailing = isRTL ? logicalTopStart : logicalTopEnd;
|
||||
const auto bottomLeading = isRTL ? logicalBottomEnd : logicalBottomStart;
|
||||
const auto bottomTrailing = isRTL ? logicalBottomStart : logicalBottomEnd;
|
||||
|
||||
return {
|
||||
/* .topLeft = */ topLeft.value_or(
|
||||
topLeading.value_or(all.value_or(defaults))),
|
||||
/* .topRight = */
|
||||
topRight.value_or(topTrailing.value_or(all.value_or(defaults))),
|
||||
/* .bottomLeft = */
|
||||
bottomLeft.value_or(bottomLeading.value_or(all.value_or(defaults))),
|
||||
/* .bottomRight = */
|
||||
bottomRight.value_or(bottomTrailing.value_or(all.value_or(defaults))),
|
||||
};
|
||||
}
|
||||
|
||||
bool operator==(const CascadedRectangleCorners<T> &rhs) const {
|
||||
return std::tie(
|
||||
this->topLeft,
|
||||
this->topRight,
|
||||
this->bottomLeft,
|
||||
this->bottomRight,
|
||||
this->topStart,
|
||||
this->topEnd,
|
||||
this->bottomStart,
|
||||
this->bottomEnd,
|
||||
this->all,
|
||||
this->endEnd,
|
||||
this->endStart,
|
||||
this->startEnd,
|
||||
this->startStart) ==
|
||||
std::tie(
|
||||
rhs.topLeft,
|
||||
rhs.topRight,
|
||||
rhs.bottomLeft,
|
||||
rhs.bottomRight,
|
||||
rhs.topStart,
|
||||
rhs.topEnd,
|
||||
rhs.bottomStart,
|
||||
rhs.bottomEnd,
|
||||
rhs.all,
|
||||
rhs.endEnd,
|
||||
rhs.endStart,
|
||||
rhs.startEnd,
|
||||
rhs.startStart);
|
||||
}
|
||||
|
||||
bool operator!=(const CascadedRectangleCorners<T> &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
using BorderWidths = RectangleEdges<Float>;
|
||||
using BorderCurves = RectangleCorners<BorderCurve>;
|
||||
using BorderStyles = RectangleEdges<BorderStyle>;
|
||||
using BorderColors = RectangleEdges<SharedColor>;
|
||||
using BorderRadii = RectangleCorners<Float>;
|
||||
|
||||
using CascadedBorderWidths = CascadedRectangleEdges<Float>;
|
||||
using CascadedBorderCurves = CascadedRectangleCorners<BorderCurve>;
|
||||
using CascadedBorderStyles = CascadedRectangleEdges<BorderStyle>;
|
||||
using CascadedBorderColors = CascadedRectangleEdges<SharedColor>;
|
||||
using CascadedBorderRadii = CascadedRectangleCorners<Float>;
|
||||
|
||||
struct BorderMetrics {
|
||||
BorderColors borderColors{};
|
||||
BorderWidths borderWidths{};
|
||||
BorderRadii borderRadii{};
|
||||
BorderCurves borderCurves{};
|
||||
BorderStyles borderStyles{};
|
||||
|
||||
bool operator==(const BorderMetrics &rhs) const {
|
||||
return std::tie(
|
||||
this->borderColors,
|
||||
this->borderWidths,
|
||||
this->borderRadii,
|
||||
this->borderCurves,
|
||||
this->borderStyles) ==
|
||||
std::tie(
|
||||
rhs.borderColors,
|
||||
rhs.borderWidths,
|
||||
rhs.borderRadii,
|
||||
rhs.borderCurves,
|
||||
rhs.borderStyles);
|
||||
}
|
||||
|
||||
bool operator!=(const BorderMetrics &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
|
@ -73,30 +73,6 @@
|
|||
"baseHash": "c0335b67345452991d3356ffe83808434d290724",
|
||||
"issue": 7821
|
||||
},
|
||||
{
|
||||
"type": "derived",
|
||||
"file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/BaseViewProps.cpp",
|
||||
"baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp",
|
||||
"baseHash": "a9be2d4068cb18a94b8ee8f289afae6695a2f35e"
|
||||
},
|
||||
{
|
||||
"type": "derived",
|
||||
"file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/primitives.h",
|
||||
"baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/primitives.h",
|
||||
"baseHash": "ad53fd4887145b0b804d730fd6cd8731b029419d"
|
||||
},
|
||||
{
|
||||
"type": "derived",
|
||||
"file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/TouchEventEmitter.cpp",
|
||||
"baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp",
|
||||
"baseHash": "76ca148d4715dd053ffb0279782c472e8dcc0ba9"
|
||||
},
|
||||
{
|
||||
"type": "derived",
|
||||
"file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/TouchEventEmitter.h",
|
||||
"baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.h",
|
||||
"baseHash": "a76c1bf4ee03ffa180990c86d31af2c3d9d08d62"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp",
|
||||
|
|
Загрузка…
Ссылка в новой задаче