Skip to content

Commit 5e7a03f

Browse files
mdvaccafacebook-github-bot
authored andcommitted
Implement findNodeAtPoint method
Summary: This diff implements the findNodeAtPoint method to return the ShadowNode that is positioned into a Point of the screen. What's not supported: - Scroll position - Transform - return layoutable nodes that are contained inside a non-layoutable node Changelog: [internal] Reviewed By: shergin Differential Revision: D19190285 fbshipit-source-id: fdc0358dc21312e9950a4eb16c36020e9e43e33f
1 parent ac83f75 commit 5e7a03f

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,32 @@ void LayoutableShadowNode::layout(LayoutContext layoutContext) {
114114
}
115115
}
116116

117+
ShadowNode::Shared LayoutableShadowNode::findNodeAtPoint(
118+
ShadowNode::Shared node,
119+
Point point) {
120+
auto layoutableShadowNode =
121+
dynamic_cast<const LayoutableShadowNode *>(node.get());
122+
123+
if (!layoutableShadowNode) {
124+
return nullptr;
125+
}
126+
auto frame = layoutableShadowNode->getLayoutMetrics().frame;
127+
auto isPointInside = frame.containsPoint(point);
128+
129+
if (!isPointInside) {
130+
return nullptr;
131+
}
132+
133+
auto newPoint = point - frame.origin;
134+
for (const auto &childShadowNode : node->getChildren()) {
135+
auto hitView = findNodeAtPoint(childShadowNode, newPoint);
136+
if (hitView) {
137+
return hitView;
138+
}
139+
}
140+
return isPointInside ? node : nullptr;
141+
}
142+
117143
void LayoutableShadowNode::layoutChildren(LayoutContext layoutContext) {
118144
// Default implementation does nothing.
119145
}

ReactCommon/fabric/core/layout/LayoutableShadowNode.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <react/core/Sealable.h>
1818
#include <react/core/ShadowNode.h>
1919
#include <react/debug/DebugStringConvertible.h>
20+
#include <react/graphics/Geometry.h>
2021
#include <react/graphics/Transform.h>
2122

2223
namespace facebook {
@@ -86,6 +87,14 @@ class LayoutableShadowNode : public virtual Sealable {
8687
LayoutableShadowNode const &ancestorLayoutableShadowNode,
8788
LayoutInspectingPolicy policy) const;
8889

90+
/*
91+
* Returns the ShadowNode that is rendered at the Point received as a
92+
* parameter.
93+
*/
94+
static ShadowNode::Shared findNodeAtPoint(
95+
ShadowNode::Shared node,
96+
Point point);
97+
8998
protected:
9099
/*
91100
* Clean or Dirty layout state:

ReactCommon/fabric/uimanager/UIManager.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <react/core/ShadowNodeFragment.h>
1111
#include <react/debug/SystraceSection.h>
12+
#include <react/graphics/Geometry.h>
1213

1314
#include <glog/logging.h>
1415

@@ -134,6 +135,12 @@ void UIManager::clearJSResponder() const {
134135
}
135136
}
136137

138+
ShadowNode::Shared UIManager::findNodeAtPoint(
139+
const ShadowNode::Shared &node,
140+
Point point) const {
141+
return LayoutableShadowNode::findNodeAtPoint(node, point);
142+
}
143+
137144
void UIManager::setNativeProps(
138145
ShadowNode const &shadowNode,
139146
RawProps const &rawProps) const {

ReactCommon/fabric/uimanager/UIManager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class UIManager final : public ShadowTreeDelegate {
8888

8989
void clearJSResponder() const;
9090

91+
ShadowNode::Shared findNodeAtPoint(
92+
const ShadowNode::Shared &shadowNode,
93+
Point point) const;
94+
9195
/*
9296
* Returns layout metrics of given `shadowNode` relative to
9397
* `ancestorShadowNode` (relative to the root node in case if provided

0 commit comments

Comments
 (0)