Compare commits
21 Commits
1.8.0
...
yxping/mas
Author | SHA1 | Date | |
---|---|---|---|
|
8bea26d0a0 | ||
|
187fc54596 | ||
|
c951ad7c7b | ||
|
9785975f77 | ||
|
79281049f2 | ||
|
7d2b84aab6 | ||
|
cda328fa7e | ||
|
5d7b75a47a | ||
|
ae86824636 | ||
|
0dde40ce0b | ||
|
369c9ad12a | ||
|
cfb9eeca20 | ||
|
3dfb68887d | ||
|
d567885070 | ||
|
877c275a13 | ||
|
8aadae8ce4 | ||
|
2232d7603a | ||
|
b3f8851bc2 | ||
|
47ad3f63cf | ||
|
c75adb0671 | ||
|
178b8f5f64 |
@@ -1,10 +1,3 @@
|
||||
# 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.
|
||||
|
||||
language: node_js
|
||||
node_js:
|
||||
- "8"
|
||||
|
12
Yoga.podspec
12
Yoga.podspec
@@ -1,9 +1,9 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'Yoga'
|
||||
spec.version = '1.7.0'
|
||||
spec.version = '1.8.0'
|
||||
spec.license = { :type => 'MIT', :file => "LICENSE" }
|
||||
spec.homepage = 'https://facebook.github.io/yoga/'
|
||||
spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/c/'
|
||||
spec.homepage = 'https://yogalayout.com/'
|
||||
spec.documentation_url = 'https://yogalayout.com/docs'
|
||||
|
||||
spec.summary = 'Yoga is a cross-platform layout engine which implements Flexbox.'
|
||||
spec.description = 'Yoga is a cross-platform layout engine enabling maximum collaboration within your team by implementing an API many designers are familiar with, and opening it up to developers across different platforms.'
|
||||
@@ -11,9 +11,9 @@ Pod::Spec.new do |spec|
|
||||
spec.authors = 'Facebook'
|
||||
spec.source = {
|
||||
:git => 'https://github.com/facebook/yoga.git',
|
||||
:tag => '1.7.0',
|
||||
:tag => '1.8.0',
|
||||
}
|
||||
|
||||
spec.osx.deployment_target = '10.13'
|
||||
spec.module_name = 'yoga'
|
||||
spec.requires_arc = false
|
||||
spec.compiler_flags = [
|
||||
@@ -25,4 +25,6 @@ Pod::Spec.new do |spec|
|
||||
'-fPIC'
|
||||
]
|
||||
spec.source_files = 'yoga/**/*.{c,h,cpp}'
|
||||
spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros}.h'
|
||||
|
||||
end
|
||||
|
@@ -1,9 +1,7 @@
|
||||
# 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.
|
||||
# This source code is licensed under the license found in the
|
||||
# LICENSE-examples file in the root directory of this source tree.
|
||||
|
||||
load("//:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_SAMPLE_RES_TARGET", "ANDROID_SUPPORT_TARGET", "APPCOMPAT_TARGET", "SOLOADER_TARGET", "android_library")
|
||||
|
||||
|
@@ -7,9 +7,6 @@
|
||||
|
||||
package com.facebook.yoga.android;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -21,9 +18,6 @@ import android.util.SparseArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.yoga.android.R;
|
||||
import com.facebook.yoga.YogaAlign;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import com.facebook.yoga.YogaDirection;
|
||||
@@ -35,10 +29,11 @@ import com.facebook.yoga.YogaMeasureFunction;
|
||||
import com.facebook.yoga.YogaMeasureMode;
|
||||
import com.facebook.yoga.YogaMeasureOutput;
|
||||
import com.facebook.yoga.YogaNode;
|
||||
import com.facebook.yoga.YogaNode;
|
||||
import com.facebook.yoga.YogaOverflow;
|
||||
import com.facebook.yoga.YogaPositionType;
|
||||
import com.facebook.yoga.YogaWrap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@code ViewGroup} based on the Yoga layout engine.
|
||||
@@ -291,6 +286,8 @@ public class YogaLayout extends ViewGroup {
|
||||
if (view.getVisibility() == GONE) {
|
||||
return;
|
||||
}
|
||||
int left = Math.round(xOffset + node.getLayoutX());
|
||||
int top = Math.round(yOffset + node.getLayoutY());
|
||||
view.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(
|
||||
Math.round(node.getLayoutWidth()),
|
||||
@@ -298,11 +295,7 @@ public class YogaLayout extends ViewGroup {
|
||||
View.MeasureSpec.makeMeasureSpec(
|
||||
Math.round(node.getLayoutHeight()),
|
||||
View.MeasureSpec.EXACTLY));
|
||||
view.layout(
|
||||
Math.round(xOffset + node.getLayoutX()),
|
||||
Math.round(yOffset + node.getLayoutY()),
|
||||
Math.round(xOffset + node.getLayoutX() + node.getLayoutWidth()),
|
||||
Math.round(yOffset + node.getLayoutY() + node.getLayoutHeight()));
|
||||
view.layout(left, top, left + view.getMeasuredWidth(), top + view.getMeasuredHeight());
|
||||
}
|
||||
|
||||
final int childrenCount = node.getChildCount();
|
||||
|
@@ -104,5 +104,58 @@ namespace Facebook.Yoga
|
||||
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_zero_size_with_child()
|
||||
{
|
||||
YogaConfig config = new YogaConfig();
|
||||
|
||||
YogaNode root = new YogaNode(config);
|
||||
|
||||
YogaNode root_child0 = new YogaNode(config);
|
||||
root_child0.Width = 0;
|
||||
root_child0.Height = 0;
|
||||
root.Insert(0, root_child0);
|
||||
|
||||
YogaNode root_child0_child0 = new YogaNode(config);
|
||||
root_child0_child0.Width = 100;
|
||||
root_child0_child0.Height = 100;
|
||||
root_child0.Insert(0, root_child0_child0);
|
||||
root.StyleDirection = YogaDirection.LTR;
|
||||
root.CalculateLayout();
|
||||
|
||||
Assert.AreEqual(0f, root.LayoutX);
|
||||
Assert.AreEqual(0f, root.LayoutY);
|
||||
Assert.AreEqual(0f, root.LayoutWidth);
|
||||
Assert.AreEqual(0f, root.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(0f, root_child0.LayoutX);
|
||||
Assert.AreEqual(0f, root_child0.LayoutY);
|
||||
Assert.AreEqual(0f, root_child0.LayoutWidth);
|
||||
Assert.AreEqual(0f, root_child0.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(0f, root_child0_child0.LayoutX);
|
||||
Assert.AreEqual(0f, root_child0_child0.LayoutY);
|
||||
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
|
||||
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
|
||||
|
||||
root.StyleDirection = YogaDirection.RTL;
|
||||
root.CalculateLayout();
|
||||
|
||||
Assert.AreEqual(0f, root.LayoutX);
|
||||
Assert.AreEqual(0f, root.LayoutY);
|
||||
Assert.AreEqual(0f, root.LayoutWidth);
|
||||
Assert.AreEqual(0f, root.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(0f, root_child0.LayoutX);
|
||||
Assert.AreEqual(0f, root_child0.LayoutY);
|
||||
Assert.AreEqual(0f, root_child0.LayoutWidth);
|
||||
Assert.AreEqual(0f, root_child0.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(-100f, root_child0_child0.LayoutX);
|
||||
Assert.AreEqual(0f, root_child0_child0.LayoutY);
|
||||
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
|
||||
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -7,3 +7,9 @@
|
||||
<div style="width: 100px; height: 100px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="zero_size_with_child">
|
||||
<div style="width: 0px; height: 0px;">
|
||||
<div style="width: 100px; height: 100px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -411,6 +411,8 @@ function getDefaultStyleValue(style) {
|
||||
case 'bottom':
|
||||
case 'start':
|
||||
case 'end':
|
||||
case 'width':
|
||||
case 'height':
|
||||
return 'undefined';
|
||||
}
|
||||
var node = document.getElementById('default');
|
||||
|
@@ -74,6 +74,19 @@ public class YogaConfig {
|
||||
jni_YGConfigSetUseLegacyStretchBehaviour(mNativePointer, useLegacyStretchBehaviour);
|
||||
}
|
||||
|
||||
private native void jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
long nativePointer, boolean shouldDiffLayoutWithoutLegacyStretchBehaviour);
|
||||
/**
|
||||
* If this flag is set then yoga would diff the layout without legacy flag and would set a bool in
|
||||
* YogaNode(mDoesLegacyStretchFlagAffectsLayout) with true if the layouts were different and false
|
||||
* if not
|
||||
*/
|
||||
public void setShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
boolean shouldDiffLayoutWithoutLegacyStretchBehaviour) {
|
||||
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
mNativePointer, shouldDiffLayoutWithoutLegacyStretchBehaviour);
|
||||
}
|
||||
|
||||
private native void jni_YGConfigSetLogger(long nativePointer, Object logger);
|
||||
public void setLogger(YogaLogger logger) {
|
||||
mLogger = logger;
|
||||
|
@@ -82,6 +82,7 @@ public class YogaNode implements Cloneable {
|
||||
private int mLayoutDirection = 0;
|
||||
@DoNotStrip
|
||||
private boolean mHasNewLayout = true;
|
||||
@DoNotStrip private boolean mDoesLegacyStretchFlagAffectsLayout = false;
|
||||
|
||||
private native long jni_YGNodeNew();
|
||||
public YogaNode() {
|
||||
@@ -136,6 +137,7 @@ public class YogaNode implements Cloneable {
|
||||
mMeasureFunction = null;
|
||||
mBaselineFunction = null;
|
||||
mData = null;
|
||||
mDoesLegacyStretchFlagAffectsLayout = false;
|
||||
|
||||
jni_YGNodeReset(mNativePointer);
|
||||
}
|
||||
@@ -573,6 +575,10 @@ public class YogaNode implements Cloneable {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
public boolean getDoesLegacyStretchFlagAffectsLayout() {
|
||||
return mDoesLegacyStretchFlagAffectsLayout;
|
||||
}
|
||||
|
||||
public float getLayoutMargin(YogaEdge edge) {
|
||||
switch (edge) {
|
||||
case LEFT:
|
||||
|
@@ -67,6 +67,9 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
|
||||
|
||||
static auto edgeSetFlagField = obj->getClass()->getField<jint>("mEdgeSetFlag");
|
||||
static auto hasNewLayoutField = obj->getClass()->getField<jboolean>("mHasNewLayout");
|
||||
static auto doesLegacyStretchBehaviour =
|
||||
obj->getClass()->getField<jboolean>(
|
||||
"mDoesLegacyStretchFlagAffectsLayout");
|
||||
|
||||
/* Those flags needs be in sync with YogaNode.java */
|
||||
const int MARGIN = 1;
|
||||
@@ -79,12 +82,19 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
|
||||
obj->setFieldValue(heightField, YGNodeLayoutGetHeight(root));
|
||||
obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root));
|
||||
obj->setFieldValue(topField, YGNodeLayoutGetTop(root));
|
||||
obj->setFieldValue<jboolean>(
|
||||
doesLegacyStretchBehaviour,
|
||||
YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(root));
|
||||
|
||||
if ((hasEdgeSetFlag & MARGIN) == MARGIN) {
|
||||
obj->setFieldValue(marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft));
|
||||
obj->setFieldValue(marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop));
|
||||
obj->setFieldValue(marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight));
|
||||
obj->setFieldValue(marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom));
|
||||
obj->setFieldValue(
|
||||
marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft));
|
||||
obj->setFieldValue(
|
||||
marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop));
|
||||
obj->setFieldValue(
|
||||
marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight));
|
||||
obj->setFieldValue(
|
||||
marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom));
|
||||
}
|
||||
|
||||
if ((hasEdgeSetFlag & PADDING) == PADDING) {
|
||||
@@ -467,6 +477,14 @@ void jni_YGConfigSetExperimentalFeatureEnabled(alias_ref<jobject>,
|
||||
enabled);
|
||||
}
|
||||
|
||||
void jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
alias_ref<jobject>,
|
||||
jlong nativePointer,
|
||||
jboolean enabled) {
|
||||
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
|
||||
YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(config, enabled);
|
||||
}
|
||||
|
||||
void jni_YGConfigSetUseWebDefaults(alias_ref<jobject>,
|
||||
jlong nativePointer,
|
||||
jboolean useWebDefaults) {
|
||||
@@ -624,16 +642,19 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
|
||||
YGMakeNativeMethod(jni_YGNodePrint),
|
||||
YGMakeNativeMethod(jni_YGNodeClone),
|
||||
});
|
||||
registerNatives("com/facebook/yoga/YogaConfig",
|
||||
{
|
||||
YGMakeNativeMethod(jni_YGConfigNew),
|
||||
YGMakeNativeMethod(jni_YGConfigFree),
|
||||
YGMakeNativeMethod(jni_YGConfigSetExperimentalFeatureEnabled),
|
||||
YGMakeNativeMethod(jni_YGConfigSetUseWebDefaults),
|
||||
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
|
||||
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
|
||||
YGMakeNativeMethod(jni_YGConfigSetLogger),
|
||||
YGMakeNativeMethod(jni_YGConfigSetHasNodeClonedFunc),
|
||||
});
|
||||
registerNatives(
|
||||
"com/facebook/yoga/YogaConfig",
|
||||
{
|
||||
YGMakeNativeMethod(jni_YGConfigNew),
|
||||
YGMakeNativeMethod(jni_YGConfigFree),
|
||||
YGMakeNativeMethod(jni_YGConfigSetExperimentalFeatureEnabled),
|
||||
YGMakeNativeMethod(jni_YGConfigSetUseWebDefaults),
|
||||
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
|
||||
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
|
||||
YGMakeNativeMethod(jni_YGConfigSetLogger),
|
||||
YGMakeNativeMethod(jni_YGConfigSetHasNodeClonedFunc),
|
||||
YGMakeNativeMethod(
|
||||
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@@ -101,4 +101,56 @@ public class YGDimensionTest {
|
||||
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_zero_size_with_child() {
|
||||
YogaConfig config = new YogaConfig();
|
||||
|
||||
final YogaNode root = new YogaNode(config);
|
||||
|
||||
final YogaNode root_child0 = new YogaNode(config);
|
||||
root_child0.setWidth(0f);
|
||||
root_child0.setHeight(0f);
|
||||
root.addChildAt(root_child0, 0);
|
||||
|
||||
final YogaNode root_child0_child0 = new YogaNode(config);
|
||||
root_child0_child0.setWidth(100f);
|
||||
root_child0_child0.setHeight(100f);
|
||||
root_child0.addChildAt(root_child0_child0, 0);
|
||||
root.setDirection(YogaDirection.LTR);
|
||||
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
|
||||
assertEquals(0f, root.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutY(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutWidth(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(100f, root_child0_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
|
||||
|
||||
root.setDirection(YogaDirection.RTL);
|
||||
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
|
||||
assertEquals(0f, root.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutY(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutWidth(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(-100f, root_child0_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(100f, root_child0_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@
|
||||
package com.facebook.yoga;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -109,21 +110,23 @@ public class YogaNodeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMeasureFloatMax() {
|
||||
public void testMeasureFloatBigNumber() {
|
||||
final YogaNode node = new YogaNode();
|
||||
node.setMeasureFunction(new YogaMeasureFunction() {
|
||||
public long measure(
|
||||
YogaNode node,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode) {
|
||||
return YogaMeasureOutput.make(Float.MAX_VALUE, Float.MAX_VALUE);
|
||||
}
|
||||
});
|
||||
final float bigNumber = (float) 10E5;
|
||||
node.setMeasureFunction(
|
||||
new YogaMeasureFunction() {
|
||||
public long measure(
|
||||
YogaNode node,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode) {
|
||||
return YogaMeasureOutput.make(bigNumber, bigNumber);
|
||||
}
|
||||
});
|
||||
node.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
assertEquals(Float.MAX_VALUE, node.getLayoutWidth(), 0.01f);
|
||||
assertEquals(Float.MAX_VALUE, node.getLayoutHeight(), 0.01f);
|
||||
assertEquals(bigNumber, node.getLayoutWidth(), 0.01f);
|
||||
assertEquals(bigNumber, node.getLayoutHeight(), 0.01f);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -302,4 +305,27 @@ public class YogaNodeTest {
|
||||
}
|
||||
fail("YogaConfig leaked");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlagShouldDiffLayoutWithoutLegacyStretchBehaviour() throws Exception {
|
||||
YogaConfig config = new YogaConfig();
|
||||
config.setShouldDiffLayoutWithoutLegacyStretchBehaviour(true);
|
||||
config.setUseLegacyStretchBehaviour(true);
|
||||
YogaNode root = new YogaNode(config);
|
||||
root.setWidth(500);
|
||||
root.setHeight(500);
|
||||
YogaNode root_child0 = new YogaNode(config);
|
||||
root_child0.setAlignItems(YogaAlign.FLEX_START);
|
||||
root.addChildAt(root_child0, 0);
|
||||
YogaNode root_child0_child0 = new YogaNode(config);
|
||||
root_child0_child0.setFlexGrow(1);
|
||||
root_child0_child0.setFlexShrink(1);
|
||||
root_child0.addChildAt(root_child0_child0, 0);
|
||||
YogaNode root_child0_child0_child0 = new YogaNode(config);
|
||||
root_child0_child0_child0.setFlexGrow(1);
|
||||
root_child0_child0_child0.setFlexShrink(1);
|
||||
root_child0_child0.addChildAt(root_child0_child0_child0, 0);
|
||||
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
assertFalse(root.getDoesLegacyStretchFlagAffectsLayout());
|
||||
}
|
||||
}
|
||||
|
@@ -104,3 +104,59 @@ it("wrap_grandchild", function () {
|
||||
config.free();
|
||||
}
|
||||
});
|
||||
it("zero_size_with_child", function () {
|
||||
var config = Yoga.Config.create();
|
||||
|
||||
try {
|
||||
var root = Yoga.Node.create(config);
|
||||
|
||||
var root_child0 = Yoga.Node.create(config);
|
||||
root_child0.setWidth(0);
|
||||
root_child0.setHeight(0);
|
||||
root.insertChild(root_child0, 0);
|
||||
|
||||
var root_child0_child0 = Yoga.Node.create(config);
|
||||
root_child0_child0.setWidth(100);
|
||||
root_child0_child0.setHeight(100);
|
||||
root_child0.insertChild(root_child0_child0, 0);
|
||||
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
|
||||
|
||||
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
|
||||
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
|
||||
console.assert(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
|
||||
console.assert(0 === root.getComputedHeight(), "0 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
|
||||
|
||||
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
|
||||
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
|
||||
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
|
||||
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
|
||||
|
||||
console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")");
|
||||
console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")");
|
||||
console.assert(100 === root_child0_child0.getComputedWidth(), "100 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")");
|
||||
console.assert(100 === root_child0_child0.getComputedHeight(), "100 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")");
|
||||
|
||||
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL);
|
||||
|
||||
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
|
||||
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
|
||||
console.assert(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
|
||||
console.assert(0 === root.getComputedHeight(), "0 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
|
||||
|
||||
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
|
||||
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
|
||||
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
|
||||
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
|
||||
|
||||
console.assert(-100 === root_child0_child0.getComputedLeft(), "-100 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")");
|
||||
console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")");
|
||||
console.assert(100 === root_child0_child0.getComputedWidth(), "100 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")");
|
||||
console.assert(100 === root_child0_child0.getComputedHeight(), "100 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")");
|
||||
} finally {
|
||||
if (typeof root !== "undefined") {
|
||||
root.freeRecursive();
|
||||
}
|
||||
|
||||
config.free();
|
||||
}
|
||||
});
|
||||
|
@@ -98,3 +98,56 @@ TEST(YogaTest, wrap_grandchild) {
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
||||
|
||||
TEST(YogaTest, zero_size_with_child) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root_child0, 0);
|
||||
YGNodeStyleSetHeight(root_child0, 0);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root_child0_child0, 100);
|
||||
YGNodeStyleSetHeight(root_child0_child0, 100);
|
||||
YGNodeInsertChild(root_child0, root_child0_child0, 0);
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(0, 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(0, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
|
||||
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(0, 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(0, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
||||
|
@@ -57,3 +57,26 @@ TEST(YogaTest, copy_style_modified_same) {
|
||||
YGNodeFree(node0);
|
||||
YGNodeFree(node1);
|
||||
}
|
||||
|
||||
TEST(YogaTest, initialise_flexShrink_flexGrow) {
|
||||
const YGNodeRef node0 = YGNodeNew();
|
||||
YGNodeStyleSetFlexShrink(node0, 1);
|
||||
ASSERT_EQ(1, YGNodeStyleGetFlexShrink(node0));
|
||||
|
||||
YGNodeStyleSetFlexShrink(node0, YGUndefined);
|
||||
YGNodeStyleSetFlexGrow(node0, 3);
|
||||
ASSERT_EQ(
|
||||
0,
|
||||
YGNodeStyleGetFlexShrink(
|
||||
node0)); // Default value is Zero, if flex shrink is not defined
|
||||
ASSERT_EQ(3, YGNodeStyleGetFlexGrow(node0));
|
||||
|
||||
YGNodeStyleSetFlexGrow(node0, YGUndefined);
|
||||
YGNodeStyleSetFlexShrink(node0, 3);
|
||||
ASSERT_EQ(
|
||||
0,
|
||||
YGNodeStyleGetFlexGrow(
|
||||
node0)); // Default value is Zero, if flex grow is not defined
|
||||
ASSERT_EQ(3, YGNodeStyleGetFlexShrink(node0));
|
||||
YGNodeFree(node0);
|
||||
}
|
||||
|
34
tests/YGTraversalTest.cpp
Normal file
34
tests/YGTraversalTest.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
TEST(YogaTest, pre_order_traversal) {
|
||||
YGNodeRef const root = YGNodeNew();
|
||||
YGNodeRef const root_child0 = YGNodeNew();
|
||||
YGNodeRef const root_child1 = YGNodeNew();
|
||||
YGNodeRef const root_child0_child0 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child0, root_child1});
|
||||
YGNodeInsertChild(root_child0, root_child0_child0, 0);
|
||||
|
||||
std::vector<YGNodeRef> visited;
|
||||
YGTraversePreOrder(root, [&visited](YGNodeRef node) {
|
||||
visited.push_back(node);
|
||||
});
|
||||
|
||||
const std::vector<YGNodeRef> expected = {
|
||||
root,
|
||||
root_child0,
|
||||
root_child0_child0,
|
||||
root_child1
|
||||
};
|
||||
ASSERT_EQ(visited, expected);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
111
tests/YGTreeMutationTest.cpp
Normal file
111
tests/YGTreeMutationTest.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
static std::vector<YGNodeRef> getChildren(YGNodeRef const node)
|
||||
{
|
||||
const uint32_t count = YGNodeGetChildCount(node);
|
||||
std::vector<YGNodeRef> children;
|
||||
children.reserve(count);
|
||||
for (uint32_t i = 0 ; i < count ; i++) {
|
||||
children.push_back(YGNodeGetChild(node, i));
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
TEST(YogaTest, set_children_adds_children_to_parent) {
|
||||
YGNodeRef const root = YGNodeNew();
|
||||
YGNodeRef const root_child0 = YGNodeNew();
|
||||
YGNodeRef const root_child1 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child0, root_child1});
|
||||
|
||||
const std::vector<YGNodeRef> children = getChildren(root);
|
||||
const std::vector<YGNodeRef> expectedChildren = {root_child0, root_child1};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedParents = {root, root};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, set_children_to_empty_removes_old_children) {
|
||||
YGNodeRef const root = YGNodeNew();
|
||||
YGNodeRef const root_child0 = YGNodeNew();
|
||||
YGNodeRef const root_child1 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child0, root_child1});
|
||||
YGNodeSetChildren(root, {});
|
||||
|
||||
const std::vector<YGNodeRef> children = getChildren(root);
|
||||
const std::vector<YGNodeRef> expectedChildren = {};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedParents = {nullptr, nullptr};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, set_children_replaces_non_common_children) {
|
||||
YGNodeRef const root = YGNodeNew();
|
||||
YGNodeRef const root_child0 = YGNodeNew();
|
||||
YGNodeRef const root_child1 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child0, root_child1});
|
||||
|
||||
YGNodeRef const root_child2 = YGNodeNew();
|
||||
YGNodeRef const root_child3 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child2, root_child3});
|
||||
|
||||
const std::vector<YGNodeRef> children = getChildren(root);
|
||||
const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child3};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedParents = {nullptr, nullptr};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
YGNodeFree(root_child0);
|
||||
YGNodeFree(root_child1);
|
||||
}
|
||||
|
||||
TEST(YogaTest, set_children_keeps_and_reorders_common_children) {
|
||||
YGNodeRef const root = YGNodeNew();
|
||||
YGNodeRef const root_child0 = YGNodeNew();
|
||||
YGNodeRef const root_child1 = YGNodeNew();
|
||||
YGNodeRef const root_child2 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child0, root_child1, root_child2});
|
||||
|
||||
YGNodeRef const root_child3 = YGNodeNew();
|
||||
|
||||
YGNodeSetChildren(root, {root_child2, root_child1, root_child3});
|
||||
|
||||
const std::vector<YGNodeRef> children = getChildren(root);
|
||||
const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child1, root_child3};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {
|
||||
YGNodeGetParent(root_child0),
|
||||
YGNodeGetParent(root_child1),
|
||||
YGNodeGetParent(root_child2),
|
||||
YGNodeGetParent(root_child3)
|
||||
};
|
||||
const std::vector<YGNodeRef> expectedParents = {nullptr, root, root, root};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
YGNodeFree(root_child0);
|
||||
}
|
@@ -18,10 +18,45 @@ dependencies {
|
||||
|
||||
### Javascript
|
||||
|
||||
The JavaScript bindings for Yoga can be used from node.js and within the browser.
|
||||
When using Yoga from node.js the native library is used, in browesers a pure JS
|
||||
version is used (corss-compiled using [emscripten](http://kripken.github.io/emscripten-site/)).
|
||||
|
||||
```
|
||||
$> yarn add yoga-layout
|
||||
```
|
||||
|
||||
This is an example on how to use Yoga in JavaScript, for a full API reference,
|
||||
have a look at the [flow-type definitions](https://github.com/facebook/yoga/blob/master/javascript/sources/entry-common.js#L123).
|
||||
|
||||
```js
|
||||
import yoga, {Node} from 'yoga-layout';
|
||||
|
||||
const root = Node.create();
|
||||
root.setWidth(500);
|
||||
root.setHeight(300);
|
||||
root.setJustifyContent(yoga.JUSTIFY_CENTER);
|
||||
|
||||
const node1 = Node.create();
|
||||
node1.setWidth(100);
|
||||
node1.setHeight(100);
|
||||
|
||||
const node2 = Node.create();
|
||||
node2.setWidth(100);
|
||||
node2.setHeight(100);
|
||||
|
||||
root.insertChild(node1, 0);
|
||||
root.insertChild(node2, 1);
|
||||
|
||||
root.calculateLayout(500, 300, yoga.DIRECTION_LTR);
|
||||
console.log(root.getComputedLayout());
|
||||
// {left: 0, top: 0, width: 500, height: 300}
|
||||
console.log(node1.getComputedLayout());
|
||||
// {left: 150, top: 0, width: 100, height: 100}
|
||||
console.log(node2.getComputedLayout());
|
||||
// {left: 250, top: 0, width: 100, height: 100}
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
```
|
||||
|
@@ -49,3 +49,17 @@ bool YGFloatsEqual(const float a, const float b) {
|
||||
}
|
||||
return YGFloatIsUndefined(a) && YGFloatIsUndefined(b);
|
||||
}
|
||||
|
||||
float YGFloatSanitize(const float& val) {
|
||||
return YGFloatIsUndefined(val) ? 0 : val;
|
||||
}
|
||||
|
||||
float YGUnwrapFloatOptional(const YGFloatOptional& op) {
|
||||
return op.isUndefined() ? YGUndefined : op.getValue();
|
||||
}
|
||||
|
||||
bool YGFloatOptionalFloatEquals(
|
||||
const YGFloatOptional& optional,
|
||||
const float& val) {
|
||||
return YGUnwrapFloatOptional(optional) == val;
|
||||
}
|
||||
|
27
yoga/Utils.h
27
yoga/Utils.h
@@ -86,6 +86,20 @@ bool YGFloatArrayEqual(
|
||||
return areEqual;
|
||||
}
|
||||
|
||||
// This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise
|
||||
float YGFloatSanitize(const float& val);
|
||||
|
||||
// This function unwraps optional and returns YGUndefined if not defined or
|
||||
// op.value otherwise
|
||||
// TODO: Get rid off this function
|
||||
float YGUnwrapFloatOptional(const YGFloatOptional& op);
|
||||
|
||||
// This function returns true if val and optional both are undefined or if val
|
||||
// and optional.val is true, otherwise its false.
|
||||
bool YGFloatOptionalFloatEquals(
|
||||
const YGFloatOptional& optional,
|
||||
const float& val);
|
||||
|
||||
YGFlexDirection YGFlexDirectionCross(
|
||||
const YGFlexDirection flexDirection,
|
||||
const YGDirection direction);
|
||||
@@ -95,17 +109,18 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
|
||||
flexDirection == YGFlexDirectionRowReverse;
|
||||
}
|
||||
|
||||
inline float YGResolveValue(const YGValue value, const float parentSize) {
|
||||
inline YGFloatOptional YGResolveValue(const YGValue value, const float parentSize) {
|
||||
switch (value.unit) {
|
||||
case YGUnitUndefined:
|
||||
case YGUnitAuto:
|
||||
return YGUndefined;
|
||||
return YGFloatOptional();
|
||||
case YGUnitPoint:
|
||||
return value.value;
|
||||
return YGFloatOptional(value.value);
|
||||
case YGUnitPercent:
|
||||
return value.value * parentSize * 0.01;
|
||||
return YGFloatOptional(
|
||||
static_cast<float>(value.value * parentSize * 0.01));
|
||||
}
|
||||
return YGUndefined;
|
||||
return YGFloatOptional();
|
||||
}
|
||||
|
||||
inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) {
|
||||
@@ -130,5 +145,5 @@ inline YGFlexDirection YGResolveFlexDirection(
|
||||
static inline float YGResolveValueMargin(
|
||||
const YGValue value,
|
||||
const float parentSize) {
|
||||
return value.unit == YGUnitAuto ? 0 : YGResolveValue(value, parentSize);
|
||||
return value.unit == YGUnitAuto ? 0 : YGUnwrapFloatOptional(YGResolveValue(value, parentSize));
|
||||
}
|
||||
|
32
yoga/YGFloatOptional.cpp
Normal file
32
yoga/YGFloatOptional.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "YGFloatOptional.h"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
YGFloatOptional::YGFloatOptional(const float& value)
|
||||
: value_(value), isUndefined_(false) {}
|
||||
YGFloatOptional::YGFloatOptional() : value_(0), isUndefined_(true) {}
|
||||
|
||||
float YGFloatOptional::getValue() const {
|
||||
if (isUndefined_) {
|
||||
// Abort, accessing a value of an undefined float optional
|
||||
std::cerr << "Tried to get value of an undefined YGFloatOptional\n";
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
return value_;
|
||||
}
|
||||
|
||||
void YGFloatOptional::setValue(const float& val) {
|
||||
value_ = val;
|
||||
isUndefined_ = false;
|
||||
}
|
||||
|
||||
bool YGFloatOptional::isUndefined() const {
|
||||
return isUndefined_;
|
||||
}
|
26
yoga/YGFloatOptional.h
Normal file
26
yoga/YGFloatOptional.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
struct YGFloatOptional {
|
||||
private:
|
||||
float value_;
|
||||
bool isUndefined_;
|
||||
|
||||
public:
|
||||
YGFloatOptional(const float& value);
|
||||
YGFloatOptional();
|
||||
|
||||
// Program will terminate if the value of an undefined is accessed. Please
|
||||
// make sure to check if the optional is defined before calling this function.
|
||||
// To check if float optional is defined, use `isUndefined()`.
|
||||
float getValue() const;
|
||||
|
||||
// Sets the value of float optional, and thus isUndefined is assigned false.
|
||||
void setValue(const float& val);
|
||||
|
||||
bool isUndefined() const;
|
||||
};
|
@@ -87,12 +87,12 @@ std::array<YGValue, 2> YGNode::getResolvedDimensions() const {
|
||||
|
||||
float YGNode::getLeadingPosition(
|
||||
const YGFlexDirection axis,
|
||||
const float axisSize) {
|
||||
const float axisSize) const {
|
||||
if (YGFlexDirectionIsRow(axis)) {
|
||||
const YGValue* leadingPosition =
|
||||
YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined);
|
||||
if (leadingPosition->unit != YGUnitUndefined) {
|
||||
return YGResolveValue(*leadingPosition, axisSize);
|
||||
return YGUnwrapFloatOptional(YGResolveValue(*leadingPosition, axisSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,17 +101,17 @@ float YGNode::getLeadingPosition(
|
||||
|
||||
return leadingPosition->unit == YGUnitUndefined
|
||||
? 0.0f
|
||||
: YGResolveValue(*leadingPosition, axisSize);
|
||||
: YGUnwrapFloatOptional(YGResolveValue(*leadingPosition, axisSize));
|
||||
}
|
||||
|
||||
float YGNode::getTrailingPosition(
|
||||
const YGFlexDirection axis,
|
||||
const float axisSize) {
|
||||
const float axisSize) const {
|
||||
if (YGFlexDirectionIsRow(axis)) {
|
||||
const YGValue* trailingPosition =
|
||||
YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined);
|
||||
if (trailingPosition->unit != YGUnitUndefined) {
|
||||
return YGResolveValue(*trailingPosition, axisSize);
|
||||
return YGUnwrapFloatOptional(YGResolveValue(*trailingPosition, axisSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +120,10 @@ float YGNode::getTrailingPosition(
|
||||
|
||||
return trailingPosition->unit == YGUnitUndefined
|
||||
? 0.0f
|
||||
: YGResolveValue(*trailingPosition, axisSize);
|
||||
: YGUnwrapFloatOptional(YGResolveValue(*trailingPosition, axisSize));
|
||||
}
|
||||
|
||||
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) {
|
||||
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
|
||||
return (YGFlexDirectionIsRow(axis) &&
|
||||
YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined)
|
||||
->unit != YGUnitUndefined) ||
|
||||
@@ -131,7 +131,7 @@ bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) {
|
||||
->unit != YGUnitUndefined;
|
||||
}
|
||||
|
||||
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) {
|
||||
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
|
||||
return (YGFlexDirectionIsRow(axis) &&
|
||||
YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined)
|
||||
->unit != YGUnitUndefined) ||
|
||||
@@ -141,7 +141,7 @@ bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) {
|
||||
|
||||
float YGNode::getLeadingMargin(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.margin[YGEdgeStart].unit != YGUnitUndefined) {
|
||||
return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize);
|
||||
@@ -154,7 +154,7 @@ float YGNode::getLeadingMargin(
|
||||
|
||||
float YGNode::getTrailingMargin(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.margin[YGEdgeEnd].unit != YGUnitUndefined) {
|
||||
return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize);
|
||||
@@ -167,7 +167,7 @@ float YGNode::getTrailingMargin(
|
||||
|
||||
float YGNode::getMarginForAxis(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize);
|
||||
}
|
||||
|
||||
@@ -225,11 +225,11 @@ void YGNode::setDirtiedFunc(YGDirtiedFunc dirtiedFunc) {
|
||||
dirtied_ = dirtiedFunc;
|
||||
}
|
||||
|
||||
void YGNode::setStyle(YGStyle style) {
|
||||
void YGNode::setStyle(const YGStyle& style) {
|
||||
style_ = style;
|
||||
}
|
||||
|
||||
void YGNode::setLayout(YGLayout layout) {
|
||||
void YGNode::setLayout(const YGLayout& layout) {
|
||||
layout_ = layout;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ void YGNode::setParent(YGNodeRef parent) {
|
||||
parent_ = parent;
|
||||
}
|
||||
|
||||
void YGNode::setChildren(YGVector children) {
|
||||
void YGNode::setChildren(const YGVector& children) {
|
||||
children_ = children;
|
||||
}
|
||||
|
||||
@@ -423,10 +423,10 @@ YGNode::YGNode(
|
||||
YGBaselineFunc baseline,
|
||||
YGDirtiedFunc dirtied,
|
||||
YGStyle style,
|
||||
YGLayout layout,
|
||||
const YGLayout& layout,
|
||||
uint32_t lineIndex,
|
||||
YGNodeRef parent,
|
||||
YGVector children,
|
||||
const YGVector& children,
|
||||
YGNodeRef nextChild,
|
||||
YGConfigRef config,
|
||||
bool isDirty,
|
||||
@@ -500,7 +500,7 @@ YGValue YGNode::resolveFlexBasisPtr() const {
|
||||
if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) {
|
||||
return flexBasis;
|
||||
}
|
||||
if (!YGFloatIsUndefined(style_.flex) && style_.flex > 0.0f) {
|
||||
if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) {
|
||||
return config_->useWebDefaults ? YGValueAuto : YGValueZero;
|
||||
}
|
||||
return YGValueAuto;
|
||||
@@ -592,11 +592,11 @@ float YGNode::resolveFlexGrow() {
|
||||
if (parent_ == nullptr) {
|
||||
return 0.0;
|
||||
}
|
||||
if (!YGFloatIsUndefined(style_.flexGrow)) {
|
||||
return style_.flexGrow;
|
||||
if (!style_.flexGrow.isUndefined()) {
|
||||
return style_.flexGrow.getValue();
|
||||
}
|
||||
if (!YGFloatIsUndefined(style_.flex) && style_.flex > 0.0f) {
|
||||
return style_.flex;
|
||||
if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) {
|
||||
return style_.flex.getValue();
|
||||
}
|
||||
return kDefaultFlexGrow;
|
||||
}
|
||||
@@ -605,12 +605,12 @@ float YGNode::resolveFlexShrink() {
|
||||
if (parent_ == nullptr) {
|
||||
return 0.0;
|
||||
}
|
||||
if (!YGFloatIsUndefined(style_.flexShrink)) {
|
||||
return style_.flexShrink;
|
||||
if (!style_.flexShrink.isUndefined()) {
|
||||
return style_.flexShrink.getValue();
|
||||
}
|
||||
if (!config_->useWebDefaults && !YGFloatIsUndefined(style_.flex) &&
|
||||
style_.flex < 0.0f) {
|
||||
return -style_.flex;
|
||||
if (!config_->useWebDefaults && !style_.flex.isUndefined() &&
|
||||
style_.flex.getValue() < 0.0f) {
|
||||
return -style_.flex.getValue();
|
||||
}
|
||||
return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink;
|
||||
}
|
||||
@@ -621,7 +621,7 @@ bool YGNode::isNodeFlexible() {
|
||||
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
|
||||
}
|
||||
|
||||
float YGNode::getLeadingBorder(const YGFlexDirection axis) {
|
||||
float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.border[YGEdgeStart].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(style_.border[YGEdgeStart].value) &&
|
||||
@@ -634,7 +634,7 @@ float YGNode::getLeadingBorder(const YGFlexDirection axis) {
|
||||
return YGFloatMax(computedEdgeValue, 0.0f);
|
||||
}
|
||||
|
||||
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) {
|
||||
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
|
||||
if (YGFlexDirectionIsRow(flexDirection) &&
|
||||
style_.border[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(style_.border[YGEdgeEnd].value) &&
|
||||
@@ -650,48 +650,48 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) {
|
||||
|
||||
float YGNode::getLeadingPadding(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.padding[YGEdgeStart].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(
|
||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize)) &&
|
||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize) > 0.0f) {
|
||||
return YGResolveValue(style_.padding[YGEdgeStart], widthSize);
|
||||
!YGResolveValue(style_.padding[YGEdgeStart], widthSize).isUndefined() &&
|
||||
YGUnwrapFloatOptional(
|
||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize)) > 0.0f) {
|
||||
return YGUnwrapFloatOptional(YGResolveValue(style_.padding[YGEdgeStart], widthSize));
|
||||
}
|
||||
|
||||
float resolvedValue = YGResolveValue(
|
||||
float resolvedValue = YGUnwrapFloatOptional(YGResolveValue(
|
||||
*YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero),
|
||||
widthSize);
|
||||
widthSize));
|
||||
return YGFloatMax(resolvedValue, 0.0f);
|
||||
}
|
||||
|
||||
float YGNode::getTrailingPadding(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.padding[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(
|
||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize)) &&
|
||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize) >= 0.0f) {
|
||||
return YGResolveValue(style_.padding[YGEdgeEnd], widthSize);
|
||||
!YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() &&
|
||||
YGUnwrapFloatOptional(
|
||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize)) >= 0.0f) {
|
||||
return YGUnwrapFloatOptional(YGResolveValue(style_.padding[YGEdgeEnd], widthSize));
|
||||
}
|
||||
|
||||
float resolvedValue = YGResolveValue(
|
||||
float resolvedValue = YGUnwrapFloatOptional(YGResolveValue(
|
||||
*YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero),
|
||||
widthSize);
|
||||
widthSize));
|
||||
|
||||
return YGFloatMax(resolvedValue, 0.0f);
|
||||
}
|
||||
|
||||
float YGNode::getLeadingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
return getLeadingPadding(axis, widthSize) + getLeadingBorder(axis);
|
||||
}
|
||||
|
||||
float YGNode::getTrailingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) {
|
||||
const float widthSize) const {
|
||||
return getTrailingPadding(axis, widthSize) + getTrailingBorder(axis);
|
||||
}
|
||||
|
||||
|
@@ -47,10 +47,10 @@ struct YGNode {
|
||||
YGBaselineFunc baseline,
|
||||
YGDirtiedFunc dirtied,
|
||||
YGStyle style,
|
||||
YGLayout layout,
|
||||
const YGLayout& layout,
|
||||
uint32_t lineIndex,
|
||||
YGNodeRef parent,
|
||||
YGVector children,
|
||||
const YGVector& children,
|
||||
YGNodeRef nextChild,
|
||||
YGConfigRef config,
|
||||
bool isDirty,
|
||||
@@ -80,23 +80,23 @@ struct YGNode {
|
||||
YGValue getResolvedDimension(int index);
|
||||
|
||||
// Methods related to positions, margin, padding and border
|
||||
float getLeadingPosition(const YGFlexDirection axis, const float axisSize);
|
||||
bool isLeadingPositionDefined(const YGFlexDirection axis);
|
||||
bool isTrailingPosDefined(const YGFlexDirection axis);
|
||||
float getTrailingPosition(const YGFlexDirection axis, const float axisSize);
|
||||
float getLeadingMargin(const YGFlexDirection axis, const float widthSize);
|
||||
float getTrailingMargin(const YGFlexDirection axis, const float widthSize);
|
||||
float getLeadingBorder(const YGFlexDirection flexDirection);
|
||||
float getTrailingBorder(const YGFlexDirection flexDirection);
|
||||
float getLeadingPadding(const YGFlexDirection axis, const float widthSize);
|
||||
float getTrailingPadding(const YGFlexDirection axis, const float widthSize);
|
||||
float getLeadingPosition(const YGFlexDirection axis, const float axisSize) const;
|
||||
bool isLeadingPositionDefined(const YGFlexDirection axis) const;
|
||||
bool isTrailingPosDefined(const YGFlexDirection axis) const;
|
||||
float getTrailingPosition(const YGFlexDirection axis, const float axisSize) const;
|
||||
float getLeadingMargin(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getTrailingMargin(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getLeadingBorder(const YGFlexDirection flexDirection) const;
|
||||
float getTrailingBorder(const YGFlexDirection flexDirection) const;
|
||||
float getLeadingPadding(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getTrailingPadding(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getLeadingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize);
|
||||
const float widthSize) const;
|
||||
float getTrailingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize);
|
||||
float getMarginForAxis(const YGFlexDirection axis, const float widthSize);
|
||||
const float widthSize) const;
|
||||
float getMarginForAxis(const YGFlexDirection axis, const float widthSize) const;
|
||||
// Setters
|
||||
|
||||
void setContext(void* context);
|
||||
@@ -106,13 +106,13 @@ struct YGNode {
|
||||
void setMeasureFunc(YGMeasureFunc measureFunc);
|
||||
void setBaseLineFunc(YGBaselineFunc baseLineFunc);
|
||||
void setDirtiedFunc(YGDirtiedFunc dirtiedFunc);
|
||||
void setStyle(YGStyle style);
|
||||
void setStyle(const YGStyle& style);
|
||||
void setStyleFlexDirection(YGFlexDirection direction);
|
||||
void setStyleAlignContent(YGAlign alignContent);
|
||||
void setLayout(YGLayout layout);
|
||||
void setLayout(const YGLayout& layout);
|
||||
void setLineIndex(uint32_t lineIndex);
|
||||
void setParent(YGNodeRef parent);
|
||||
void setChildren(YGVector children);
|
||||
void setChildren(const YGVector& children);
|
||||
void setNextChild(YGNodeRef nextChild);
|
||||
void setConfig(YGConfigRef config);
|
||||
void setDirty(bool isDirty);
|
||||
|
@@ -39,10 +39,12 @@ static void appendFormatedString(string* str, const char* fmt, ...) {
|
||||
str->append(result);
|
||||
}
|
||||
|
||||
static void
|
||||
appendFloatIfNotUndefined(string* base, const string key, const float num) {
|
||||
if (!YGFloatIsUndefined(num)) {
|
||||
appendFormatedString(base, "%s: %g; ", key.c_str(), num);
|
||||
static void appendFloatOptionalIfDefined(
|
||||
string* base,
|
||||
const string key,
|
||||
const YGFloatOptional num) {
|
||||
if (!num.isUndefined()) {
|
||||
appendFormatedString(base, "%s: %g; ", key.c_str(), num.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +72,10 @@ appendNumberIfNotAuto(string* base, const string& key, const YGValue number) {
|
||||
|
||||
static void
|
||||
appendNumberIfNotZero(string* base, const string& str, const YGValue number) {
|
||||
if (!YGFloatsEqual(number.value, 0)) {
|
||||
|
||||
if (number.unit == YGUnitAuto) {
|
||||
base->append(str + ": auto; ");
|
||||
} else if (!YGFloatsEqual(number.value, 0)) {
|
||||
appendNumberIfNotUndefined(base, str, number);
|
||||
}
|
||||
}
|
||||
@@ -152,10 +157,11 @@ void YGNodeToString(
|
||||
appendFormatedString(
|
||||
str, "align-self: %s; ", YGAlignToString(node->getStyle().alignSelf));
|
||||
}
|
||||
appendFloatIfNotUndefined(str, "flex-grow", node->getStyle().flexGrow);
|
||||
appendFloatIfNotUndefined(str, "flex-shrink", node->getStyle().flexShrink);
|
||||
appendFloatOptionalIfDefined(str, "flex-grow", node->getStyle().flexGrow);
|
||||
appendFloatOptionalIfDefined(
|
||||
str, "flex-shrink", node->getStyle().flexShrink);
|
||||
appendNumberIfNotAuto(str, "flex-basis", node->getStyle().flexBasis);
|
||||
appendFloatIfNotUndefined(str, "flex", node->getStyle().flex);
|
||||
appendFloatOptionalIfDefined(str, "flex", node->getStyle().flex);
|
||||
|
||||
if (node->getStyle().flexWrap != YGNode().getStyle().flexWrap) {
|
||||
appendFormatedString(
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "YGStyle.h"
|
||||
|
||||
const YGValue kYGValueUndefined = {YGUndefined, YGUnitUndefined};
|
||||
const YGValue kYGValueUndefined = {0, YGUnitUndefined};
|
||||
|
||||
const YGValue kYGValueAuto = {YGUndefined, YGUnitAuto};
|
||||
|
||||
@@ -39,10 +39,10 @@ YGStyle::YGStyle()
|
||||
flexWrap(YGWrapNoWrap),
|
||||
overflow(YGOverflowVisible),
|
||||
display(YGDisplayFlex),
|
||||
flex(YGUndefined),
|
||||
flexGrow(YGUndefined),
|
||||
flexShrink(YGUndefined),
|
||||
flexBasis(kYGValueAuto),
|
||||
flex(YGFloatOptional()),
|
||||
flexGrow(YGFloatOptional()),
|
||||
flexShrink(YGFloatOptional()),
|
||||
flexBasis({0, YGUnitAuto}),
|
||||
margin(kYGDefaultEdgeValuesUnit),
|
||||
position(kYGDefaultEdgeValuesUnit),
|
||||
padding(kYGDefaultEdgeValuesUnit),
|
||||
@@ -69,19 +69,26 @@ bool YGStyle::operator==(const YGStyle& style) {
|
||||
YGValueArrayEqual(minDimensions, style.minDimensions) &&
|
||||
YGValueArrayEqual(maxDimensions, style.maxDimensions);
|
||||
|
||||
if (!(YGFloatIsUndefined(flex) && YGFloatIsUndefined(style.flex))) {
|
||||
areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex;
|
||||
areNonFloatValuesEqual =
|
||||
areNonFloatValuesEqual && flex.isUndefined() == style.flex.isUndefined();
|
||||
if (areNonFloatValuesEqual && !flex.isUndefined() &&
|
||||
!style.flex.isUndefined()) {
|
||||
areNonFloatValuesEqual =
|
||||
areNonFloatValuesEqual && flex.getValue() == style.flex.getValue();
|
||||
}
|
||||
|
||||
if (!(YGFloatIsUndefined(flexGrow) && YGFloatIsUndefined(style.flexGrow))) {
|
||||
areNonFloatValuesEqual =
|
||||
areNonFloatValuesEqual && flexGrow == style.flexGrow;
|
||||
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||
flexGrow.isUndefined() == style.flexGrow.isUndefined();
|
||||
if (areNonFloatValuesEqual && !flexGrow.isUndefined()) {
|
||||
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||
flexGrow.getValue() == style.flexGrow.getValue();
|
||||
}
|
||||
|
||||
if (!(YGFloatIsUndefined(flexShrink) &&
|
||||
YGFloatIsUndefined(style.flexShrink))) {
|
||||
areNonFloatValuesEqual =
|
||||
areNonFloatValuesEqual && flexShrink == style.flexShrink;
|
||||
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||
flexShrink.isUndefined() == style.flexShrink.isUndefined();
|
||||
if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) {
|
||||
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||
flexShrink.getValue() == style.flexShrink.getValue();
|
||||
}
|
||||
|
||||
if (!(YGFloatIsUndefined(aspectRatio) &&
|
||||
|
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "YGFloatOptional.h"
|
||||
#include "Yoga-internal.h"
|
||||
#include "Yoga.h"
|
||||
|
||||
@@ -20,9 +21,9 @@ struct YGStyle {
|
||||
YGWrap flexWrap;
|
||||
YGOverflow overflow;
|
||||
YGDisplay display;
|
||||
float flex;
|
||||
float flexGrow;
|
||||
float flexShrink;
|
||||
YGFloatOptional flex;
|
||||
YGFloatOptional flexGrow;
|
||||
YGFloatOptional flexShrink;
|
||||
YGValue flexBasis;
|
||||
std::array<YGValue, YGEdgeCount> margin;
|
||||
std::array<YGValue, YGEdgeCount> position;
|
||||
|
364
yoga/Yoga.cpp
364
yoga/Yoga.cpp
@@ -6,13 +6,13 @@
|
||||
*/
|
||||
|
||||
#include "Yoga.h"
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include "Utils.h"
|
||||
#include "YGNode.h"
|
||||
#include "YGNodePrint.h"
|
||||
#include "Yoga-internal.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <float.h>
|
||||
|
||||
@@ -295,8 +295,8 @@ static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) {
|
||||
}
|
||||
|
||||
void YGNodeFree(const YGNodeRef node) {
|
||||
if (node->getParent()) {
|
||||
node->getParent()->removeChild(node);
|
||||
if (YGNodeRef parent = node->getParent()) {
|
||||
parent->removeChild(node);
|
||||
node->setParent(nullptr);
|
||||
}
|
||||
|
||||
@@ -477,6 +477,48 @@ void YGNodeRemoveAllChildren(const YGNodeRef parent) {
|
||||
parent->markDirtyAndPropogate();
|
||||
}
|
||||
|
||||
static void YGNodeSetChildrenInternal(YGNodeRef const parent, const std::vector<YGNodeRef> &children)
|
||||
{
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
if (children.size() == 0) {
|
||||
if (YGNodeGetChildCount(parent) > 0) {
|
||||
for (YGNodeRef const child : parent->getChildren()) {
|
||||
child->setLayout(YGLayout());
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
parent->setChildren(YGVector());
|
||||
parent->markDirtyAndPropogate();
|
||||
}
|
||||
} else {
|
||||
if (YGNodeGetChildCount(parent) > 0) {
|
||||
for (YGNodeRef const oldChild : parent->getChildren()) {
|
||||
// Our new children may have nodes in common with the old children. We don't reset these common nodes.
|
||||
if (std::find(children.begin(), children.end(), oldChild) == children.end()) {
|
||||
oldChild->setLayout(YGLayout());
|
||||
oldChild->setParent(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
parent->setChildren(children);
|
||||
for (YGNodeRef child : children) {
|
||||
child->setParent(parent);
|
||||
}
|
||||
parent->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
void YGNodeSetChildren(YGNodeRef const parent, const YGNodeRef c[], const uint32_t count) {
|
||||
const YGVector children = {c, c + count};
|
||||
YGNodeSetChildrenInternal(parent, children);
|
||||
}
|
||||
|
||||
void YGNodeSetChildren(YGNodeRef const parent, const std::vector<YGNodeRef> &children)
|
||||
{
|
||||
YGNodeSetChildrenInternal(parent, children);
|
||||
}
|
||||
|
||||
YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index) {
|
||||
if (index < node->getChildren().size()) {
|
||||
return node->getChild(index);
|
||||
@@ -510,16 +552,16 @@ void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode) {
|
||||
}
|
||||
|
||||
float YGNodeStyleGetFlexGrow(const YGNodeRef node) {
|
||||
return YGFloatIsUndefined(node->getStyle().flexGrow)
|
||||
return node->getStyle().flexGrow.isUndefined()
|
||||
? kDefaultFlexGrow
|
||||
: node->getStyle().flexGrow;
|
||||
: node->getStyle().flexGrow.getValue();
|
||||
}
|
||||
|
||||
float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
return YGFloatIsUndefined(node->getStyle().flexShrink)
|
||||
return node->getStyle().flexShrink.isUndefined()
|
||||
? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink
|
||||
: kDefaultFlexShrink)
|
||||
: node->getStyle().flexShrink;
|
||||
: node->getStyle().flexShrink.getValue();
|
||||
}
|
||||
|
||||
#define YG_NODE_STYLE_PROPERTY_SETTER_IMPL( \
|
||||
@@ -537,7 +579,7 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
type, name, paramName, instanceName) \
|
||||
void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \
|
||||
YGValue value = { \
|
||||
.value = paramName, \
|
||||
.value = YGFloatSanitize(paramName), \
|
||||
.unit = YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \
|
||||
}; \
|
||||
if ((node->getStyle().instanceName.value != value.value && \
|
||||
@@ -553,7 +595,7 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
void YGNodeStyleSet##name##Percent( \
|
||||
const YGNodeRef node, const type paramName) { \
|
||||
YGValue value = { \
|
||||
.value = paramName, \
|
||||
.value = YGFloatSanitize(paramName), \
|
||||
.unit = \
|
||||
YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPercent, \
|
||||
}; \
|
||||
@@ -620,7 +662,11 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
float, name, paramName, instanceName) \
|
||||
\
|
||||
type YGNodeStyleGet##name(const YGNodeRef node) { \
|
||||
return node->getStyle().instanceName; \
|
||||
YGValue value = node->getStyle().instanceName; \
|
||||
if (value.unit == YGUndefined || value.unit == YGUnitAuto) { \
|
||||
value.value = YGUndefined; \
|
||||
} \
|
||||
return value; \
|
||||
}
|
||||
|
||||
#define YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL( \
|
||||
@@ -636,7 +682,7 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge) { \
|
||||
if (node->getStyle().instanceName[edge].unit != YGUnitAuto) { \
|
||||
YGStyle style = node->getStyle(); \
|
||||
style.instanceName[edge].value = YGUndefined; \
|
||||
style.instanceName[edge].value = 0; \
|
||||
style.instanceName[edge].unit = YGUnitAuto; \
|
||||
node->setStyle(style); \
|
||||
node->markDirtyAndPropogate(); \
|
||||
@@ -648,7 +694,7 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
void YGNodeStyleSet##name( \
|
||||
const YGNodeRef node, const YGEdge edge, const float paramName) { \
|
||||
YGValue value = { \
|
||||
.value = paramName, \
|
||||
.value = YGFloatSanitize(paramName), \
|
||||
.unit = YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \
|
||||
}; \
|
||||
if ((node->getStyle().instanceName[edge].value != value.value && \
|
||||
@@ -664,7 +710,7 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
void YGNodeStyleSet##name##Percent( \
|
||||
const YGNodeRef node, const YGEdge edge, const float paramName) { \
|
||||
YGValue value = { \
|
||||
.value = paramName, \
|
||||
.value = YGFloatSanitize(paramName), \
|
||||
.unit = \
|
||||
YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPercent, \
|
||||
}; \
|
||||
@@ -680,28 +726,11 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
|
||||
\
|
||||
WIN_STRUCT(type) \
|
||||
YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge) { \
|
||||
return WIN_STRUCT_REF(node->getStyle().instanceName[edge]); \
|
||||
}
|
||||
|
||||
#define YG_NODE_STYLE_EDGE_PROPERTY_IMPL(type, name, paramName, instanceName) \
|
||||
void YGNodeStyleSet##name( \
|
||||
const YGNodeRef node, const YGEdge edge, const float paramName) { \
|
||||
YGValue value = { \
|
||||
.value = paramName, \
|
||||
.unit = YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \
|
||||
}; \
|
||||
if ((node->getStyle().instanceName[edge].value != value.value && \
|
||||
value.unit != YGUnitUndefined) || \
|
||||
node->getStyle().instanceName[edge].unit != value.unit) { \
|
||||
YGStyle style = node->getStyle(); \
|
||||
style.instanceName[edge] = value; \
|
||||
node->setStyle(style); \
|
||||
node->markDirtyAndPropogate(); \
|
||||
YGValue value = node->getStyle().instanceName[edge]; \
|
||||
if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \
|
||||
value.value = YGUndefined; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
float YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge) { \
|
||||
return node->getStyle().instanceName[edge].value; \
|
||||
return WIN_STRUCT_REF(value); \
|
||||
}
|
||||
|
||||
#define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \
|
||||
@@ -751,16 +780,136 @@ 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_IMPL(float, Flex, flex, flex);
|
||||
YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexGrow, flexGrow, flexGrow);
|
||||
YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexShrink, flexShrink, flexShrink);
|
||||
YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, FlexBasis, flexBasis, flexBasis);
|
||||
// TODO(T26792433): Change the API to accept YGFloatOptional.
|
||||
void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) {
|
||||
if (!YGFloatOptionalFloatEquals(node->getStyle().flex, flex)) {
|
||||
YGStyle style = node->getStyle();
|
||||
if (YGFloatIsUndefined(flex)) {
|
||||
style.flex = YGFloatOptional();
|
||||
} else {
|
||||
style.flex = YGFloatOptional(flex);
|
||||
}
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(T26792433): Change the API to accept YGFloatOptional.
|
||||
float YGNodeStyleGetFlex(const YGNodeRef node) {
|
||||
return node->getStyle().flex.isUndefined() ? YGUndefined
|
||||
: node->getStyle().flex.getValue();
|
||||
}
|
||||
|
||||
// TODO(T26792433): Change the API to accept YGFloatOptional.
|
||||
void YGNodeStyleSetFlexGrow(const YGNodeRef node, const float flexGrow) {
|
||||
if (!YGFloatOptionalFloatEquals(node->getStyle().flexGrow, flexGrow)) {
|
||||
YGStyle style = node->getStyle();
|
||||
if (YGFloatIsUndefined(flexGrow)) {
|
||||
style.flexGrow = YGFloatOptional();
|
||||
} else {
|
||||
style.flexGrow = YGFloatOptional(flexGrow);
|
||||
}
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(T26792433): Change the API to accept YGFloatOptional.
|
||||
void YGNodeStyleSetFlexShrink(const YGNodeRef node, const float flexShrink) {
|
||||
if (!YGFloatOptionalFloatEquals(node->getStyle().flexShrink, flexShrink)) {
|
||||
YGStyle style = node->getStyle();
|
||||
if (YGFloatIsUndefined(flexShrink)) {
|
||||
style.flexShrink = YGFloatOptional();
|
||||
} else {
|
||||
style.flexShrink = YGFloatOptional(flexShrink);
|
||||
}
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
YGValue YGNodeStyleGetFlexBasis(const YGNodeRef node) {
|
||||
YGValue flexBasis = node->getStyle().flexBasis;
|
||||
if (flexBasis.unit == YGUnitUndefined || flexBasis.unit == YGUnitAuto) {
|
||||
// TODO(T26792433): Get rid off the use of YGUndefined at client side
|
||||
flexBasis.value = YGUndefined;
|
||||
}
|
||||
return flexBasis;
|
||||
}
|
||||
|
||||
void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) {
|
||||
YGValue value = {
|
||||
.value = YGFloatSanitize(flexBasis),
|
||||
.unit = YGFloatIsUndefined(flexBasis) ? YGUnitUndefined : YGUnitPoint,
|
||||
};
|
||||
if ((node->getStyle().flexBasis.value != value.value &&
|
||||
value.unit != YGUnitUndefined) ||
|
||||
node->getStyle().flexBasis.unit != value.unit) {
|
||||
YGStyle style = node->getStyle();
|
||||
style.flexBasis = value;
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
void YGNodeStyleSetFlexBasisPercent(
|
||||
const YGNodeRef node,
|
||||
const float flexBasisPercent) {
|
||||
if (node->getStyle().flexBasis.value != flexBasisPercent ||
|
||||
node->getStyle().flexBasis.unit != YGUnitPercent) {
|
||||
YGStyle style = node->getStyle();
|
||||
style.flexBasis.value = YGFloatSanitize(flexBasisPercent);
|
||||
style.flexBasis.unit =
|
||||
YGFloatIsUndefined(flexBasisPercent) ? YGUnitAuto : YGUnitPercent;
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) {
|
||||
if (node->getStyle().flexBasis.unit != YGUnitAuto) {
|
||||
YGStyle style = node->getStyle();
|
||||
style.flexBasis.value = 0;
|
||||
style.flexBasis.unit = YGUnitAuto;
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Position, position, position);
|
||||
YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Margin, margin, margin);
|
||||
YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Margin, margin);
|
||||
YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Padding, padding, padding);
|
||||
YG_NODE_STYLE_EDGE_PROPERTY_IMPL(float, Border, border, border);
|
||||
|
||||
// TODO(T26792433): Change the API to accept YGFloatOptional.
|
||||
void YGNodeStyleSetBorder(
|
||||
const YGNodeRef node,
|
||||
const YGEdge edge,
|
||||
const float border) {
|
||||
YGValue value = {
|
||||
.value = YGFloatSanitize(border),
|
||||
.unit = YGFloatIsUndefined(border) ? YGUnitUndefined : YGUnitPoint,
|
||||
};
|
||||
if ((node->getStyle().border[edge].value != value.value &&
|
||||
value.unit != YGUnitUndefined) ||
|
||||
node->getStyle().border[edge].unit != value.unit) {
|
||||
YGStyle style = node->getStyle();
|
||||
style.border[edge] = value;
|
||||
node->setStyle(style);
|
||||
node->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
|
||||
float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) {
|
||||
if (node->getStyle().border[edge].unit == YGUnitUndefined ||
|
||||
node->getStyle().border[edge].unit == YGUnitAuto) {
|
||||
// TODO(T26792433): Rather than returning YGUndefined, change the api to
|
||||
// return YGFloatOptional.
|
||||
return YGUndefined;
|
||||
}
|
||||
|
||||
return node->getStyle().border[edge].value;
|
||||
}
|
||||
|
||||
YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Width, width, dimensions[YGDimensionWidth]);
|
||||
YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Height, height, dimensions[YGDimensionHeight]);
|
||||
@@ -785,6 +934,10 @@ YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Margin, margin);
|
||||
YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Border, border);
|
||||
YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Padding, padding);
|
||||
|
||||
bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node) {
|
||||
return node->getLayout().doesLegacyStretchFlagAffectsLayout;
|
||||
}
|
||||
|
||||
uint32_t gCurrentGenerationCount = 0;
|
||||
|
||||
bool YGLayoutNodeInternal(const YGNodeRef node,
|
||||
@@ -939,15 +1092,15 @@ static float YGNodeBoundAxisWithinMinAndMax(const YGNodeRef node,
|
||||
float max = YGUndefined;
|
||||
|
||||
if (YGFlexDirectionIsColumn(axis)) {
|
||||
min = YGResolveValue(
|
||||
node->getStyle().minDimensions[YGDimensionHeight], axisSize);
|
||||
max = YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight], axisSize);
|
||||
min = YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().minDimensions[YGDimensionHeight], axisSize));
|
||||
max = YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight], axisSize));
|
||||
} else if (YGFlexDirectionIsRow(axis)) {
|
||||
min = YGResolveValue(
|
||||
node->getStyle().minDimensions[YGDimensionWidth], axisSize);
|
||||
max = YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth], axisSize);
|
||||
min = YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().minDimensions[YGDimensionWidth], axisSize));
|
||||
max = YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth], axisSize));
|
||||
}
|
||||
|
||||
float boundValue = value;
|
||||
@@ -993,8 +1146,8 @@ static void YGConstrainMaxSizeForMode(const YGNodeRef node,
|
||||
YGMeasureMode *mode,
|
||||
float *size) {
|
||||
const float maxSize =
|
||||
YGResolveValue(
|
||||
node->getStyle().maxDimensions[dim[axis]], parentAxisSize) +
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().maxDimensions[dim[axis]], parentAxisSize)) +
|
||||
node->getMarginForAxis(axis, parentWidth);
|
||||
switch (*mode) {
|
||||
case YGMeasureModeExactly:
|
||||
@@ -1032,7 +1185,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
|
||||
YGMeasureMode childHeightMeasureMode;
|
||||
|
||||
const float resolvedFlexBasis =
|
||||
YGResolveValue(child->resolveFlexBasisPtr(), mainAxisParentSize);
|
||||
YGUnwrapFloatOptional(YGResolveValue(child->resolveFlexBasisPtr(), mainAxisParentSize));
|
||||
const bool isRowStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, parentWidth);
|
||||
const bool isColumnStyleDimDefined =
|
||||
YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, parentHeight);
|
||||
@@ -1050,14 +1203,14 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
|
||||
} else if (isMainAxisRow && isRowStyleDimDefined) {
|
||||
// The width is definite, so use that as the flex basis.
|
||||
child->setLayoutComputedFlexBasis(YGFloatMax(
|
||||
YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionWidth), parentWidth),
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionWidth), parentWidth)),
|
||||
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth)));
|
||||
} else if (!isMainAxisRow && isColumnStyleDimDefined) {
|
||||
// The height is definite, so use that as the flex basis.
|
||||
child->setLayoutComputedFlexBasis(YGFloatMax(
|
||||
YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionHeight), parentHeight),
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionHeight), parentHeight)),
|
||||
YGNodePaddingAndBorderForAxis(
|
||||
child, YGFlexDirectionColumn, parentWidth)));
|
||||
} else {
|
||||
@@ -1075,15 +1228,15 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
|
||||
|
||||
if (isRowStyleDimDefined) {
|
||||
childWidth =
|
||||
YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionWidth), parentWidth) +
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionWidth), parentWidth)) +
|
||||
marginRow;
|
||||
childWidthMeasureMode = YGMeasureModeExactly;
|
||||
}
|
||||
if (isColumnStyleDimDefined) {
|
||||
childHeight =
|
||||
YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionHeight), parentHeight) +
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
child->getResolvedDimension(YGDimensionHeight), parentHeight)) +
|
||||
marginColumn;
|
||||
childHeightMeasureMode = YGMeasureModeExactly;
|
||||
}
|
||||
@@ -1200,7 +1353,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||
|
||||
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) {
|
||||
childWidth =
|
||||
YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width) +
|
||||
YGUnwrapFloatOptional(YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width)) +
|
||||
marginRow;
|
||||
} else {
|
||||
// If the child doesn't have a specified width, compute the width based
|
||||
@@ -1219,7 +1372,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||
|
||||
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) {
|
||||
childHeight =
|
||||
YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height) +
|
||||
YGUnwrapFloatOptional(YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height)) +
|
||||
marginColumn;
|
||||
} else {
|
||||
// If the child doesn't have a specified height, compute the height
|
||||
@@ -1556,15 +1709,16 @@ static float YGNodeCalculateAvailableInnerDim(
|
||||
if (!YGFloatIsUndefined(availableInnerDim)) {
|
||||
// We want to make sure our available height does not violate min and max
|
||||
// constraints
|
||||
const float minInnerDim =
|
||||
YGFloatIsUndefined(YGResolveValue(
|
||||
node->getStyle().minDimensions[dimension], parentDim))
|
||||
const YGFloatOptional minDimensionOptional = YGResolveValue(node->getStyle().minDimensions[dimension], parentDim);
|
||||
const float minInnerDim = minDimensionOptional.isUndefined()
|
||||
? 0.0f
|
||||
: YGResolveValue(node->getStyle().minDimensions[dimension], parentDim) -
|
||||
paddingAndBorder;
|
||||
const float maxInnerDim =
|
||||
YGResolveValue(node->getStyle().maxDimensions[dimension], parentDim) -
|
||||
paddingAndBorder;
|
||||
: minDimensionOptional.getValue() - paddingAndBorder;
|
||||
|
||||
const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions[dimension], parentDim) ;
|
||||
|
||||
const float maxInnerDim = maxDimensionOptional.isUndefined()
|
||||
? FLT_MAX
|
||||
: maxDimensionOptional.getValue() - paddingAndBorder;
|
||||
availableInnerDim =
|
||||
YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim);
|
||||
}
|
||||
@@ -1853,9 +2007,9 @@ static float YGDistributeFreeSpaceSecondPass(
|
||||
: YGMeasureModeAtMost;
|
||||
} else {
|
||||
childCrossSize =
|
||||
YGResolveValue(
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
currentRelativeChild->getResolvedDimension(dim[crossAxis]),
|
||||
availableInnerCrossDim) +
|
||||
availableInnerCrossDim)) +
|
||||
marginCross;
|
||||
const bool isLoosePercentageMeasurement =
|
||||
currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit ==
|
||||
@@ -2096,12 +2250,12 @@ static void YGJustifyMainAxis(
|
||||
if (measureModeMainDim == YGMeasureModeAtMost &&
|
||||
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||
if (style.minDimensions[dim[mainAxis]].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(YGResolveValue(
|
||||
style.minDimensions[dim[mainAxis]], mainAxisParentSize))) {
|
||||
!YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisParentSize)
|
||||
.isUndefined()) {
|
||||
collectedFlexItemsValues.remainingFreeSpace = YGFloatMax(
|
||||
0,
|
||||
YGResolveValue(
|
||||
style.minDimensions[dim[mainAxis]], mainAxisParentSize) -
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
style.minDimensions[dim[mainAxis]], mainAxisParentSize)) -
|
||||
(availableInnerMainDim -
|
||||
collectedFlexItemsValues.remainingFreeSpace));
|
||||
} else {
|
||||
@@ -2459,20 +2613,17 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
node->getMarginForAxis(YGFlexDirectionColumn, parentWidth);
|
||||
|
||||
const float minInnerWidth =
|
||||
YGResolveValue(
|
||||
node->getStyle().minDimensions[YGDimensionWidth], parentWidth) -
|
||||
YGUnwrapFloatOptional(YGResolveValue(node->getStyle().minDimensions[YGDimensionWidth], parentWidth)) -
|
||||
paddingAndBorderAxisRow;
|
||||
const float maxInnerWidth =
|
||||
YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth) -
|
||||
YGUnwrapFloatOptional(YGResolveValue(node->getStyle().maxDimensions[YGDimensionWidth], parentWidth)) -
|
||||
paddingAndBorderAxisRow;
|
||||
const float minInnerHeight =
|
||||
YGResolveValue(
|
||||
node->getStyle().minDimensions[YGDimensionHeight], parentHeight) -
|
||||
YGUnwrapFloatOptional(YGResolveValue(node->getStyle().minDimensions[YGDimensionHeight], parentHeight)) -
|
||||
paddingAndBorderAxisColumn;
|
||||
const float maxInnerHeight =
|
||||
YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight) -
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight)) -
|
||||
paddingAndBorderAxisColumn;
|
||||
|
||||
const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight;
|
||||
@@ -3601,15 +3752,15 @@ void YGNodeCalculateLayout(
|
||||
YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
|
||||
if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, parentWidth)) {
|
||||
width =
|
||||
YGResolveValue(
|
||||
node->getResolvedDimension(dim[YGFlexDirectionRow]), parentWidth) +
|
||||
YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getResolvedDimension(dim[YGFlexDirectionRow]), parentWidth)) +
|
||||
node->getMarginForAxis(YGFlexDirectionRow, parentWidth);
|
||||
widthMeasureMode = YGMeasureModeExactly;
|
||||
} else if (!YGFloatIsUndefined(YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth],
|
||||
parentWidth))) {
|
||||
width = YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth);
|
||||
} else if (!YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth)
|
||||
.isUndefined()) {
|
||||
width = YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth));
|
||||
widthMeasureMode = YGMeasureModeAtMost;
|
||||
} else {
|
||||
width = parentWidth;
|
||||
@@ -3620,16 +3771,16 @@ void YGNodeCalculateLayout(
|
||||
float height = YGUndefined;
|
||||
YGMeasureMode heightMeasureMode = YGMeasureModeUndefined;
|
||||
if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, parentHeight)) {
|
||||
height = YGResolveValue(
|
||||
height = YGUnwrapFloatOptional(YGResolveValue(
|
||||
node->getResolvedDimension(dim[YGFlexDirectionColumn]),
|
||||
parentHeight) +
|
||||
parentHeight)) +
|
||||
node->getMarginForAxis(YGFlexDirectionColumn, parentWidth);
|
||||
heightMeasureMode = YGMeasureModeExactly;
|
||||
} else if (!YGFloatIsUndefined(YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight],
|
||||
parentHeight))) {
|
||||
height = YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight);
|
||||
} else if (!YGResolveValue(
|
||||
node->getStyle().maxDimensions[YGDimensionHeight],
|
||||
parentHeight)
|
||||
.isUndefined()) {
|
||||
height = YGUnwrapFloatOptional(YGResolveValue(node->getStyle().maxDimensions[YGDimensionHeight], parentHeight));
|
||||
heightMeasureMode = YGMeasureModeAtMost;
|
||||
} else {
|
||||
height = parentHeight;
|
||||
@@ -3729,6 +3880,12 @@ void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) {
|
||||
}
|
||||
}
|
||||
|
||||
void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
const YGConfigRef config,
|
||||
const bool shouldDiffLayout) {
|
||||
config->shouldDiffLayoutWithoutLegacyStretchBehaviour = shouldDiffLayout;
|
||||
}
|
||||
|
||||
static void YGVLog(const YGConfigRef config,
|
||||
const YGNodeRef node,
|
||||
YGLogLevel level,
|
||||
@@ -3810,3 +3967,18 @@ void *YGConfigGetContext(const YGConfigRef config) {
|
||||
void YGConfigSetNodeClonedFunc(const YGConfigRef config, const YGNodeClonedFunc callback) {
|
||||
config->cloneNodeCallback = callback;
|
||||
}
|
||||
|
||||
static void YGTraverseChildrenPreOrder(const YGVector& children, const std::function<void(YGNodeRef node)>& f) {
|
||||
for (YGNodeRef node : children) {
|
||||
f(node);
|
||||
YGTraverseChildrenPreOrder(node->getChildren(), f);
|
||||
}
|
||||
}
|
||||
|
||||
void YGTraversePreOrder(YGNodeRef const node, std::function<void(YGNodeRef node)>&& f) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
f(node);
|
||||
YGTraverseChildrenPreOrder(node->getChildren(), f);
|
||||
}
|
||||
|
19
yoga/Yoga.h
19
yoga/Yoga.h
@@ -84,6 +84,7 @@ WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node);
|
||||
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeSetChildren(YGNodeRef const parent, const YGNodeRef children[], const uint32_t count);
|
||||
|
||||
WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
|
||||
const float availableWidth,
|
||||
@@ -190,7 +191,6 @@ 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);
|
||||
|
||||
YG_NODE_STYLE_PROPERTY(float, Flex, flex);
|
||||
YG_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow);
|
||||
YG_NODE_STYLE_PROPERTY(float, FlexShrink, flexShrink);
|
||||
@@ -232,6 +232,7 @@ YG_NODE_LAYOUT_PROPERTY(float, Width);
|
||||
YG_NODE_LAYOUT_PROPERTY(float, Height);
|
||||
YG_NODE_LAYOUT_PROPERTY(YGDirection, Direction);
|
||||
YG_NODE_LAYOUT_PROPERTY(bool, HadOverflow);
|
||||
bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node);
|
||||
|
||||
// Get the computed values for these nodes after performing layout. If they were set using
|
||||
// point values then the returned value will be the same as YGNodeStyleGetXXX. However if
|
||||
@@ -249,10 +250,12 @@ WIN_EXPORT void YGAssertWithNode(const YGNodeRef node, const bool condition, con
|
||||
WIN_EXPORT void YGAssertWithConfig(const YGConfigRef config,
|
||||
const bool condition,
|
||||
const char *message);
|
||||
|
||||
// Set this to number of pixels in 1 point to round calculation results
|
||||
// If you want to avoid rounding - set PointScaleFactor to 0
|
||||
WIN_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInPoint);
|
||||
void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
const YGConfigRef config,
|
||||
const bool shouldDiffLayout);
|
||||
|
||||
// Yoga previously had an error where containers would take the maximum space possible instead of
|
||||
// the minimum
|
||||
@@ -296,3 +299,15 @@ WIN_EXPORT float YGRoundValueToPixelGrid(
|
||||
const bool forceFloor);
|
||||
|
||||
YG_EXTERN_C_END
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
// Calls f on each node in the tree including the given node argument.
|
||||
extern void YGTraversePreOrder(YGNodeRef const node, std::function<void(YGNodeRef node)>&& f);
|
||||
|
||||
extern void YGNodeSetChildren(YGNodeRef const parent, const std::vector<YGNodeRef> &children);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user