diff --git a/esphome/components/lvgl/__init__.py b/esphome/components/lvgl/__init__.py index 736fba759f..3b4f150699 100644 --- a/esphome/components/lvgl/__init__.py +++ b/esphome/components/lvgl/__init__.py @@ -380,8 +380,10 @@ async def to_code(configs): # This must be done after all widgets are created for comp in helpers.lvgl_components_required: cg.add_define(f"USE_LVGL_{comp.upper()}") - # Currently always need RGB565 for the display buffer, and ARGB8888 is used for layer blending - lv_image_formats = {"RGB565", "ARGB8888"} + for use in helpers.lv_uses: + df.add_define(f"LV_USE_{use.upper()}") + cg.add_define(f"USE_LVGL_{use.upper()}") + if { "transform_rotation", "transform_scale", @@ -389,9 +391,18 @@ async def to_code(configs): "transform_scale_y", } & styles_used: df.add_define("LV_COLOR_SCREEN_TRANSP", "1") - for use in helpers.lv_uses: - df.add_define(f"LV_USE_{use.upper()}") - cg.add_define(f"USE_LVGL_{use.upper()}") + + # Currently always need RGB565 for the display buffer, and ARGB8888 is used for layer blending + lv_image_formats = {"RGB565", "ARGB8888"} + if { + "drop_shadow_color", + "drop_shadow_offset_x", + "drop_shadow_offset_y", + "drop_shadow_opa", + "drop_shadow_quality", + "drop_shadow_radius", + } & styles_used: + lv_image_formats.add("A8") for image_id in lv_images_used: await cg.get_variable(image_id) @@ -410,6 +421,7 @@ async def to_code(configs): lv_image_formats.add("RGB888") for fmt in lv_image_formats: df.add_define(f"LV_DRAW_SW_SUPPORT_{fmt}", "1") + lv_conf_h_file = CORE.relative_src_path(LV_CONF_FILENAME) write_file_if_changed(lv_conf_h_file, generate_lv_conf_h()) cg.add_build_flag("-DLV_CONF_H=1") diff --git a/esphome/components/lvgl/lvgl_esphome.h b/esphome/components/lvgl/lvgl_esphome.h index 21d1e0d417..8d139b23cb 100644 --- a/esphome/components/lvgl/lvgl_esphome.h +++ b/esphome/components/lvgl/lvgl_esphome.h @@ -74,11 +74,13 @@ inline void lv_style_set_text_font(lv_style_t *style, const font::Font *font) { #if defined(USE_LVGL_IMAGE) && defined(USE_IMAGE) // Shortcut / overload, so that the source of an image can easily be updated // from within a lambda. -inline void lv_image_set_src(lv_obj_t *obj, esphome::image::Image *image) { - lv_image_set_src(obj, image->get_lv_image_dsc()); +inline void lv_image_set_src(lv_obj_t *obj, image::Image *image) { lv_image_set_src(obj, image->get_lv_image_dsc()); } + +inline void lv_obj_set_style_bitmap_mask_src(lv_obj_t *obj, image::Image *image, lv_style_selector_t selector) { + lv_obj_set_style_bitmap_mask_src(obj, image->get_lv_image_dsc(), selector); } -inline void lv_obj_set_style_bg_image_src(lv_obj_t *obj, esphome::image::Image *image, lv_style_selector_t selector) { +inline void lv_obj_set_style_bg_image_src(lv_obj_t *obj, image::Image *image, lv_style_selector_t selector) { lv_obj_set_style_bg_image_src(obj, image->get_lv_image_dsc(), selector); } #endif // USE_LVGL_IMAGE diff --git a/esphome/components/lvgl/schemas.py b/esphome/components/lvgl/schemas.py index 9c9504f05f..4f1473b652 100644 --- a/esphome/components/lvgl/schemas.py +++ b/esphome/components/lvgl/schemas.py @@ -168,6 +168,7 @@ BASE_PROPS = { "bg_main_opa": lvalid.opacity, "bg_main_stop": lvalid.stop_value, "bg_opa": lvalid.opacity, + "bitmap_mask_src": lvalid.lv_image, "blend_mode": df.LvConstant( "LV_BLEND_MODE_", "NORMAL", diff --git a/tests/components/lvgl/lvgl-package.yaml b/tests/components/lvgl/lvgl-package.yaml index b8c9a1809e..abc66ef587 100644 --- a/tests/components/lvgl/lvgl-package.yaml +++ b/tests/components/lvgl/lvgl-package.yaml @@ -511,6 +511,7 @@ lvgl: image: src: cat_image align: top_left + bitmap_mask_src: alert on_click: - lvgl.widget.focus: spin_up - lvgl.widget.focus: next @@ -1189,6 +1190,13 @@ image: type: BINARY transparency: chroma_key + - id: alert + file: $component_dir/logo-text.svg + type: grayscale + resize: 100x100 + invert_alpha: true + transparency: alpha_channel + color: - id: light_blue hex: "3340FF"