xamarin / flex

Flex is a flexible box layout system written in C, designed to be easy to consume from other languages
MIT License
193 stars 26 forks source link

Stretching issue #30

Closed StephaneDelcroix closed 6 years ago

StephaneDelcroix commented 6 years ago

here's a test that fails.

all the heights are 100, and the y for the 2 last items are 100 also.

this is what I'm expecting

2017-11-30_1643
static void
self_sizing7(struct flex_item *item, float size[2])
{
    size[0] = 50;
    size[1] = 20;
}

void
test_align_content7(void)
{
    struct flex_item *root = flex_item_with_size(150,100);
    flex_item_set_wrap(root, FLEX_WRAP_WRAP);
    flex_item_set_align_content(root, FLEX_ALIGN_STRETCH);
    flex_item_set_align_items(root, FLEX_ALIGN_STRETCH);
    flex_item_set_direction(root, FLEX_DIRECTION_ROW);

    struct flex_item *child1 = flex_item_new();
    flex_item_set_width(child1, 50);
    flex_item_set_self_sizing(child1, self_sizing7);
    flex_item_add(root, child1);

    struct flex_item *child2 = flex_item_new();
    flex_item_set_width(child2, 50);
    flex_item_set_self_sizing(child2, self_sizing7);
    flex_item_add(root, child2);

    struct flex_item *child3 = flex_item_new();
    flex_item_set_width(child3, 50);
    flex_item_set_self_sizing(child3, self_sizing7);
    flex_item_add(root, child3);

    struct flex_item *child4 = flex_item_new();
    flex_item_set_width(child4, 50);
    flex_item_set_self_sizing(child4, self_sizing7);
    flex_item_add(root, child4);

    struct flex_item *child5 = flex_item_new();
    flex_item_set_width(child5, 50);
    flex_item_set_self_sizing(child5, self_sizing7);
    flex_item_add(root, child5);

    flex_layout(root);

    TEST_FRAME_EQUAL(child1, 0, 0, 50, 50);
    TEST_FRAME_EQUAL(child2, 50, 0, 50, 50);
    TEST_FRAME_EQUAL(child3, 100, 0, 50, 50);
    TEST_FRAME_EQUAL(child4, 0, 50, 50, 50);
    TEST_FRAME_EQUAL(child5, 50, 50, 50, 50);

    flex_item_free(root);
}
lrz commented 6 years ago

The problem here is that if the cross-axis size isn't set (is NaN) we default to the cross-axis size of the parent. In this case, all items will have a height of 100. Of course this works fine for one-line layouts but not in wrap mode.

I reduced the test to the following (the align_content, align_items and self_sizing callbacks aren't necessary):

void
test_align_content7(void)
{
    struct flex_item *root = flex_item_with_size(150,100);
    flex_item_set_wrap(root, FLEX_WRAP_WRAP);
    flex_item_set_direction(root, FLEX_DIRECTION_ROW);

    struct flex_item *child1 = flex_item_new();
    flex_item_set_width(child1, 50);
    flex_item_add(root, child1);

    struct flex_item *child2 = flex_item_new();
    flex_item_set_width(child2, 50);
    flex_item_add(root, child2);

    struct flex_item *child3 = flex_item_new();
    flex_item_set_width(child3, 50);
    flex_item_add(root, child3);

    struct flex_item *child4 = flex_item_new();
    flex_item_set_width(child4, 50);
    flex_item_add(root, child4);

    struct flex_item *child5 = flex_item_new();
    flex_item_set_width(child5, 50);
    flex_item_add(root, child5);

    flex_layout(root);

    TEST_FRAME_EQUAL(child1, 0, 0, 50, 50);
    TEST_FRAME_EQUAL(child2, 50, 0, 50, 50);
    TEST_FRAME_EQUAL(child3, 100, 0, 50, 50);
    TEST_FRAME_EQUAL(child4, 0, 50, 50, 50);
    TEST_FRAME_EQUAL(child5, 50, 50, 50, 50);

    flex_item_free(root);
}
lrz commented 6 years ago

Another behavior we should follow as well, pictured in this screenshot:

screen shot 2017-11-30 at 11 46 16 pm

Same example as above except that the first item has a height of 10 (the others do not have one). FF renders this so that the first line's height is 55 and the second one 45.

void
test_wrap19(void)
{
    struct flex_item *root = flex_item_with_size(150, 100);
    flex_item_set_wrap(root, FLEX_WRAP_WRAP);
    flex_item_set_direction(root, FLEX_DIRECTION_ROW);

    struct flex_item *child1 = flex_item_new();
    flex_item_set_width(child1, 50);
    flex_item_set_height(child1, 10);
    flex_item_add(root, child1);

    struct flex_item *child2 = flex_item_new();
    flex_item_set_width(child2, 50);
    flex_item_add(root, child2);

    struct flex_item *child3 = flex_item_new();
    flex_item_set_width(child3, 50);
    flex_item_add(root, child3);

    struct flex_item *child4 = flex_item_new();
    flex_item_set_width(child4, 50);
    flex_item_add(root, child4);

    struct flex_item *child5 = flex_item_new();
    flex_item_set_width(child5, 50);
    flex_item_add(root, child5);

    flex_layout(root);

    TEST_FRAME_EQUAL(child1, 0, 0, 50, 10);
    TEST_FRAME_EQUAL(child2, 50, 0, 50, 55);
    TEST_FRAME_EQUAL(child3, 100, 0, 50, 55);
    TEST_FRAME_EQUAL(child4, 0, 55, 50, 45);
    TEST_FRAME_EQUAL(child5, 50, 55, 50, 45);

    flex_item_free(root);
}
lrz commented 6 years ago

Should be fixed by e6546774d648f53655fdf4f4bf613f9d85fb3567