193 lines
5.7 KiB
Python
193 lines
5.7 KiB
Python
from esphome import automation, codegen as cg
|
|
from esphome.automation import Trigger
|
|
import esphome.config_validation as cv
|
|
from esphome.const import CONF_ID, CONF_PAGES, CONF_TIME, CONF_TRIGGER_ID
|
|
from esphome.cpp_generator import MockObj, TemplateArguments
|
|
|
|
from ..defines import (
|
|
CONF_ANIMATION,
|
|
CONF_LVGL_ID,
|
|
CONF_PAGE,
|
|
CONF_PAGE_WRAP,
|
|
CONF_SKIP,
|
|
LV_ANIM,
|
|
literal,
|
|
)
|
|
from ..lv_validation import lv_bool, lv_milliseconds
|
|
from ..lvcode import (
|
|
EVENT_ARG,
|
|
LVGL_COMP_ARG,
|
|
LambdaContext,
|
|
ReturnStatement,
|
|
add_line_marks,
|
|
lv_add,
|
|
lvgl_comp,
|
|
lvgl_static,
|
|
)
|
|
from ..schemas import LVGL_SCHEMA
|
|
from ..types import LvglAction, LvglCondition, lv_page_t
|
|
from . import (
|
|
Widget,
|
|
WidgetType,
|
|
add_widgets,
|
|
get_widgets,
|
|
set_obj_properties,
|
|
wait_for_widgets,
|
|
)
|
|
|
|
CONF_ON_LOAD = "on_load"
|
|
CONF_ON_UNLOAD = "on_unload"
|
|
|
|
PAGE_ARG = "_page"
|
|
|
|
PAGE_SCHEMA = cv.Schema(
|
|
{
|
|
cv.Optional(CONF_SKIP, default=False): lv_bool,
|
|
cv.Optional(CONF_ON_LOAD): automation.validate_automation(
|
|
{
|
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(Trigger.template()),
|
|
}
|
|
),
|
|
cv.Optional(CONF_ON_UNLOAD): automation.validate_automation(
|
|
{
|
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(Trigger.template()),
|
|
}
|
|
),
|
|
}
|
|
)
|
|
|
|
|
|
class PageType(WidgetType):
|
|
def __init__(self):
|
|
super().__init__(
|
|
CONF_PAGE,
|
|
lv_page_t,
|
|
(),
|
|
PAGE_SCHEMA,
|
|
modify_schema={},
|
|
)
|
|
|
|
async def to_code(self, w: Widget, config: dict):
|
|
return []
|
|
|
|
|
|
SHOW_SCHEMA = LVGL_SCHEMA.extend(
|
|
{
|
|
cv.Optional(CONF_ANIMATION, default="NONE"): LV_ANIM.one_of,
|
|
cv.Optional(CONF_TIME, default="50ms"): lv_milliseconds,
|
|
}
|
|
)
|
|
|
|
page_spec = PageType()
|
|
|
|
|
|
@automation.register_action(
|
|
"lvgl.page.next",
|
|
LvglAction,
|
|
SHOW_SCHEMA,
|
|
)
|
|
async def page_next_to_code(config, action_id, template_arg, args):
|
|
animation = await LV_ANIM.process(config[CONF_ANIMATION])
|
|
time = await lv_milliseconds.process(config[CONF_TIME])
|
|
async with LambdaContext(LVGL_COMP_ARG) as context:
|
|
add_line_marks(action_id)
|
|
lv_add(lvgl_comp.show_next_page(animation, time))
|
|
var = cg.new_Pvariable(action_id, template_arg, await context.get_lambda())
|
|
await cg.register_parented(var, config[CONF_LVGL_ID])
|
|
return var
|
|
|
|
|
|
@automation.register_condition(
|
|
"lvgl.page.is_showing",
|
|
LvglCondition,
|
|
cv.maybe_simple_value(
|
|
cv.Schema({cv.Required(CONF_ID): cv.use_id(lv_page_t)}),
|
|
key=CONF_ID,
|
|
),
|
|
)
|
|
async def page_is_showing_to_code(config, condition_id, template_arg, args):
|
|
await wait_for_widgets()
|
|
page = await cg.get_variable(config[CONF_ID])
|
|
async with LambdaContext(
|
|
[(lv_page_t.operator("ptr"), PAGE_ARG)], return_type=cg.bool_
|
|
) as context:
|
|
lv_add(ReturnStatement(MockObj(PAGE_ARG, "->").is_showing()))
|
|
var = cg.new_Pvariable(
|
|
condition_id,
|
|
TemplateArguments(lv_page_t, *template_arg),
|
|
await context.get_lambda(),
|
|
)
|
|
await cg.register_parented(var, page)
|
|
return var
|
|
|
|
|
|
@automation.register_action(
|
|
"lvgl.page.previous",
|
|
LvglAction,
|
|
SHOW_SCHEMA,
|
|
)
|
|
async def page_previous_to_code(config, action_id, template_arg, args):
|
|
animation = await LV_ANIM.process(config[CONF_ANIMATION])
|
|
time = await lv_milliseconds.process(config[CONF_TIME])
|
|
async with LambdaContext(LVGL_COMP_ARG) as context:
|
|
add_line_marks(action_id)
|
|
lv_add(lvgl_comp.show_prev_page(animation, time))
|
|
var = cg.new_Pvariable(action_id, template_arg, await context.get_lambda())
|
|
await cg.register_parented(var, config[CONF_LVGL_ID])
|
|
return var
|
|
|
|
|
|
@automation.register_action(
|
|
"lvgl.page.show",
|
|
LvglAction,
|
|
cv.maybe_simple_value(
|
|
SHOW_SCHEMA.extend(
|
|
{
|
|
cv.Required(CONF_ID): cv.use_id(lv_page_t),
|
|
}
|
|
),
|
|
key=CONF_ID,
|
|
),
|
|
)
|
|
async def page_show_to_code(config, action_id, template_arg, args):
|
|
widget = await cg.get_variable(config[CONF_ID])
|
|
animation = await LV_ANIM.process(config[CONF_ANIMATION])
|
|
time = await lv_milliseconds.process(config[CONF_TIME])
|
|
async with LambdaContext(LVGL_COMP_ARG) as context:
|
|
add_line_marks(action_id)
|
|
lv_add(lvgl_comp.show_page(widget.index, animation, time))
|
|
var = cg.new_Pvariable(action_id, template_arg, await context.get_lambda())
|
|
await cg.register_parented(var, config[CONF_LVGL_ID])
|
|
return var
|
|
|
|
|
|
async def add_pages(lv_component, config):
|
|
lv_add(lv_component.set_page_wrap(config[CONF_PAGE_WRAP]))
|
|
for pconf in config.get(CONF_PAGES, ()):
|
|
id = pconf[CONF_ID]
|
|
skip = pconf[CONF_SKIP]
|
|
var = cg.new_Pvariable(id, skip)
|
|
page = Widget.create(id, var, page_spec, pconf)
|
|
lv_add(lv_component.add_page(var))
|
|
# Set outer config first
|
|
await set_obj_properties(page, config)
|
|
await set_obj_properties(page, pconf)
|
|
await add_widgets(page, pconf)
|
|
|
|
|
|
async def generate_page_triggers(config):
|
|
for pconf in config.get(CONF_PAGES, ()):
|
|
page = (await get_widgets(pconf))[0]
|
|
for ev in (CONF_ON_LOAD, CONF_ON_UNLOAD):
|
|
for loaded in pconf.get(ev, ()):
|
|
trigger = cg.new_Pvariable(loaded[CONF_TRIGGER_ID])
|
|
await automation.build_automation(trigger, [], loaded)
|
|
async with LambdaContext(EVENT_ARG, where=id) as context:
|
|
lv_add(trigger.trigger())
|
|
lv_add(
|
|
lvgl_static.add_event_cb(
|
|
page.obj,
|
|
await context.get_lambda(),
|
|
literal(f"LV_EVENT_SCREEN_{ev[3:].upper()}_START"),
|
|
)
|
|
)
|