1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-06 05:12:21 +01:00

LVGL stage 2 (#7129)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Clyde Stubbs
2024-07-30 09:41:34 +10:00
committed by GitHub
parent 12e840ee88
commit 7c1aa771aa
18 changed files with 503 additions and 183 deletions

View File

@@ -8,6 +8,7 @@ import esphome.config_validation as cv
from esphome.const import CONF_ARGS, CONF_COLOR, CONF_FORMAT
from esphome.core import HexInt
from esphome.cpp_generator import MockObj
from esphome.cpp_types import uint32
from esphome.helpers import cpp_string_escape
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
@@ -23,6 +24,28 @@ from .lvcode import ConstantLiteral, lv_expr
from .types import lv_font_t
def literal_mapper(value, args=()):
if isinstance(value, str):
return ConstantLiteral(value)
return value
opacity_consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
@schema_extractor("one_of")
def opacity_validator(value):
if value == SCHEMA_EXTRACT:
return opacity_consts.choices
value = cv.Any(cv.percentage, opacity_consts.one_of)(value)
if isinstance(value, float):
return int(value * 255)
return value
opacity = LValidator(opacity_validator, uint32, retmapper=literal_mapper)
@schema_extractor("one_of")
def color(value):
if value == SCHEMA_EXTRACT:
@@ -43,16 +66,24 @@ def color_retmapper(value):
return lv_expr.color_from(MockObj(value))
def pixels_or_percent(value):
lv_color = LValidator(color, ty.lv_color_t, retmapper=color_retmapper)
def pixels_or_percent_validator(value):
"""A length in one axis - either a number (pixels) or a percentage"""
if value == SCHEMA_EXTRACT:
return ["pixels", "..%"]
if isinstance(value, int):
return str(cv.int_(value))
return cv.int_(value)
# Will throw an exception if not a percentage.
return f"lv_pct({int(cv.percentage(value) * 100)})"
pixels_or_percent = LValidator(
pixels_or_percent_validator, uint32, retmapper=literal_mapper
)
def zoom(value):
value = cv.float_range(0.1, 10.0)(value)
return int(value * 256)
@@ -68,7 +99,7 @@ def angle(value):
@schema_extractor("one_of")
def size(value):
def size_validator(value):
"""A size in one axis - one of "size_content", a number (pixels) or a percentage"""
if value == SCHEMA_EXTRACT:
return ["size_content", "pixels", "..%"]
@@ -79,28 +110,42 @@ def size(value):
return "LV_SIZE_CONTENT"
raise cv.Invalid("must be 'size_content', a pixel position or a percentage")
if isinstance(value, int):
return str(cv.int_(value))
return cv.int_(value)
# Will throw an exception if not a percentage.
return f"lv_pct({int(cv.percentage(value) * 100)})"
size = LValidator(size_validator, uint32, retmapper=literal_mapper)
radius_consts = LvConstant("LV_RADIUS_", "CIRCLE")
@schema_extractor("one_of")
def opacity(value):
consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
def radius_validator(value):
if value == SCHEMA_EXTRACT:
return consts.choices
value = cv.Any(cv.percentage, consts.one_of)(value)
return radius_consts.choices
value = cv.Any(size, cv.percentage, radius_consts.one_of)(value)
if isinstance(value, float):
return int(value * 255)
return value
def id_name(value):
if value == SCHEMA_EXTRACT:
return "id"
return cv.validate_id_name(value)
radius = LValidator(radius_validator, uint32, retmapper=literal_mapper)
def stop_value(value):
return cv.int_range(0, 255)(value)
lv_color = LValidator(color, ty.lv_color_t, retmapper=color_retmapper)
lv_bool = LValidator(cv.boolean, cg.bool_, BinarySensor, "get_state()")
lv_bool = LValidator(
cv.boolean, cg.bool_, BinarySensor, "get_state()", retmapper=literal_mapper
)
def lvms_validator_(value):
@@ -145,26 +190,32 @@ lv_float = LValidator(cv.float_, cg.float_, Sensor, "get_state()")
lv_int = LValidator(cv.int_, cg.int_, Sensor, "get_state()")
def is_lv_font(font):
return isinstance(font, str) and font.lower() in LV_FONTS
class LvFont(LValidator):
def __init__(self):
def lv_builtin_font(value):
fontval = cv.one_of(*LV_FONTS, lower=True)(value)
lv_fonts_used.add(fontval)
return "&lv_font_" + fontval
return fontval
def validator(value):
if value == SCHEMA_EXTRACT:
return LV_FONTS
if isinstance(value, str) and value.lower() in LV_FONTS:
if is_lv_font(value):
return lv_builtin_font(value)
fontval = cv.use_id(Font)(value)
esphome_fonts_used.add(fontval)
return requires_component("font")(f"{fontval}_engine->get_lv_font()")
return requires_component("font")(fontval)
super().__init__(validator, lv_font_t)
async def process(self, value, args=()):
return ConstantLiteral(value)
if is_lv_font(value):
return ConstantLiteral(f"&lv_font_{value}")
return ConstantLiteral(f"{value}_engine->get_lv_font()")
lv_font = LvFont()