[lvgl] Add utility gradient function (#16048)

This commit is contained in:
Clyde Stubbs
2026-04-29 06:29:38 +10:00
committed by GitHub
parent 1f4136e76f
commit 9af557de6d
4 changed files with 42 additions and 1 deletions
+5 -1
View File
@@ -1,3 +1,5 @@
from operator import itemgetter
from esphome import config_validation as cv
import esphome.codegen as cg
from esphome.const import (
@@ -11,6 +13,7 @@ from esphome.core import ID
from esphome.cpp_generator import MockObj
from .defines import CONF_GRADIENTS, CONF_OPA, LV_DITHER, add_define, add_warning
from .helpers import add_lv_use
from .lv_validation import lv_color, lv_percentage, opacity
from .lvcode import lv
from .types import lv_color_t, lv_gradient_t, lv_opa_t
@@ -50,6 +53,7 @@ GRADIENT_SCHEMA = cv.ensure_list(
async def gradients_to_code(config):
add_lv_use("gradient")
max_stops = 2
if any(CONF_DITHER in x for x in config.get(CONF_GRADIENTS, ())):
add_warning(
@@ -58,7 +62,7 @@ async def gradients_to_code(config):
for gradient in config.get(CONF_GRADIENTS, ()):
var = MockObj(cg.new_Pvariable(gradient[CONF_ID]), "->")
idbase = gradient[CONF_ID].id
stops = gradient[CONF_STOPS]
stops = sorted(gradient[CONF_STOPS], key=itemgetter(CONF_POSITION))
max_stops = max(max_stops, len(stops))
if gradient[CONF_DIRECTION].startswith("VER"):
lv.grad_vertical_init(var)
+26
View File
@@ -864,6 +864,32 @@ void lv_scale_draw_event_cb(lv_event_t *e, int16_t range_start, int16_t range_en
}
#endif // USE_LVGL_SCALE
#ifdef USE_LVGL_GRADIENT
/**
*
* @param dsc The gradient descriptor containing the color stops
* @param pos The current position to calculate the color for
* @return The color for the given position
*/
lv_color_t lv_grad_calculate_color(const lv_grad_dsc_t *dsc, int32_t pos) {
if (dsc->stops_count == 0)
return lv_color_black();
if (dsc->stops_count == 1 || pos <= dsc->stops[0].frac)
return dsc->stops[0].color;
if (pos >= dsc->stops[dsc->stops_count - 1].frac)
return dsc->stops[dsc->stops_count - 1].color;
int i = 1;
while (i < dsc->stops_count && dsc->stops[i].frac < pos)
i++;
auto *stop1 = &dsc->stops[i - 1];
auto *stop2 = &dsc->stops[i];
int32_t range = stop2->frac - stop1->frac;
int32_t offset = pos - stop1->frac;
return lv_color_mix(stop2->color, stop1->color, range == 0 ? 0 : (offset * 255) / range);
}
#endif
static void lv_container_constructor(const lv_obj_class_t *class_p, lv_obj_t *obj) {
LV_TRACE_OBJ_CREATE("begin");
LV_UNUSED(class_p);
+10
View File
@@ -115,6 +115,16 @@ inline void lv_animimg_set_src(lv_obj_t *img, std::vector<image::Image *> images
int16_t lv_get_needle_angle_for_value(lv_obj_t *obj, int value);
#endif
#ifdef USE_LVGL_GRADIENT
/**
*
* @param dsc The gradient descriptor containing the color stops
* @param pos The current position to calculate the color for
* @return The color for the given position
*/
lv_color_t lv_grad_calculate_color(const lv_grad_dsc_t *dsc, int32_t pos);
#endif
// Parent class for things that wrap an LVGL object
class LvCompound {
public:
+1
View File
@@ -96,6 +96,7 @@
#define USE_LVGL_CHECKBOX
#define USE_LVGL_DROPDOWN
#define USE_LVGL_FONT
#define USE_LVGL_GRADIENT
#define USE_LVGL_IMAGE
#define USE_LVGL_IMAGEBUTTON
#define USE_LVGL_KEY_LISTENER