1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-08 06:00:56 +00:00

[lvgl] add triggers for swipe gestures (#8190)

This commit is contained in:
Clyde Stubbs 2025-02-05 10:13:21 +11:00 committed by GitHub
parent 2e61229aed
commit 9b56f9cc6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 10 deletions

View File

@ -61,7 +61,14 @@ from .types import (
lv_style_t, lv_style_t,
lvgl_ns, lvgl_ns,
) )
from .widgets import Widget, add_widgets, get_scr_act, set_obj_properties, styles_used from .widgets import (
LvScrActType,
Widget,
add_widgets,
get_scr_act,
set_obj_properties,
styles_used,
)
from .widgets.animimg import animimg_spec from .widgets.animimg import animimg_spec
from .widgets.arc import arc_spec from .widgets.arc import arc_spec
from .widgets.button import button_spec from .widgets.button import button_spec
@ -318,7 +325,7 @@ async def to_code(configs):
config[df.CONF_RESUME_ON_INPUT], config[df.CONF_RESUME_ON_INPUT],
) )
await cg.register_component(lv_component, config) await cg.register_component(lv_component, config)
Widget.create(config[CONF_ID], lv_component, obj_spec, config) Widget.create(config[CONF_ID], lv_component, LvScrActType(), config)
lv_scr_act = get_scr_act(lv_component) lv_scr_act = get_scr_act(lv_component)
async with LvContext(): async with LvContext():
@ -391,7 +398,7 @@ FINAL_VALIDATE_SCHEMA = final_validation
LVGL_SCHEMA = ( LVGL_SCHEMA = (
cv.polling_component_schema("1s") cv.polling_component_schema("1s")
.extend(obj_schema(obj_spec)) .extend(obj_schema(LvScrActType()))
.extend( .extend(
{ {
cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent), cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent),

View File

@ -146,6 +146,8 @@ TYPE_FLEX = "flex"
TYPE_GRID = "grid" TYPE_GRID = "grid"
TYPE_NONE = "none" TYPE_NONE = "none"
DIRECTIONS = LvConstant("LV_DIR_", "LEFT", "RIGHT", "BOTTOM", "TOP")
LV_FONTS = list(f"montserrat_{s}" for s in range(8, 50, 2)) + [ LV_FONTS = list(f"montserrat_{s}" for s in range(8, 50, 2)) + [
"dejavu_16_persian_hebrew", "dejavu_16_persian_hebrew",
"simsun_16_cjk", "simsun_16_cjk",
@ -169,9 +171,13 @@ LV_EVENT_MAP = {
"CANCEL": "CANCEL", "CANCEL": "CANCEL",
"ALL_EVENTS": "ALL", "ALL_EVENTS": "ALL",
"CHANGE": "VALUE_CHANGED", "CHANGE": "VALUE_CHANGED",
"GESTURE": "GESTURE",
} }
LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP) LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)
SWIPE_TRIGGERS = tuple(
f"on_swipe_{x.lower()}" for x in DIRECTIONS.choices + ("up", "down")
)
LV_ANIM = LvConstant( LV_ANIM = LvConstant(
@ -250,7 +256,6 @@ KEYBOARD_MODES = LvConstant(
"NUMBER", "NUMBER",
) )
ROLLER_MODES = LvConstant("LV_ROLLER_MODE_", "NORMAL", "INFINITE") ROLLER_MODES = LvConstant("LV_ROLLER_MODE_", "NORMAL", "INFINITE")
DIRECTIONS = LvConstant("LV_DIR_", "LEFT", "RIGHT", "BOTTOM", "TOP")
TILE_DIRECTIONS = DIRECTIONS.extend("HOR", "VER", "ALL") TILE_DIRECTIONS = DIRECTIONS.extend("HOR", "VER", "ALL")
CHILD_ALIGNMENTS = LvConstant( CHILD_ALIGNMENTS = LvConstant(
"LV_ALIGN_", "LV_ALIGN_",

View File

@ -211,10 +211,9 @@ def part_schema(parts):
def automation_schema(typ: LvType): def automation_schema(typ: LvType):
events = df.LV_EVENT_TRIGGERS + df.SWIPE_TRIGGERS
if typ.has_on_value: if typ.has_on_value:
events = df.LV_EVENT_TRIGGERS + (CONF_ON_VALUE,) events = events + (CONF_ON_VALUE,)
else:
events = df.LV_EVENT_TRIGGERS
args = typ.get_arg_type() if isinstance(typ, LvType) else [] args = typ.get_arg_type() if isinstance(typ, LvType) else []
args.append(lv_event_t_ptr) args.append(lv_event_t_ptr)
return { return {

View File

@ -7,8 +7,10 @@ from .defines import (
CONF_ALIGN_TO, CONF_ALIGN_TO,
CONF_X, CONF_X,
CONF_Y, CONF_Y,
DIRECTIONS,
LV_EVENT_MAP, LV_EVENT_MAP,
LV_EVENT_TRIGGERS, LV_EVENT_TRIGGERS,
SWIPE_TRIGGERS,
literal, literal,
) )
from .lvcode import ( from .lvcode import (
@ -23,7 +25,7 @@ from .lvcode import (
lvgl_static, lvgl_static,
) )
from .types import LV_EVENT from .types import LV_EVENT
from .widgets import widget_map from .widgets import LvScrActType, get_scr_act, widget_map
async def generate_triggers(): async def generate_triggers():
@ -33,6 +35,9 @@ async def generate_triggers():
""" """
for w in widget_map.values(): for w in widget_map.values():
if isinstance(w.type, LvScrActType):
w = get_scr_act(w.var)
if w.config: if w.config:
for event, conf in { for event, conf in {
event: conf event: conf
@ -43,6 +48,24 @@ async def generate_triggers():
w.add_flag("LV_OBJ_FLAG_CLICKABLE") w.add_flag("LV_OBJ_FLAG_CLICKABLE")
event = literal("LV_EVENT_" + LV_EVENT_MAP[event[3:].upper()]) event = literal("LV_EVENT_" + LV_EVENT_MAP[event[3:].upper()])
await add_trigger(conf, w, event) await add_trigger(conf, w, event)
for event, conf in {
event: conf
for event, conf in w.config.items()
if event in SWIPE_TRIGGERS
}.items():
conf = conf[0]
dir = event[9:].upper()
dir = {"UP": "TOP", "DOWN": "BOTTOM"}.get(dir, dir)
dir = DIRECTIONS.mapper(dir)
w.clear_flag("LV_OBJ_FLAG_SCROLLABLE")
selected = literal(
f"lv_indev_get_gesture_dir(lv_indev_get_act()) == {dir}"
)
await add_trigger(
conf, w, literal("LV_EVENT_GESTURE"), is_selected=selected
)
for conf in w.config.get(CONF_ON_VALUE, ()): for conf in w.config.get(CONF_ON_VALUE, ()):
await add_trigger( await add_trigger(
conf, conf,
@ -61,13 +84,14 @@ async def generate_triggers():
lv.obj_align_to(w.obj, target, align, x, y) lv.obj_align_to(w.obj, target, align, x, y)
async def add_trigger(conf, w, *events): async def add_trigger(conf, w, *events, is_selected=None):
is_selected = is_selected or w.is_selected()
tid = conf[CONF_TRIGGER_ID] tid = conf[CONF_TRIGGER_ID]
trigger = cg.new_Pvariable(tid) trigger = cg.new_Pvariable(tid)
args = w.get_args() + [(lv_event_t_ptr, "event")] args = w.get_args() + [(lv_event_t_ptr, "event")]
value = w.get_values() value = w.get_values()
await automation.build_automation(trigger, args, conf) await automation.build_automation(trigger, args, conf)
async with LambdaContext(EVENT_ARG, where=tid) as context: async with LambdaContext(EVENT_ARG, where=tid) as context:
with LvConditional(w.is_selected()): with LvConditional(is_selected):
lv_add(trigger.trigger(*value, literal("event"))) lv_add(trigger.trigger(*value, literal("event")))
lv_add(lvgl_static.add_event_cb(w.obj, await context.get_lambda(), *events)) lv_add(lvgl_static.add_event_cb(w.obj, await context.get_lambda(), *events))

View File

@ -133,6 +133,18 @@ lvgl:
pages: pages:
- id: page1 - id: page1
on_swipe_top:
logger.log: "swiped up"
on_swipe_bottom:
logger.log: "swiped down"
on_swipe_up:
logger.log: "swiped up"
on_swipe_down:
logger.log: "swiped down"
on_swipe_left:
logger.log: "swiped left"
on_swipe_right:
logger.log: "swiped right"
bg_image_src: cat_image bg_image_src: cat_image
on_load: on_load:
- logger.log: page loaded - logger.log: page loaded