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