Skip to content

Commit

Permalink
Fix sizing of non strech items
Browse files Browse the repository at this point in the history
Summary:
Fixes the sizing of items so that under most scenarios it calcultes its height by it's content for non exact measurings. This introduces a new useLegacyStretchBehaviour flag on the config to opt out of this change as it is breaking.

See facebook/yoga#505
Closes facebook/yoga#506

Reviewed By: astreet

Differential Revision: D4954016

Pulled By: emilsjolander

fbshipit-source-id: d28bd5d174cd76951fb94df85e3b0cfab7f81ff7
  • Loading branch information
woehrl01 authored and facebook-github-bot committed Apr 28, 2017
1 parent 9934131 commit 992e37c
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 16 deletions.
2 changes: 1 addition & 1 deletion React/Views/RCTShadowView.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ + (YGConfigRef)yogaConfig
yogaConfig = YGConfigNew();
// Turnig off pixel rounding.
YGConfigSetPointScaleFactor(yogaConfig, 0.0);
YGConfigSetUseLegacyStretchBehaviour(yogaConfig, true);
});
return yogaConfig;
}
Expand Down Expand Up @@ -347,7 +348,6 @@ - (instancetype)init
_reactSubviews = [NSMutableArray array];

_yogaNode = YGNodeNewWithConfig([[self class] yogaConfig]);

YGNodeSetContext(_yogaNode, (__bridge void *)self);
YGNodeSetPrintFunc(_yogaNode, RCTPrint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public ReactShadowNode() {
if (sYogaConfig == null) {
sYogaConfig = new YogaConfig();
sYogaConfig.setPointScaleFactor(0f);
sYogaConfig.setUseLegacyStretchBehaviour(true);
}
if (node == null) {
node = new YogaNode(sYogaConfig);
Expand Down
11 changes: 11 additions & 0 deletions ReactAndroid/src/main/java/com/facebook/yoga/YogaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,15 @@ public void setUseWebDefaults(boolean useWebDefaults) {
public void setPointScaleFactor(float pixelsInPoint) {
jni_YGConfigSetPointScaleFactor(mNativePointer, pixelsInPoint);
}

private native void jni_YGConfigSetUseLegacyStretchBehaviour(long nativePointer, boolean useLegacyStretchBehaviour);

/**
* Yoga previously had an error where containers would take the maximum space possible instead of the minimum
* like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch;
* Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour.
*/
public void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour) {
jni_YGConfigSetUseLegacyStretchBehaviour(mNativePointer, useLegacyStretchBehaviour);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@

@DoNotStrip
public enum YogaExperimentalFeature {
WEB_FLEX_BASIS(0),
MIN_FLEX_FIX(1);
WEB_FLEX_BASIS(0);

private int mIntValue;

Expand All @@ -29,7 +28,6 @@ public int intValue() {
public static YogaExperimentalFeature fromInt(int value) {
switch (value) {
case 0: return WEB_FLEX_BASIS;
case 1: return MIN_FLEX_FIX;
default: throw new IllegalArgumentException("Unknown enum value: " + value);
}
}
Expand Down
6 changes: 6 additions & 0 deletions ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,11 @@ void jni_YGConfigSetPointScaleFactor(alias_ref<jobject>, jlong nativePointer, jf
YGConfigSetPointScaleFactor(config, pixelsInPoint);
}

void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref<jobject>, jlong nativePointer, jboolean useLegacyStretchBehaviour) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour);
}

jint jni_YGNodeGetInstanceCount(alias_ref<jclass> clazz) {
return YGNodeGetInstanceCount();
}
Expand Down Expand Up @@ -504,6 +509,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGConfigSetExperimentalFeatureEnabled),
YGMakeNativeMethod(jni_YGConfigSetUseWebDefaults),
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
});
});
}
2 changes: 0 additions & 2 deletions ReactCommon/yoga/yoga/YGEnums.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ const char *YGExperimentalFeatureToString(const YGExperimentalFeature value){
switch(value){
case YGExperimentalFeatureWebFlexBasis:
return "web-flex-basis";
case YGExperimentalFeatureMinFlexFix:
return "min-flex-fix";
}
return "unknown";
}
Expand Down
3 changes: 1 addition & 2 deletions ReactCommon/yoga/yoga/YGEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ typedef YG_ENUM_BEGIN(YGEdge) {
} YG_ENUM_END(YGEdge);
WIN_EXPORT const char *YGEdgeToString(const YGEdge value);

#define YGExperimentalFeatureCount 2
#define YGExperimentalFeatureCount 1
typedef YG_ENUM_BEGIN(YGExperimentalFeature) {
YGExperimentalFeatureWebFlexBasis,
YGExperimentalFeatureMinFlexFix,
} YG_ENUM_END(YGExperimentalFeature);
WIN_EXPORT const char *YGExperimentalFeatureToString(const YGExperimentalFeature value);

Expand Down
22 changes: 14 additions & 8 deletions ReactCommon/yoga/yoga/Yoga.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ typedef struct YGStyle {
typedef struct YGConfig {
bool experimentalFeatures[YGExperimentalFeatureCount + 1];
bool useWebDefaults;
bool useLegacyStretchBehaviour;
float pointScaleFactor;
} YGConfig;

Expand Down Expand Up @@ -202,7 +203,6 @@ static YGNode gYGNodeDefaults = {
static YGConfig gYGConfigDefaults = {
.experimentalFeatures =
{
[YGExperimentalFeatureMinFlexFix] = false,
[YGExperimentalFeatureWebFlexBasis] = false,
},
.useWebDefaults = false,
Expand Down Expand Up @@ -2199,23 +2199,25 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// If the main dimension size isn't known, it is computed based on
// the line length, so there's no more space left to distribute.

bool sizeBasedOnContent = false;
// If we don't measure with exact main dimension we want to ensure we don't violate min and max
if (measureModeMainDim != YGMeasureModeExactly) {
if (!YGFloatIsUndefined(minInnerMainDim) && sizeConsumedOnCurrentLine < minInnerMainDim) {
availableInnerMainDim = minInnerMainDim;
} else if (!YGFloatIsUndefined(maxInnerMainDim) && sizeConsumedOnCurrentLine > maxInnerMainDim) {
availableInnerMainDim = maxInnerMainDim;
} else if (YGConfigIsExperimentalFeatureEnabled(node->config, YGExperimentalFeatureMinFlexFix) &&
(totalFlexGrowFactors == 0 || YGResolveFlexGrow(node) == 0)) {
// TODO: this needs to be moved out of experimental feature, as this is legitimate fix
// If we don't have any children to flex or we can't flex the node itself,
// space we've used is all space we need
availableInnerMainDim = sizeConsumedOnCurrentLine;
} else {
if (!node->config->useLegacyStretchBehaviour && (totalFlexGrowFactors == 0 || YGResolveFlexGrow(node) == 0)) {
// If we don't have any children to flex or we can't flex the node itself,
// space we've used is all space we need
availableInnerMainDim = sizeConsumedOnCurrentLine;
}
sizeBasedOnContent = true;
}
}

float remainingFreeSpace = 0;
if (!YGFloatIsUndefined(availableInnerMainDim)) {
if ((!sizeBasedOnContent || node->config->useLegacyStretchBehaviour) && !YGFloatIsUndefined(availableInnerMainDim)) {
remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine;
} else if (sizeConsumedOnCurrentLine < 0) {
// availableInnerMainDim is indefinite which means the node is being sized
Expand Down Expand Up @@ -3427,6 +3429,10 @@ void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled) {
config->useWebDefaults = enabled;
}

void YGConfigSetUseLegacyStretchBehaviour(const YGConfigRef config, const bool useLegacyStretchBehaviour) {
config->useLegacyStretchBehaviour = useLegacyStretchBehaviour;
}

bool YGConfigGetUseWebDefaults(const YGConfigRef config) {
return config->useWebDefaults;
}
Expand Down
5 changes: 5 additions & 0 deletions ReactCommon/yoga/yoga/Yoga.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ WIN_EXPORT void YGLog(YGLogLevel level, const char *message, ...);
// If you want to avoid rounding - set PointScaleFactor to 0
WIN_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint);

// Yoga previously had an error where containers would take the maximum space possible instead of the minimum
// like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch;
// Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour.
WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour(const YGConfigRef config, const bool useLegacyStretchBehaviour);

// YGConfig
WIN_EXPORT YGConfigRef YGConfigNew(void);
WIN_EXPORT void YGConfigFree(const YGConfigRef config);
Expand Down

0 comments on commit 992e37c

Please sign in to comment.