Added property display: flex and none

Summary:
Fix #241 and successor for #302

Added new property ```display``` with ```YGDisplayFlex``` and ```YGDisplayNone```. Allows to hide nodes from the layout without the need to remove it from the DOM.
Closes https://github.com/facebook/yoga/pull/369

Reviewed By: astreet

Differential Revision: D4501141

Pulled By: emilsjolander

fbshipit-source-id: 0dfeee381f6d1e4bbba81926126b83dd7abab9d6
This commit is contained in:
Lukas Wöhrl 2017-02-06 09:31:22 -08:00 committed by Facebook Github Bot
parent 968aa56ca3
commit ccc56bba8f
7 changed files with 100 additions and 6 deletions

View File

@ -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);
}
}
}

View File

@ -310,6 +310,18 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
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) {

View File

@ -87,6 +87,8 @@ public interface YogaNodeAPI<YogaNodeType extends YogaNodeAPI> {
YogaDirection getLayoutDirection();
YogaOverflow getOverflow();
void setOverflow(YogaOverflow overflow);
YogaDisplay getDisplay();
void setDisplay(YogaDisplay display);
void setData(Object data);
Object getData();
void reset();

View File

@ -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<jobject>, jlong nativePointer, jfloat value) {
YGNodeStyleSetFlex(_jlong2YGNodeRef(nativePointer), static_cast<float>(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),

View File

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

View File

@ -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);
}

View File

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