What MCU/Processor/Board and compiler are you using?
Custom board with a STM32H753 MCU
What LVGL version are you using?
Latest v8.4 release
What do you want to achieve?
I’d like to create a vertical gradient with the same size of the full screen which goes from transparent to full black; however if I’m understanding correctly alpha is supported for colors only when using LV_COLOR_DEPTH set as 32 (which is currently 16 for my application). Is there a way to do that anyway? I’ve looked and in LVGL V9 there is the lv_obj_set_style_bg_grad_opa
function which seems to implement this kind of gradient, is this correct?
I did manage to implement a solution, however the results are underwhelming due to the low gamma of the display.
I implemented it by adding a simple rectangle with a custom draw function; the idea was taken by one of the chart examples which had a gradient under the graph lines.
static lv_style_t grad_style;
static lv_obj_t *grad;
void init_grad()
{
lv_style_init(&grad_style);
lv_style_set_pad_all(&grad_style, 0);
lv_style_set_border_width(&grad_style, 0);
lv_style_set_radius(&grad_style, 0);
lv_style_set_bg_color(&grad_style, lv_color_hex(COLOR_BLACK));
grad = lv_obj_create(lv_layer_top());
lv_obj_set_scrollbar_mode(grad, LV_SCROLLBAR_MODE_OFF);
lv_obj_set_size(grad, SCREEN_WIDTH, SCREEN_HEIGHT);
lv_obj_set_pos(grad, 0, 0);
lv_obj_add_style(grad, &grad_style, LV_PART_MAIN);
lv_obj_set_style_bg_opa(grad, LV_OPA_0, LV_PART_MAIN);
lv_obj_add_event_cb(grad, gradient_draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
}
/* Custom draw function */
static void gradient_draw_event_cb(lv_event_t *e)
{
lv_obj_t *obj = lv_event_get_target(e);
lv_obj_draw_part_dsc_t *dsc = lv_event_get_draw_part_dsc(e);
if (dsc->part == LV_PART_MAIN)
{
lv_draw_mask_fade_param_t fade_mask_param;
lv_draw_mask_fade_init(&fade_mask_param, &obj->coords, LV_OPA_TRANSP, obj->coords.y1, LV_OPA_COVER,
obj->coords.y2);
int16_t fade_mask_id = lv_draw_mask_add(&fade_mask_param, NULL);
lv_draw_rect_dsc_t draw_rect_dsc;
lv_draw_rect_dsc_init(&draw_rect_dsc);
draw_rect_dsc.bg_opa = LV_OPA_100;
draw_rect_dsc.bg_color = lv_obj_get_style_bg_color(obj, dsc->part);
lv_area_t a;
a.x1 = obj->coords.x1;
a.x2 = obj->coords.x2;
a.y1 = obj->coords.y1;
a.y2 = obj->coords.y2;
lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
lv_draw_mask_free_param(&fade_mask_param);
lv_draw_mask_remove_id(fade_mask_id);
}
}
Maybe simpler and more flex is place png alpha image over screen. Image require only full size in direction for gradient for example 8x240px … LVGL tile copy it to set size.
That would be another idea, I didn’t know LVGL could tile images while keeping them in memory only one time