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
This commit is contained in:
Valentin Shergin 2018-04-26 17:51:57 -07:00 committed by Facebook Github Bot
parent 6bbc2ec921
commit f8ab0e0b08
3 changed files with 56 additions and 0 deletions

View File

@ -20,6 +20,9 @@ using Float = CGFloat;
*/
const Float kFloatUndefined = CGFLOAT_MAX;
const Float kFloatMax = CGFLOAT_MAX;
const Float kFloatMin = CGFLOAT_MIN;
/*
* Point
*/

View File

@ -12,6 +12,7 @@
#include <yoga/Yoga.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/core/LayoutConstraints.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#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();

View File

@ -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