Increase checkbox indicator size

Hi there,

I’m having some trouble with applying my desired size to the checkbox with lvgl v8.3.

My goal ist to have the indicator (the part on the left, holding the checkmark) square to be 48x48 pixels.

I tried setting the width, height and size through styles in themes.c like so:

lv_style_set_size(&styles->cbxCmk, 48);
.
.
.
static void themeapply(...)
{ ....
    lv_obj_add_style(obj, &styles->cbxCmk, LV_STATE_ANY | LV_PART_INDICATOR);
....}

Any suggestion why this doesn’t work? The same works fine for a switch.
I have also tried to increase the size of the LV_PART_MAIN of the checkbox to something really big (60 high, and 500 width) but it didn’t have any effect. I also tried changing the background color which didn’t have any effect. I feel like I’m not understanding how styles are properly applied on the checkbox and would appreciate any tips and tricks on how to achieve it.

I hope the question is asked in the right way. If not please let me know if I need to clarify any detail!

Thanks!

You can refer to it.(https://blog.csdn.net/weixin_41572450/article/details/112261265)

Thanks for taking the time but your link implement a callback which barely has anything to do with setting the size through a style.

Hi @LennSar ,

Having looked into the source code it seems the checkbox object uses the text font height. So if you use a bigger font the box will resize to suite, but if you would like to change the size of the box independently of this is a way you could do it:

    lv_obj_t * cb;
    cb = lv_checkbox_create(lv_scr_act());
    lv_checkbox_set_text(cb, "Check!");
    lv_coord_t box_size = 48;
    const lv_font_t * font = lv_obj_get_style_text_font(cb, LV_PART_MAIN);
    lv_coord_t font_h = lv_font_get_line_height(font);
    lv_coord_t pad = (box_size - font_h) / 2;
    lv_obj_set_style_pad_left(cb, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_right(cb, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_top(cb, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_bottom(cb, pad, LV_PART_INDICATOR);

Note: You may need to tweak the value of pad to get a box exactly 48px.

I hope that helps…

Kind Regards,

Pete

1 Like

Hi Pete,

thank you very much. Without knowing I figured it would be the font size that determines the objects height and in the meantime I found the right values for the padding. Not as dynamically as you did but it works so far.
What I don’t understand however is that lv_obj_get_height(cb); always returns 0. I did configure the height in the theme style and I can see that it works but …get_height still returns 0. Can you reproduce that or is there a reasonable explanation for this?

Thanks again!

Lenn

I just realised that this might be caused from our end. We basically wrote a c++ wrapper for lvgl … or started doing so … and in lvgl v7 we used to make sure that the styles are applied to the object BEFORE we leave our constructor. With the lack of that signaling stuff and not having implemented the alternative yet, the style is applied later some time at which point the getHeight method returns the expected value.

Hi @LennSar ,

I have seen this happen randomly before with all different objects, I know the solution but I haven’t had time to study why it happens, but if you call lv_obj_update_layout() after creating and setting up the object, all will be well. Applying this to our previous example it would be as follows:

    lv_obj_t * cb;
    cb = lv_checkbox_create(lv_scr_act());
    lv_checkbox_set_text(cb, "Check!");
    lv_coord_t box_size = 48;
    const lv_font_t * font = lv_obj_get_style_text_font(cb, LV_PART_MAIN);
    lv_coord_t font_h = lv_font_get_line_height(font);
    lv_coord_t pad = (box_size - font_h) / 2;
    lv_obj_set_style_pad_left(cb, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_right(cb, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_top(cb, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_bottom(cb, pad, LV_PART_INDICATOR);

    lv_obj_update_layout(cb);

    lv_coord_t h = lv_obj_get_height(cb);

Now ‘h’ will = 48 as expected…

I hope that helps.

Kind Regards,

Pete

awesome. Thank you so much for your quick responses. Now it works fine. However, I wonder whether calling this after every object creation is the right approach or whether this should be done through some event handling callback?

1 Like

Hi @LennSar ,

I believe just setting everything at the objects creation time is best in this instance I can’t see any need to do anything extra on an ongoing basis.

Kind Regards,

Pete.

well I’m thinking about realigning or resizing objects at run time. I think in lvgl 7 the children objects didin’t resize automatically right? Is that different in lvgl 8?

Hi @LennSar ,

I am not an expert on the internals of LVGL, I made some small contributions a few years ago but unfortunately of late I have been far to busy to contribute very much…
I can only speak from my own experience, I have a couple of large projects written in C using LVGL but I only ever use fixed layouts where I create everything at start up and sometimes show and hide things if necessary. The only dynamic things I create are message boxes. I migrated the projects from version 5 right through to version 8.3 and the need for the lv_obj_update_layout() calls started from version 8 onwards for me. I believe @kisvegabor is aware of the need to call lv_obj_update_layout() in some cases after object creation, especially when using tabviews within tabviews. Hopefully @kisvegabor can find time to comment further about this as I am not really sure, to be honest. :slight_smile:

Kind Regards,

Pete

wow from lvgl 5 on?! Not bad. We had a v7 project and when we tried to update it to lvgl v8 we quickly resigned.
But thank you so much for you’re insight. I already have som trouble with lv_obj_update_layout :stuck_out_tongue: but I’m sure we’ll figure it out this or the other way.

Thanks for your reply. Highly appreciate it!

1 Like

thanks @pete-pjb for the solution!
Do you think is possible to override the text size used by lv_checkbox_set_text?
I’m trying to differentiate the two sizes, box and font…but i can’t :confused:

static lv_obj_t * create_radiobutton(lv_obj_t * mBoxParent, const char * txt, const int32_t x, const int32_t y, const int32_t size,const lv_font_t * font)
{
    lv_obj_t * obj = (lv_obj_t *)lv_checkbox_create(mBoxParent);
    
    lv_style_init(&style_radio_font);
    lv_style_set_text_font(&style_radio_font, font);
    lv_checkbox_set_text(obj, txt);

  
    lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);
   
    lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);
    lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
    lv_obj_add_style(obj, &style_radio_font, LV_PART_MAIN);
    lv_obj_align(obj, LV_ALIGN_RIGHT_MID, x, y);


    lv_coord_t box_size = size;
    //const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);
    lv_coord_t font_h = lv_font_get_line_height(font);
    //lv_coord_t pad = (box_size - font_h) / 2;
    lv_coord_t pad = box_size / 2;
    lv_obj_set_style_pad_left(obj, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_right(obj, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_top(obj, pad, LV_PART_INDICATOR);
    lv_obj_set_style_pad_bottom(obj, pad, LV_PART_INDICATOR);

    lv_obj_update_layout(obj);
    lv_obj_refresh_style(obj, LV_PART_MAIN,LV_STYLE_PROP_ANY);
    return obj;
}

Hi @yesnoj,

The checkbox indicators size is basically set by the font size so I am guessing this might be the type of thing you are looking for?

static lv_obj_t * create_radiobutton(lv_obj_t * mBoxParent, const char * txt, const int32_t x, const int32_t y, const lv_font_t * font)
{
    lv_obj_t * obj = (lv_obj_t *)lv_checkbox_create(mBoxParent);

    lv_obj_set_style_text_font(obj, font, LV_PART_MAIN);
    lv_obj_set_style_text_font(obj, font, LV_PART_INDICATOR);
    lv_obj_set_style_text_font(obj, font, LV_PART_INDICATOR | LV_STATE_CHECKED);
    lv_checkbox_set_text(obj, txt);
    lv_obj_align(obj, LV_ALIGN_RIGHT_MID, x, y);

    lv_obj_update_layout(obj);
    return obj;
}

The following calls:

	  create_radiobutton(lv_scr_act(), "test1", -100, 0, 20, &lv_font_montserrat_10 );
	  create_radiobutton(lv_scr_act(), "test2", -250, 0, 60, &lv_font_montserrat_20 );
	  create_radiobutton(lv_scr_act(), "test3", -400, 0, 80, &lv_font_montserrat_30 );
	  create_radiobutton(lv_scr_act(), "test4", -550, 0, 100, &lv_font_montserrat_40 );

Yield this result:
Animation

It is important if you are using your own fonts you include the tick symbol in your font builds also…

See the font converter page for details here.

Look at ‘Useful Notes’ No 4 at the bottom of the page for a list of all the font awesome symbols which you should include with your own fonts to work well with the LVGL environment.

I hope that helps,

Kind Regards,

Pete

1 Like

thank you so much @pete-pjb , this is ok if i want to have text and squarebox of the checkbox of the “same size”, but if i want to have a bigger squarebox related to the text, i can’t :confused:
I want to manage the two sizes, one for the text and one for the checkbox square :thinking:

Hi @yesnoj,

Here is a variation which allows an override on the box size…

Hope it helps:

static lv_obj_t * create_radiobutton(lv_obj_t * mBoxParent, const char * txt, const int32_t x, const int32_t y, const int32_t size, const lv_font_t * font)
{
	lv_obj_t * obj = (lv_obj_t *)lv_checkbox_create(mBoxParent);

	lv_obj_set_style_text_font(obj, font, LV_PART_MAIN);
	lv_obj_set_style_text_font(obj, font, LV_PART_INDICATOR);
	lv_obj_set_style_text_font(obj, font, LV_PART_INDICATOR | LV_STATE_CHECKED);
	lv_checkbox_set_text(obj, txt);
	lv_obj_align(obj, LV_ALIGN_RIGHT_MID, x, y);


	lv_coord_t font_h = lv_font_get_line_height(font);
	lv_coord_t pad = (size - font_h) / 2;
	lv_obj_set_style_pad_left(obj, pad, LV_PART_INDICATOR);
	lv_obj_set_style_pad_right(obj, pad, LV_PART_INDICATOR);
	lv_obj_set_style_pad_top(obj, pad, LV_PART_INDICATOR);
	lv_obj_set_style_pad_bottom(obj, pad, LV_PART_INDICATOR);

	lv_obj_update_layout(obj);
	return obj;
}

The calls were:

	  create_radiobutton(lv_scr_act(), "test1", -100, 0, 20, &lv_font_montserrat_10 );
	  create_radiobutton(lv_scr_act(), "test2", -200, 0, 40, &lv_font_montserrat_10 );
	  create_radiobutton(lv_scr_act(), "test3", -300, 0, 50, &lv_font_montserrat_40 );
	  create_radiobutton(lv_scr_act(), "test4", -500, 0, 100, &lv_font_montserrat_40 );

Here’s the result:
Animation

Is that what you are trying to achieve? :blush:

Cheers,

Pete

You are THE MAN!Thank you so much!This is exactly what i was trying to achieve!
Thanks!!

1 Like

You’re welcome… No worries…

For completeness and ultimate flexibility we could take it one step further:

static lv_obj_t * create_radiobutton(lv_obj_t * mBoxParent, const char * txt, const int32_t x, const int32_t y, const int32_t size, const lv_font_t * text_font, constlv_font_t * check_font )
{
	lv_obj_t * obj = (lv_obj_t *)lv_checkbox_create(mBoxParent);

	lv_obj_set_style_text_font(obj, text_font, LV_PART_MAIN);
	lv_obj_set_style_text_font(obj, check_font, LV_PART_INDICATOR);
	lv_obj_set_style_text_font(obj, check_font, LV_PART_INDICATOR | LV_STATE_CHECKED);
	lv_checkbox_set_text(obj, txt);
	lv_obj_align(obj, LV_ALIGN_RIGHT_MID, x, y);


	lv_coord_t font_h = lv_font_get_line_height(check_font);
	lv_coord_t pad = (size - font_h) / 2;
	lv_obj_set_style_pad_left(obj, pad, LV_PART_INDICATOR);
	lv_obj_set_style_pad_right(obj, pad, LV_PART_INDICATOR);
	lv_obj_set_style_pad_top(obj, pad, LV_PART_INDICATOR);
	lv_obj_set_style_pad_bottom(obj, pad, LV_PART_INDICATOR);

	lv_obj_update_layout(obj);
	return obj;
}

Allowing separate sizes of text and tick…
Cheers,

Pete

1 Like

for me this is a complete solution!Don’t know how mark this one as a solution, however this is it! :smiley:

1 Like