Fabric: Support for `onLayout` event
Summary: `onLayout` event is fired when some layoutable node got inserted or updated (with changed layout) during commit phase. Reviewed By: fkgozali Differential Revision: D8119826 fbshipit-source-id: 831003c88fe5c4358a80328aa715be80e484b52e
This commit is contained in:
parent
0be26092a5
commit
9b7f6abd87
|
@ -76,6 +76,8 @@ void ShadowTree::complete(UnsharedRootShadowNode newRootShadowNode) {
|
|||
);
|
||||
|
||||
if (commit(newRootShadowNode)) {
|
||||
emitLayoutEvents(instructions);
|
||||
|
||||
if (delegate_) {
|
||||
delegate_->shadowTreeDidCommit(shared_from_this(), instructions);
|
||||
}
|
||||
|
@ -93,6 +95,46 @@ bool ShadowTree::commit(const SharedRootShadowNode &newRootShadowNode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ShadowTree::emitLayoutEvents(const TreeMutationInstructionList &instructions) {
|
||||
for (auto &&instruction : instructions) {
|
||||
auto &&type = instruction.getType();
|
||||
|
||||
// Only `Insertion` and `Replacement` instructions can affect layout metrics.
|
||||
if (
|
||||
type == TreeMutationInstruction::Insertion ||
|
||||
type == TreeMutationInstruction::Replacement
|
||||
) {
|
||||
auto &&newShadowNode = instruction.getNewChildNode();
|
||||
auto &&eventHandlers = newShadowNode->getEventHandlers();
|
||||
auto &&viewEventHandlers = std::dynamic_pointer_cast<const ViewEventHandlers>(eventHandlers);
|
||||
|
||||
// Checking if particular shadow node supports `onLayout` event (part of `ViewEventHandlers`).
|
||||
if (viewEventHandlers) {
|
||||
// Now we know that both (old and new) shadow nodes must be `LayoutableShadowNode` subclasses.
|
||||
assert(std::dynamic_pointer_cast<const LayoutableShadowNode>(newShadowNode));
|
||||
// TODO(T29661055): Consider using `std::reinterpret_pointer_cast`.
|
||||
auto &&newLayoutableShadowNode =
|
||||
std::dynamic_pointer_cast<const LayoutableShadowNode>(newShadowNode);
|
||||
|
||||
// In case if we have `oldShadowNode`, we have to check that layout metrics have changed.
|
||||
if (type == TreeMutationInstruction::Replacement) {
|
||||
auto &&oldShadowNode = instruction.getOldChildNode();
|
||||
assert(std::dynamic_pointer_cast<const LayoutableShadowNode>(oldShadowNode));
|
||||
// TODO(T29661055): Consider using `std::reinterpret_pointer_cast`.
|
||||
auto &&oldLayoutableShadowNode =
|
||||
std::dynamic_pointer_cast<const LayoutableShadowNode>(oldShadowNode);
|
||||
|
||||
if (oldLayoutableShadowNode->getLayoutMetrics() == newLayoutableShadowNode->getLayoutMetrics()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
viewEventHandlers->onLayout(newLayoutableShadowNode->getLayoutMetrics());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Delegate
|
||||
|
||||
void ShadowTree::setDelegate(ShadowTreeDelegate *delegate) {
|
||||
|
|
|
@ -76,6 +76,7 @@ private:
|
|||
UnsharedRootShadowNode cloneRootShadowNode(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const;
|
||||
void complete(UnsharedRootShadowNode newRootShadowNode);
|
||||
bool commit(const SharedRootShadowNode &newRootShadowNode);
|
||||
void emitLayoutEvents(const TreeMutationInstructionList &instructions);
|
||||
|
||||
const Tag rootTag_;
|
||||
SharedRootShadowNode rootShadowNode_;
|
||||
|
|
|
@ -24,5 +24,19 @@ void ViewEventHandlers::onAccessibilityMagicTap() const {
|
|||
dispatchEvent("magicTap");
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
void ViewEventHandlers::onLayout(const LayoutMetrics &layoutMetrics) const {
|
||||
folly::dynamic payload = folly::dynamic::object();
|
||||
auto &&frame = layoutMetrics.frame;
|
||||
payload["layout"] = folly::dynamic::object
|
||||
("x", frame.origin.x)
|
||||
("y", frame.origin.y)
|
||||
("width", frame.size.width)
|
||||
("height", frame.size.height);
|
||||
|
||||
dispatchEvent("layout", payload);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <memory>
|
||||
|
||||
#include <fabric/core/EventHandlers.h>
|
||||
#include <fabric/core/LayoutMetrics.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
@ -24,9 +25,15 @@ public:
|
|||
|
||||
using EventHandlers::EventHandlers;
|
||||
|
||||
#pragma mark - Accessibility
|
||||
|
||||
void onAccessibilityAction(const std::string &name) const;
|
||||
void onAccessibilityTap() const;
|
||||
void onAccessibilityMagicTap() const;
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
void onLayout(const LayoutMetrics &layoutMetrics) const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
Loading…
Reference in New Issue