fix: wrap classic Home screen in a sized container, separate dial arc radii

Two bugs found on first hardware test:

1. page_home placed all widgets directly on the page with no sized
   wrapper container, unlike every other page in this codebase (which
   all wrap content in an explicit width/height obj before using
   align:). The dial and its siblings rendered tiny and pinned to the
   top-left instead of filling/centering on the real 1024x600 screen.
   Wrapped all of page_home's content in a width:100%/height:100% obj,
   matching the established pattern.

2. heat_arc and cool_arc were both adjustable:true at the identical
   400x400 size, so their rings occupied the same physical pixels.
   LVGL hit-tests arcs by distance from center, so a shared radius is
   touch-ambiguous, and the topmost widget (cool_arc, declared last)
   won every touch regardless of where on the ring you tapped. Shrunk
   cool_arc to 360x360 so the two rings are physically distinguishable
   by touch position.
This commit is contained in:
pyr0ball 2026-07-12 10:02:56 -07:00
parent 3d47e80de6
commit 1f750ea779

View file

@ -7,215 +7,226 @@ lvgl:
pages:
- id: page_home
widgets:
- label:
align: top_left
x: 70
y: 20
text: "-- --" # static placeholder clock — live time is a fast-follow, no time: component this pass
text_font: montserrat_16
- obj:
id: mode_toggle
align: top_mid
y: 12
width: 400px
height: 44px
radius: 22
bg_color: 0x333333
border_width: 0
outline_width: 0
pad_all: 4
scrollable: false
layout:
type: flex
flex_flow: row
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- button:
width: 120px
height: 36px
radius: 18
bg_color: 0xFFFFFF
widgets:
- label:
text: "Temp"
text_color: 0x000000
text_font: montserrat_16
- button:
width: 120px
height: 36px
radius: 18
bg_opa: transp
widgets:
- label:
text: "Status"
text_font: montserrat_16
- button:
width: 120px
height: 36px
radius: 18
bg_opa: transp
widgets:
- label:
text: "My Home"
text_font: montserrat_16
- label:
align: top_right
x: -16
y: 20
text: "Firecrest"
text_font: montserrat_16
- arc:
id: dial_bg_arc
align: center
y: -20
width: 400px
height: 400px
start_angle: 315
end_angle: 225
min_value: 0
max_value: 1
value: 0
adjustable: false
main:
arc_color: 0x444444
arc_width: 10
indicator:
arc_opa: transp
knob:
arc_opa: transp
- arc:
id: heat_arc
align: center
y: -20
width: 400px
height: 400px
start_angle: 315
end_angle: 225
min_value: 60
max_value: 90
value: 70
adjustable: true
main:
arc_opa: transp
indicator:
arc_color: 0xFF3B30
arc_width: 10
knob:
bg_color: 0xFF3B30
on_value:
then:
- climate.control:
id: main_thermostat
target_temperature_low: !lambda "return (x - 32.0f) * 5.0f / 9.0f;"
- lvgl.label.update:
id: heat_to_value_label
text:
format: "%.0f"
args: ["x"]
- arc:
id: cool_arc
align: center
y: -20
width: 400px
height: 400px
start_angle: 315
end_angle: 225
mode: REVERSE
min_value: 60
max_value: 90
value: 75
adjustable: true
main:
arc_opa: transp
indicator:
arc_color: 0x0A84FF
arc_width: 10
knob:
bg_color: 0x0A84FF
on_value:
then:
- climate.control:
id: main_thermostat
target_temperature_high: !lambda "return (x - 32.0f) * 5.0f / 9.0f;"
- lvgl.label.update:
id: cool_to_value_label
text:
format: "%.0f"
args: ["x"]
- obj:
align: center
y: -40
width: 200px
height: size_content
width: 100%
height: 100%
pad_all: 0
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: column
flex_align_cross: center
flex_align_track: center
flex_align_main: center
widgets:
- label:
id: home_mode_label
text: "Mode: --"
text_font: montserrat_20
- label:
id: home_temp_label
text: "-- °C"
text_font: montserrat_48
- button:
align: bottom_left
x: 24
y: -24
width: 90px
height: 90px
radius: 45
on_click:
climate.control:
id: main_thermostat
preset: away
widgets:
- label:
align: center
y: -10
text: "Away"
align: top_left
x: 70
y: 20
text: "-- --" # static placeholder clock — live time is a fast-follow, no time: component this pass
text_font: montserrat_16
- button:
align: bottom_mid
x: -110
y: -24
width: 90px
height: 60px
radius: 30
widgets:
- obj:
id: mode_toggle
align: top_mid
y: 12
width: 400px
height: 44px
radius: 22
bg_color: 0x333333
border_width: 0
outline_width: 0
pad_all: 4
scrollable: false
layout:
type: flex
flex_flow: row
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- button:
width: 120px
height: 36px
radius: 18
bg_color: 0xFFFFFF
widgets:
- label:
text: "Temp"
text_color: 0x000000
text_font: montserrat_16
- button:
width: 120px
height: 36px
radius: 18
bg_opa: transp
widgets:
- label:
text: "Status"
text_font: montserrat_16
- button:
width: 120px
height: 36px
radius: 18
bg_opa: transp
widgets:
- label:
text: "My Home"
text_font: montserrat_16
- label:
id: heat_to_value_label
align: top_right
x: -16
y: 20
text: "Firecrest"
text_font: montserrat_16
- arc:
id: dial_bg_arc
align: center
text: "70"
text_font: montserrat_20
- button:
align: bottom_mid
x: 110
y: -24
width: 90px
height: 60px
radius: 30
widgets:
y: -20
width: 400px
height: 400px
start_angle: 315
end_angle: 225
min_value: 0
max_value: 1
value: 0
adjustable: false
main:
arc_color: 0x444444
arc_width: 10
indicator:
arc_opa: transp
knob:
arc_opa: transp
- arc:
id: heat_arc
align: center
y: -20
width: 400px
height: 400px
start_angle: 315
end_angle: 225
min_value: 60
max_value: 90
value: 70
adjustable: true
main:
arc_opa: transp
indicator:
arc_color: 0xFF3B30
arc_width: 10
knob:
bg_color: 0xFF3B30
on_value:
then:
- climate.control:
id: main_thermostat
target_temperature_low: !lambda "return (x - 32.0f) * 5.0f / 9.0f;"
- lvgl.label.update:
id: heat_to_value_label
text:
format: "%.0f"
args: ["x"]
- arc:
id: cool_arc
align: center
y: -20
width: 360px # smaller radius than heat_arc (400px) so the two rings occupy
height: 360px # different physical pixels — LVGL hit-tests arcs by distance
# from center, and two arcs at the same radius are touch-ambiguous;
# the topmost one (this one, declared last) always wins regardless
# of where along the ring you actually tap
start_angle: 315
end_angle: 225
mode: REVERSE
min_value: 60
max_value: 90
value: 75
adjustable: true
main:
arc_opa: transp
indicator:
arc_color: 0x0A84FF
arc_width: 10
knob:
bg_color: 0x0A84FF
on_value:
then:
- climate.control:
id: main_thermostat
target_temperature_high: !lambda "return (x - 32.0f) * 5.0f / 9.0f;"
- lvgl.label.update:
id: cool_to_value_label
text:
format: "%.0f"
args: ["x"]
- obj:
align: center
y: -40
width: 200px
height: size_content
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: column
flex_align_cross: center
flex_align_track: center
flex_align_main: center
widgets:
- label:
id: home_mode_label
text: "Mode: --"
text_font: montserrat_20
- label:
id: home_temp_label
text: "-- °C"
text_font: montserrat_48
- button:
align: bottom_left
x: 24
y: -24
width: 90px
height: 90px
radius: 45
on_click:
climate.control:
id: main_thermostat
preset: away
widgets:
- label:
align: center
y: -10
text: "Away"
text_font: montserrat_16
- button:
align: bottom_mid
x: -110
y: -24
width: 90px
height: 60px
radius: 30
widgets:
- label:
id: heat_to_value_label
align: center
text: "70"
text_font: montserrat_20
- button:
align: bottom_mid
x: 110
y: -24
width: 90px
height: 60px
radius: 30
widgets:
- label:
id: cool_to_value_label
align: center
text: "75"
text_font: montserrat_20
- label:
id: cool_to_value_label
align: center
text: "75"
align: bottom_right
x: -24
y: -24
text: "-- °" # outside temp stub — weather data source deferred per design spec
text_font: montserrat_20
- label:
align: bottom_right
x: -24
y: -24
text: "-- °" # outside temp stub — weather data source deferred per design spec
text_font: montserrat_20
- id: page_sensors
widgets:
- obj: