1212#endif
1313#include < vector>
1414#include " ESPNowUtils.h"
15+
16+ // Card colours for the dark theme (0xRRGGBB): background, border, name/value text.
17+ struct CardColors { uint32_t bg; uint32_t border; uint32_t nameC; uint32_t valueC; };
1518/* ******************************************************************************
1619 * Please configure the touch panel in touch.h
1720 ******************************************************************************/
@@ -121,6 +124,18 @@ void initUI() {
121124
122125 lv_scr_load (mainScreen);
123126
127+ // ---- Dark theme ----
128+ lv_disp_t *dispp = lv_disp_get_default ();
129+ lv_theme_t *th = lv_theme_default_init (dispp,
130+ lv_color_hex (0x33bdef ) /* primary (cyan) */ , lv_color_hex (0xc23a30 ) /* secondary (red) */ ,
131+ true /* dark */ , LV_FONT_DEFAULT );
132+ lv_disp_set_theme (dispp, th);
133+ // Slate page background on both screens
134+ lv_obj_set_style_bg_color (mainScreen, lv_color_hex (0x0f1620 ), LV_PART_MAIN );
135+ lv_obj_set_style_bg_opa (mainScreen, LV_OPA_COVER , LV_PART_MAIN );
136+ lv_obj_set_style_bg_color (sensorBasedControlPanel, lv_color_hex (0x0f1620 ), LV_PART_MAIN );
137+ lv_obj_set_style_bg_opa (sensorBasedControlPanel, LV_OPA_COVER , LV_PART_MAIN );
138+
124139 // style for button panel
125140 lv_style_init (&style);
126141 lv_style_set_flex_flow (&style, LV_FLEX_FLOW_ROW_WRAP );
@@ -143,8 +158,12 @@ void initUI() {
143158 lv_style_set_pad_bottom (&styleNoPadding, 0 );
144159 lv_style_set_pad_left (&styleNoPadding, 0 );
145160 lv_style_set_pad_right (&styleNoPadding, 0 );
146- lv_style_set_pad_row (&styleNoPadding, 0 );
147- lv_style_set_pad_column (&styleNoPadding, 0 );
161+ lv_style_set_pad_row (&styleNoPadding, 6 );
162+ lv_style_set_pad_column (&styleNoPadding, 6 );
163+ // transparent, borderless containers (let the slate page show through)
164+ lv_style_set_bg_opa (&styleNoPadding, LV_OPA_TRANSP );
165+ lv_style_set_border_width (&styleNoPadding, 0 );
166+ lv_style_set_radius (&styleNoPadding, 0 );
148167 // requires enabling this font in lv_conf.h
149168 lv_style_set_text_font (&styleNoPadding, &lv_font_montserrat_24);
150169
@@ -187,6 +206,8 @@ void initUI() {
187206 TRACE (" UI 2" );
188207 bannerLabel = lv_label_create (top_thing);
189208 lv_label_set_long_mode (bannerLabel, LV_LABEL_LONG_WRAP ); /* Break the long lines*/
209+ lv_label_set_recolor (bannerLabel, true ); /* allow #RRGGBB inline colour*/
210+ lv_obj_set_style_text_font (bannerLabel, &lv_font_montserrat_24, LV_PART_MAIN );
190211 TRACE (" UI 2.1" );
191212 lv_label_set_text (bannerLabel, " Connecting" );
192213 TRACE (" UI 2.2" );
@@ -482,8 +503,8 @@ void updateStatusBar(unsigned long frequency) {
482503
483504 // LVGL's printf has float formatting disabled (LV_SPRINTF_USE_FLOAT 0), so build
484505 // the string with the standard library's snprintf (which supports %f) instead.
485- char banner[48 ];
486- snprintf (banner, sizeof (banner), " %s @ %.1f%c " , lastServerStatus->server_name ,
506+ char banner[72 ];
507+ snprintf (banner, sizeof (banner), " #8fa6b6 %s# #33bdef %.1f%c# " , lastServerStatus->server_name ,
487508 toDisplayTemp (lastServerStatus->water_temp ), displayUnitChar ());
488509 lv_label_set_text (bannerLabel, banner);
489510
@@ -543,6 +564,23 @@ void dataReceivedControlStatus(struct_status_control *status) {
543564
544565}
545566
567+ // Card colours by control state (dark theme). e_value = getOnState (0/1/2).
568+ static CardColors cardColorsFor (struct_status_control *s) {
569+ const uint32_t OFF_BG = 0x1a2431 , OFF_BD = 0x2c3a4d , OFF_NAME = 0xc7d5e2 , OFF_VAL = 0x5f7183 ;
570+ if (strcmp (s->type , " sensor-based" ) == 0 ) {
571+ bool heating = s->e_value > 0 ;
572+ return { 0x1a2431 , (uint32_t )(heating ? 0x5a3420 : 0x3a2a1e ), 0xc7d5e2 , 0xff7a45 };
573+ }
574+ if (strcmp (s->type , " off-low-high" ) == 0 ) {
575+ if (s->e_value == 1 ) return { 0xe0952b , 0xe0952b , 0xffffff , 0xffffff }; // LOW (amber)
576+ if (s->e_value >= 2 ) return { 0xe0652b , 0xe0652b , 0xffffff , 0xffffff }; // HIGH (orange)
577+ return { OFF_BG , OFF_BD , OFF_NAME , OFF_VAL };
578+ }
579+ // off-on
580+ if (s->e_value > 0 ) return { 0xc23a30 , 0xc23a30 , 0xffffff , 0xffffff }; // ON (red)
581+ return { OFF_BG , OFF_BD , OFF_NAME , OFF_VAL }; // OFF
582+ }
583+
546584void updateButtons (unsigned long frequency) {
547585 static unsigned long last_update = 0 ;
548586 if ((millis () - last_update) > frequency) {
@@ -563,41 +601,30 @@ void updateButtons(unsigned long frequency) {
563601 // TRACE("Update Buttons 2.04");
564602
565603 lv_obj_t *btn = lv_btn_create (singleControlContainer);
566- // TRACE("Update Buttons 2.1");
567- lv_obj_set_size (btn, 220 , 68 );
604+ lv_obj_set_size (btn, 150 , 82 );
568605 lv_obj_align (btn, LV_ALIGN_BOTTOM_MID , 0 , 0 );
569- // TRACE("Update Buttons 2.2");
570- lv_obj_add_event_cb (btn, btn_event_cb, LV_EVENT_CLICKED ,
571- controlStatuses[i]);
572- lv_obj_set_style_border_width (btn, 3 , LV_PART_MAIN | LV_STATE_DEFAULT );
573- // TRACE("Update Buttons 2.3");
574-
606+ lv_obj_add_event_cb (btn, btn_event_cb, LV_EVENT_CLICKED , controlStatuses[i]);
607+ lv_obj_set_style_radius (btn, 14 , LV_PART_MAIN );
608+ lv_obj_set_style_border_width (btn, 1 , LV_PART_MAIN | LV_STATE_DEFAULT );
609+ lv_obj_set_style_shadow_width (btn, 0 , LV_PART_MAIN );
610+ lv_obj_set_style_pad_all (btn, 11 , LV_PART_MAIN );
575611
612+ // child 0: name (top-left)
576613 lv_obj_t *label = lv_label_create (btn);
577- lv_obj_align (label, LV_ALIGN_TOP_MID , 0 , 0 );
578- // TRACE("Update Buttons 2.4");
579- lv_label_set_text_fmt (label, " %s" , controlStatuses[i]->name );
580- // TRACE("Update Buttons 2.5");
581- lv_obj_center (label);
582- // TRACE("Update Buttons 3");
614+ lv_obj_add_style (label, &styleSmallFont, LV_PART_MAIN );
615+ lv_obj_align (label, LV_ALIGN_TOP_LEFT , 0 , 0 );
616+ lv_label_set_text (label, controlStatuses[i]->name );
583617
618+ // child 1: override-remaining chip (bottom-right, small)
584619 lv_obj_t *labelORT = lv_label_create (btn);
585- lv_obj_align (labelORT, LV_ALIGN_BOTTOM_LEFT , -10 , 5 );
586620 lv_obj_add_style (labelORT, &styleSmallFont, LV_PART_MAIN );
587- // lv_obj_set_style_border_color(labelORT, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
588- // lv_obj_set_style_border_width(labelORT, 1, LV_PART_MAIN | LV_STATE_DEFAULT);
589- lv_obj_set_style_text_color (labelORT, lv_palette_main (LV_PALETTE_ORANGE ), LV_PART_MAIN );
590- lv_obj_set_style_bg_color (labelORT, lv_color_white (), 0 );
591- lv_obj_set_style_bg_opa (labelORT, LV_OPA_50 , 0 );
592- // TRACE("Update Buttons 3");
621+ lv_obj_align (labelORT, LV_ALIGN_BOTTOM_RIGHT , 0 , 2 );
593622
623+ // child 2: value (bottom-left, large)
594624 lv_obj_t *labelValue = lv_label_create (btn);
595- lv_obj_align (labelValue, LV_ALIGN_TOP_RIGHT , 10 , - 5 );
596- lv_obj_add_style (labelValue, &styleSmallFont, LV_PART_MAIN );
625+ lv_obj_set_style_text_font (labelValue, &lv_font_montserrat_24, LV_PART_MAIN );
626+ lv_obj_align (labelValue, LV_ALIGN_BOTTOM_LEFT , 0 , 0 );
597627 lv_label_set_text (labelValue, " " );
598- // lv_obj_set_style_border_color(labelValue, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
599- // lv_obj_set_style_border_width(labelValue, 1, LV_PART_MAIN | LV_STATE_DEFAULT);
600- lv_obj_set_style_text_color (labelValue, lv_palette_main (LV_PALETTE_AMBER ), LV_PART_MAIN );
601628
602629 controlButtons.push_back (singleControlContainer);
603630 }
@@ -647,35 +674,26 @@ void updateButtons(unsigned long frequency) {
647674 showStatusMessage (" No response for %s" , status->name );
648675 }
649676 }
650- lv_obj_set_style_border_color (
651- btn,
652- pending ? lv_color_white () : lv_palette_main (MODE_COLORS [status->e_value ]),
653- LV_PART_MAIN | LV_STATE_DEFAULT
654- );
677+ CardColors cc = cardColorsFor (status);
678+ lv_obj_set_style_bg_color (btn, lv_color_hex (cc.bg ), LV_PART_MAIN );
679+ lv_obj_set_style_bg_opa (btn, LV_OPA_COVER , LV_PART_MAIN );
680+ lv_obj_set_style_border_color (btn, pending ? lv_color_white () : lv_color_hex (cc.border ), LV_PART_MAIN );
681+ lv_obj_set_style_border_width (btn, pending ? 3 : 1 , LV_PART_MAIN );
682+ lv_obj_set_style_text_color (label, lv_color_hex (cc.nameC ), LV_PART_MAIN );
683+ lv_obj_set_style_text_color (labelValue, lv_color_hex (cc.valueC ), LV_PART_MAIN );
684+ lv_obj_set_style_text_color (labelORT, lv_color_hex (cc.valueC ), LV_PART_MAIN );
655685 // TRACE("Update Buttons 5.2");
656686
657687
658688 if (strcmp (status->type , " off-low-high" ) == 0 ) {
659- if (status->e_value > 0 ) {
660- // TRACE("Update Buttons 5.4");
661- // lv_label_set_text_fmt(label, "%s (%s)", status->name, status->e_value == 1 ? "LOW" : "HIGH");
662- lv_label_set_text (labelValue, status->e_value == 1 ? " LOW" : " HIGH" );
663- lv_obj_clear_flag (labelValue, LV_OBJ_FLAG_HIDDEN );
664- } else {
665- lv_label_set_text (labelValue, " OFF" );
666- if (status->ORT <= 0 ) { // if we're in override, show "OFF"
667- lv_obj_add_flag (labelValue, LV_OBJ_FLAG_HIDDEN );
668- }
669- }
670- // TRACE("Update Buttons 5.5");
671- // lv_led_set_color(led, lv_palette_main(status->e_value == 1 ? LV_PALETTE_RED : LV_PALETTE_YELLOW));
672-
689+ lv_label_set_text (labelValue, status->e_value == 0 ? " OFF" : (status->e_value == 1 ? " LOW" : " HIGH" ));
673690 } else if (strcmp (status->type , " sensor-based" ) == 0 ) {
674- // lv_label_set_text_fmt(label, "%s (%d)", status->name, status->value);
675691 lv_label_set_text_fmt (labelValue, " %d%c" , (int )lroundf (toDisplayTemp ((float )status->value )), displayUnitChar ());
676692 } else {
677- lv_label_set_text (label, status->name );
693+ // off-on
694+ lv_label_set_text (labelValue, status->e_value > 0 ? " ON" : " OFF" );
678695 }
696+ lv_obj_clear_flag (labelValue, LV_OBJ_FLAG_HIDDEN );
679697 }
680698 // TRACE("Update Buttons 6");
681699 }
0 commit comments