Add YGLayoutGetMargin

Summary:
Fix #326. I'll open another PR once this one gets accepted to add support for `YGLayoutGetBorder` 👌
Closes https://github.com/facebook/yoga/pull/335

Reviewed By: gkassabli

Differential Revision: D4409399

Pulled By: emilsjolander

fbshipit-source-id: 8153f6701cab60b55a485f6d2e0b9f7767481090
This commit is contained in:
Maël Nison
2017-01-15 15:16:10 -08:00
committed by Facebook Github Bot
parent 498a5980e8
commit d70f289e73
16 changed files with 288 additions and 29 deletions

View File

@@ -312,6 +312,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern float YGNodeLayoutGetHeight(YGNodeHandle node); public static extern float YGNodeLayoutGetHeight(YGNodeHandle node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern float YGNodeLayoutGetMargin(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern float YGNodeLayoutGetPadding(YGNodeHandle node, YogaEdge edge); public static extern float YGNodeLayoutGetPadding(YGNodeHandle node, YogaEdge edge);

View File

@@ -452,6 +452,54 @@ namespace Facebook.Yoga
} }
} }
public float LayoutMarginLeft
{
get
{
return Native.YGNodeLayoutGetMargin(_ygNode, YogaEdge.Left);
}
}
public float LayoutMarginTop
{
get
{
return Native.YGNodeLayoutGetMargin(_ygNode, YogaEdge.Top);
}
}
public float LayoutMarginRight
{
get
{
return Native.YGNodeLayoutGetMargin(_ygNode, YogaEdge.Right);
}
}
public float LayoutMarginBottom
{
get
{
return Native.YGNodeLayoutGetMargin(_ygNode, YogaEdge.Bottom);
}
}
public float LayoutMarginStart
{
get
{
return Native.YGNodeLayoutGetMargin(_ygNode, YogaEdge.Start);
}
}
public float LayoutMarginEnd
{
get
{
return Native.YGNodeLayoutGetMargin(_ygNode, YogaEdge.End);
}
}
public float LayoutPaddingLeft public float LayoutPaddingLeft
{ {
get get

View File

@@ -434,6 +434,23 @@ namespace Facebook.Yoga
}); });
} }
[Test]
public void TestLayoutMargin() {
YogaNode node = new YogaNode();
node.Width = 100;
node.Height = 100;
node.MarginStart = 1;
node.MarginEnd = 2;
node.MarginTop = 3;
node.MarginBottom = 4;
node.CalculateLayout();
Assert.AreEqual(1, node.LayoutMarginLeft);
Assert.AreEqual(2, node.LayoutMarginRight);
Assert.AreEqual(3, node.LayoutMarginTop);
Assert.AreEqual(4, node.LayoutMarginBottom);
}
[Test] [Test]
public void TestLayoutPadding() { public void TestLayoutPadding() {
YogaNode node = new YogaNode(); YogaNode node = new YogaNode();

View File

@@ -70,6 +70,14 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
@DoNotStrip @DoNotStrip
private float mLeft = YogaConstants.UNDEFINED; private float mLeft = YogaConstants.UNDEFINED;
@DoNotStrip @DoNotStrip
private float mMarginLeft = 0;
@DoNotStrip
private float mMarginTop = 0;
@DoNotStrip
private float mMarginRight = 0;
@DoNotStrip
private float mMarginBottom = 0;
@DoNotStrip
private float mPaddingLeft = 0; private float mPaddingLeft = 0;
@DoNotStrip @DoNotStrip
private float mPaddingTop = 0; private float mPaddingTop = 0;
@@ -573,6 +581,26 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
return mHeight; return mHeight;
} }
@Override
public float getLayoutMargin(YogaEdge edge) {
switch (edge) {
case LEFT:
return mMarginLeft;
case TOP:
return mMarginTop;
case RIGHT:
return mMarginRight;
case BOTTOM:
return mMarginBottom;
case START:
return getLayoutDirection() == YogaDirection.RTL ? mMarginRight : mMarginLeft;
case END:
return getLayoutDirection() == YogaDirection.RTL ? mMarginLeft : mMarginRight;
default:
throw new IllegalArgumentException("Cannot get layout margins of multi-edge shorthands");
}
}
@Override @Override
public float getLayoutPadding(YogaEdge edge) { public float getLayoutPadding(YogaEdge edge) {
switch (edge) { switch (edge) {

View File

@@ -82,6 +82,7 @@ public interface YogaNodeAPI<YogaNodeType extends YogaNodeAPI> {
float getLayoutY(); float getLayoutY();
float getLayoutWidth(); float getLayoutWidth();
float getLayoutHeight(); float getLayoutHeight();
float getLayoutMargin(YogaEdge edge);
float getLayoutPadding(YogaEdge edge); float getLayoutPadding(YogaEdge edge);
YogaDirection getLayoutDirection(); YogaDirection getLayoutDirection();
YogaOverflow getOverflow(); YogaOverflow getOverflow();

View File

@@ -30,6 +30,11 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
static auto leftField = obj->getClass()->getField<jfloat>("mLeft"); static auto leftField = obj->getClass()->getField<jfloat>("mLeft");
static auto topField = obj->getClass()->getField<jfloat>("mTop"); static auto topField = obj->getClass()->getField<jfloat>("mTop");
static auto marginLeftField = obj->getClass()->getField<jfloat>("mMarginLeft");
static auto marginTopField = obj->getClass()->getField<jfloat>("mMarginTop");
static auto marginRightField = obj->getClass()->getField<jfloat>("mMarginRight");
static auto marginBottomField = obj->getClass()->getField<jfloat>("mMarginBottom");
static auto paddingLeftField = obj->getClass()->getField<jfloat>("mPaddingLeft"); static auto paddingLeftField = obj->getClass()->getField<jfloat>("mPaddingLeft");
static auto paddingTopField = obj->getClass()->getField<jfloat>("mPaddingTop"); static auto paddingTopField = obj->getClass()->getField<jfloat>("mPaddingTop");
static auto paddingRightField = obj->getClass()->getField<jfloat>("mPaddingRight"); static auto paddingRightField = obj->getClass()->getField<jfloat>("mPaddingRight");
@@ -40,6 +45,11 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root)); obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root));
obj->setFieldValue(topField, YGNodeLayoutGetTop(root)); obj->setFieldValue(topField, YGNodeLayoutGetTop(root));
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(paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft)); obj->setFieldValue(paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft));
obj->setFieldValue(paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop)); obj->setFieldValue(paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop));
obj->setFieldValue(paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight)); obj->setFieldValue(paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight));

View File

@@ -168,6 +168,23 @@ public class YogaNodeTest {
assertEquals(100, (int) node0.getMaxHeight().value); assertEquals(100, (int) node0.getMaxHeight().value);
} }
@Test
public void testLayoutMargin() {
final YogaNode node = new YogaNode();
node.setWidth(100);
node.setHeight(100);
node.setMargin(YogaEdge.START, 1);
node.setMargin(YogaEdge.END, 2);
node.setMargin(YogaEdge.TOP, 3);
node.setMargin(YogaEdge.BOTTOM, 4);
node.calculateLayout();
assertEquals(1, (int) node.getLayoutMargin(YogaEdge.LEFT));
assertEquals(2, (int) node.getLayoutMargin(YogaEdge.RIGHT));
assertEquals(3, (int) node.getLayoutMargin(YogaEdge.TOP));
assertEquals(4, (int) node.getLayoutMargin(YogaEdge.BOTTOM));
}
@Test @Test
public void testLayoutPadding() { public void testLayoutPadding() {
final YogaNode node = new YogaNode(); final YogaNode node = new YogaNode();

File diff suppressed because one or more lines are too long

View File

@@ -453,3 +453,13 @@ Layout Node::getComputedLayout(void) const
return layout; return layout;
} }
double Node::getComputedMargin(int edge) const
{
return YGNodeLayoutGetMargin(m_node, static_cast<YGEdge>(edge));
}
double Node::getComputedPadding(int edge) const
{
return YGNodeLayoutGetPadding(m_node, static_cast<YGEdge>(edge));
}

View File

@@ -176,6 +176,9 @@ class Node {
Layout getComputedLayout(void) const; Layout getComputedLayout(void) const;
double getComputedMargin(int edge) const;
double getComputedPadding(int edge) const;
private: private:
YGNodeRef m_node; YGNodeRef m_node;

View File

@@ -153,4 +153,7 @@ NBIND_CLASS(Node)
method(getComputedHeight); method(getComputedHeight);
method(getComputedLayout); method(getComputedLayout);
method(getComputedMargin);
method(getComputedPadding);
} }

View File

@@ -0,0 +1,33 @@
/**
* 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.
*/
var Yoga = Yoga || require("../../sources/entry-" + process.env.TEST_ENTRY);
it("margin_start", function () {
var root = Yoga.Node.create();
root.setWidth(100);
root.setHeight(100);
root.setMargin(Yoga.EDGE_START, `10%`);
root.calculateLayout(100, 100, Yoga.DIRECTION_LTR);
console.assert(10 === root.getComputedMargin(Yoga.EDGE_LEFT), "10 === root.getComputedMargin(Yoga.EDGE_LEFT)");
console.assert(0 === root.getComputedMargin(Yoga.EDGE_RIGHT), "0 === root.getComputedMargin(Yoga.EDGE_RIGHT)");
root.calculateLayout(100, 100, Yoga.DIRECTION_RTL);
console.assert(0 === root.getComputedMargin(Yoga.EDGE_LEFT), "0 === root.getComputedMargin(Yoga.EDGE_LEFT)");
console.assert(10 === root.getComputedMargin(Yoga.EDGE_RIGHT), "10 === root.getComputedMargin(Yoga.EDGE_RIGHT)");
if (typeof root !== "undefined")
root.freeRecursive();
(typeof gc !== "undefined") && gc();
console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")");
});

View File

@@ -0,0 +1,33 @@
/**
* 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.
*/
var Yoga = Yoga || require("../../sources/entry-" + process.env.TEST_ENTRY);
it("padding_start", function () {
var root = Yoga.Node.create();
root.setWidth(100);
root.setHeight(100);
root.setPadding(Yoga.EDGE_START, `10%`);
root.calculateLayout(100, 100, Yoga.DIRECTION_LTR);
console.assert(10 === root.getComputedPadding(Yoga.EDGE_LEFT), "10 === root.getComputedPadding(Yoga.EDGE_LEFT)");
console.assert(0 === root.getComputedPadding(Yoga.EDGE_RIGHT), "0 === root.getComputedPadding(Yoga.EDGE_RIGHT)");
root.calculateLayout(100, 100, Yoga.DIRECTION_RTL);
console.assert(0 === root.getComputedPadding(Yoga.EDGE_LEFT), "0 === root.getComputedPadding(Yoga.EDGE_LEFT)");
console.assert(10 === root.getComputedPadding(Yoga.EDGE_RIGHT), "10 === root.getComputedPadding(Yoga.EDGE_RIGHT)");
if (typeof root !== "undefined")
root.freeRecursive();
(typeof gc !== "undefined") && gc();
console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")");
});

View File

@@ -0,0 +1,30 @@
/**
* 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.
*/
#include <yoga/Yoga.h>
#include <gtest/gtest.h>
TEST(YogaTest, computed_layout_margin) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeStyleSetMarginPercent(root, YGEdgeStart, 10);
YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR);
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetMargin(root, YGEdgeLeft));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeRight));
YGNodeCalculateLayout(root, 100, 100, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(root, YGEdgeLeft));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetMargin(root, YGEdgeRight));
YGNodeFreeRecursive(root);
}

View File

@@ -47,6 +47,7 @@ typedef struct YGCachedMeasurement {
typedef struct YGLayout { typedef struct YGLayout {
float position[4]; float position[4];
float dimensions[2]; float dimensions[2];
float margin[6];
float padding[6]; float padding[6];
YGDirection direction; YGDirection direction;
@@ -530,6 +531,29 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) {
return node->layout.instanceName; \ return node->layout.instanceName; \
} }
#define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \
type YGNodeLayoutGet##name(const YGNodeRef node, const YGEdge edge) { \
YG_ASSERT(edge <= YGEdgeEnd, "Cannot get layout properties of multi-edge shorthands"); \
\
if (edge == YGEdgeLeft) { \
if (node->layout.direction == YGDirectionRTL) { \
return node->layout.instanceName[YGEdgeEnd]; \
} else { \
return node->layout.instanceName[YGEdgeStart]; \
} \
} \
\
if (edge == YGEdgeRight) { \
if (node->layout.direction == YGDirectionRTL) { \
return node->layout.instanceName[YGEdgeStart]; \
} else { \
return node->layout.instanceName[YGEdgeEnd]; \
} \
} \
\
return node->layout.instanceName[edge]; \
}
YG_NODE_PROPERTY_IMPL(void *, Context, context, context); YG_NODE_PROPERTY_IMPL(void *, Context, context, context);
YG_NODE_PROPERTY_IMPL(YGPrintFunc, PrintFunc, printFunc, print); YG_NODE_PROPERTY_IMPL(YGPrintFunc, PrintFunc, printFunc, print);
YG_NODE_PROPERTY_IMPL(bool, HasNewLayout, hasNewLayout, hasNewLayout); YG_NODE_PROPERTY_IMPL(bool, HasNewLayout, hasNewLayout, hasNewLayout);
@@ -571,27 +595,8 @@ YG_NODE_LAYOUT_PROPERTY_IMPL(float, Width, dimensions[YGDimensionWidth]);
YG_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[YGDimensionHeight]); YG_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[YGDimensionHeight]);
YG_NODE_LAYOUT_PROPERTY_IMPL(YGDirection, Direction, direction); YG_NODE_LAYOUT_PROPERTY_IMPL(YGDirection, Direction, direction);
float YGNodeLayoutGetPadding(const YGNodeRef node, const YGEdge edge) { YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Margin, margin);
YG_ASSERT(edge <= YGEdgeEnd, "Cannot get layout paddings of multi-edge shorthands"); YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Padding, padding);
if (edge == YGEdgeLeft) {
if (node->layout.direction == YGDirectionRTL) {
return node->layout.padding[YGEdgeEnd];
} else {
return node->layout.padding[YGEdgeStart];
}
}
if (edge == YGEdgeRight) {
if (node->layout.direction == YGDirectionRTL) {
return node->layout.padding[YGEdgeStart];
} else {
return node->layout.padding[YGEdgeEnd];
}
}
return node->layout.padding[edge];
}
uint32_t gCurrentGenerationCount = 0; uint32_t gCurrentGenerationCount = 0;
@@ -1742,6 +1747,23 @@ static void YGNodelayoutImpl(const YGNodeRef node,
const YGDirection direction = YGNodeResolveDirection(node, parentDirection); const YGDirection direction = YGNodeResolveDirection(node, parentDirection);
node->layout.direction = direction; node->layout.direction = direction;
node->layout.margin[YGEdgeStart] =
YGNodeLeadingMargin(node,
YGFlexDirectionResolve(YGFlexDirectionRow, direction),
parentWidth);
node->layout.margin[YGEdgeEnd] =
YGNodeTrailingMargin(node,
YGFlexDirectionResolve(YGFlexDirectionRow, direction),
parentWidth);
node->layout.margin[YGEdgeTop] =
YGNodeLeadingMargin(node,
YGFlexDirectionResolve(YGFlexDirectionColumn, direction),
parentWidth);
node->layout.margin[YGEdgeBottom] =
YGNodeTrailingMargin(node,
YGFlexDirectionResolve(YGFlexDirectionColumn, direction),
parentWidth);
node->layout.padding[YGEdgeStart] = node->layout.padding[YGEdgeStart] =
YGNodeLeadingPadding(node, YGNodeLeadingPadding(node,
YGFlexDirectionResolve(YGFlexDirectionRow, direction), YGFlexDirectionResolve(YGFlexDirectionRow, direction),

View File

@@ -199,6 +199,7 @@ YG_NODE_LAYOUT_PROPERTY(YGDirection, Direction);
// pixel values then the returned value will be the same as YGNodeStyleGetPadding. However if // pixel values then the returned value will be the same as YGNodeStyleGetPadding. However if
// padding was set using a percentage value then the returned value is the computed value used // padding was set using a percentage value then the returned value is the computed value used
// during layout. // during layout.
WIN_EXPORT float YGNodeLayoutGetMargin(const YGNodeRef node, const YGEdge edge);
WIN_EXPORT float YGNodeLayoutGetPadding(const YGNodeRef node, const YGEdge edge); WIN_EXPORT float YGNodeLayoutGetPadding(const YGNodeRef node, const YGEdge edge);
WIN_EXPORT void YGSetLogger(YGLogger logger); WIN_EXPORT void YGSetLogger(YGLogger logger);