Skip to content
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

[Fabric] Fixes findNodeAtPoint when views were inverted #45519

Closed
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,31 @@ ShadowNode::Shared LayoutableShadowNode::findNodeAtPoint(
return nullptr;
}

auto transform = layoutableShadowNode->getTransform();
auto frame = layoutableShadowNode->getLayoutMetrics().frame;
auto transformedFrame = frame * layoutableShadowNode->getTransform();
auto transformedFrame = frame * transform;
auto isPointInside = transformedFrame.containsPoint(point);

if (Transform::isVerticalInversion(transform) ||
Transform::isHorizontalInversion(transform)) {
auto centerX =
transformedFrame.origin.x + transformedFrame.size.width / 2.0;
auto centerY =
transformedFrame.origin.y + transformedFrame.size.height / 2.0;

auto relativeX = point.x - centerX;
auto relativeY = point.y - centerY;

if (Transform::isVerticalInversion(transform)) {
relativeY = -relativeY;
}
if (Transform::isHorizontalInversion(transform)) {
relativeX = -relativeX;
}

point.x = centerX + relativeX;
point.y = centerY + relativeY;
}
realsoelynn marked this conversation as resolved.
Show resolved Hide resolved
if (!isPointInside) {
return nullptr;
} else if (!layoutableShadowNode->canChildrenBeTouchTarget()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,3 +366,52 @@ TEST(FindNodeAtPointTest, overlappingViewsWithParentPointerEventsNone) {
EXPECT_EQ(
LayoutableShadowNode::findNodeAtPoint(parentShadowNode, {50, 50}), nullptr);
}

TEST(FindNodeAtPointTest, invertedList) {
auto builder = simpleComponentBuilder();

// clang-format off
auto element =
Element<ScrollViewShadowNode>()
.props([] {
auto sharedProps = std::make_shared<ScrollViewProps>();
sharedProps->transform = Transform::VerticalInversion();
return sharedProps;
})
.tag(1)
.finalize([](ScrollViewShadowNode &shadowNode){
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.size = {100, 200};
shadowNode.setLayoutMetrics(layoutMetrics);
})
.children({
Element<ViewShadowNode>()
.tag(2)
.finalize([](ViewShadowNode &shadowNode){
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.origin = {0, 0};
layoutMetrics.frame.size = {100, 100};
shadowNode.setLayoutMetrics(layoutMetrics);
}),
Element<ViewShadowNode>()
.tag(3)
.finalize([](ViewShadowNode &shadowNode){
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.origin = {0, 100};
layoutMetrics.frame.size = {100, 100};
shadowNode.setLayoutMetrics(layoutMetrics);
})
});
// clang-format on

auto parentShadowNode = builder.build(element);

EXPECT_EQ(
LayoutableShadowNode::findNodeAtPoint(parentShadowNode, {10, 10})
->getTag(),
3);
EXPECT_EQ(
LayoutableShadowNode::findNodeAtPoint(parentShadowNode, {10, 105})
->getTag(),
2);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <glog/logging.h>
#include <react/debug/react_native_assert.h>
#include <react/utils/FloatComparison.h>

namespace facebook::react {

Expand Down Expand Up @@ -305,11 +306,11 @@ Transform Transform::Interpolate(
}

bool Transform::isVerticalInversion(const Transform& transform) {
return transform.at(1, 1) == -1;
return facebook::react::floatEquality(transform.at(1, 1), -1.0f);
}

bool Transform::isHorizontalInversion(const Transform& transform) {
return transform.at(0, 0) == -1;
return facebook::react::floatEquality(transform.at(0, 0), -1.0f);
}

bool Transform::operator==(const Transform& rhs) const {
Expand Down
Loading