fix bug where nested align: stretch were not properly working
The way the algorithm work is that you first layout fixed children on the main axis, then compute all the dimensions so that you can layout flexible children. This separation doesn't work anymore if we add the other axis. The solution here is a hacky (but working!) attempt at fixing the issue. We start by doing a pass to set the children dimensions if they are stretch.
This commit is contained in:
19
src/Layout.c
19
src/Layout.c
@@ -364,6 +364,25 @@ void layoutNode(css_node_t *node) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pre-fill cross axis dimensions when the child is using stretch before
|
||||
// we call the recursive layout pass
|
||||
for (int i = 0; i < node->children_count; ++i) {
|
||||
css_node_t* child = &node->children[i];
|
||||
if (getAlignItem(node, child) == CSS_ALIGN_STRETCH &&
|
||||
getPositionType(child) == CSS_POSITION_RELATIVE &&
|
||||
!isUndefined(node->layout.dimensions[dim[crossAxis]]) &&
|
||||
!isDimDefined(child, crossAxis) &&
|
||||
!isPosDefined(child, leading[crossAxis])) {
|
||||
child->layout.dimensions[dim[crossAxis]] = fmaxf(
|
||||
node->layout.dimensions[dim[crossAxis]] -
|
||||
getPaddingAndBorderAxis(node, crossAxis) -
|
||||
getMarginAxis(child, crossAxis),
|
||||
// You never want to go smaller than padding
|
||||
getPaddingAndBorderAxis(child, crossAxis)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// <Loop A> Layout non flexible children and count children by type
|
||||
|
||||
// mainContentDim is accumulation of the dimensions and margin of all the
|
||||
|
@@ -242,6 +242,25 @@ var computeLayout = (function() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pre-fill cross axis dimensions when the child is using stretch before
|
||||
// we call the recursive layout pass
|
||||
for (var/*int*/ i = 0; i < node.children.length; ++i) {
|
||||
var/*css_node_t**/ child = node.children[i];
|
||||
if (getAlignItem(node, child) === CSS_ALIGN_STRETCH &&
|
||||
getPositionType(child) === CSS_POSITION_RELATIVE &&
|
||||
!isUndefined(node.layout[dim[crossAxis]]) &&
|
||||
!isDimDefined(child, crossAxis) &&
|
||||
!isPosDefined(child, leading[crossAxis])) {
|
||||
child.layout[dim[crossAxis]] = fmaxf(
|
||||
node.layout[dim[crossAxis]] -
|
||||
getPaddingAndBorderAxis(node, crossAxis) -
|
||||
getMarginAxis(child, crossAxis),
|
||||
// You never want to go smaller than padding
|
||||
getPaddingAndBorderAxis(child, crossAxis)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// <Loop A> Layout non flexible children and count children by type
|
||||
|
||||
// mainContentDim is accumulation of the dimensions and margin of all the
|
||||
|
@@ -2563,6 +2563,55 @@ int main()
|
||||
test("should layout node with text and position absolute", root_node, root_layout);
|
||||
}
|
||||
|
||||
{
|
||||
css_node_t *root_node = new_css_node();
|
||||
{
|
||||
css_node_t *node_0 = root_node;
|
||||
node_0->style.dimensions[CSS_WIDTH] = 300;
|
||||
init_css_node_children(node_0, 1);
|
||||
{
|
||||
css_node_t *node_1;
|
||||
node_1 = &node_0->children[0];
|
||||
node_1->style.align_self = CSS_ALIGN_STRETCH;
|
||||
init_css_node_children(node_1, 1);
|
||||
{
|
||||
css_node_t *node_2;
|
||||
node_2 = &node_1->children[0];
|
||||
node_2->style.align_self = CSS_ALIGN_STRETCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
css_node_t *root_layout = new_css_node();
|
||||
{
|
||||
css_node_t *node_0 = root_layout;
|
||||
node_0->layout.position[CSS_TOP] = 0;
|
||||
node_0->layout.position[CSS_LEFT] = 0;
|
||||
node_0->layout.dimensions[CSS_WIDTH] = 300;
|
||||
node_0->layout.dimensions[CSS_HEIGHT] = 0;
|
||||
init_css_node_children(node_0, 1);
|
||||
{
|
||||
css_node_t *node_1;
|
||||
node_1 = &node_0->children[0];
|
||||
node_1->layout.position[CSS_TOP] = 0;
|
||||
node_1->layout.position[CSS_LEFT] = 0;
|
||||
node_1->layout.dimensions[CSS_WIDTH] = 300;
|
||||
node_1->layout.dimensions[CSS_HEIGHT] = 0;
|
||||
init_css_node_children(node_1, 1);
|
||||
{
|
||||
css_node_t *node_2;
|
||||
node_2 = &node_1->children[0];
|
||||
node_2->layout.position[CSS_TOP] = 0;
|
||||
node_2->layout.position[CSS_LEFT] = 0;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 300;
|
||||
node_2->layout.dimensions[CSS_HEIGHT] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("should layout node with nested alignSelf: stretch", root_node, root_layout);
|
||||
}
|
||||
|
||||
{
|
||||
css_node_t *root_node = new_css_node();
|
||||
{
|
||||
|
@@ -777,7 +777,20 @@ describe('Layout', function() {
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
it('should layout node with nested alignSelf: stretch', function() {
|
||||
testLayout(
|
||||
{style: {width: 300}, children: [
|
||||
{style: {alignSelf: 'stretch'}, children: [
|
||||
{style: {alignSelf: 'stretch'}}
|
||||
]}
|
||||
]},
|
||||
{width: 300, height: 0, top: 0, left: 0, children: [
|
||||
{width: 300, height: 0, top: 0, left: 0, children: [
|
||||
{width: 300, height: 0, top: 0, left: 0}
|
||||
]}
|
||||
]}
|
||||
);
|
||||
});
|
||||
|
||||
it('should layout randomly', function() {
|
||||
function RNG(seed) {
|
||||
|
Reference in New Issue
Block a user