From f8ab0e0b08da5a2318a6a583983ab4dc9b0867a0 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Thu, 26 Apr 2018 17:51:57 -0700 Subject: [PATCH] Fabric: YogaLayoutableShadowNode::enableMeasurement() enables custom measuring for Yoga based shadow nodes Summary: YogaLayoutableShadowNode::enableMeasurement() connects Yoga's measuring API and Fabric measuring API. `enableMeasurement` should be called for leaf Yoga nodes with custom content which should be measured manually during layout. Reviewed By: mdvacca Differential Revision: D7738574 fbshipit-source-id: ffe883905c4809290d4d973ad29dc5f0e1ec7573 --- ReactCommon/fabric/graphics/Geometry.h | 3 ++ .../view/yoga/YogaLayoutableShadowNode.cpp | 46 +++++++++++++++++++ .../view/yoga/YogaLayoutableShadowNode.h | 7 +++ 3 files changed, 56 insertions(+) diff --git a/ReactCommon/fabric/graphics/Geometry.h b/ReactCommon/fabric/graphics/Geometry.h index 6c2b0f041..00efbe62f 100644 --- a/ReactCommon/fabric/graphics/Geometry.h +++ b/ReactCommon/fabric/graphics/Geometry.h @@ -20,6 +20,9 @@ using Float = CGFloat; */ const Float kFloatUndefined = CGFLOAT_MAX; +const Float kFloatMax = CGFLOAT_MAX; +const Float kFloatMin = CGFLOAT_MIN; + /* * Point */ diff --git a/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp b/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp index 2b6a6e233..d91def613 100644 --- a/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp +++ b/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include "yogaValuesConversions.h" @@ -90,6 +91,12 @@ void YogaLayoutableShadowNode::setHasNewLayout(bool hasNewLayout) { #pragma mark - Mutating Methods +void YogaLayoutableShadowNode::enableMeasurement() { + ensureUnsealed(); + + yogaNode_->setMeasureFunc(YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector); +} + void YogaLayoutableShadowNode::appendChild(SharedYogaLayoutableShadowNode child) { ensureUnsealed(); @@ -164,6 +171,45 @@ YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode *oldYoga return newShadowNode->yogaNode_.get(); } +YGSize YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(YGNode *yogaNode, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) { + YogaLayoutableShadowNode *shadowNodeRawPtr = (YogaLayoutableShadowNode *)yogaNode->getContext(); + assert(shadowNodeRawPtr); + + Size minimumSize = Size {0, 0}; + Size maximumSize = Size {kFloatMax, kFloatMax}; + + switch (widthMode) { + case YGMeasureModeUndefined: + break; + case YGMeasureModeExactly: + minimumSize.width = fabricFloatFromYogaFloat(width); + maximumSize.width = fabricFloatFromYogaFloat(width); + break; + case YGMeasureModeAtMost: + maximumSize.width = fabricFloatFromYogaFloat(width); + break; + } + + switch (heightMode) { + case YGMeasureModeUndefined: + break; + case YGMeasureModeExactly: + minimumSize.height = fabricFloatFromYogaFloat(height); + maximumSize.height = fabricFloatFromYogaFloat(height); + break; + case YGMeasureModeAtMost: + maximumSize.height = fabricFloatFromYogaFloat(height); + break; + } + + Size size = shadowNodeRawPtr->measure(LayoutConstraints {minimumSize, maximumSize}); + + return YGSize { + yogaFloatFromFabricFloat(size.width), + yogaFloatFromFabricFloat(size.height) + }; +} + void YogaLayoutableShadowNode::setYogaNodeChildrenBasedOnShadowNodeChildren(YGNode &yogaNode, const SharedShadowNodeSharedList &children) { auto yogaNodeChildren = YGVector(); diff --git a/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.h b/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.h index 8b367e5e9..0d00a3f36 100644 --- a/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.h +++ b/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.h @@ -54,6 +54,12 @@ public: #pragma mark - Mutating Methods + /* + * Connects `measureFunc` function of Yoga node with + * `LayoutableShadowNode::measure()` method. + */ + void enableMeasurement(); + /* * Appends `child`'s Yoga node to the own Yoga node. * So, it complements `ShadowNode::appendChild(...)` functionality from Yoga @@ -82,6 +88,7 @@ private: static SharedYogaConfig suitableYogaConfig(); static void setYogaNodeChildrenBasedOnShadowNodeChildren(YGNode &yogaNode, const SharedShadowNodeSharedList &children); static YGNode *yogaNodeCloneCallbackConnector(YGNode *oldYogaNode, YGNode *parentYogaNode, int childIndex); + static YGSize yogaNodeMeasureCallbackConnector(YGNode *yogaNode, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); }; } // namespace react