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:
parent
3d47e80de6
commit
1f750ea779
1 changed files with 209 additions and 198 deletions
|
|
@ -7,215 +7,226 @@ lvgl:
|
||||||
pages:
|
pages:
|
||||||
- id: page_home
|
- id: page_home
|
||||||
widgets:
|
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:
|
- obj:
|
||||||
id: mode_toggle
|
width: 100%
|
||||||
align: top_mid
|
height: 100%
|
||||||
y: 12
|
pad_all: 0
|
||||||
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
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
outline_width: 0
|
outline_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
layout:
|
|
||||||
type: flex
|
|
||||||
flex_flow: column
|
|
||||||
flex_align_cross: center
|
|
||||||
flex_align_track: center
|
|
||||||
flex_align_main: center
|
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
id: home_mode_label
|
align: top_left
|
||||||
text: "Mode: --"
|
x: 70
|
||||||
text_font: montserrat_20
|
y: 20
|
||||||
- label:
|
text: "-- --" # static placeholder clock — live time is a fast-follow, no time: component this pass
|
||||||
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
|
text_font: montserrat_16
|
||||||
- button:
|
- obj:
|
||||||
align: bottom_mid
|
id: mode_toggle
|
||||||
x: -110
|
align: top_mid
|
||||||
y: -24
|
y: 12
|
||||||
width: 90px
|
width: 400px
|
||||||
height: 60px
|
height: 44px
|
||||||
radius: 30
|
radius: 22
|
||||||
widgets:
|
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:
|
- 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
|
align: center
|
||||||
text: "70"
|
y: -20
|
||||||
text_font: montserrat_20
|
width: 400px
|
||||||
- button:
|
height: 400px
|
||||||
align: bottom_mid
|
start_angle: 315
|
||||||
x: 110
|
end_angle: 225
|
||||||
y: -24
|
min_value: 0
|
||||||
width: 90px
|
max_value: 1
|
||||||
height: 60px
|
value: 0
|
||||||
radius: 30
|
adjustable: false
|
||||||
widgets:
|
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:
|
- label:
|
||||||
id: cool_to_value_label
|
align: bottom_right
|
||||||
align: center
|
x: -24
|
||||||
text: "75"
|
y: -24
|
||||||
|
text: "-- °" # outside temp stub — weather data source deferred per design spec
|
||||||
text_font: montserrat_20
|
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
|
- id: page_sensors
|
||||||
widgets:
|
widgets:
|
||||||
- obj:
|
- obj:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue