Button matrix size calculation

Description

I noticed that my button matrix buttons were not getting the correct size recently.
The bottom row height seems to be too big.

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

I have been testing this in the simulator sdl eclipse project.

What do you experience?

The bottom row buttons are being drawn too tall and row positions are slightly wrong.

What do you expect?

If you set the spacing of the btnm widget so that it divides the widget size exactly then all the rows should have the same height.
With the following code example you should end up with 6 rows of buttons which are 73 pixels high each.

//6 rows + 
//5 inner spaces + 
//top space + 
//bottom space
6*73 + 5*8 + 1 + 1 = 480

But you end up with the bottom row being 78 high. This also means that all but the first row start at the incorrect height.

Code to reproduce

static lv_style_t style_btnm;
lv_style_copy(&style_btnm, &lv_style_plain_color);
style_btnm.body.padding.top = 1;
style_btnm.body.padding.bottom = 1;
style_btnm.body.padding.left = 1;
style_btnm.body.padding.right = 1;
style_btnm.body.padding.inner = 8;

static const char * btn_map[] = {
		"1", "2", "\n",
		"3", "4", "\n",
		"5", "6", "\n",
		"7", "8", "\n",
		"9", "n", "\n",
		"0", "y", ""
};

lv_obj_t* pinpad = lv_btnm_create(lv_disp_get_scr_act(NULL), NULL);
lv_btnm_set_style(pinpad, LV_BTNM_STYLE_BG, &style_btnm);
lv_btnm_set_map(pinpad, btn_map);
lv_obj_set_size(pinpad, 320, 480);

Screenshot and/or video

I put an overlay of the bottom row button in to make the size difference more obvious.

Solution

I looked into it and found what seems like a slight miscalculation to me on line 244 of lv_btnm.c

act_y += btn_h + style_bg->body.padding.inner;

I think this should be adding another 1 to act_y each row because the btn_h is 1 smaller than the actual button height.

That’s correct it really was 1-pixel miscalculation in every row which accumulated to the last row. Although the issue was in the position not in size.

I’ve fixed it in the master branch.

The overlay you create really should be higher with one pixel. It’s because lv_obj_set_height(obj, 20) will set y2 = y1 + 20. So e.g. 100, 120. However, LittlevGL counts the first and the last pixel too, so it draws 21 px. So the coordinates tells which pixels are occupied by the object.

Perfect thanks :slight_smile:

1 Like