Scrolling text within a label

I’m using LVGL V9.5 on an ESP32-S3 with a TFT 2.78 display. I’d like to have one line on the display scrolling text from right to left.I would like to know when the scroll is complete. At the moment I have the code below:

static void eventHandler(lv_event_t * e)
{
// Pull out the label object

lv_obj_t *label = (lv_obj_t *)lv_event_get_target(e);

lv_coord_t scroll_x = lv_obj_get_scroll_x(label);
lv_coord_t scroll_y = lv_obj_get_scroll_y(label);

Serial.printf(“X = %d, Y = %d\n”,scroll_x, scroll_y);
}

lv_obj_t * buildLabel(char *labelText, int yPosition)
{
// Create the label object

lv_obj_t *label = lv_label_create(lv_screen_active());

// Set the size and position, and font of the label

lv_obj_set_width(label, 428);
lv_obj_set_pos(label, 0, yPosition);
lv_obj_set_style_text_font(label, &lv_font_montserrat_26, 0);

// Set the text colour, text, and mode

lv_obj_set_style_text_color(label, lv_color_hex(0x00FF00), 0);
lv_label_set_text(label, labelText);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL);
lv_obj_set_scroll_dir(label, LV_DIR_LEFT);

// Set the scrolling speed

lv_point_t size;
lv_coord_t max_width = LV_COORD_MAX;
lv_text_get_size(&size, labelText, &lv_font_montserrat_26, 0, 0, max_width, LV_TEXT_FLAG_NONE);

int speed_px_per_sec = 50;
int anim_time = ((size.x + 428) * 1000) / speed_px_per_sec;
lv_obj_set_style_anim_duration(label, anim_time, LV_PART_MAIN);

// Set the event handler

lv_obj_add_event_cb(label, eventHandler, LV_EVENT_ALL, NULL);

return label;
}

and I call it with:

lv_obj_t *line2 = buildLabel(“The quick brown fox jumped over the lazy dog.”,40);

The line appears as expected but the scrolling is slow and the event handler shows scroll X and Y being 0.

I’ve been down a few internet rabbit holes trying to figure out what I’m doing wrong but have failed to answer two questions?

How can I have the line scroll at a nice speed independent of text length being scrolled?
How can I detect the end of the scroll. I was hoping to pick up the X position and check it against the previous X to see if the scroll direction had changed.

Any advice greatly appreciated.

Martin

Hi @MartinDavidWaller ,

Thank you for send a message.
Well, it seem a few issues with your current approach

lv_obj_get_scroll_x() / lv_obj_get_scroll_y() reads the container’s scroll position. With LV_LABEL_LONG_MODE_SCROLL , the label widget animates an internal text offset (label->offset.x ), not the object’s scroll position. That’s why you always get 0.

Also, LV_LABEL_LONG_MODE_SCROLL uses lv_obj_set_style_anim_duration() as the total animation time , so longer text scrolls at the same speed only if you scale the duration to the text length.

Since the internal offset is not exposed via lv_obj_get_scroll_x() , the correct approach is to listen for LV_EVENT_SCROLL_END on a scrollable containe

Hi Many thanks for the reply. I’ll experiment more based on what you have said and see how far I get. Many thanks, Martin