From f287512f5d0a2741b2ccc17d3e8580b3efcca5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20W=C3=B6hrl?= Date: Tue, 31 Jan 2017 20:42:31 +0100 Subject: [PATCH] added display property --- enums.py | 4 ++ gentest/fixtures/YGDisplayTest.html | 6 ++ gentest/gentest-cpp.js | 7 +++ gentest/gentest-cs.js | 7 +++ gentest/gentest-java.js | 7 +++ gentest/gentest-javascript.js | 7 +++ gentest/gentest.js | 12 ++++ tests/YGDisplayTest.cpp | 95 +++++++++++++++++++++++++++++ yoga/YGEnums.h | 6 ++ yoga/Yoga.c | 34 +++++++++-- yoga/Yoga.h | 1 + 11 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 gentest/fixtures/YGDisplayTest.html create mode 100644 tests/YGDisplayTest.cpp diff --git a/enums.py b/enums.py index 47a74551..b67e5b10 100644 --- a/enums.py +++ b/enums.py @@ -51,6 +51,10 @@ ENUMS = { 'PositionType': [ 'Relative', 'Absolute', + ], + 'Display': [ + 'Flex', + 'None', ], 'Wrap': [ 'NoWrap', diff --git a/gentest/fixtures/YGDisplayTest.html b/gentest/fixtures/YGDisplayTest.html new file mode 100644 index 00000000..e4f85222 --- /dev/null +++ b/gentest/fixtures/YGDisplayTest.html @@ -0,0 +1,6 @@ +
+
+
+
+
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js index 4834b45a..76fdea5f 100644 --- a/gentest/gentest-cpp.js +++ b/gentest/gentest-cpp.js @@ -118,6 +118,9 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { YGUndefined:{value:'YGUndefined'}, + YGDisplayFlex:{value:'YGDisplayFlex'}, + YGDisplayNone:{value:'YGDisplayNone'}, + YGNodeCalculateLayout:{value:function(node, dir) { this.push('YGNodeCalculateLayout(' + node + ', YGUndefined, YGUndefined, ' + dir + ');'); }}, @@ -162,6 +165,10 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { this.push('YGNodeStyleSetDirection(' + nodeName + ', ' + toValueCpp(value) + ');'); }}, + YGNodeStyleSetDisplay:{value:function(nodeName, value) { + this.push('YGNodeStyleSetDisplay(' + nodeName + ', ' + toValueCpp(value) + ');'); + }}, + YGNodeStyleSetFlexBasis:{value:function(nodeName, value) { this.push('YGNodeStyleSetFlexBasis' + toFunctionName(value) + '(' + nodeName + ', ' + toValueCpp(value) + ');'); }}, diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js index 08b08588..3650d862 100644 --- a/gentest/gentest-cs.js +++ b/gentest/gentest-cs.js @@ -128,6 +128,9 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { YGUndefined:{value:'YogaConstants.Undefined'}, + YGDisplayFlex:{value:'YogaDisplay.Flex'}, + YGDisplayNone:{value:'YogaDisplay.None'}, + YGWrapNoWrap:{value:'YogaWrap.NoWrap'}, YGWrapWrap:{value:'YogaWrap.Wrap'}, @@ -176,6 +179,10 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { this.push(nodeName + '.StyleDirection = ' + toValueCs(value) + ';'); }}, + YGNodeStyleSetDisplay:{value:function(nodeName, value) { + this.push(nodeName + '.Display = ' + toValueCs(value) + ';'); + }}, + YGNodeStyleSetFlexBasis:{value:function(nodeName, value) { this.push(nodeName + '.FlexBasis = ' + toCsUnitValue(value) + ';'); }}, diff --git a/gentest/gentest-java.js b/gentest/gentest-java.js index 1c510c48..727c090d 100644 --- a/gentest/gentest-java.js +++ b/gentest/gentest-java.js @@ -132,6 +132,9 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, { YGUndefined:{value:'YogaConstants.UNDEFINED'}, + YGDisplayFlex:{value:'YogaDisplay.FLEX'}, + YGDisplayNone:{value:'YogaDisplay.NONE'}, + YGWrapNoWrap:{value:'YogaWrap.NO_WRAP'}, YGWrapWrap:{value:'YogaWrap.WRAP'}, @@ -180,6 +183,10 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, { this.push(nodeName + '.setDirection(' + toValueJava(value) + ');'); }}, + YGNodeStyleSetDisplay:{value:function(nodeName, value) { + this.push(nodeName + '.setDisplay(' + toValueJavascript(value) + ');'); + }}, + YGNodeStyleSetFlexBasis:{value:function(nodeName, value) { this.push(nodeName + '.setFlexBasis' + toMethodName(value) + '(' + toValueJava(value) + 'f);'); }}, diff --git a/gentest/gentest-javascript.js b/gentest/gentest-javascript.js index 8f56477e..67c38e83 100644 --- a/gentest/gentest-javascript.js +++ b/gentest/gentest-javascript.js @@ -125,6 +125,9 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, { YGUndefined:{value:'Yoga.UNDEFINED'}, + YGDisplayFlex:{value:'Yoga.DISPLAY_FLEX'}, + YGDisplayNone:{value:'Yoga.DISPLAY_NONE'}, + YGNodeCalculateLayout:{value:function(node, dir) { this.push(node + '.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, ' + dir + ');'); }}, @@ -169,6 +172,10 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, { this.push(nodeName + '.setDirection(' + toValueJavascript(value) + ');'); }}, + YGNodeStyleSetDisplay:{value:function(nodeName, value) { + this.push(nodeName + '.setDisplay(' + toValueJavascript(value) + ');'); + }}, + YGNodeStyleSetFlexBasis:{value:function(nodeName, value) { this.push(nodeName + '.setFlexBasis(' + toValueJavascript(value) + ');'); }}, diff --git a/gentest/gentest.js b/gentest/gentest.js index 2c63d9ae..49f4e42b 100755 --- a/gentest/gentest.js +++ b/gentest/gentest.js @@ -140,6 +140,7 @@ function checkDefaultValues() { {style:'top', value:'undefined'}, {style:'right', value:'undefined'}, {style:'bottom', value:'undefined'}, + {style:'display', value:'flex'}, ].forEach(function(item) { assert(item.value === getDefaultStyleValue(item.style), item.style + ' should be ' + item.value); @@ -300,6 +301,9 @@ function setupTestTree(e, parent, node, genericNode, nodeName, parentName, index case 'max-height': e.YGNodeStyleSetMaxHeight(nodeName, pixelValue(e, node.style[style])); break; + case 'display': + e.YGNodeStyleSetDisplay(nodeName, displayValue(e, node.style[style])) + break; } } } @@ -389,6 +393,13 @@ function pixelValue(e, value) { } } +function displayValue(e, value){ + switch(value){ + case 'flex': return e.YGDisplayFlex; + case 'none': return e.YGDisplayNone; + } +} + function getDefaultStyleValue(style) { if (style == 'position') { return 'relative'; @@ -466,6 +477,7 @@ function getYogaStyle(node) { 'height', 'min-height', 'max-height', + 'display', ].reduce(function(map, key) { map[key] = node.style[key] || getComputedStyle(node, null).getPropertyValue(key); return map; diff --git a/tests/YGDisplayTest.cpp b/tests/YGDisplayTest.cpp new file mode 100644 index 00000000..747faa47 --- /dev/null +++ b/tests/YGDisplayTest.cpp @@ -0,0 +1,95 @@ +/** + * 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. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html + +#include +#include + +TEST(YogaTest, display_none) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetDisplay(root_child1, YGDisplayNone); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetDisplay(root_child3, YGDisplayNone); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 21eb4809..576a8dbd 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -100,4 +100,10 @@ typedef YG_ENUM_BEGIN(YGUnit) { } YG_ENUM_END(YGUnit); +#define YGDisplayCount 2 +typedef YG_ENUM_BEGIN(YGDisplay) { + YGDisplayFlex, YGDisplayNone, +} +YG_ENUM_END(YGDisplay); + YG_EXTERN_C_END diff --git a/yoga/Yoga.c b/yoga/Yoga.c index 792464b6..4381ed93 100644 --- a/yoga/Yoga.c +++ b/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, @@ -568,6 +570,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); @@ -1915,7 +1918,13 @@ 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) { + child->layout.dimensions[YGDimensionHeight] = 0; + child->layout.dimensions[YGDimensionWidth] = 0; + child->hasNewLayout = true; + child->isDirty = false; + continue; + } if (performLayout) { // Set the initial position (relative to the parent). const YGDirection childDirection = YGNodeResolveDirection(child, direction); @@ -1995,6 +2004,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) { @@ -2386,7 +2398,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) { @@ -2467,7 +2481,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 @@ -2618,7 +2634,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; @@ -2647,7 +2665,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: { @@ -2757,7 +2777,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/yoga/Yoga.h b/yoga/Yoga.h index ab6a2f89..bf9bd3e8 100644 --- a/yoga/Yoga.h +++ b/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);