mirror of
https://github.com/esphome/esphome.git
synced 2026-05-10 05:37:55 +08:00
[lvgl] Fix setting triggers on display (#15364)
This commit is contained in:
@@ -2,7 +2,7 @@ import importlib
|
||||
from pathlib import Path
|
||||
import pkgutil
|
||||
|
||||
from esphome.automation import build_automation, validate_automation
|
||||
from esphome.automation import Trigger, build_automation, validate_automation
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.const import (
|
||||
CONF_BYTE_ORDER,
|
||||
@@ -34,7 +34,6 @@ from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_LOG_LEVEL,
|
||||
CONF_ON_BOOT,
|
||||
CONF_ON_IDLE,
|
||||
CONF_PAGES,
|
||||
CONF_ROTATION,
|
||||
@@ -59,7 +58,7 @@ from .encoders import (
|
||||
from .gradient import GRADIENT_SCHEMA, gradients_to_code
|
||||
from .keypads import KEYPADS_CONFIG, keypads_to_code
|
||||
from .lv_validation import lv_bool, lv_images_used
|
||||
from .lvcode import LvContext, LvglComponent, lvgl_static
|
||||
from .lvcode import LvContext, LvglComponent, lv_event_t_ptr, lvgl_static
|
||||
from .schemas import (
|
||||
DISP_BG_SCHEMA,
|
||||
FULL_STYLE_SCHEMA,
|
||||
@@ -71,7 +70,7 @@ from .schemas import (
|
||||
)
|
||||
from .styles import styles_to_code, theme_to_code
|
||||
from .touchscreens import touchscreen_schema, touchscreens_to_code
|
||||
from .trigger import add_on_boot_triggers, generate_align_tos, generate_triggers
|
||||
from .trigger import generate_align_tos, generate_triggers
|
||||
from .types import (
|
||||
IdleTrigger,
|
||||
PlainTrigger,
|
||||
@@ -79,6 +78,7 @@ from .types import (
|
||||
lv_font_t,
|
||||
lv_group_t,
|
||||
lv_lambda_t,
|
||||
lv_obj_t_ptr,
|
||||
lv_style_t,
|
||||
lvgl_ns,
|
||||
)
|
||||
@@ -398,7 +398,6 @@ async def to_code(configs):
|
||||
f"set_{trigger_name.removeprefix('on_')}_trigger",
|
||||
)(trigger_var)
|
||||
)
|
||||
await add_on_boot_triggers(config.get(CONF_ON_BOOT, ()))
|
||||
|
||||
# This must be done after all widgets are created
|
||||
for comp in helpers.lvgl_components_required:
|
||||
@@ -502,6 +501,17 @@ LVGL_SCHEMA = cv.All(
|
||||
cv.polling_component_schema("1s")
|
||||
.extend(
|
||||
{
|
||||
**{
|
||||
cv.Optional(event): validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
Trigger.template(lv_obj_t_ptr, lv_event_t_ptr)
|
||||
),
|
||||
}
|
||||
)
|
||||
for event in df.LV_SCREEN_EVENT_TRIGGERS
|
||||
+ df.LV_DISPLAY_EVENT_TRIGGERS
|
||||
},
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent),
|
||||
cv.GenerateID(CONF_ALIGN_TO_LAMBDA_ID): cv.declare_id(lv_lambda_t),
|
||||
cv.GenerateID(df.CONF_DISPLAYS): display_schema,
|
||||
|
||||
@@ -276,10 +276,6 @@ LV_EVENT_MAP = {
|
||||
"DRAW_POST_BEGIN": "DRAW_POST_BEGIN",
|
||||
"DRAW_POST_END": "DRAW_POST_END",
|
||||
"DRAW_TASK_ADD": "DRAW_TASK_ADDED",
|
||||
"FLUSH_FINISH": "FLUSH_FINISH",
|
||||
"FLUSH_START": "FLUSH_START",
|
||||
"FLUSH_WAIT_FINISH": "FLUSH_WAIT_FINISH",
|
||||
"FLUSH_WAIT_START": "FLUSH_WAIT_START",
|
||||
"FOCUS": "FOCUSED",
|
||||
"GESTURE": "GESTURE",
|
||||
"GET_SELF_SIZE": "GET_SELF_SIZE",
|
||||
@@ -300,18 +296,8 @@ LV_EVENT_MAP = {
|
||||
"READY": "READY",
|
||||
"REFRESH": "REFRESH",
|
||||
"REFR_EXT_DRAW_SIZE": "REFR_EXT_DRAW_SIZE",
|
||||
"REFR_READY": "REFR_READY",
|
||||
"REFR_REQUEST": "REFR_REQUEST",
|
||||
"REFR_START": "REFR_START",
|
||||
"RELEASE": "RELEASED",
|
||||
"RENDER_READY": "RENDER_READY",
|
||||
"RENDER_START": "RENDER_START",
|
||||
"RESOLUTION_CHANGE": "RESOLUTION_CHANGED",
|
||||
"ROTARY": "ROTARY",
|
||||
"SCREEN_LOAD": "SCREEN_LOADED",
|
||||
"SCREEN_LOAD_START": "SCREEN_LOAD_START",
|
||||
"SCREEN_UNLOAD": "SCREEN_UNLOADED",
|
||||
"SCREEN_UNLOAD_START": "SCREEN_UNLOAD_START",
|
||||
"SCROLL": "SCROLL",
|
||||
"SCROLL_BEGIN": "SCROLL_BEGIN",
|
||||
"SCROLL_END": "SCROLL_END",
|
||||
@@ -322,12 +308,34 @@ LV_EVENT_MAP = {
|
||||
"STATE_CHANGE": "STATE_CHANGED",
|
||||
"STYLE_CHANGE": "STYLE_CHANGED",
|
||||
"TRIPLE_CLICK": "TRIPLE_CLICKED",
|
||||
}
|
||||
LV_SCREEN_EVENT_MAP = {
|
||||
"SCREEN_LOAD": "SCREEN_LOADED",
|
||||
"SCREEN_LOAD_START": "SCREEN_LOAD_START",
|
||||
"SCREEN_UNLOAD": "SCREEN_UNLOADED",
|
||||
"SCREEN_UNLOAD_START": "SCREEN_UNLOAD_START",
|
||||
}
|
||||
|
||||
LV_DISPLAY_EVENT_MAP = {
|
||||
"FLUSH_FINISH": "FLUSH_FINISH",
|
||||
"FLUSH_START": "FLUSH_START",
|
||||
"FLUSH_WAIT_FINISH": "FLUSH_WAIT_FINISH",
|
||||
"FLUSH_WAIT_START": "FLUSH_WAIT_START",
|
||||
"REFR_READY": "REFR_READY",
|
||||
"REFR_REQUEST": "REFR_REQUEST",
|
||||
"REFR_START": "REFR_START",
|
||||
"RENDER_READY": "RENDER_READY",
|
||||
"RENDER_START": "RENDER_START",
|
||||
"RESOLUTION_CHANGE": "RESOLUTION_CHANGED",
|
||||
"UPDATE_LAYOUT_COMPLETE": "UPDATE_LAYOUT_COMPLETED",
|
||||
"VSYNC": "VSYNC",
|
||||
"VSYNC_REQUEST": "VSYNC_REQUEST",
|
||||
}
|
||||
|
||||
LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)
|
||||
LV_DISPLAY_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_DISPLAY_EVENT_MAP)
|
||||
LV_SCREEN_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_SCREEN_EVENT_MAP)
|
||||
|
||||
SWIPE_TRIGGERS = tuple(
|
||||
f"on_swipe_{x.lower()}" for x in DIRECTIONS.choices + ("up", "down")
|
||||
)
|
||||
|
||||
@@ -8,16 +8,21 @@ from esphome.const import (
|
||||
CONF_X,
|
||||
CONF_Y,
|
||||
)
|
||||
from esphome.cpp_generator import new_Pvariable
|
||||
from esphome.cpp_generator import MockObj, new_Pvariable
|
||||
from esphome.cpp_helpers import register_component
|
||||
from esphome.cpp_types import nullptr
|
||||
|
||||
from .defines import (
|
||||
CONF_ALIGN,
|
||||
CONF_ALIGN_TO,
|
||||
CONF_ALIGN_TO_LAMBDA_ID,
|
||||
DIRECTIONS,
|
||||
LV_DISPLAY_EVENT_MAP,
|
||||
LV_DISPLAY_EVENT_TRIGGERS,
|
||||
LV_EVENT_MAP,
|
||||
LV_EVENT_TRIGGERS,
|
||||
LV_SCREEN_EVENT_MAP,
|
||||
LV_SCREEN_EVENT_TRIGGERS,
|
||||
SWIPE_TRIGGERS,
|
||||
literal,
|
||||
)
|
||||
@@ -30,6 +35,7 @@ from .lvcode import (
|
||||
lv,
|
||||
lv_add,
|
||||
lv_event_t_ptr,
|
||||
lv_expr,
|
||||
lvgl_static,
|
||||
)
|
||||
from .types import LV_EVENT
|
||||
@@ -49,25 +55,24 @@ async def generate_triggers():
|
||||
Must be done after all widgets completed
|
||||
"""
|
||||
|
||||
all_triggers = (
|
||||
LV_EVENT_TRIGGERS + LV_DISPLAY_EVENT_TRIGGERS + LV_SCREEN_EVENT_TRIGGERS
|
||||
)
|
||||
for w in widget_map.values():
|
||||
config = w.config
|
||||
if isinstance(w.type, LvScrActType):
|
||||
w = get_screen_active(w.var)
|
||||
|
||||
if w.config:
|
||||
if config:
|
||||
for event, conf in {
|
||||
event: conf
|
||||
for event, conf in w.config.items()
|
||||
if event in LV_EVENT_TRIGGERS
|
||||
event: conf for event, conf in config.items() if event in all_triggers
|
||||
}.items():
|
||||
conf = conf[0]
|
||||
w.add_flag("LV_OBJ_FLAG_CLICKABLE")
|
||||
event = literal("LV_EVENT_" + LV_EVENT_MAP[event[3:].upper()])
|
||||
await add_trigger(conf, w, event)
|
||||
|
||||
for event, conf in {
|
||||
event: conf
|
||||
for event, conf in w.config.items()
|
||||
if event in SWIPE_TRIGGERS
|
||||
event: conf for event, conf in config.items() if event in SWIPE_TRIGGERS
|
||||
}.items():
|
||||
conf = conf[0]
|
||||
dir = event[9:].upper()
|
||||
@@ -77,11 +82,9 @@ async def generate_triggers():
|
||||
selected = literal(
|
||||
f"lv_indev_get_gesture_dir(lv_indev_active()) == {dir}"
|
||||
)
|
||||
await add_trigger(
|
||||
conf, w, literal("LV_EVENT_GESTURE"), is_selected=selected
|
||||
)
|
||||
await add_trigger(conf, w, "GESTURE", is_selected=selected)
|
||||
|
||||
for conf in w.config.get(CONF_ON_VALUE, ()):
|
||||
for conf in config.get(CONF_ON_VALUE, ()):
|
||||
await add_trigger(
|
||||
conf,
|
||||
w,
|
||||
@@ -90,7 +93,7 @@ async def generate_triggers():
|
||||
UPDATE_EVENT,
|
||||
)
|
||||
|
||||
await add_on_boot_triggers(w.config.get(CONF_ON_BOOT, ()))
|
||||
await add_on_boot_triggers(config.get(CONF_ON_BOOT, ()))
|
||||
|
||||
|
||||
async def generate_align_tos(config: dict):
|
||||
@@ -119,6 +122,17 @@ async def generate_align_tos(config: dict):
|
||||
await register_component(var, {})
|
||||
|
||||
|
||||
TRIGGER_MAP = LV_EVENT_MAP | LV_DISPLAY_EVENT_MAP | LV_SCREEN_EVENT_MAP
|
||||
DISPLAY_TRIGGERS = set(LV_DISPLAY_EVENT_TRIGGERS)
|
||||
|
||||
|
||||
def _get_event_literal(trigger: str | MockObj) -> MockObj:
|
||||
if isinstance(trigger, MockObj):
|
||||
return trigger
|
||||
trigger = trigger.removeprefix("on_")
|
||||
return literal("LV_EVENT_" + TRIGGER_MAP[trigger.upper()])
|
||||
|
||||
|
||||
async def add_trigger(conf, w, *events, is_selected=None):
|
||||
is_selected = is_selected or w.is_selected()
|
||||
tid = conf[CONF_TRIGGER_ID]
|
||||
@@ -129,4 +143,14 @@ async def add_trigger(conf, w, *events, is_selected=None):
|
||||
async with LambdaContext(EVENT_ARG, where=tid) as context:
|
||||
with LvConditional(is_selected):
|
||||
lv_add(trigger.trigger(*value, literal("event")))
|
||||
lv_add(lvgl_static.add_event_cb(w.obj, await context.get_lambda(), *events))
|
||||
callback = await context.get_lambda()
|
||||
event_literals = [_get_event_literal(event) for event in events]
|
||||
if isinstance(events[0], str) and events[0] in DISPLAY_TRIGGERS:
|
||||
assert len(events) == 1
|
||||
lv.display_add_event_cb(
|
||||
lv_expr.obj_get_display(w.obj), callback, event_literals[0], nullptr
|
||||
)
|
||||
else:
|
||||
lv_add(
|
||||
lvgl_static.add_event_cb(w.obj, await context.get_lambda(), *event_literals)
|
||||
)
|
||||
|
||||
@@ -49,6 +49,44 @@ lvgl:
|
||||
id: meter_arc_indicator
|
||||
start_value: 0
|
||||
end_value: 180
|
||||
on_invalidate_area:
|
||||
logger.log: Invalidate area
|
||||
on_resolution_change:
|
||||
logger.log: Resolution changed
|
||||
on_color_format_change:
|
||||
logger.log: Color format changed
|
||||
on_refr_request:
|
||||
logger.log: Refresh request
|
||||
on_refr_start:
|
||||
logger.log: Refresh start
|
||||
on_refr_ready:
|
||||
logger.log: Refresh ready
|
||||
on_render_start:
|
||||
logger.log: Render start
|
||||
on_render_ready:
|
||||
logger.log: Render ready
|
||||
on_flush_start:
|
||||
logger.log: Flush start
|
||||
on_flush_finish:
|
||||
logger.log: Flush finish
|
||||
on_flush_wait_start:
|
||||
logger.log: Flush wait start
|
||||
on_flush_wait_finish:
|
||||
logger.log: Flush wait finish
|
||||
on_update_layout_complete:
|
||||
logger.log: Update layout complete
|
||||
on_vsync:
|
||||
logger.log: Vsync
|
||||
on_vsync_request:
|
||||
logger.log: Vsync request
|
||||
on_screen_load_start:
|
||||
logger.log: Screen load start
|
||||
on_screen_load:
|
||||
logger.log: Screen loaded
|
||||
on_screen_unload:
|
||||
logger.log: Screen unloaded
|
||||
on_screen_unload_start:
|
||||
logger.log: Screen unload start
|
||||
bg_color: light_blue
|
||||
bottom_layer:
|
||||
widgets:
|
||||
@@ -660,14 +698,6 @@ lvgl:
|
||||
logger.log: Child created
|
||||
on_child_delete:
|
||||
logger.log: Child deleted
|
||||
on_screen_unload_start:
|
||||
logger.log: Screen unload start
|
||||
on_screen_load_start:
|
||||
logger.log: Screen load start
|
||||
on_screen_load:
|
||||
logger.log: Screen loaded
|
||||
on_screen_unload:
|
||||
logger.log: Screen unloaded
|
||||
on_size_change:
|
||||
logger.log: Size changed
|
||||
on_style_change:
|
||||
@@ -676,36 +706,6 @@ lvgl:
|
||||
logger.log: Layout changed
|
||||
on_get_self_size:
|
||||
logger.log: Get self size
|
||||
on_invalidate_area:
|
||||
logger.log: Invalidate area
|
||||
on_resolution_change:
|
||||
logger.log: Resolution changed
|
||||
on_color_format_change:
|
||||
logger.log: Color format changed
|
||||
on_refr_request:
|
||||
logger.log: Refresh request
|
||||
on_refr_start:
|
||||
logger.log: Refresh start
|
||||
on_refr_ready:
|
||||
logger.log: Refresh ready
|
||||
on_render_start:
|
||||
logger.log: Render start
|
||||
on_render_ready:
|
||||
logger.log: Render ready
|
||||
on_flush_start:
|
||||
logger.log: Flush start
|
||||
on_flush_finish:
|
||||
logger.log: Flush finish
|
||||
on_flush_wait_start:
|
||||
logger.log: Flush wait start
|
||||
on_flush_wait_finish:
|
||||
logger.log: Flush wait finish
|
||||
on_update_layout_complete:
|
||||
logger.log: Update layout complete
|
||||
on_vsync:
|
||||
logger.log: Vsync
|
||||
on_vsync_request:
|
||||
logger.log: Vsync request
|
||||
- led:
|
||||
id: lv_led
|
||||
color: 0x00FF00
|
||||
|
||||
Reference in New Issue
Block a user