diff --git a/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java b/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java new file mode 100644 index 000000000..14e79967a --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.yoga; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public enum YogaDisplay { + FLEX(0), + NONE(1); + + private int mIntValue; + + YogaDisplay(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static YogaDisplay fromInt(int value) { + switch (value) { + case 0: return FLEX; + case 1: return NONE; + default: throw new IllegalArgumentException("Unknown enum value: " + value); + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java b/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java index 9ac262191..1bca03729 100644 --- a/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java +++ b/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java @@ -310,6 +310,18 @@ public class YogaNode implements YogaNodeAPI { jni_YGNodeStyleSetOverflow(mNativePointer, overflow.intValue()); } + private native int jni_YGNodeStyleGetDisplay(long nativePointer); + @Override + public YogaDisplay getDisplay() { + return YogaDisplay.fromInt(jni_YGNodeStyleGetDisplay(mNativePointer)); + } + + private native void jni_YGNodeStyleSetDisplay(long nativePointer, int display); + @Override + public void setDisplay(YogaDisplay display) { + jni_YGNodeStyleSetDisplay(mNativePointer, display.intValue()); + } + private native void jni_YGNodeStyleSetFlex(long nativePointer, float flex); @Override public void setFlex(float flex) { diff --git a/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeAPI.java b/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeAPI.java index 2dcfa4097..a2ca32009 100644 --- a/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeAPI.java +++ b/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeAPI.java @@ -87,6 +87,8 @@ public interface YogaNodeAPI { YogaDirection getLayoutDirection(); YogaOverflow getOverflow(); void setOverflow(YogaOverflow overflow); + YogaDisplay getDisplay(); + void setDisplay(YogaDisplay display); void setData(Object data); Object getData(); void reset(); diff --git a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp index 88044a965..19a7210a7 100644 --- a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp +++ b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp @@ -319,6 +319,7 @@ YG_NODE_JNI_STYLE_PROP(jint, YGAlign, AlignContent); YG_NODE_JNI_STYLE_PROP(jint, YGPositionType, PositionType); YG_NODE_JNI_STYLE_PROP(jint, YGWrap, FlexWrap); YG_NODE_JNI_STYLE_PROP(jint, YGOverflow, Overflow); +YG_NODE_JNI_STYLE_PROP(jint, YGDisplay, Display); void jni_YGNodeStyleSetFlex(alias_ref, jlong nativePointer, jfloat value) { YGNodeStyleSetFlex(_jlong2YGNodeRef(nativePointer), static_cast(value)); @@ -378,6 +379,8 @@ jint JNI_OnLoad(JavaVM *vm, void *) { YGMakeNativeMethod(jni_YGNodeStyleSetFlexWrap), YGMakeNativeMethod(jni_YGNodeStyleGetOverflow), YGMakeNativeMethod(jni_YGNodeStyleSetOverflow), + YGMakeNativeMethod(jni_YGNodeStyleGetDisplay), + YGMakeNativeMethod(jni_YGNodeStyleSetDisplay), YGMakeNativeMethod(jni_YGNodeStyleSetFlex), YGMakeNativeMethod(jni_YGNodeStyleGetFlexGrow), YGMakeNativeMethod(jni_YGNodeStyleSetFlexGrow), diff --git a/ReactCommon/yoga/yoga/YGEnums.h b/ReactCommon/yoga/yoga/YGEnums.h index afc44513b..3e65e1035 100644 --- a/ReactCommon/yoga/yoga/YGEnums.h +++ b/ReactCommon/yoga/yoga/YGEnums.h @@ -36,6 +36,12 @@ typedef YG_ENUM_BEGIN(YGDirection) { YGDirectionRTL, } YG_ENUM_END(YGDirection); +#define YGDisplayCount 2 +typedef YG_ENUM_BEGIN(YGDisplay) { + YGDisplayFlex, + YGDisplayNone, +} YG_ENUM_END(YGDisplay); + #define YGEdgeCount 9 typedef YG_ENUM_BEGIN(YGEdge) { YGEdgeLeft, diff --git a/ReactCommon/yoga/yoga/Yoga.c b/ReactCommon/yoga/yoga/Yoga.c index cb71ed999..4073d1029 100644 --- a/ReactCommon/yoga/yoga/Yoga.c +++ b/ReactCommon/yoga/yoga/Yoga.c @@ -77,6 +77,7 @@ typedef struct YGStyle { YGPositionType positionType; YGWrap flexWrap; YGOverflow overflow; + YGDisplay display; float flex; float flexGrow; float flexShrink; @@ -148,6 +149,7 @@ static YGNode gYGNodeDefaults = { .direction = YGDirectionInherit, .flexDirection = YGFlexDirectionColumn, .overflow = YGOverflowVisible, + .display = YGDisplayFlex, .dimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, .minDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, .maxDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, @@ -572,6 +574,7 @@ YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignSelf, alignSelf, alignSelf); YG_NODE_STYLE_PROPERTY_IMPL(YGPositionType, PositionType, positionType, positionType); YG_NODE_STYLE_PROPERTY_IMPL(YGWrap, FlexWrap, flexWrap, flexWrap); YG_NODE_STYLE_PROPERTY_IMPL(YGOverflow, Overflow, overflow, overflow); +YG_NODE_STYLE_PROPERTY_IMPL(YGDisplay, Display, display, display); YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexGrow, flexGrow, flexGrow); YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexShrink, flexShrink, flexShrink); @@ -1656,6 +1659,19 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node, return false; } +static void YGZeroOutLayoutRecursivly(const YGNodeRef node) { + node->layout.dimensions[YGDimensionHeight] = 0; + node->layout.dimensions[YGDimensionWidth] = 0; + node->layout.position[YGEdgeTop] = 0; + node->layout.position[YGEdgeBottom] = 0; + node->layout.position[YGEdgeLeft] = 0; + node->layout.position[YGEdgeRight] = 0; + for (uint32_t i = 0; i < YGNodeGetChildCount(node); i++) { + const YGNodeRef child = YGNodeListGet(node->children, i); + YGZeroOutLayoutRecursivly(child); + } +} + // // This is the main routine that implements a subset of the flexbox layout // algorithm @@ -1925,7 +1941,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeListGet(node->children, i); - + if (child->style.display == YGDisplayNone) { + YGZeroOutLayoutRecursivly(child); + child->hasNewLayout = true; + child->isDirty = false; + continue; + } if (performLayout) { // Set the initial position (relative to the parent). const YGDirection childDirection = YGNodeResolveDirection(child, direction); @@ -2005,6 +2026,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Add items to the current line until it's full or we run out of items. for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) { const YGNodeRef child = YGNodeListGet(node->children, i); + if (child->style.display == YGDisplayNone) { + continue; + } child->lineIndex = lineCount; if (child->style.positionType != YGPositionTypeAbsolute) { @@ -2406,7 +2430,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { const YGNodeRef child = YGNodeListGet(node->children, i); - + if (child->style.display == YGDisplayNone) { + continue; + } if (child->style.positionType == YGPositionTypeAbsolute && YGNodeIsLeadingPosDefined(child, mainAxis)) { if (performLayout) { @@ -2487,7 +2513,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (performLayout) { for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { const YGNodeRef child = YGNodeListGet(node->children, i); - + if (child->style.display == YGDisplayNone) { + continue; + } if (child->style.positionType == YGPositionTypeAbsolute) { // If the child is absolutely positioned and has a // top/left/bottom/right @@ -2640,7 +2668,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, float maxDescentForCurrentLine = 0; for (ii = startIndex; ii < childCount; ii++) { const YGNodeRef child = YGNodeListGet(node->children, ii); - + if (child->style.display == YGDisplayNone) { + continue; + } if (child->style.positionType == YGPositionTypeRelative) { if (child->lineIndex != i) { break; @@ -2669,7 +2699,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (performLayout) { for (ii = startIndex; ii < endIndex; ii++) { const YGNodeRef child = YGNodeListGet(node->children, ii); - + if (child->style.display == YGDisplayNone) { + continue; + } if (child->style.positionType == YGPositionTypeRelative) { switch (YGNodeAlignItem(node, child)) { case YGAlignFlexStart: { @@ -2779,7 +2811,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (needsMainTrailingPos || needsCrossTrailingPos) { for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeListGet(node->children, i); - + if (child->style.display == YGDisplayNone) { + continue; + } if (needsMainTrailingPos) { YGNodeSetChildTrailingPosition(node, child, mainAxis); } diff --git a/ReactCommon/yoga/yoga/Yoga.h b/ReactCommon/yoga/yoga/Yoga.h index ab6a2f89f..bf9bd3e89 100644 --- a/ReactCommon/yoga/yoga/Yoga.h +++ b/ReactCommon/yoga/yoga/Yoga.h @@ -157,6 +157,7 @@ YG_NODE_STYLE_PROPERTY(YGAlign, AlignSelf, alignSelf); YG_NODE_STYLE_PROPERTY(YGPositionType, PositionType, positionType); YG_NODE_STYLE_PROPERTY(YGWrap, FlexWrap, flexWrap); YG_NODE_STYLE_PROPERTY(YGOverflow, Overflow, overflow); +YG_NODE_STYLE_PROPERTY(YGDisplay, Display, display); WIN_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex); YG_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow);