mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 01:58:39 +00:00
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
co-authored by
Jesse Hills
parent
2064eef273
commit
66b6d36a26
@@ -380,7 +380,8 @@ 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()}")
|
||||
lv_image_formats = df.get_color_formats().copy()
|
||||
# Currently always need RGB565 for the display buffer, and ARGB8888 is used for layer blending
|
||||
lv_image_formats = {"RGB565", "ARGB8888"}
|
||||
if {
|
||||
"transform_rotation",
|
||||
"transform_scale",
|
||||
@@ -388,10 +389,6 @@ async def to_code(configs):
|
||||
"transform_scale_y",
|
||||
} & styles_used:
|
||||
df.add_define("LV_COLOR_SCREEN_TRANSP", "1")
|
||||
lv_image_formats.add("ARGB8888")
|
||||
lv_image_formats.add(
|
||||
"RGB565"
|
||||
) # Currently always need RGB565 for the display buffer
|
||||
for use in helpers.lv_uses:
|
||||
df.add_define(f"LV_USE_{use.upper()}")
|
||||
cg.add_define(f"USE_LVGL_{use.upper()}")
|
||||
@@ -401,9 +398,6 @@ async def to_code(configs):
|
||||
metadata = get_image_metadata(image_id.id)
|
||||
image_type = IMAGE_TYPE[metadata.image_type]
|
||||
transparent = metadata.transparency != CONF_OPAQUE
|
||||
if transparent:
|
||||
# Internal draw layer will use ARGB8888
|
||||
lv_image_formats.add("ARGB8888")
|
||||
if image_type == ImageBinary:
|
||||
lv_image_formats.add("I1")
|
||||
if image_type == ImageGrayscale:
|
||||
|
||||
@@ -52,10 +52,6 @@ def get_remapped_uses():
|
||||
return get_data(KEY_REMAPPED_USES, set())
|
||||
|
||||
|
||||
def get_color_formats():
|
||||
return get_data(KEY_COLOR_FORMATS, set())
|
||||
|
||||
|
||||
def add_warning(msg: str):
|
||||
get_warnings().add(msg)
|
||||
|
||||
|
||||
@@ -4,26 +4,12 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.core import ID
|
||||
|
||||
from .defines import (
|
||||
CONF_STYLE_DEFINITIONS,
|
||||
CONF_THEME,
|
||||
CONF_TOP_LAYER,
|
||||
LValidator,
|
||||
literal,
|
||||
)
|
||||
from .defines import CONF_STYLE_DEFINITIONS, CONF_THEME, LValidator, literal
|
||||
from .helpers import add_lv_use
|
||||
from .lvcode import LambdaContext, LocalVariable, lv
|
||||
from .lvcode import LambdaContext, lv
|
||||
from .schemas import ALL_STYLES, FULL_STYLE_SCHEMA, remap_property
|
||||
from .types import ObjUpdateAction, lv_obj_t, lv_style_t
|
||||
from .widgets import (
|
||||
Widget,
|
||||
add_widgets,
|
||||
collect_parts,
|
||||
set_obj_properties,
|
||||
theme_widget_map,
|
||||
wait_for_widgets,
|
||||
)
|
||||
from .widgets.obj import obj_spec
|
||||
from .types import ObjUpdateAction, lv_style_t
|
||||
from .widgets import collect_parts, theme_widget_map, wait_for_widgets
|
||||
|
||||
|
||||
def has_style_props(config) -> bool:
|
||||
@@ -112,12 +98,3 @@ async def theme_to_code(config):
|
||||
for state, props in states.items()
|
||||
}
|
||||
theme_widget_map[w_name] = styles
|
||||
|
||||
|
||||
async def add_top_layer(lv_component, config):
|
||||
top_layer = lv.disp_get_layer_top(lv_component.var.get_disp())
|
||||
if top_conf := config.get(CONF_TOP_LAYER):
|
||||
with LocalVariable("top_layer", lv_obj_t, top_layer) as top_layer_obj:
|
||||
top_w = Widget(top_layer_obj, obj_spec, top_conf)
|
||||
await set_obj_properties(top_w, top_conf)
|
||||
await add_widgets(top_w, top_conf)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from esphome import codegen as cg, config_validation as cv
|
||||
from esphome.automation import register_action
|
||||
@@ -405,7 +404,11 @@ class Widget:
|
||||
|
||||
|
||||
# Map of widgets to their config, used for trigger generation
|
||||
widget_map: dict[Any, Widget] = {}
|
||||
widget_map: dict[ID, Widget] = {}
|
||||
|
||||
|
||||
def is_widget_completed(name: ID) -> bool:
|
||||
return name in widget_map
|
||||
|
||||
|
||||
class LvScrActType(WidgetType):
|
||||
|
||||
@@ -42,7 +42,6 @@ from ..defines import (
|
||||
CONF_SRC,
|
||||
CONF_START_ANGLE,
|
||||
addr,
|
||||
get_color_formats,
|
||||
literal,
|
||||
)
|
||||
from ..lv_validation import (
|
||||
@@ -99,7 +98,6 @@ class CanvasType(WidgetType):
|
||||
# RGB565 is 16-bit (2 bytes per pixel), ARGB8888 is 32-bit (4 bytes per pixel)
|
||||
if config[CONF_TRANSPARENT]:
|
||||
color_format = "LV_COLOR_FORMAT_ARGB8888"
|
||||
get_color_formats().add("ARGB8888")
|
||||
else:
|
||||
color_format = "LV_COLOR_FORMAT_NATIVE"
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from esphome.components.key_provider import KeyProvider
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ITEMS, CONF_MODE
|
||||
from esphome.core import CORE
|
||||
from esphome.cpp_types import std_string
|
||||
|
||||
from .. import LvContext
|
||||
from ..defines import CONF_MAIN, KEYBOARD_MODES, literal
|
||||
from ..helpers import add_lv_use, lvgl_components_required
|
||||
from ..helpers import lvgl_components_required
|
||||
from ..types import LvCompound, LvType
|
||||
from . import Widget, WidgetType, get_widgets
|
||||
from . import Widget, WidgetType, get_widgets, is_widget_completed
|
||||
from .buttonmatrix import CONF_BUTTONMATRIX
|
||||
from .textarea import CONF_TEXTAREA, lv_textarea_t
|
||||
|
||||
CONF_KEYBOARD = "keyboard"
|
||||
@@ -41,16 +44,27 @@ class KeyboardType(WidgetType):
|
||||
)
|
||||
|
||||
def get_uses(self):
|
||||
return CONF_KEYBOARD, CONF_TEXTAREA
|
||||
return CONF_KEYBOARD, CONF_TEXTAREA, CONF_BUTTONMATRIX
|
||||
|
||||
async def to_code(self, w: Widget, config: dict):
|
||||
lvgl_components_required.add("KEY_LISTENER")
|
||||
lvgl_components_required.add(CONF_KEYBOARD)
|
||||
add_lv_use("btnmatrix")
|
||||
if mode := config.get(CONF_MODE):
|
||||
await w.set_property(CONF_MODE, await KEYBOARD_MODES.process(mode))
|
||||
if ta := await get_widgets(config, CONF_TEXTAREA):
|
||||
await w.set_property(CONF_TEXTAREA, ta[0].obj)
|
||||
if textarea := config.get(CONF_TEXTAREA):
|
||||
# If a textarea is configured, it must be generated before the keyboard can attach it.
|
||||
# If not yet configured, defer the attachment code.
|
||||
|
||||
async def add_textarea():
|
||||
async with LvContext():
|
||||
await w.set_property(
|
||||
CONF_TEXTAREA, (await get_widgets(config, CONF_TEXTAREA))[0].obj
|
||||
)
|
||||
|
||||
if is_widget_completed(textarea):
|
||||
await add_textarea()
|
||||
else:
|
||||
CORE.add_job(add_textarea)
|
||||
|
||||
|
||||
keyboard_spec = KeyboardType()
|
||||
|
||||
@@ -35,7 +35,7 @@ class LabelType(WidgetType):
|
||||
if (value := config.get(CONF_TEXT)) is not None:
|
||||
await w.set_property(CONF_TEXT, await lv_text.process(value))
|
||||
await w.set_property(CONF_LONG_MODE, config)
|
||||
await w.set_property(CONF_RECOLOR, config)
|
||||
await w.set_property(CONF_RECOLOR, config, processor=lv_bool)
|
||||
|
||||
|
||||
label_spec = LabelType()
|
||||
|
||||
@@ -17,11 +17,6 @@ lv_point_t = cg.global_ns.struct("lv_point_t")
|
||||
lv_point_precise_t = cg.global_ns.struct("lv_point_precise_t")
|
||||
|
||||
|
||||
LINE_SCHEMA = {
|
||||
cv.Required(CONF_POINTS): cv.ensure_list(point_schema),
|
||||
}
|
||||
|
||||
|
||||
async def process_coord(coord):
|
||||
if isinstance(coord, Lambda):
|
||||
return call_lambda(await cg.process_lambda(coord, [], return_type=lv_coord_t))
|
||||
@@ -34,15 +29,17 @@ class LineType(WidgetType):
|
||||
CONF_LINE,
|
||||
LvType("LvLineType", parents=(LvCompound,)),
|
||||
(CONF_MAIN,),
|
||||
LINE_SCHEMA,
|
||||
schema={cv.Required(CONF_POINTS): cv.ensure_list(point_schema)},
|
||||
modify_schema={cv.Optional(CONF_POINTS): cv.ensure_list(point_schema)},
|
||||
)
|
||||
|
||||
async def to_code(self, w: Widget, config):
|
||||
points = [
|
||||
[await process_coord(p[CONF_X]), await process_coord(p[CONF_Y])]
|
||||
for p in config[CONF_POINTS]
|
||||
]
|
||||
lv_add(w.var.set_points(points))
|
||||
if CONF_POINTS in config:
|
||||
points = [
|
||||
[await process_coord(p[CONF_X]), await process_coord(p[CONF_Y])]
|
||||
for p in config[CONF_POINTS]
|
||||
]
|
||||
lv_add(w.var.set_points(points))
|
||||
|
||||
|
||||
line_spec = LineType()
|
||||
|
||||
@@ -33,6 +33,7 @@ from ..styles import LVStyle
|
||||
from ..types import LV_EVENT, lv_obj_t
|
||||
from . import Widget, WidgetType, add_widgets, set_obj_properties, widget_to_code
|
||||
from .button import button_spec, lv_button_t
|
||||
from .img import CONF_IMAGE
|
||||
from .label import CONF_LABEL
|
||||
from .obj import obj_spec
|
||||
|
||||
@@ -41,7 +42,7 @@ CONF_MSGBOX = "msgbox"
|
||||
OUTER_STYLE = LVStyle(
|
||||
"msgbox_outer",
|
||||
{
|
||||
"bg_opa": 128,
|
||||
"bg_opa": 0.5,
|
||||
"bg_color": "black",
|
||||
"border_width": 0,
|
||||
"pad_all": 0,
|
||||
@@ -119,6 +120,7 @@ async def msgbox_to_code(top_layer, conf):
|
||||
CONF_BUTTON,
|
||||
CONF_LABEL,
|
||||
CONF_MSGBOX,
|
||||
CONF_IMAGE,
|
||||
*button_spec.get_uses(),
|
||||
)
|
||||
if CONF_BUTTON_STYLE in conf:
|
||||
@@ -156,7 +158,7 @@ async def msgbox_to_code(top_layer, conf):
|
||||
with LocalVariable(
|
||||
"close_btn_", lv_obj_t, lv_expr.msgbox_add_close_button(msgbox)
|
||||
) as close_btn:
|
||||
lv_obj.remove_event_cb(close_btn, nullptr)
|
||||
lv_obj.remove_event(close_btn, 0)
|
||||
lv_obj.add_event_cb(
|
||||
close_btn,
|
||||
await close_action.get_lambda(),
|
||||
@@ -170,6 +172,6 @@ async def msgbox_to_code(top_layer, conf):
|
||||
|
||||
|
||||
async def msgboxes_to_code(lv_component, config):
|
||||
top_layer = lv.disp_get_layer_top(lv_component.get_disp())
|
||||
top_layer = lv_expr.disp_get_layer_top(lv_component.get_disp())
|
||||
for conf in config.get(CONF_MSGBOXES, ()):
|
||||
await msgbox_to_code(top_layer, conf)
|
||||
|
||||
@@ -2,7 +2,7 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_SIZE, CONF_TEXT
|
||||
|
||||
from ..defines import CONF_MAIN, get_color_formats
|
||||
from ..defines import CONF_MAIN
|
||||
from ..lv_validation import color, lv_color, lv_int, lv_text
|
||||
from ..lvcode import LocalVariable, lv
|
||||
from ..schemas import TEXT_SCHEMA
|
||||
@@ -44,7 +44,6 @@ class QrCodeType(WidgetType):
|
||||
return CONF_CANVAS, CONF_IMAGE
|
||||
|
||||
async def to_code(self, w: Widget, config):
|
||||
get_color_formats().add("ARGB8888")
|
||||
await w.set_property(
|
||||
CONF_LIGHT_COLOR, await lv_color.process(config.get(CONF_LIGHT_COLOR))
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ from ..schemas import container_schema, part_schema
|
||||
from ..types import LV_EVENT, LvType, ObjUpdateAction, lv_obj_t, lv_obj_t_ptr
|
||||
from . import Widget, WidgetType, add_widgets, get_widgets, set_obj_properties
|
||||
from .button import button_spec
|
||||
from .buttonmatrix import buttonmatrix_spec
|
||||
from .buttonmatrix import CONF_BUTTONMATRIX, buttonmatrix_spec
|
||||
from .obj import obj_spec
|
||||
|
||||
CONF_TABVIEW = "tabview"
|
||||
@@ -73,7 +73,7 @@ class TabviewType(WidgetType):
|
||||
)
|
||||
|
||||
def get_uses(self):
|
||||
return "btnmatrix", TYPE_FLEX
|
||||
return CONF_BUTTONMATRIX, TYPE_FLEX
|
||||
|
||||
async def to_code(self, w: Widget, config: dict):
|
||||
await w.set_property(
|
||||
|
||||
Reference in New Issue
Block a user