[Issue facebook/css-layout#78]: Implemented alignContent ;
This commit is contained in:
@@ -103,6 +103,7 @@ var JavaTranspiler = {
|
|||||||
.replace('node.style.measure', 'node.measure')
|
.replace('node.style.measure', 'node.measure')
|
||||||
.replace(/\.children\.length/g, '.getChildCount()')
|
.replace(/\.children\.length/g, '.getChildCount()')
|
||||||
.replace(/node.children\[i\]/g, 'node.getChildAt(i)')
|
.replace(/node.children\[i\]/g, 'node.getChildAt(i)')
|
||||||
|
.replace(/node.children\[ii\]/g, 'node.getChildAt(ii)')
|
||||||
.replace(/fmaxf/g, 'Math.max')
|
.replace(/fmaxf/g, 'Math.max')
|
||||||
.replace(/\/\*\([^\/]+\*\/\n/g, '') // remove comments for other languages
|
.replace(/\/\*\([^\/]+\*\/\n/g, '') // remove comments for other languages
|
||||||
.replace(/var\/\*([^\/]+)\*\//g, '$1')
|
.replace(/var\/\*([^\/]+)\*\//g, '$1')
|
||||||
|
110
src/Layout.c
110
src/Layout.c
@@ -35,6 +35,7 @@ static bool eq(float a, float b) {
|
|||||||
|
|
||||||
void init_css_node(css_node_t *node) {
|
void init_css_node(css_node_t *node) {
|
||||||
node->style.align_items = CSS_ALIGN_STRETCH;
|
node->style.align_items = CSS_ALIGN_STRETCH;
|
||||||
|
node->style.align_content = CSS_ALIGN_STRETCH;
|
||||||
|
|
||||||
// Some of the fields default to undefined and not 0
|
// Some of the fields default to undefined and not 0
|
||||||
node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
|
node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
|
||||||
@@ -271,6 +272,10 @@ static css_justify_t getJustifyContent(css_node_t *node) {
|
|||||||
return node->style.justify_content;
|
return node->style.justify_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static css_align_t getAlignContent(css_node_t *node) {
|
||||||
|
return node->style.align_content;
|
||||||
|
}
|
||||||
|
|
||||||
static css_align_t getAlignItem(css_node_t *node, css_node_t *child) {
|
static css_align_t getAlignItem(css_node_t *node, css_node_t *child) {
|
||||||
if (child->style.align_self != CSS_ALIGN_AUTO) {
|
if (child->style.align_self != CSS_ALIGN_AUTO) {
|
||||||
return child->style.align_self;
|
return child->style.align_self;
|
||||||
@@ -492,6 +497,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
|
|||||||
// We aggregate the total dimensions of the container in those two variables
|
// We aggregate the total dimensions of the container in those two variables
|
||||||
float linesCrossDim = 0;
|
float linesCrossDim = 0;
|
||||||
float linesMainDim = 0;
|
float linesMainDim = 0;
|
||||||
|
int linesCount = 0;
|
||||||
while (endLine < node->children_count) {
|
while (endLine < node->children_count) {
|
||||||
// <Loop A> Layout non flexible children and count children by type
|
// <Loop A> Layout non flexible children and count children by type
|
||||||
|
|
||||||
@@ -676,6 +682,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
|
|||||||
|
|
||||||
for (i = startLine; i < endLine; ++i) {
|
for (i = startLine; i < endLine; ++i) {
|
||||||
child = node->get_child(node->context, i);
|
child = node->get_child(node->context, i);
|
||||||
|
child->line_index = linesCount;
|
||||||
|
|
||||||
if (getPositionType(child) == CSS_POSITION_ABSOLUTE &&
|
if (getPositionType(child) == CSS_POSITION_ABSOLUTE &&
|
||||||
isPosDefined(child, leading[mainAxis])) {
|
isPosDefined(child, leading[mainAxis])) {
|
||||||
@@ -770,9 +777,112 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
|
|||||||
|
|
||||||
linesCrossDim += crossDim;
|
linesCrossDim += crossDim;
|
||||||
linesMainDim = fmaxf(linesMainDim, mainDim);
|
linesMainDim = fmaxf(linesMainDim, mainDim);
|
||||||
|
linesCount += 1;
|
||||||
startLine = endLine;
|
startLine = endLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <Loop DD>
|
||||||
|
//
|
||||||
|
// PIERRE: More than one line, we need to layout the crossAxis according to
|
||||||
|
// alignContent.
|
||||||
|
//
|
||||||
|
// Note that we could probably remove <Loop D> and handle the one line case
|
||||||
|
// here too, but for the moment this is safer since it won't interfere with
|
||||||
|
// previously working code.
|
||||||
|
//
|
||||||
|
// See specs:
|
||||||
|
// http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm
|
||||||
|
// section 9.4
|
||||||
|
//
|
||||||
|
if (linesCount > 1 &&
|
||||||
|
(!isUndefined(node->layout.dimensions[dim[crossAxis]])))
|
||||||
|
{
|
||||||
|
float nodeCrossAxisInnerSize = node->layout.dimensions[dim[crossAxis]] -
|
||||||
|
getPaddingAndBorderAxis(node, crossAxis);
|
||||||
|
float remainingCrossDim = nodeCrossAxisInnerSize - linesCrossDim;
|
||||||
|
|
||||||
|
float crossDimAdd = 0;
|
||||||
|
float currentLead = getPaddingAndBorder(node, leading[crossAxis]);
|
||||||
|
|
||||||
|
css_align_t alignContent = getAlignContent(node);
|
||||||
|
if (alignContent == CSS_ALIGN_FLEX_END) {
|
||||||
|
currentLead += remainingCrossDim;
|
||||||
|
}
|
||||||
|
else if (alignContent == CSS_ALIGN_CENTER) {
|
||||||
|
currentLead += remainingCrossDim / 2;
|
||||||
|
}
|
||||||
|
else if (alignContent == CSS_ALIGN_STRETCH) {
|
||||||
|
if (nodeCrossAxisInnerSize > linesCrossDim) {
|
||||||
|
crossDimAdd = (remainingCrossDim / linesCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the first node on the first line
|
||||||
|
for (i = 0; i < node->children_count; ) {
|
||||||
|
int startIndex = i;
|
||||||
|
int lineIndex = -1;
|
||||||
|
|
||||||
|
// get the first child on the current line
|
||||||
|
{
|
||||||
|
child = node->get_child(node->context, i);
|
||||||
|
if (getPositionType(child) != CSS_POSITION_RELATIVE) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lineIndex = child->line_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the line's height and find the endIndex
|
||||||
|
float lineHeight = 0;
|
||||||
|
for (ii = startIndex; ii < node->children_count; ++ii) {
|
||||||
|
child = node->get_child(node->context, ii);
|
||||||
|
if (getPositionType(child) != CSS_POSITION_RELATIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (child->line_index != lineIndex) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isUndefined(child->layout.dimensions[dim[crossAxis]])) {
|
||||||
|
lineHeight = fmaxf(lineHeight,child->layout.dimensions[dim[crossAxis]] +
|
||||||
|
getMarginAxis(child,crossAxis));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int endIndex = ii;
|
||||||
|
lineHeight += crossDimAdd;
|
||||||
|
|
||||||
|
for (ii = startIndex; ii < endIndex; ++ii) {
|
||||||
|
child = node->get_child(node->context, ii);
|
||||||
|
if (getPositionType(child) != CSS_POSITION_RELATIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
css_align_t alignItem = getAlignItem(node, child);
|
||||||
|
float crossPosition = child->layout.position[pos[crossAxis]]; // preserve current position if someting goes wrong with alignItem?
|
||||||
|
if (alignItem == CSS_ALIGN_FLEX_START) {
|
||||||
|
crossPosition = currentLead + getMargin(child,leading[crossAxis]);
|
||||||
|
}
|
||||||
|
else if (alignItem == CSS_ALIGN_FLEX_END) {
|
||||||
|
crossPosition = currentLead + lineHeight -
|
||||||
|
getMargin(child,trailing[crossAxis]) -
|
||||||
|
child->layout.dimensions[dim[crossAxis]];
|
||||||
|
}
|
||||||
|
else if (alignItem == CSS_ALIGN_CENTER) {
|
||||||
|
float childHeight = child->layout.dimensions[dim[crossAxis]];
|
||||||
|
crossPosition = currentLead + ((lineHeight - childHeight)/2);
|
||||||
|
}
|
||||||
|
else if (alignItem == CSS_ALIGN_STRETCH) {
|
||||||
|
crossPosition = currentLead + getMargin(child,leading[crossAxis]);
|
||||||
|
// TODO: Correctly set the height of items with undefined (auto)
|
||||||
|
// crossAxis dimension.
|
||||||
|
}
|
||||||
|
child->layout.position[pos[crossAxis]] = crossPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLead += lineHeight;
|
||||||
|
i = endIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the user didn't specify a width or height, and it has not been set
|
// If the user didn't specify a width or height, and it has not been set
|
||||||
// by the container, then we set it via the children.
|
// by the container, then we set it via the children.
|
||||||
if (isUndefined(node->layout.dimensions[dim[mainAxis]])) {
|
if (isUndefined(node->layout.dimensions[dim[mainAxis]])) {
|
||||||
|
@@ -82,6 +82,7 @@ typedef struct {
|
|||||||
float last_parent_max_width;
|
float last_parent_max_width;
|
||||||
float last_dimensions[2];
|
float last_dimensions[2];
|
||||||
float last_position[2];
|
float last_position[2];
|
||||||
|
|
||||||
} css_layout_t;
|
} css_layout_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -91,6 +92,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
css_flex_direction_t flex_direction;
|
css_flex_direction_t flex_direction;
|
||||||
css_justify_t justify_content;
|
css_justify_t justify_content;
|
||||||
|
css_align_t align_content;
|
||||||
css_align_t align_items;
|
css_align_t align_items;
|
||||||
css_align_t align_self;
|
css_align_t align_self;
|
||||||
css_position_type_t position_type;
|
css_position_type_t position_type;
|
||||||
@@ -119,6 +121,7 @@ typedef struct css_node {
|
|||||||
css_style_t style;
|
css_style_t style;
|
||||||
css_layout_t layout;
|
css_layout_t layout;
|
||||||
int children_count;
|
int children_count;
|
||||||
|
int line_index;
|
||||||
|
|
||||||
css_dim_t (*measure)(void *context, float width);
|
css_dim_t (*measure)(void *context, float width);
|
||||||
void (*print)(void *context);
|
void (*print)(void *context);
|
||||||
|
112
src/Layout.js
112
src/Layout.js
@@ -144,6 +144,13 @@ var computeLayout = (function() {
|
|||||||
return 'flex-start';
|
return 'flex-start';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAlignContent(node) {
|
||||||
|
if ('alignContent' in node.style) {
|
||||||
|
return node.style.alignContent;
|
||||||
|
}
|
||||||
|
return 'stretch';
|
||||||
|
}
|
||||||
|
|
||||||
function getAlignItem(node, child) {
|
function getAlignItem(node, child) {
|
||||||
if ('alignSelf' in child.style) {
|
if ('alignSelf' in child.style) {
|
||||||
return child.style.alignSelf;
|
return child.style.alignSelf;
|
||||||
@@ -376,6 +383,7 @@ var computeLayout = (function() {
|
|||||||
// We aggregate the total dimensions of the container in those two variables
|
// We aggregate the total dimensions of the container in those two variables
|
||||||
var/*float*/ linesCrossDim = 0;
|
var/*float*/ linesCrossDim = 0;
|
||||||
var/*float*/ linesMainDim = 0;
|
var/*float*/ linesMainDim = 0;
|
||||||
|
var/*int*/ linesCount = 0;
|
||||||
while (endLine < node.children.length) {
|
while (endLine < node.children.length) {
|
||||||
// <Loop A> Layout non flexible children and count children by type
|
// <Loop A> Layout non flexible children and count children by type
|
||||||
|
|
||||||
@@ -560,6 +568,7 @@ var computeLayout = (function() {
|
|||||||
|
|
||||||
for (i = startLine; i < endLine; ++i) {
|
for (i = startLine; i < endLine; ++i) {
|
||||||
child = node.children[i];
|
child = node.children[i];
|
||||||
|
child.lineIndex = linesCount;
|
||||||
|
|
||||||
if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&
|
if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&
|
||||||
isPosDefined(child, leading[mainAxis])) {
|
isPosDefined(child, leading[mainAxis])) {
|
||||||
@@ -654,9 +663,112 @@ var computeLayout = (function() {
|
|||||||
|
|
||||||
linesCrossDim += crossDim;
|
linesCrossDim += crossDim;
|
||||||
linesMainDim = fmaxf(linesMainDim, mainDim);
|
linesMainDim = fmaxf(linesMainDim, mainDim);
|
||||||
|
linesCount += 1;
|
||||||
startLine = endLine;
|
startLine = endLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <Loop DD>
|
||||||
|
//
|
||||||
|
// PIERRE: More than one line, we need to layout the crossAxis according to
|
||||||
|
// alignContent.
|
||||||
|
//
|
||||||
|
// Note that we could probably remove <Loop D> and handle the one line case
|
||||||
|
// here too, but for the moment this is safer since it won't interfere with
|
||||||
|
// previously working code.
|
||||||
|
//
|
||||||
|
// See specs:
|
||||||
|
// http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm
|
||||||
|
// section 9.4
|
||||||
|
//
|
||||||
|
if (linesCount > 1 &&
|
||||||
|
(!isUndefined(node.layout[dim[crossAxis]])))
|
||||||
|
{
|
||||||
|
var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] -
|
||||||
|
getPaddingAndBorderAxis(node, crossAxis);
|
||||||
|
var/*float*/ remainingCrossDim = nodeCrossAxisInnerSize - linesCrossDim;
|
||||||
|
|
||||||
|
var/*float*/ crossDimAdd = 0;
|
||||||
|
var/*float*/ currentLead = getPaddingAndBorder(node, leading[crossAxis]);
|
||||||
|
|
||||||
|
var/*css_align_t*/ alignContent = getAlignContent(node);
|
||||||
|
if (alignContent == CSS_ALIGN_FLEX_END) {
|
||||||
|
currentLead += remainingCrossDim;
|
||||||
|
}
|
||||||
|
else if (alignContent == CSS_ALIGN_CENTER) {
|
||||||
|
currentLead += remainingCrossDim / 2;
|
||||||
|
}
|
||||||
|
else if (alignContent == CSS_ALIGN_STRETCH) {
|
||||||
|
if (nodeCrossAxisInnerSize > linesCrossDim) {
|
||||||
|
crossDimAdd = (remainingCrossDim / linesCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the first node on the first line
|
||||||
|
for (i = 0; i < node.children.length; ) {
|
||||||
|
var/*int*/ startIndex = i;
|
||||||
|
var/*int*/ lineIndex = -1;
|
||||||
|
|
||||||
|
// get the first child on the current line
|
||||||
|
{
|
||||||
|
child = node.children[i];
|
||||||
|
if (getPositionType(child) != CSS_POSITION_RELATIVE) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lineIndex = child.lineIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the line's height and find the endIndex
|
||||||
|
var/*float*/ lineHeight = 0;
|
||||||
|
for (ii = startIndex; ii < node.children.length; ++ii) {
|
||||||
|
child = node.children[ii];
|
||||||
|
if (getPositionType(child) != CSS_POSITION_RELATIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (child.lineIndex != lineIndex) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isUndefined(child.layout[dim[crossAxis]])) {
|
||||||
|
lineHeight = fmaxf(lineHeight,child.layout[dim[crossAxis]] +
|
||||||
|
getMarginAxis(child,crossAxis));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var/*int*/ endIndex = ii;
|
||||||
|
lineHeight += crossDimAdd;
|
||||||
|
|
||||||
|
for (ii = startIndex; ii < endIndex; ++ii) {
|
||||||
|
child = node.children[ii];
|
||||||
|
if (getPositionType(child) != CSS_POSITION_RELATIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var/*css_align_t*/ alignItem = getAlignItem(node, child);
|
||||||
|
var/*float*/ crossPosition = child.layout[pos[crossAxis]]; // preserve current position if someting goes wrong with alignItem?
|
||||||
|
if (alignItem == CSS_ALIGN_FLEX_START) {
|
||||||
|
crossPosition = currentLead + getMargin(child,leading[crossAxis]);
|
||||||
|
}
|
||||||
|
else if (alignItem == CSS_ALIGN_FLEX_END) {
|
||||||
|
crossPosition = currentLead + lineHeight -
|
||||||
|
getMargin(child,trailing[crossAxis]) -
|
||||||
|
child.layout[dim[crossAxis]];
|
||||||
|
}
|
||||||
|
else if (alignItem == CSS_ALIGN_CENTER) {
|
||||||
|
var/*float*/ childHeight = child.layout[dim[crossAxis]];
|
||||||
|
crossPosition = currentLead + ((lineHeight - childHeight)/2);
|
||||||
|
}
|
||||||
|
else if (alignItem == CSS_ALIGN_STRETCH) {
|
||||||
|
crossPosition = currentLead + getMargin(child,leading[crossAxis]);
|
||||||
|
// TODO: Correctly set the height of items with undefined (auto)
|
||||||
|
// crossAxis dimension.
|
||||||
|
}
|
||||||
|
child.layout[pos[crossAxis]] = crossPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLead += lineHeight;
|
||||||
|
i = endIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the user didn't specify a width or height, and it has not been set
|
// If the user didn't specify a width or height, and it has not been set
|
||||||
// by the container, then we set it via the children.
|
// by the container, then we set it via the children.
|
||||||
if (isUndefined(node.layout[dim[mainAxis]])) {
|
if (isUndefined(node.layout[dim[mainAxis]])) {
|
||||||
|
@@ -58,6 +58,8 @@ public class CSSNode {
|
|||||||
/*package*/ final CSSLayout layout = new CSSLayout();
|
/*package*/ final CSSLayout layout = new CSSLayout();
|
||||||
/*package*/ final CachedCSSLayout lastLayout = new CachedCSSLayout();
|
/*package*/ final CachedCSSLayout lastLayout = new CachedCSSLayout();
|
||||||
|
|
||||||
|
public int lineIndex = 0;
|
||||||
|
|
||||||
// 4 is kinda arbitrary, but the default of 10 seems really high for an average View.
|
// 4 is kinda arbitrary, but the default of 10 seems really high for an average View.
|
||||||
private final ArrayList<CSSNode> mChildren = new ArrayList<CSSNode>(4);
|
private final ArrayList<CSSNode> mChildren = new ArrayList<CSSNode>(4);
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ public class CSSStyle {
|
|||||||
|
|
||||||
public CSSFlexDirection flexDirection = CSSFlexDirection.COLUMN;
|
public CSSFlexDirection flexDirection = CSSFlexDirection.COLUMN;
|
||||||
public CSSJustify justifyContent = CSSJustify.FLEX_START;
|
public CSSJustify justifyContent = CSSJustify.FLEX_START;
|
||||||
|
public CSSAlign alignContent = CSSAlign.STRETCH;
|
||||||
public CSSAlign alignItems = CSSAlign.STRETCH;
|
public CSSAlign alignItems = CSSAlign.STRETCH;
|
||||||
public CSSAlign alignSelf = CSSAlign.AUTO;
|
public CSSAlign alignSelf = CSSAlign.AUTO;
|
||||||
public CSSPositionType positionType = CSSPositionType.RELATIVE;
|
public CSSPositionType positionType = CSSPositionType.RELATIVE;
|
||||||
|
@@ -260,6 +260,10 @@ public class LayoutEngine {
|
|||||||
return node.style.alignItems;
|
return node.style.alignItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static CSSAlign getAlignContent(CSSNode node) {
|
||||||
|
return node.style.alignContent;
|
||||||
|
}
|
||||||
|
|
||||||
private static CSSJustify getJustifyContent(CSSNode node) {
|
private static CSSJustify getJustifyContent(CSSNode node) {
|
||||||
return node.style.justifyContent;
|
return node.style.justifyContent;
|
||||||
}
|
}
|
||||||
@@ -430,6 +434,7 @@ public class LayoutEngine {
|
|||||||
// We aggregate the total dimensions of the container in those two variables
|
// We aggregate the total dimensions of the container in those two variables
|
||||||
float linesCrossDim = 0;
|
float linesCrossDim = 0;
|
||||||
float linesMainDim = 0;
|
float linesMainDim = 0;
|
||||||
|
int linesCount = 0;
|
||||||
while (endLine < node.getChildCount()) {
|
while (endLine < node.getChildCount()) {
|
||||||
// <Loop A> Layout non flexible children and count children by type
|
// <Loop A> Layout non flexible children and count children by type
|
||||||
|
|
||||||
@@ -614,6 +619,7 @@ public class LayoutEngine {
|
|||||||
|
|
||||||
for (i = startLine; i < endLine; ++i) {
|
for (i = startLine; i < endLine; ++i) {
|
||||||
child = node.getChildAt(i);
|
child = node.getChildAt(i);
|
||||||
|
child.lineIndex = linesCount;
|
||||||
|
|
||||||
if (getPositionType(child) == CSSPositionType.ABSOLUTE &&
|
if (getPositionType(child) == CSSPositionType.ABSOLUTE &&
|
||||||
isPosDefined(child, getLeading(mainAxis))) {
|
isPosDefined(child, getLeading(mainAxis))) {
|
||||||
@@ -708,9 +714,112 @@ public class LayoutEngine {
|
|||||||
|
|
||||||
linesCrossDim = linesCrossDim + crossDim;
|
linesCrossDim = linesCrossDim + crossDim;
|
||||||
linesMainDim = Math.max(linesMainDim, mainDim);
|
linesMainDim = Math.max(linesMainDim, mainDim);
|
||||||
|
linesCount = linesCount + 1;
|
||||||
startLine = endLine;
|
startLine = endLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <Loop DD>
|
||||||
|
//
|
||||||
|
// PIERRE: More than one line, we need to layout the crossAxis according to
|
||||||
|
// alignContent.
|
||||||
|
//
|
||||||
|
// Note that we could probably remove <Loop D> and handle the one line case
|
||||||
|
// here too, but for the moment this is safer since it won't interfere with
|
||||||
|
// previously working code.
|
||||||
|
//
|
||||||
|
// See specs:
|
||||||
|
// http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm
|
||||||
|
// section 9.4
|
||||||
|
//
|
||||||
|
if (linesCount > 1 &&
|
||||||
|
(!CSSConstants.isUndefined(getLayoutDimension(node, getDim(crossAxis)))))
|
||||||
|
{
|
||||||
|
float nodeCrossAxisInnerSize = getLayoutDimension(node, getDim(crossAxis)) -
|
||||||
|
getPaddingAndBorderAxis(node, crossAxis);
|
||||||
|
float remainingCrossDim = nodeCrossAxisInnerSize - linesCrossDim;
|
||||||
|
|
||||||
|
float crossDimAdd = 0;
|
||||||
|
float currentLead = getPaddingAndBorder(node, getLeading(crossAxis));
|
||||||
|
|
||||||
|
CSSAlign alignContent = getAlignContent(node);
|
||||||
|
if (alignContent == CSSAlign.FLEX_END) {
|
||||||
|
currentLead = currentLead + remainingCrossDim;
|
||||||
|
}
|
||||||
|
else if (alignContent == CSSAlign.CENTER) {
|
||||||
|
currentLead = currentLead + remainingCrossDim / 2;
|
||||||
|
}
|
||||||
|
else if (alignContent == CSSAlign.STRETCH) {
|
||||||
|
if (nodeCrossAxisInnerSize > linesCrossDim) {
|
||||||
|
crossDimAdd = (remainingCrossDim / linesCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the first node on the first line
|
||||||
|
for (i = 0; i < node.getChildCount(); ) {
|
||||||
|
int startIndex = i;
|
||||||
|
int lineIndex = -1;
|
||||||
|
|
||||||
|
// get the first child on the current line
|
||||||
|
{
|
||||||
|
child = node.getChildAt(i);
|
||||||
|
if (getPositionType(child) != CSSPositionType.RELATIVE) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lineIndex = child.lineIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the line's height and find the endIndex
|
||||||
|
float lineHeight = 0;
|
||||||
|
for (ii = startIndex; ii < node.getChildCount(); ++ii) {
|
||||||
|
child = node.getChildAt(ii);
|
||||||
|
if (getPositionType(child) != CSSPositionType.RELATIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (child.lineIndex != lineIndex) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!CSSConstants.isUndefined(getLayoutDimension(child, getDim(crossAxis)))) {
|
||||||
|
lineHeight = Math.max(lineHeight,getLayoutDimension(child, getDim(crossAxis)) +
|
||||||
|
getMarginAxis(child,crossAxis));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int endIndex = ii;
|
||||||
|
lineHeight = lineHeight + crossDimAdd;
|
||||||
|
|
||||||
|
for (ii = startIndex; ii < endIndex; ++ii) {
|
||||||
|
child = node.getChildAt(ii);
|
||||||
|
if (getPositionType(child) != CSSPositionType.RELATIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSSAlign alignItem = getAlignItem(node, child);
|
||||||
|
float crossPosition = getLayoutPosition(child, getPos(crossAxis)); // preserve current position if someting goes wrong with alignItem?
|
||||||
|
if (alignItem == CSSAlign.FLEX_START) {
|
||||||
|
crossPosition = currentLead + getMargin(child,getLeading(crossAxis));
|
||||||
|
}
|
||||||
|
else if (alignItem == CSSAlign.FLEX_END) {
|
||||||
|
crossPosition = currentLead + lineHeight -
|
||||||
|
getMargin(child,getTrailing(crossAxis)) -
|
||||||
|
getLayoutDimension(child, getDim(crossAxis));
|
||||||
|
}
|
||||||
|
else if (alignItem == CSSAlign.CENTER) {
|
||||||
|
float childHeight = getLayoutDimension(child, getDim(crossAxis));
|
||||||
|
crossPosition = currentLead + ((lineHeight - childHeight)/2);
|
||||||
|
}
|
||||||
|
else if (alignItem == CSSAlign.STRETCH) {
|
||||||
|
crossPosition = currentLead + getMargin(child,getLeading(crossAxis));
|
||||||
|
// TODO: Correctly set the height of items with undefined (auto)
|
||||||
|
// crossAxis dimension.
|
||||||
|
}
|
||||||
|
setLayoutPosition(child, getPos(crossAxis), crossPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLead = currentLead + lineHeight;
|
||||||
|
i = endIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the user didn't specify a width or height, and it has not been set
|
// If the user didn't specify a width or height, and it has not been set
|
||||||
// by the container, then we set it via the children.
|
// by the container, then we set it via the children.
|
||||||
if (CSSConstants.isUndefined(getLayoutDimension(node, getDim(mainAxis)))) {
|
if (CSSConstants.isUndefined(getLayoutDimension(node, getDim(mainAxis)))) {
|
||||||
|
@@ -122,6 +122,12 @@ function printLayout(test) {
|
|||||||
'space-between': 'CSS_JUSTIFY_SPACE_BETWEEN',
|
'space-between': 'CSS_JUSTIFY_SPACE_BETWEEN',
|
||||||
'space-around': 'CSS_JUSTIFY_SPACE_AROUND'
|
'space-around': 'CSS_JUSTIFY_SPACE_AROUND'
|
||||||
});
|
});
|
||||||
|
addEnum(node, 'alignContent', 'align_content', {
|
||||||
|
'flex-start': 'CSS_ALIGN_FLEX_START',
|
||||||
|
'center': 'CSS_ALIGN_CENTER',
|
||||||
|
'flex-end': 'CSS_ALIGN_FLEX_END',
|
||||||
|
'stretch': 'CSS_ALIGN_STRETCH'
|
||||||
|
});
|
||||||
addEnum(node, 'alignItems', 'align_items', {
|
addEnum(node, 'alignItems', 'align_items', {
|
||||||
'flex-start': 'CSS_ALIGN_FLEX_START',
|
'flex-start': 'CSS_ALIGN_FLEX_START',
|
||||||
'center': 'CSS_ALIGN_CENTER',
|
'center': 'CSS_ALIGN_CENTER',
|
||||||
@@ -231,11 +237,13 @@ function transpileAnnotatedJStoC(jsCode) {
|
|||||||
.replace(/\.maxHeight/g, '.maxDimensions[CSS_HEIGHT]')
|
.replace(/\.maxHeight/g, '.maxDimensions[CSS_HEIGHT]')
|
||||||
.replace(/\.minWidth/g, '.minDimensions[CSS_WIDTH]')
|
.replace(/\.minWidth/g, '.minDimensions[CSS_WIDTH]')
|
||||||
.replace(/\.minHeight/g, '.minDimensions[CSS_HEIGHT]')
|
.replace(/\.minHeight/g, '.minDimensions[CSS_HEIGHT]')
|
||||||
|
.replace(/\.lineIndex/g, '.line_index')
|
||||||
.replace(/layout\[dim/g, 'layout.dimensions[dim')
|
.replace(/layout\[dim/g, 'layout.dimensions[dim')
|
||||||
.replace(/layout\[pos/g, 'layout.position[pos')
|
.replace(/layout\[pos/g, 'layout.position[pos')
|
||||||
.replace(/layout\[leading/g, 'layout.position[leading')
|
.replace(/layout\[leading/g, 'layout.position[leading')
|
||||||
.replace(/style\[dim/g, 'style.dimensions[dim')
|
.replace(/style\[dim/g, 'style.dimensions[dim')
|
||||||
.replace(/node.children\[i\]/g, 'node->get_child(node->context, i)')
|
.replace(/node.children\[i\]/g, 'node->get_child(node->context, i)')
|
||||||
|
.replace(/node.children\[ii\]/g, 'node->get_child(node->context, ii)')
|
||||||
.replace(/node\./g, 'node->')
|
.replace(/node\./g, 'node->')
|
||||||
.replace(/child\./g, 'child->')
|
.replace(/child\./g, 'child->')
|
||||||
.replace(/parent\./g, 'parent->')
|
.replace(/parent\./g, 'parent->')
|
||||||
|
Reference in New Issue
Block a user