Remove padding on nested container

Description

What MCU/Processor/Board and compiler are you using?

ESP32-C3

What LVGL version are you using?

v9, esp_lvgl_port 2.3.3

What do you want to achieve?

I want to have nested flex containers, one vertical and one horizontal, without padding.

What have you tried so far?

I tried to set all padding & margin values to zero but it doesn’t seem to work. As soon as there are two nested flex containers the whole thing gets shifted by a few pixels to the right. When I print the coordinates of the last image, it is at x=105, but when I manually place the same image at the same coordinates, it is ~3px to the left (which would be correct). (int)lv_obj_get_x(_icons[5]) is what i’m using to get the X coordinate. You can see that in the image icon at the very end.

Code to reproduce

Here is my code, sorry it’s not 100% self-contained but hopefully enough? I hope the problem is obvious without needing to execute this, otherwise I’ll create a smaller example. The code is already slightly simplified.


LV_IMAGE_DECLARE(dice1);

void create() {
    lv_obj_t *_root = nullptr;
    std::vector<lv_obj_t*> _icons;
    _root = lv_obj_create(nullptr);
    // flex doesn't make a difference
    //lv_obj_set_layout(_root, LV_LAYOUT_FLEX);
    //lv_obj_set_flex_flow(_root, LV_FLEX_FLOW_COLUMN);
    //lv_obj_set_flex_align(_root, lv_flex_align_t::LV_FLEX_ALIGN_SPACE_BETWEEN, lv_flex_align_t::LV_FLEX_ALIGN_CENTER, lv_flex_align_t::LV_FLEX_ALIGN_CENTER);

    lv_obj_set_width(_root, lv_pct(100));
    lv_obj_set_height(_root, lv_pct(100));

    lv_obj_set_style_pad_column(_root, 0, 0);
    lv_obj_set_style_pad_row(_root, 0, 0);
    lv_obj_set_style_pad_all(_root, 0, 0);
    lv_obj_set_style_margin_all(_root, 0, 0);
    lv_obj_set_style_pad_gap(_root, 0, 0);

    auto diceRow = lv_obj_create(_root);
    lv_obj_set_layout(diceRow, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(diceRow, LV_FLEX_FLOW_ROW);
    lv_obj_set_width(diceRow, lv_pct(100));
    lv_obj_set_height(diceRow, LV_SIZE_CONTENT);

    lv_obj_set_style_pad_column(diceRow, 0, 0);
    lv_obj_set_style_pad_row(diceRow, 0, 0);
    lv_obj_set_style_pad_all(diceRow, 0, 0);
    lv_obj_set_style_margin_all(diceRow, 0, 0);
    lv_obj_set_style_pad_gap(diceRow, 0, 0);

    for(int i = 0; i < 6; ++i) {
        lv_obj_t * icon = lv_image_create(diceRow);
        lv_image_set_src(icon, &dice1);
        _icons.push_back(icon);
    }
    lv_obj_t * icon = lv_image_create(_root);
    lv_obj_set_pos(icon, 105, 25);

    lv_image_set_src(icon, &dice1);
}

This looks like this:

But this code:

    auto diceRow = lv_obj_create(nullptr);
    lv_obj_set_layout(diceRow, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(diceRow, LV_FLEX_FLOW_ROW);
    lv_obj_set_width(diceRow, lv_pct(100));
    lv_obj_set_height(diceRow, LV_SIZE_CONTENT);

    lv_obj_set_style_pad_column(diceRow, 0, 0);
    lv_obj_set_style_pad_row(diceRow, 0, 0);
    lv_obj_set_style_pad_all(diceRow, 0, 0);
    lv_obj_set_style_margin_all(diceRow, 0, 0);
    lv_obj_set_style_pad_gap(diceRow, 0, 0);

    for(int i = 0; i < 6; ++i) {
        lv_obj_t * icon = lv_image_create(diceRow);
        lv_image_set_src(icon, &dice1);
        _icons.push_back(icon);
    }
    _root = diceRow;

Looks like this:

This is correct as the display is 128pixels wide & each image is 21x21px, meaning 6 take up 126 pixels.

How do I make this works with nested containers? Why does the upper container introduce some padding & why do the coordinates that i get using get_x differ from the ones where the images are actually drawn?

Solved it! The solution was lv_obj_set_style_border_width(obj, 0, 0);. It seems like there is a default border around every object?

Still seems like a bug to me that get_x doesn’t seem to factor in the border widths of the parents resulting in wrong coordinates.