mirror of
https://github.com/esphome/esphome.git
synced 2026-05-24 18:06:27 +08:00
[lvgl] Add utility gradient function (#16048)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user