Smooth graphs, sun path card, skeleton page switches and editor drag & drop

Firmware 0.2.15: trend graphs use a Catmull-Rom curve with a soft fill
drawn by the card's draw event; sun.sun gets a wide sun-path card with
horizon, arc and the sun at its current position; page switches show
the new page's card frames immediately and fill them from a one-shot
timer; the navigation is one full-width bar without a divider; the CYD
adopts the Guition light palette in styles and overlays.

App 0.2.13: pointer-based drag & drop (mouse and touch) to reorder tiles
in the mockup and to drop entities from the list, sticky save bar, a new
header with explained actions and a three-step guide, clearer firmware
dialog. New sun, weather and clock tiles start wide in their best view.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-13 09:09:37 +02:00
parent 517b102786
commit 4af92e1b4c
15 changed files with 807 additions and 321 deletions
+120 -103
View File
@@ -58,7 +58,7 @@
############################################################
substitutions:
SCREEN_FIRMWARE_VERSION: "0.2.14"
SCREEN_FIRMWARE_VERSION: "0.2.15"
DYNAMIC_TILES: "false"
DASHBOARD_INBOX_INTERNAL: "true"
DEVICE_NAME: "cyd-new"
@@ -643,8 +643,8 @@ substitutions:
OVERLAY_SLIDER_W: "96"
OVERLAY_SLIDER_H: "160"
OVERLAY_ICON_Y: "74"
BG_TOP_COLOR: "0xAEC4D9" # achtergrond boven (zacht blauw)
BG_BOTTOM_COLOR: "0xD6BB9E" # achtergrond onder (warm zand)
BG_TOP_COLOR: "0xE7E7E7" # lichte achtergrond, gelijk aan de Guition
BG_BOTTOM_COLOR: "0xE7E7E7"
TILE_ICON_X: "0"
TILE_ICON_Y: "0"
TILE_TITLE_X: "48"
@@ -809,6 +809,7 @@ esphome:
settings.night_start = atoi("${NIGHT_START_HOUR}") * 60;
settings.night_end = atoi("${NIGHT_END_HOUR}") * 60;
settings.night_brightness = atoi("${NIGHT_DIM_BRIGHTNESS}");
runtime_tiles::light_theme = true;
runtime_tiles::watch_font = id(headline)->get_lv_font();
runtime_tiles::watch_value_font = id(watch_value)->get_lv_font();
runtime_tiles::watch_icon_font = id(watch_icon)->get_lv_font();
@@ -898,7 +899,7 @@ esphome:
- lambda: |-
static const char *entities[] = {"${TILE1_ENTITY}", "${TILE2_ENTITY}", "${TILE3_ENTITY}", "${TILE4_ENTITY}", "${TILE5_ENTITY}", "${TILE6_ENTITY}", "${TILE7_ENTITY}", "${TILE9_ENTITY}"};
if (!runtime_tiles::enabled) light_controls::subscribe(entities, 8);
light_controls::setup(id(color_detail_overlay), id(sublabel)->get_lv_font(), atoi("${DISPLAY_W}"), atoi("${DISPLAY_H}"));
light_controls::setup(id(color_detail_overlay), id(sublabel)->get_lv_font(), atoi("${DISPLAY_W}"), atoi("${DISPLAY_H}"), true);
light_controls::commits[0] = [](int value) { id(set_light_hue).execute(value); };
light_controls::commits[1] = [](int value) { id(set_light_color_temperature).execute(value); };
light_controls::commits[2] = [](int value) { id(color_brightness_commit).execute(value); };
@@ -2059,7 +2060,9 @@ lvgl:
bg_color: 0xFFFFFF
bg_opa: COVER
radius: 18
border_width: 0
border_width: 1
border_color: 0xDDDDDD
border_opa: COVER
pad_left: 8
pad_right: 8
pad_top: 8
@@ -2068,10 +2071,12 @@ lvgl:
shadow_opa: 40%
- id: style_tile_disabled
bg_color: 0x939391
bg_color: 0xFFFFFF
bg_opa: COVER
radius: 18
border_width: 0
border_width: 1
border_color: 0xDDDDDD
border_opa: COVER
pad_left: 8
pad_right: 8
pad_top: 8
@@ -2080,25 +2085,25 @@ lvgl:
shadow_opa: 25%
- id: style_icon_circle
bg_color: 0xFEC600
bg_color: 0xD5EEFC
bg_opa: COVER
radius: 999
border_width: 0
- id: style_icon_circle_disabled
bg_color: 0x7B7B6F
bg_color: 0xEEEEEE
bg_opa: COVER
radius: 999
border_width: 0
- id: style_room
text_font: headline
text_color: 0xFFFFFF
text_color: 0x1B1B1B
text_opa: 100%
- id: style_time
text_font: time_label
text_color: 0xFFFFFF
text_color: 0x1B1B1B
text_opa: 100%
- id: style_title
@@ -2113,17 +2118,17 @@ lvgl:
- id: style_value_big
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
text_opa: 80%
- id: style_title_disabled
text_font: label
text_color: 0xFFFFFF
text_color: 0x1B1B1B
text_opa: 100%
- id: style_value_disabled
text_font: sublabel
text_color: 0xD9D9D9
text_color: 0x1B1B1B
text_opa: 100%
pages:
@@ -3364,19 +3369,22 @@ lvgl:
was_on: false
# ---------- VALUE SLIDER OVERLAY ----------
# ---------- PAGE NAVIGATION: one full-width bar ----------
- obj:
id: page_prev
align: BOTTOM_LEFT
x: 9
y: -2
width: 100
x: 0
y: 0
width: 130
height: 32
pad_all: 0
radius: 8
bg_color: 0x3C3C40
bg_opa: COVER
radius: 0
bg_opa: TRANSP
border_width: 0
scrollable: false
pressed:
bg_color: 0xE3E3E3
bg_opa: COVER
on_short_click:
- if:
condition:
@@ -3386,31 +3394,39 @@ lvgl:
- script.execute: show_tile_page
widgets:
- label:
align: CENTER
text: "< Vorige"
text_font: sublabel
text_color: 0xFFFFFF
align: LEFT_MID
x: 12
text: "< Vorige"
text_font: label
text_color: 0x1B1B1B
clickable: false
- label:
id: page_number
align: BOTTOM_MID
y: -9
y: 0
width: 60
height: 32
pad_top: 9
border_width: 0
text: "1 / 2"
text_align: CENTER
text_font: sublabel
text_color: 0xFFFFFF
text_color: 0x1B1B1B
- obj:
id: page_next
align: BOTTOM_RIGHT
x: -9
y: -2
width: 100
x: 0
y: 0
width: 130
height: 32
pad_all: 0
radius: 8
bg_color: 0x3C3C40
bg_opa: COVER
radius: 0
bg_opa: TRANSP
border_width: 0
scrollable: false
pressed:
bg_color: 0xE3E3E3
bg_opa: COVER
on_short_click:
- if:
condition:
@@ -3420,10 +3436,11 @@ lvgl:
- script.execute: show_tile_page
widgets:
- label:
align: CENTER
text: "Volgende >"
text_font: sublabel
text_color: 0xFFFFFF
align: RIGHT_MID
x: -12
text: "Volgende >"
text_font: label
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -3460,7 +3477,7 @@ lvgl:
y: 0
width: ${DISPLAY_W}
height: ${DISPLAY_H}
bg_color: 0x000000
bg_color: 0xFFFFFF
bg_opa: 18%
border_width: 0
clickable: false
@@ -3491,7 +3508,7 @@ lvgl:
value: 100
adv_hittest: false
bg_color: 0x939391
bg_color: 0xFFFFFF
bg_opa: 100%
radius: 28
# Enige widget met ZOWEL radius ALS een kind (overlay_icon).
@@ -3504,7 +3521,7 @@ lvgl:
border_width: 0
indicator:
bg_color: 0xFEC600
bg_color: 0xD5EEFC
bg_opa: 100%
radius: 28
@@ -3536,7 +3553,7 @@ lvgl:
align: CENTER
y: ${OVERLAY_ICON_Y}
text_font: materialdesign_icons
text_color: 0xFFFFFF
text_color: 0x1B1B1B
text: "${TILE1_ICON}"
clickable: false
@@ -3745,7 +3762,7 @@ lvgl:
y: 0
width: ${DISPLAY_W}
height: ${DISPLAY_H}
bg_color: 0x171719
bg_color: 0xF7F7F7
bg_opa: COVER
hidden: true
scrollable: false
@@ -3771,7 +3788,7 @@ lvgl:
y: 0
width: ${DISPLAY_W}
height: ${DISPLAY_H}
bg_color: 0x000000
bg_color: 0xFFFFFF
bg_opa: 72%
border_width: 0
clickable: false
@@ -3785,7 +3802,7 @@ lvgl:
width: 36
height: 36
radius: 999
bg_color: 0x3C3C40
bg_color: 0xEEEEEE
bg_opa: COVER
border_width: 1
border_color: 0xFFFFFF
@@ -3799,7 +3816,7 @@ lvgl:
align: CENTER
text: "x"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- label:
@@ -3832,7 +3849,7 @@ lvgl:
align: CENTER
text: "\U000F012C"
text_font: materialdesign_icons
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
# ---------- CLIMATE DETAIL OVERLAY ----------
@@ -3842,7 +3859,7 @@ lvgl:
y: 0
width: ${DISPLAY_W}
height: ${DISPLAY_H}
bg_color: 0x171719
bg_color: 0xF7F7F7
bg_opa: COVER
hidden: true
scrollable: false
@@ -3868,7 +3885,7 @@ lvgl:
y: 0
width: ${DISPLAY_W}
height: ${DISPLAY_H}
bg_color: 0x000000
bg_color: 0xFFFFFF
bg_opa: 62%
border_width: 0
clickable: false
@@ -3884,7 +3901,7 @@ lvgl:
width: 44
height: 44
radius: 999
bg_color: 0x3C3C40
bg_color: 0xEEEEEE
bg_opa: COVER
border_width: 1
border_color: 0xFFFFFF
@@ -3898,7 +3915,7 @@ lvgl:
align: CENTER
text: "x"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -3909,7 +3926,7 @@ lvgl:
width: 44
height: 44
radius: 999
bg_color: 0xFEC600
bg_color: 0xD5EEFC
bg_opa: COVER
border_width: 0
clickable: true
@@ -3921,7 +3938,7 @@ lvgl:
align: CENTER
text: "\U000F012C"
text_font: materialdesign_icons
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- label:
@@ -3937,7 +3954,7 @@ lvgl:
y: 42
text: "Current: --"
text_font: sublabel_big
text_color: 0xD1E8FF
text_color: 0x1B1B1B
text_opa: 85%
clickable: false
@@ -3988,7 +4005,7 @@ lvgl:
y: -16
text: "SET TO"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
text_opa: 68%
clickable: false
@@ -3998,7 +4015,7 @@ lvgl:
y: 20
text: "20.0°"
text_font: headline
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4009,7 +4026,7 @@ lvgl:
width: 48
height: 36
radius: 18
bg_color: 0x3C3C40
bg_color: 0xEEEEEE
bg_opa: COVER
border_width: 1
border_color: 0xFFFFFF
@@ -4025,7 +4042,7 @@ lvgl:
align: CENTER
text: "-"
text_font: headline
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4036,7 +4053,7 @@ lvgl:
width: 48
height: 36
radius: 18
bg_color: 0x3C3C40
bg_color: 0xEEEEEE
bg_opa: COVER
border_width: 1
border_color: 0xFFFFFF
@@ -4052,7 +4069,7 @@ lvgl:
align: CENTER
text: "+"
text_font: headline
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4062,7 +4079,7 @@ lvgl:
width: 126
height: 34
radius: 17
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 82%
border_width: 0
clickable: true
@@ -4075,7 +4092,7 @@ lvgl:
align: CENTER
text: "Auto"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
# ---------- CLIMATE MODE PICKER ----------
# Vervangt het doorcyclen van modi. Cyclen stuurt bij elke tik een
@@ -4089,7 +4106,7 @@ lvgl:
width: ${DISPLAY_W}
height: ${DISPLAY_H}
hidden: true
bg_color: 0x000000
bg_color: 0xFFFFFF
bg_opa: 90%
border_width: 0
clickable: true
@@ -4101,7 +4118,7 @@ lvgl:
y: 16
text: "Mode"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
# Flex zorgt dat niet-ondersteunde modi geen gat achterlaten:
@@ -4128,7 +4145,7 @@ lvgl:
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4141,14 +4158,14 @@ lvgl:
align: CENTER
text: "Off"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: cmode_heat
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4161,14 +4178,14 @@ lvgl:
align: CENTER
text: "Heat"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: cmode_cool
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4181,14 +4198,14 @@ lvgl:
align: CENTER
text: "Cool"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: cmode_heat_cool
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4201,14 +4218,14 @@ lvgl:
align: CENTER
text: "Heat/Cool"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: cmode_auto
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4221,14 +4238,14 @@ lvgl:
align: CENTER
text: "Auto"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: cmode_dry
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4241,14 +4258,14 @@ lvgl:
align: CENTER
text: "Dry"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: cmode_fan_only
width: 132
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4261,7 +4278,7 @@ lvgl:
align: CENTER
text: "Fan"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4272,7 +4289,7 @@ lvgl:
width: 36
height: 36
radius: 999
bg_color: 0x3C3C40
bg_color: 0xEEEEEE
bg_opa: COVER
border_width: 1
border_color: 0xFFFFFF
@@ -4286,7 +4303,7 @@ lvgl:
align: CENTER
text: "x"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4297,7 +4314,7 @@ lvgl:
width: 36
height: 36
radius: 999
bg_color: 0xFEC600
bg_color: 0xD5EEFC
bg_opa: COVER
border_width: 0
clickable: true
@@ -4309,7 +4326,7 @@ lvgl:
align: CENTER
text: "\U000F012C"
text_font: materialdesign_icons
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
# ---------- VACUUM CONTROL ----------
@@ -4322,7 +4339,7 @@ lvgl:
width: ${DISPLAY_W}
height: ${DISPLAY_H}
hidden: true
bg_color: 0x000000
bg_color: 0xFFFFFF
bg_opa: 90%
border_width: 0
clickable: true
@@ -4335,7 +4352,7 @@ lvgl:
y: 16
text: "Vacuum"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4360,7 +4377,7 @@ lvgl:
width: 72
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4373,14 +4390,14 @@ lvgl:
align: CENTER
text: "Start"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: vac_pause
width: 72
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4393,14 +4410,14 @@ lvgl:
align: CENTER
text: "Pause"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: vac_return_to_base
width: 72
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4413,14 +4430,14 @@ lvgl:
align: CENTER
text: "Dock"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: vac_stop
width: 72
height: 38
radius: 19
bg_color: 0x2C2C30
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4433,7 +4450,7 @@ lvgl:
align: CENTER
text: "Stop"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- label:
@@ -4441,7 +4458,7 @@ lvgl:
y: 138
text: "Suction"
text_font: sublabel
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4466,7 +4483,7 @@ lvgl:
width: 72
height: 32
radius: 19
bg_color: 0x1F1F23
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4481,14 +4498,14 @@ lvgl:
align: CENTER
text: "Quiet"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: vacspd_balanced
width: 72
height: 32
radius: 19
bg_color: 0x1F1F23
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4503,14 +4520,14 @@ lvgl:
align: CENTER
text: "Balanced"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: vacspd_turbo
width: 72
height: 32
radius: 19
bg_color: 0x1F1F23
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4525,14 +4542,14 @@ lvgl:
align: CENTER
text: "Turbo"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
id: vacspd_max
width: 72
height: 32
radius: 19
bg_color: 0x1F1F23
bg_color: 0xF0F0F0
bg_opa: 92%
border_width: 0
clickable: true
@@ -4547,7 +4564,7 @@ lvgl:
align: CENTER
text: "Max"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4558,7 +4575,7 @@ lvgl:
width: 36
height: 36
radius: 999
bg_color: 0x3C3C40
bg_color: 0xEEEEEE
bg_opa: COVER
border_width: 1
border_color: 0xFFFFFF
@@ -4572,7 +4589,7 @@ lvgl:
align: CENTER
text: "x"
text_font: sublabel_big
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
- obj:
@@ -4583,7 +4600,7 @@ lvgl:
width: 36
height: 36
radius: 999
bg_color: 0xFEC600
bg_color: 0xD5EEFC
bg_opa: COVER
border_width: 0
clickable: true
@@ -4595,7 +4612,7 @@ lvgl:
align: CENTER
text: "\U000F012C"
text_font: materialdesign_icons
text_color: 0xFFFFFF
text_color: 0x1B1B1B
clickable: false
# ---------- DIM / WAKE OVERLAY ----------