Remove line under window header


I have noticed that when using headers on windows a weird line is created under it, and i can’t find a way to remove it or another post addressing this.

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

I’m using a Simulator

What LVGL version are you using?

I have a pretty new version, and the same problem occurs in the documentation, so i don’t think that a new feature has been added addressing this

What do you want to achieve?

I would like to know how to modify this line if it is even possible as of right now.

What have you tried so far?

I have tried different things and experimented, so I’m certain that the line is a part of the header, because it doesn’t show when header height is set to 0.

I also took a look at the lv_win.c file, to try to figure out where the line was being drawn but since I’m a beginner i couldn’t seem to figure it out .

Code to reproduce

This is the exact code from the documentation

#include "../../../lv_examples.h"

void lv_ex_win_1(void)
    /*Create a window*/
    lv_obj_t * win = lv_win_create(lv_scr_act(), NULL);
    lv_win_set_title(win, "Window title");                        /*Set the title*/

    /*Add control button to the header*/
    lv_obj_t * close_btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE);           /*Add close button and use built-in close action*/
    lv_obj_set_event_cb(close_btn, lv_win_close_event_cb);
    lv_win_add_btn(win, LV_SYMBOL_SETTINGS);        /*Add a setup button*/

    /*Add some dummy content*/
    lv_obj_t * txt = lv_label_create(win, NULL);
    lv_label_set_text(txt, "This is the content of the window\n\n"
                           "You can add control buttons to\n"
                           "the window header\n\n"
                           "The content area becomes\n"
                           "automatically scrollable is it's \n"
                           "large enough.\n\n"
                           " You can scroll the content\n"
                           "See the scroll bar on the right!");


Screenshot and/or video

This is a picture from the documentation, but the line is a bit difficult to see so i have included a picture of my own where its easier to spot
Picture of my own project showcasing this weird line:

Give this a try:

lv_obj_set_style_local_border_width(win, LV_WIN_PART_HEADER, LV_STATE_DEFAULT, 0);
1 Like

Im sorry for opening this up again, but I can’t see a good way to align text in the header. The problem is that i cant get a pointer to the title label.
I found that adding padding to the left moves the text, but maybe it would be beneficial to get a direct pointer to the title label?

You can get the header container itself with ((lv_win_ext_t *)lv_obj_get_ext_attr(win))->header. Then you would need to use lv_obj_get_child to get the label. I think it would be the first child, but I’m not 100% sure.

It doesn’t seem that the label created is “getable” with lv_obj_get_child or lv_obj_get_child_back, at least i wasn’t able to. Both methods returns the same header button, which seems to indicate that it’s the only child of the header.

You are correct; I was wrong. The title is drawn by the window directly so it is not possible to get a reference to the label. You would have to customize the drawing logic for the window.

I have now repeatedly tried to work a custom drawing method out in the lv_win_header_design in lv_win.c, since I think it would be a very nice feature and benefit all users unless there is a reason behind drawing it the way done in the current code. But the text looks very odd, and i cant figure out why?

This is test code i have replaced it with the other code you referenced, where i tried to change the font but it looks very odd work. Any help or insight?
PS. The color works as normal

static lv_style_t style_label;
        lv_style_set_text_color(&style_label, LV_STATE_DEFAULT, LV_COLOR_BLACK);                                  //Text color
        lv_style_set_text_font(&style_label, LV_STATE_DEFAULT, &lv_font_montserrat_16);                            //Text font

lv_obj_t *header_title = lv_label_create(ext->header,NULL);
        lv_obj_set_size(header_title, 30, 100);
        lv_obj_add_style(header_title, LV_LABEL_PART_MAIN, &style_label);

This is the same font(lv_font_montserrat_16), but they look vastly different, and i can’t figure out why

You can’t create objects inside the design function; you have to draw things manually using the lv_draw_label APIs.

The text is probably looking weird because you have 100+ labels stacked on top of each other. :slightly_smiling_face:

1 Like

I may be asking a bunch of beginner questions :smile:, but how would i then return a pointer to an label object i could modify? Could i do that by creating an empty object or label and then set the design callback to the method which does the lv_draw_label(&txt_area, clip_area, &label_dsc, ext->title_txt, NULL);thing?
So when i modify the empty object i call the design callback with the modified variables. Is that a viable way of doing it?

And as a side note would it be something worth considering to implement, so the header was more customizable?

You would need to tweak the window object to create a label in lv_win_create and change its text whenever the title changes. Then you don’t need to do any special drawing in the design function.

The reason we aren’t doing this upstream is likely because labels take up much more memory than simply calling lv_draw_label manually.

There is a way to get lv_draw_label to align the text; you may want to look into that instead.

Yet another option is to create a custom window object yourself using containers and pages.

1 Like

Okay, i get it know. I think i will keep using the padding to align the text :slight_smile: since I don’t have the needed understanding, but thank you very much for the help.

Last question, I promise :smile:
Does a smart method of detecting an animation ending exist?

ready_cb gets called when the animation finishes.

When it finishes? So when its “released” or ready again?

Yes. For example, if I was moving a button from x=0 to x=10, ready_cb gets called when it reaches x=10.

But it would also get called when I initialize it right? Thank you

It doesn’t get called when you first initialize it, only after it has finished running.

Then its absolutely perfect.

Is it possible to change to font if its drawn directly? In the lv_win.c code a lv_draw_label_dsc_t label_dsc; is created and referenced as the descriptor of color, font etc as far as i understand. Does that depend on the style assigned to LV_WIN_PART_HEADER, because it doesn’t change anything when i modify the style?

It should use the font in LV_WIN_PART_HEADER. If not that’s probably a bug.