Hello. I use LVGL v 9.4
My device has the 128x64 monochrome LCD display and i use a screen with a list where it shows the registered users. I use lv_table widget (because it’s lightweight) with a single row and i want to add the feature to always show the last selected item (for example to modify the selected item like deleting/edit name etc.).
My startup code uses theme to make all the widgets properly displayed:
static lv_style_t s_hSelectedStyle;
static lv_style_t s_hLabelStyle;
void setup_theme(void) {
lv_style_init(&s_hLabelStyle);
lv_style_set_pad_all(&s_hLabelStyle, 1);
lv_style_init(&s_hSelectedStyle);
lv_style_copy(&s_hSelectedStyle, &s_hLabelStyle);
lv_style_set_bg_color(&s_hSelectedStyle, lv_color_black());
lv_style_set_text_color(&s_hSelectedStyle, lv_color_white());
lv_style_set_bg_opa(&s_hSelectedStyle, 255);
lv_theme_t *hNewTheme = lv_theme_default_init(lv_display_get_default(), lv_color_white(), lv_color_white(), false, &NanoFont);
lv_theme_set_apply_cb(hNewTheme, new_theme_apply_cb);
/*Assign the new theme to the current display*/
lv_display_set_theme(lv_display_get_default(), hNewTheme);
return;
}
void new_theme_apply_cb(lv_theme_t *th, lv_obj_t *obj) {
LV_UNUSED(th);
if (lv_obj_check_type(obj, &lv_table_class)) {
lv_obj_add_style(obj, &s_hSelectedStyle, LV_PART_ITEMS);
lv_obj_set_style_pad_all(obj, 2, 0);
lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
}
}
So i always can get LV_DRAW_TASK_TYPE_FILL notification to drawing callback:
void page_users_list(void) {
static const char *s_pszList[] = {"The trick", "User01", "Test user", "12345", "Hello"};
if (!s_pScreen) {
s_pScreen = lv_obj_create(NULL);
s_pTable = lv_table_create(s_pScreen);
lv_obj_set_size(s_pTable, 100, 64);
lv_obj_align(s_pTable, LV_ALIGN_LEFT_MID, 0, 0);
lv_table_set_column_count(s_pTable, 1);
for (uint8_t i = 0; i < ARRAYSIZE(s_pszList); i++) {
lv_table_set_cell_value(s_pTable, i, 0, s_pszList[i]);
}
lv_obj_add_event_cb(s_pTable, DrawEvent, LV_EVENT_DRAW_TASK_ADDED, NULL);
lv_obj_add_flag(s_pTable, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
lv_obj_add_event_cb(s_pTable, SelectEvent, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_remove_style(s_pTable, NULL, LV_PART_ITEMS | LV_STATE_PRESSED);
}
s_nSelRow = LV_TABLE_CELL_NONE;
lv_scr_load_anim(s_pScreen, LV_SCR_LOAD_ANIM_MOVE_BOTTOM, 500, 0, false);
return;
}
void SelectEvent(lv_event_t* e) {
uint32_t col;
uint32_t row;
lv_obj_t *obj = lv_event_get_target_obj(e);
lv_table_get_selected_cell(obj, &row, &col);
if (row != LV_TABLE_CELL_NONE && row != s_nSelRow) {
if (s_nSelRow != LV_TABLE_CELL_NONE) {
lv_table_clear_cell_ctrl(obj, s_nSelRow, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
}
lv_table_set_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
}
s_nSelRow = row;
lv_obj_invalidate(obj);
return;
}
void DrawEvent(lv_event_t *e) {
lv_obj_t *table = lv_event_get_target(e);
lv_draw_task_t *draw_task = lv_event_get_draw_task(e);
lv_draw_dsc_base_t *base_dsc = (lv_draw_dsc_base_t *)lv_draw_task_get_draw_dsc(draw_task);
if (base_dsc->part == LV_PART_ITEMS) {
uint32_t row = base_dsc->id1;
uint32_t col = base_dsc->id2;
// Проверить, выделена ли строка
bool is_selected = lv_table_has_cell_ctrl(table, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
switch (lv_draw_task_get_type(draw_task)) {
case LV_DRAW_TASK_TYPE_FILL:
lv_draw_fill_dsc_t *fill_dsc = lv_draw_task_get_fill_dsc(draw_task);
if (fill_dsc) {
fill_dsc->color = is_selected ? lv_color_black() : lv_color_white();
fill_dsc->opa = LV_OPA_COVER;
}
break;
case LV_DRAW_TASK_TYPE_LABEL:
lv_draw_label_dsc_t *lbl_dsc = lv_draw_task_get_label_dsc(draw_task);
if (lbl_dsc) {
lbl_dsc->color = is_selected ? lv_color_white() : lv_color_black();
}
break;
}
}
return;
}
But i get the problem with border drawing - it disappears (overwrites):

How to avoid this?
Thanks in advance!