mirror of https://github.com/esphome/esphome.git
Implemented tabview
This commit is contained in:
parent
891c7833b5
commit
74630d4c17
|
@ -62,6 +62,8 @@ from esphome.const import (
|
|||
CONF_TYPE,
|
||||
CONF_NAME,
|
||||
CONF_POSITION,
|
||||
CONF_SIZE,
|
||||
CONF_INDEX,
|
||||
)
|
||||
from esphome.cpp_generator import LambdaExpression
|
||||
|
||||
|
@ -864,7 +866,7 @@ def container_schema(widget_type, extras=None):
|
|||
def validator(value):
|
||||
result = schema
|
||||
ltype = df.TYPE_NONE
|
||||
if layout := value.get(df.CONF_LAYOUT):
|
||||
if value and (layout := value.get(df.CONF_LAYOUT)):
|
||||
if not isinstance(layout, dict):
|
||||
raise cv.Invalid("Layout value must be a dict")
|
||||
ltype = layout.get(CONF_TYPE)
|
||||
|
@ -887,14 +889,15 @@ def any_widget_schema(extras=None):
|
|||
return cv.Any(dict(map(lambda wt: widget_schema(wt, extras), WIDGET_TYPES)))
|
||||
|
||||
|
||||
TILE_SCHEMA = any_widget_schema(
|
||||
{
|
||||
cv.Required(CONF_ROW): lv_int,
|
||||
cv.Required(df.CONF_COLUMN): lv_int,
|
||||
cv.GenerateID(df.CONF_TILE_ID): cv.declare_id(ty.lv_tile_t),
|
||||
cv.Optional(df.CONF_DIR, default="ALL"): df.TILE_DIRECTIONS.several_of,
|
||||
}
|
||||
)
|
||||
WIDGET_SCHEMA = any_widget_schema()
|
||||
|
||||
TILE_SCHEMA = {
|
||||
cv.Required(CONF_ROW): lv_int,
|
||||
cv.Required(df.CONF_COLUMN): lv_int,
|
||||
cv.GenerateID(): cv.declare_id(ty.lv_tile_t),
|
||||
cv.Optional(df.CONF_DIR, default="ALL"): df.TILE_DIRECTIONS.several_of,
|
||||
cv.Required(df.CONF_WIDGETS): cv.ensure_list(WIDGET_SCHEMA),
|
||||
}
|
||||
|
||||
TILEVIEW_SCHEMA = {
|
||||
cv.Required(df.CONF_TILES): cv.ensure_list(TILE_SCHEMA),
|
||||
|
@ -907,15 +910,16 @@ TILEVIEW_SCHEMA = {
|
|||
),
|
||||
}
|
||||
|
||||
TAB_SCHEMA = any_widget_schema(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
cv.GenerateID(df.CONF_TILE_ID): cv.declare_id(ty.lv_tab_t),
|
||||
cv.Optional(CONF_POSITION, default="ALL"): df.DIRECTIONS.one_of,
|
||||
}
|
||||
)
|
||||
TAB_SCHEMA = {
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
cv.GenerateID(): cv.declare_id(ty.lv_tab_t),
|
||||
cv.Required(df.CONF_WIDGETS): cv.ensure_list(WIDGET_SCHEMA),
|
||||
}
|
||||
|
||||
TABVIEW_SCHEMA = {
|
||||
cv.Required(df.CONF_TABS): cv.ensure_list(TAB_SCHEMA),
|
||||
cv.Optional(CONF_POSITION, default="top"): df.DIRECTIONS.one_of,
|
||||
cv.Optional(CONF_SIZE, default="10%"): lv.size,
|
||||
cv.Optional(CONF_ON_VALUE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
|
@ -925,7 +929,6 @@ TABVIEW_SCHEMA = {
|
|||
),
|
||||
}
|
||||
|
||||
WIDGET_SCHEMA = any_widget_schema()
|
||||
|
||||
MSGBOX_SCHEMA = STYLE_SCHEMA.extend(
|
||||
{
|
||||
|
@ -1086,6 +1089,16 @@ def collect_parts(config):
|
|||
return parts
|
||||
|
||||
|
||||
async def add_widgets(parent: Widget, config: dict):
|
||||
init = []
|
||||
if widgets := config.get(df.CONF_WIDGETS):
|
||||
for widg in widgets:
|
||||
w_type, w_cnfig = next(iter(widg.items()))
|
||||
ext_init = await widget_to_code(w_cnfig, w_type, parent)
|
||||
init.extend(ext_init)
|
||||
return init
|
||||
|
||||
|
||||
async def set_obj_properties(widg: Widget, config):
|
||||
"""Return a list of C++ statements to apply properties to an ty.lv_obj_t"""
|
||||
init = []
|
||||
|
@ -1234,22 +1247,38 @@ async def obj_to_code(_, __):
|
|||
return []
|
||||
|
||||
|
||||
def tabview_obj_creator(parent: Widget, config: dict):
|
||||
return (
|
||||
f"lv_tabview_create({parent.obj}, {config[CONF_POSITION]}, {config[CONF_SIZE]})"
|
||||
)
|
||||
|
||||
|
||||
async def tabview_to_code(tv: Widget, config: dict):
|
||||
init = []
|
||||
for widg in config[df.CONF_TABS]:
|
||||
w_id = widg[CONF_ID]
|
||||
tab_obj = cg.Pvariable(w_id, cg.nullptr, type_=ty.lv_tab_t)
|
||||
tab = Widget(tab_obj, ty.lv_tab_t)
|
||||
widget_map[w_id] = tab
|
||||
init.append(f'{tab_obj} = lv_tabview_add_tab({tv.obj}, "{widg[CONF_NAME]}")')
|
||||
init.extend(await add_widgets(tab, widg))
|
||||
return init
|
||||
|
||||
|
||||
async def tileview_to_code(var: Widget, config: dict):
|
||||
init = []
|
||||
for widg in config[df.CONF_TILES]:
|
||||
w_type, wc = next(iter(widg.items()))
|
||||
w_id = wc[df.CONF_TILE_ID]
|
||||
w_id = widg[CONF_ID]
|
||||
tile_obj = cg.Pvariable(w_id, cg.nullptr, type_=ty.lv_obj_t)
|
||||
tile = Widget(tile_obj, ty.lv_tile_t)
|
||||
widget_map[w_id] = tile
|
||||
dirs = wc[df.CONF_DIR]
|
||||
dirs = widg[df.CONF_DIR]
|
||||
if isinstance(dirs, list):
|
||||
dirs = "|".join(dirs)
|
||||
init.append(
|
||||
f"{tile.obj} = lv_tileview_add_tile({var.obj}, {wc[df.CONF_COLUMN]}, {wc[CONF_ROW]}, {dirs})"
|
||||
f"{tile.obj} = lv_tileview_add_tile({var.obj}, {widg[df.CONF_COLUMN]}, {widg[CONF_ROW]}, {dirs})"
|
||||
)
|
||||
ext_init = await widget_to_code(wc, w_type, tile)
|
||||
init.extend(ext_init)
|
||||
init.extend(await add_widgets(tile, widg))
|
||||
return init
|
||||
|
||||
|
||||
|
@ -1266,11 +1295,7 @@ async def page_to_code(config, pconf, index):
|
|||
# Set outer config first
|
||||
init.extend(await set_obj_properties(page, config))
|
||||
init.extend(await set_obj_properties(page, pconf))
|
||||
if df.CONF_WIDGETS in pconf:
|
||||
for widg in pconf[df.CONF_WIDGETS]:
|
||||
w_type, w_cnfig = next(iter(widg.items()))
|
||||
ext_init = await widget_to_code(w_cnfig, w_type, page)
|
||||
init.extend(ext_init)
|
||||
init.extend(await add_widgets(page, pconf))
|
||||
return var, init
|
||||
|
||||
|
||||
|
@ -1332,11 +1357,38 @@ async def tileview_select(config, action_id, template_arg, args):
|
|||
init = [f"lv_obj_set_tile({widget.obj}, {tile}, {config[df.CONF_ANIMATED]})"]
|
||||
else:
|
||||
init = [
|
||||
f"lv_obj_set_tile_id({widget.obj}, {config[df.CONF_COLUMN]}, {config[CONF_ROW]}, {config[df.CONF_ANIMATED]})"
|
||||
f"lv_obj_set_tile_id({widget.obj}, {config[df.CONF_COLUMN]}, {config[CONF_ROW]}, {config[df.CONF_ANIMATED]})",
|
||||
f" lv_event_send({widget.obj}, LV_EVENT_VALUE_CHANGED, nullptr);",
|
||||
]
|
||||
return await action_to_code(init, action_id, widget, template_arg, args)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"lvgl.tabview.select",
|
||||
ty.ObjUpdateAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(ty.lv_tabview_t),
|
||||
cv.Optional(df.CONF_ANIMATED, default=False): lv.animated,
|
||||
cv.Exclusive(CONF_INDEX, CONF_INDEX): lv_int,
|
||||
cv.Exclusive(df.CONF_TAB_ID, CONF_INDEX): cv.use_id(ty.lv_tab_t),
|
||||
},
|
||||
).add_extra(cv.has_at_least_one_key(CONF_INDEX, df.CONF_TAB_ID)),
|
||||
)
|
||||
async def tabview_select(config, action_id, template_arg, args):
|
||||
widget = await get_widget(config[CONF_ID])
|
||||
if tab := config.get(df.CONF_TAB_ID):
|
||||
tab = await cg.get_variable(tab)
|
||||
index = f"lv_obj_get_index(lv_tabview_get_content({tab}))"
|
||||
else:
|
||||
index = config[CONF_INDEX]
|
||||
init = [
|
||||
f"lv_tabview_set_act({widget.obj}, {index}, {config[df.CONF_ANIMATED]})",
|
||||
f" lv_event_send({widget.obj}, LV_EVENT_VALUE_CHANGED, nullptr);",
|
||||
]
|
||||
return await action_to_code(init, action_id, widget, template_arg, args)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"lvgl.spinbox.increment",
|
||||
ty.ObjUpdateAction,
|
||||
|
@ -2121,9 +2173,7 @@ async def update_to_code(config, action_id, widget: Widget, init, template_arg,
|
|||
and widget.type.value_property in config
|
||||
):
|
||||
init.append(
|
||||
f"""
|
||||
lv_event_send({widget.obj}, LV_EVENT_VALUE_CHANGED, nullptr);
|
||||
"""
|
||||
f" lv_event_send({widget.obj}, LV_EVENT_VALUE_CHANGED, nullptr);"
|
||||
)
|
||||
return await action_to_code(init, action_id, widget, template_arg, args)
|
||||
|
||||
|
@ -2229,6 +2279,10 @@ def spinner_obj_creator(parent: Widget, config: dict):
|
|||
return f"lv_spinner_create({parent.obj}, {config[df.CONF_SPIN_TIME].total_milliseconds}, {config[df.CONF_ARC_LENGTH] // 10})"
|
||||
|
||||
|
||||
def tab_obj_creator(parent: Widget, config: dict):
|
||||
return f"lv_tabview_add_tab({parent.obj}, {config[CONF_NAME]})"
|
||||
|
||||
|
||||
async def widget_to_code(w_cnfig, w_type, parent: Widget):
|
||||
init = []
|
||||
|
||||
|
@ -2256,8 +2310,7 @@ async def widget_to_code(w_cnfig, w_type, parent: Widget):
|
|||
if widgets := w_cnfig.get(df.CONF_WIDGETS):
|
||||
for widg in widgets:
|
||||
sub_type, sub_config = next(iter(widg.items()))
|
||||
ext_init = await widget_to_code(sub_config, sub_type, widget)
|
||||
init.extend(ext_init)
|
||||
init.extend(await widget_to_code(sub_config, sub_type, widget))
|
||||
fun = f"{w_type}_to_code"
|
||||
if fun := globals().get(fun):
|
||||
init.extend(await fun(widget, w_cnfig))
|
||||
|
|
|
@ -407,6 +407,7 @@ CONF_STYLE_DEFINITIONS = "style_definitions"
|
|||
CONF_STYLE_ID = "style_id"
|
||||
CONF_SKIP = "skip"
|
||||
CONF_SYMBOL = "symbol"
|
||||
CONF_TAB_ID = "tab_id"
|
||||
CONF_TABS = "tabs"
|
||||
CONF_TEXT = "text"
|
||||
CONF_TILE = "tile"
|
||||
|
|
|
@ -106,7 +106,7 @@ lv_line_t = LvType("lv_line_t")
|
|||
lv_img_t = LvType("lv_img_t")
|
||||
lv_animimg_t = LvType("lv_animimg_t")
|
||||
lv_tile_t = LvType("lv_tileview_tile_t")
|
||||
lv_tab_t = LvType("lv_tabview_tab_t")
|
||||
lv_tab_t = LvType("lv_obj_t")
|
||||
lv_spinbox_t = LvNumber("lv_spinbox_t")
|
||||
lv_arc_t = LvNumber("lv_arc_t")
|
||||
lv_bar_t = LvNumber("lv_bar_t")
|
||||
|
@ -145,6 +145,11 @@ lv_tileview_t = LvType(
|
|||
largs=[(lv_obj_t_ptr, "tile")],
|
||||
lvalue=lambda w: f"lv_tileview_get_tile_act({w.obj})",
|
||||
)
|
||||
lv_tabview_t = LvType(
|
||||
"lv_tabview_t",
|
||||
largs=[(lv_obj_t_ptr, "tab")],
|
||||
lvalue=lambda w: f"lv_obj_get_child(lv_tabview_get_content({w.obj}), lv_tabview_get_tab_act({w.obj}))",
|
||||
)
|
||||
lv_spinner_t = lv_obj_t
|
||||
lv_ticks_t = lv_obj_t
|
||||
lv_tick_style_t = lv_obj_t
|
||||
|
|
|
@ -56,7 +56,7 @@ select:
|
|||
animated: true
|
||||
|
||||
image:
|
||||
- id: cat_image
|
||||
- id: cat_img
|
||||
file: $component_dir/cat.png
|
||||
- id: dog_img
|
||||
file: $component_dir/dog.png
|
||||
|
@ -82,7 +82,7 @@ lvgl:
|
|||
default_font: montserrat_14
|
||||
bg_color: my_light_red
|
||||
disp_bg_color: my_light_red
|
||||
disp_bg_image: cat_image
|
||||
disp_bg_image: cat_img
|
||||
style_definitions:
|
||||
- id: style_test
|
||||
bg_color: 0x2F8CD8
|
||||
|
@ -361,7 +361,7 @@ lvgl:
|
|||
r_mod: -4
|
||||
- img:
|
||||
id: needle_img
|
||||
src: cat_image
|
||||
src: cat_img
|
||||
value: 4
|
||||
pivot_x: 31
|
||||
pivot_y: 9
|
||||
|
@ -422,7 +422,7 @@ lvgl:
|
|||
flex_align_cross: center
|
||||
flex_align_track: start
|
||||
align: CENTER
|
||||
src: cat_image
|
||||
src: cat_img
|
||||
id: img_id
|
||||
radius: 11
|
||||
clip_corner: true
|
||||
|
@ -434,7 +434,7 @@ lvgl:
|
|||
- animimg:
|
||||
align: CENTER
|
||||
id: anim_id
|
||||
src: [cat_image, dog_img]
|
||||
src: [cat_img, dog_img]
|
||||
duration: 600ms
|
||||
on_click:
|
||||
then:
|
||||
|
@ -493,31 +493,71 @@ lvgl:
|
|||
then:
|
||||
- logger.log: "Cat tile is now showing"
|
||||
tiles:
|
||||
- img:
|
||||
tile_id: cat_tile
|
||||
dir: [LEFT, top]
|
||||
row: 0
|
||||
column: 0
|
||||
align: center
|
||||
src: cat_image
|
||||
on_click:
|
||||
then:
|
||||
- lvgl.tileview.select:
|
||||
id: tv_id
|
||||
row: 1
|
||||
column: 0
|
||||
animated: false
|
||||
- id: cat_tile
|
||||
dir: [LEFT, top]
|
||||
row: 0
|
||||
column: 0
|
||||
widgets:
|
||||
- img:
|
||||
align: center
|
||||
src: cat_img
|
||||
on_click:
|
||||
then:
|
||||
- lvgl.tileview.select:
|
||||
id: tv_id
|
||||
row: 1
|
||||
column: 0
|
||||
animated: false
|
||||
|
||||
- img:
|
||||
row: 1
|
||||
column: 0
|
||||
src: dog_img
|
||||
on_click:
|
||||
- id: dog_tile
|
||||
row: 1
|
||||
column: 0
|
||||
widgets:
|
||||
- img:
|
||||
src: dog_img
|
||||
on_click:
|
||||
then:
|
||||
- lvgl.tileview.select:
|
||||
id: tv_id
|
||||
tile_id: cat_tile
|
||||
animated: true
|
||||
- id: tabview_page
|
||||
widgets:
|
||||
- tabview:
|
||||
id: tabview_id
|
||||
width: 100%
|
||||
height: 100%
|
||||
position: top
|
||||
on_value:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: return tab == id(tabview_tab_1);
|
||||
then:
|
||||
- lvgl.tileview.select:
|
||||
id: tv_id
|
||||
tile_id: cat_tile
|
||||
animated: true
|
||||
- logger.log: "Dog tab is now showing"
|
||||
tabs:
|
||||
- name: Tab1
|
||||
id: tabview_tab_1
|
||||
widgets:
|
||||
- img:
|
||||
src: dog_img
|
||||
on_click:
|
||||
then:
|
||||
- lvgl.tabview.select:
|
||||
id: tabview_id
|
||||
tab_id: tabview_tab_2
|
||||
animated: true
|
||||
- name: Tab1
|
||||
id: tabview_tab_2
|
||||
widgets:
|
||||
- img:
|
||||
src: cat_img
|
||||
on_click:
|
||||
then:
|
||||
- lvgl.tabview.select:
|
||||
id: tabview_id
|
||||
tab_id: tabview_tab_1
|
||||
animated: true
|
||||
- id: keyboard_page
|
||||
widgets:
|
||||
- label:
|
||||
|
|
Loading…
Reference in New Issue