mirror of
https://github.com/esphome/esphome.git
synced 2025-07-28 06:06:33 +00:00
[lvgl] Allow linear positioning of grid cells (#9196)
This commit is contained in:
parent
f35be6b5cc
commit
6d0c6329ad
@ -466,7 +466,7 @@ LVGL_SCHEMA = cv.All(
|
||||
): lvalid.lv_color,
|
||||
cv.Optional(df.CONF_THEME): cv.Schema(
|
||||
{
|
||||
cv.Optional(name): obj_schema(w)
|
||||
cv.Optional(name): obj_schema(w).extend(FULL_STYLE_SCHEMA)
|
||||
for name, w in WIDGET_TYPES.items()
|
||||
}
|
||||
),
|
||||
|
@ -21,7 +21,7 @@ from esphome.core.config import StartupTrigger
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT
|
||||
|
||||
from . import defines as df, lv_validation as lvalid
|
||||
from .defines import CONF_TIME_FORMAT, LV_GRAD_DIR
|
||||
from .defines import CONF_TIME_FORMAT, LV_GRAD_DIR, TYPE_GRID
|
||||
from .helpers import add_lv_use, requires_component, validate_printf
|
||||
from .lv_validation import lv_color, lv_font, lv_gradient, lv_image, opacity
|
||||
from .lvcode import LvglComponent, lv_event_t_ptr
|
||||
@ -349,7 +349,60 @@ def obj_schema(widget_type: WidgetType):
|
||||
)
|
||||
|
||||
|
||||
def _validate_grid_layout(config):
|
||||
layout = config[df.CONF_LAYOUT]
|
||||
rows = len(layout[df.CONF_GRID_ROWS])
|
||||
columns = len(layout[df.CONF_GRID_COLUMNS])
|
||||
used_cells = [[None] * columns for _ in range(rows)]
|
||||
for index, widget in enumerate(config[df.CONF_WIDGETS]):
|
||||
_, w = next(iter(widget.items()))
|
||||
if (df.CONF_GRID_CELL_COLUMN_POS in w) != (df.CONF_GRID_CELL_ROW_POS in w):
|
||||
# pylint: disable=raise-missing-from
|
||||
raise cv.Invalid(
|
||||
"Both row and column positions must be specified, or both omitted",
|
||||
[df.CONF_WIDGETS, index],
|
||||
)
|
||||
if df.CONF_GRID_CELL_ROW_POS in w:
|
||||
row = w[df.CONF_GRID_CELL_ROW_POS]
|
||||
column = w[df.CONF_GRID_CELL_COLUMN_POS]
|
||||
else:
|
||||
try:
|
||||
row, column = next(
|
||||
(r_idx, c_idx)
|
||||
for r_idx, row in enumerate(used_cells)
|
||||
for c_idx, value in enumerate(row)
|
||||
if value is None
|
||||
)
|
||||
except StopIteration:
|
||||
# pylint: disable=raise-missing-from
|
||||
raise cv.Invalid(
|
||||
"No free cells available in grid layout", [df.CONF_WIDGETS, index]
|
||||
)
|
||||
w[df.CONF_GRID_CELL_ROW_POS] = row
|
||||
w[df.CONF_GRID_CELL_COLUMN_POS] = column
|
||||
|
||||
for i in range(w[df.CONF_GRID_CELL_ROW_SPAN]):
|
||||
for j in range(w[df.CONF_GRID_CELL_COLUMN_SPAN]):
|
||||
if row + i >= rows or column + j >= columns:
|
||||
# pylint: disable=raise-missing-from
|
||||
raise cv.Invalid(
|
||||
f"Cell at {row}/{column} span {w[df.CONF_GRID_CELL_ROW_SPAN]}x{w[df.CONF_GRID_CELL_COLUMN_SPAN]} "
|
||||
f"exceeds grid size {rows}x{columns}",
|
||||
[df.CONF_WIDGETS, index],
|
||||
)
|
||||
if used_cells[row + i][column + j] is not None:
|
||||
# pylint: disable=raise-missing-from
|
||||
raise cv.Invalid(
|
||||
f"Cell span {row + i}/{column + j} already occupied by widget at index {used_cells[row + i][column + j]}",
|
||||
[df.CONF_WIDGETS, index],
|
||||
)
|
||||
used_cells[row + i][column + j] = index
|
||||
|
||||
return config
|
||||
|
||||
|
||||
LAYOUT_SCHEMAS = {}
|
||||
LAYOUT_VALIDATORS = {TYPE_GRID: _validate_grid_layout}
|
||||
|
||||
ALIGN_TO_SCHEMA = {
|
||||
cv.Optional(df.CONF_ALIGN_TO): cv.Schema(
|
||||
@ -402,8 +455,8 @@ LAYOUT_SCHEMA = {
|
||||
}
|
||||
|
||||
GRID_CELL_SCHEMA = {
|
||||
cv.Required(df.CONF_GRID_CELL_ROW_POS): cv.positive_int,
|
||||
cv.Required(df.CONF_GRID_CELL_COLUMN_POS): cv.positive_int,
|
||||
cv.Optional(df.CONF_GRID_CELL_ROW_POS): cv.positive_int,
|
||||
cv.Optional(df.CONF_GRID_CELL_COLUMN_POS): cv.positive_int,
|
||||
cv.Optional(df.CONF_GRID_CELL_ROW_SPAN, default=1): cv.positive_int,
|
||||
cv.Optional(df.CONF_GRID_CELL_COLUMN_SPAN, default=1): cv.positive_int,
|
||||
cv.Optional(df.CONF_GRID_CELL_X_ALIGN): grid_alignments,
|
||||
@ -474,7 +527,10 @@ def container_validator(schema, widget_type: WidgetType):
|
||||
result = result.extend(
|
||||
LAYOUT_SCHEMAS.get(ltype.lower(), LAYOUT_SCHEMAS[df.TYPE_NONE])
|
||||
)
|
||||
return result(value)
|
||||
value = result(value)
|
||||
if layout_validator := LAYOUT_VALIDATORS.get(ltype):
|
||||
value = layout_validator(value)
|
||||
return value
|
||||
|
||||
return validator
|
||||
|
||||
|
@ -839,9 +839,7 @@ lvgl:
|
||||
styles: bdr_style
|
||||
grid_cell_x_align: center
|
||||
grid_cell_y_align: stretch
|
||||
grid_cell_row_pos: 0
|
||||
grid_cell_column_pos: 1
|
||||
grid_cell_column_span: 1
|
||||
grid_cell_column_span: 2
|
||||
text: "Grid cell 0/1"
|
||||
- label:
|
||||
grid_cell_x_align: end
|
||||
|
Loading…
x
Reference in New Issue
Block a user