Add support for measure mode

This commit is contained in:
Emil Sjolander
2016-01-06 16:56:56 +00:00
parent 68e0b0cc58
commit 7bd6b2b7dd
26 changed files with 237 additions and 45 deletions

View File

@@ -226,7 +226,7 @@ namespace Facebook.CSSLayout.Tests
root.calculateLayout();
markLayoutAppliedForTree(root);
c1.setMeasureFunction((node, width, height) => new MeasureOutput(100, 20));
c1.setMeasureFunction((node, width, widthMode, height, heightMode) => new MeasureOutput(100, 20));
root.calculateLayout();

View File

@@ -25,11 +25,11 @@ public class LayoutEngineTest
const int DIMENSION_HEIGHT = CSSLayout.DIMENSION_HEIGHT;
const int DIMENSION_WIDTH = CSSLayout.DIMENSION_WIDTH;
static readonly MeasureFunction sTestMeasureFunction = (node, width, height) =>
static readonly MeasureFunction sTestMeasureFunction = (node, width, widthMode, height, heightMode) =>
{
TestCSSNode testNode = (TestCSSNode) node;
if (testNode.context.Equals(TestConstants.SMALL_TEXT)) {
if (CSSConstants.IsUndefined(width)) {
if (widthMode == CSSMeasureMode.Undefined) {
width = 10000000;
}
return new MeasureOutput(
@@ -46,14 +46,20 @@ public class LayoutEngineTest
? TestConstants.SMALL_HEIGHT
: TestConstants.BIG_HEIGHT);
} else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) {
if (width > 0) {
if (widthMode != CSSMeasureMode.Undefined) {
return new MeasureOutput(width, width * 2);
} else if (height > 0) {
} else if (heightMode != CSSMeasureMode.Undefined) {
return new MeasureOutput(height * 2, height);
} else {
return new MeasureOutput(99999, 99999);
}
} else if (testNode.context.Equals(TestConstants.MEASURE_WITH_MATCH_PARENT)) {
if (widthMode == CSSMeasureMode.Undefined) {
width = 99999;
}
if (heightMode == CSSMeasureMode.Undefined) {
height = 99999;
}
return new MeasureOutput(width, height);
} else {
throw new Exception("Got unknown test: " + testNode.context);

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2014, 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.
*/
namespace Facebook.CSSLayout
{
public enum CSSMeasureMode
{
Undefined,
Exactly,
AtMost,
}
}

View File

@@ -17,7 +17,7 @@ namespace Facebook.CSSLayout
* Should measure the given node and put the result in the given MeasureOutput.
*/
public delegate MeasureOutput MeasureFunction(CSSNode node, float width, float height);
public delegate MeasureOutput MeasureFunction(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
/**
* A CSS Node. It has a style object you can manipulate at {@link #style}. After calling
@@ -140,13 +140,13 @@ namespace Facebook.CSSLayout
get { return mMeasureFunction != null; }
}
internal MeasureOutput measure(MeasureOutput measureOutput, float width, float height)
internal MeasureOutput measure(MeasureOutput measureOutput, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
{
if (!IsMeasureDefined)
{
throw new Exception("Measure function isn't defined!");
}
return Assertions.assertNotNull(mMeasureFunction)(this, width, height);
return Assertions.assertNotNull(mMeasureFunction)(this, width, widthMode, height, heightMode);
}
/**

View File

@@ -45,6 +45,7 @@
<Compile Include="CSSDirection.cs" />
<Compile Include="CSSFlexDirection.cs" />
<Compile Include="CSSJustify.cs" />
<Compile Include="CSSMeasureMode.cs" />
<Compile Include="CSSLayout.cs" />
<Compile Include="CSSLayoutContext.cs" />
<Compile Include="CSSNode.cs" />
@@ -67,4 +68,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View File

@@ -282,26 +282,40 @@ namespace Facebook.CSSLayout
boolean isResolvedRowDimDefined = (!float.IsNaN(node.layout.dimensions[dim[resolvedRowAxis]]) && node.layout.dimensions[dim[resolvedRowAxis]] >= 0.0);
float width = CSSConstants.Undefined;
CSSMeasureMode widthMode = CSSMeasureMode.Undefined;
if ((!float.IsNaN(node.style.dimensions[dim[resolvedRowAxis]]) && node.style.dimensions[dim[resolvedRowAxis]] >= 0.0)) {
width = node.style.dimensions[DIMENSION_WIDTH];
widthMode = CSSMeasureMode.Exactly;
} else if (isResolvedRowDimDefined) {
width = node.layout.dimensions[dim[resolvedRowAxis]];
widthMode = CSSMeasureMode.Exactly;
} else {
width = parentMaxWidth -
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
widthMode = CSSMeasureMode.AtMost;
}
width -= paddingAndBorderAxisResolvedRow;
if (float.IsNaN(width)) {
widthMode = CSSMeasureMode.Undefined;
}
float height = CSSConstants.Undefined;
CSSMeasureMode heightMode = CSSMeasureMode.Undefined;
if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
height = node.style.dimensions[DIMENSION_HEIGHT];
heightMode = CSSMeasureMode.Exactly;
} else if ((!float.IsNaN(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
height = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]];
heightMode = CSSMeasureMode.Exactly;
} else {
height = parentMaxHeight -
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
heightMode = CSSMeasureMode.AtMost;
}
height -= ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])));
if (float.IsNaN(height)) {
heightMode = CSSMeasureMode.Undefined;
}
// We only need to give a dimension for the text if we haven't got any
// for it computed yet. It can either be from the style attribute or because
@@ -316,7 +330,9 @@ namespace Facebook.CSSLayout
layoutContext.measureOutput,
width,
height
widthMode,
height,
heightMode
);
if (isRowUndefined) {
node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width +