From 288f61447d1e0d8b318528708ab7a89a6792ab19 Mon Sep 17 00:00:00 2001 From: raw-designs Date: Thu, 3 Sep 2026 02:36:31 +0200 Subject: [PATCH] =?UTF-8?q?fix(P4):=20Men=C3=BCvorhang=20wieder=20durchsch?= =?UTF-8?q?einend,=20weitere=20Invalidierung=20entfernt=20(1.9.3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Regression aus 1.8.7: Der deckende Drawer-Scrim verdeckte den Seiteninhalt, der dahinter sichtbar bleiben soll. Zurück auf LV_OPA_50. - ready_band_update() setzte Text, Textfarbe und Hintergrundfarbe des Zustandsbands bei jeder Zustandsmeldung neu. Das Band spannt sich über die volle Breite - allein dadurch wurde ein Streifen über den ganzen Bildschirm ungültig. Jetzt über die change-checked Helfer. - temp_progress_set() setzte Balkenwert und -farbe unbedingt; jetzt nur bei echter Änderung. - Das WLAN-Symbol ebenso. - Die Messung gibt zusätzlich die Koordinaten der invalidierten Bereiche aus. Die Fläche allein sagt nicht, welcher Teil der UI den Redraw auslöst. Beide Panel-Varianten mit arduino-cli gegengebaut. Co-Authored-By: Claude Opus 5 --- P4_Display_Firmware/Changelog.txt | 12 +++++++++ P4_Display_Firmware/ui.cpp | 42 ++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index 248f74c..a3f510b 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,15 @@ +Version 1.9.3: +- Fehlerbehebung: Bei geöffnetem Menü war der Seiteninhalt dahinter verschwunden. Der + Vorhang des Menüs war in 1.8.7 deckend gemacht worden, um Zeichenlast zu sparen - dabei + verdeckt er aber genau das, was sichtbar bleiben soll. Er ist wieder durchscheinend. +- Weitere Stellen umgestellt, die bei jeder Zustandsmeldung neu zeichnen ließen, obwohl sich + nichts geändert hatte: das Zustandsband der Darstellung „Band" (es spannt sich über die + volle Breite und machte damit allein schon einen Streifen über den ganzen Bildschirm + ungültig), die Heizleistungsbalken und das WLAN-Symbol. +- Die Messung nennt jetzt zusätzlich die Lage der neu gezeichneten Bereiche. Die Größe + allein sagt nicht, welcher Teil der Oberfläche das Neuzeichnen auslöst - die Koordinaten + schon. + Version 1.9.2: - Ursache der Trägheit endlich gefunden. Die erweiterte Messung zeigte: „1 Bereich, 100 % der Fläche" - LVGL zeichnete bei jeder Zustandsmeldung den kompletten Bildschirm neu, also diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index 4b3f95c..864bcf4 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -986,8 +986,11 @@ static lv_color_t temp_state_color(float temp, float set) { static void temp_progress_set(lv_obj_t* bar, lv_obj_t* arc, lv_obj_t* bulb, int pct, lv_color_t col) { if (pct > 100) pct = 100; else if (pct < 0) pct = 0; if (bar) { - lv_bar_set_value(bar, pct, LV_ANIM_OFF); - lv_obj_set_style_bg_color(bar, col, LV_PART_INDICATOR); + // Wert und Farbe nur bei echter Aenderung setzen - beides macht den Balken sonst + // bei jeder Zustandsmeldung ungueltig, obwohl sich meist nichts bewegt hat. + if (lv_bar_get_value(bar) != pct) lv_bar_set_value(bar, pct, LV_ANIM_OFF); + if (lv_color_to_u32(lv_obj_get_style_bg_color(bar, LV_PART_INDICATOR)) != lv_color_to_u32(col)) + lv_obj_set_style_bg_color(bar, col, LV_PART_INDICATOR); } if (arc) { lv_arc_set_value(arc, pct); @@ -3493,6 +3496,8 @@ static uint32_t g_refrStart = 0; static uint32_t g_refrPixels = 0; static uint32_t g_refrAreas = 0; +static lv_area_t g_refrArea[6]; +static uint8_t g_refrAreaCnt = 0; // Beim Start eines Zeichenzyklus festhalten, WIE VIEL neu gezeichnet wird. Erst damit laesst // sich unterscheiden, ob LVGL nur kleine Bereiche anfasst - dann ist das Zeichnen an sich zu @@ -3502,12 +3507,14 @@ static void refr_start_cb(lv_event_t*) { g_refrStart = lv_tick_get(); g_refrPixels = 0; g_refrAreas = 0; + g_refrAreaCnt = 0; lv_display_t* d = lv_display_get_default(); if (!d) return; for (uint16_t i = 0; i < d->inv_p; i++) { if (d->inv_area_joined[i]) continue; const lv_area_t* a = &d->inv_areas[i]; g_refrPixels += (uint32_t)(a->x2 - a->x1 + 1) * (uint32_t)(a->y2 - a->y1 + 1); + if (g_refrAreaCnt < 6) g_refrArea[g_refrAreaCnt++] = *a; g_refrAreas++; } } @@ -3518,6 +3525,12 @@ static void refr_ready_cb(lv_event_t*) { unsigned pct = (unsigned)((uint64_t)g_refrPixels * 100ULL / ((uint64_t)LCD_H_RES * LCD_V_RES)); esp_rom_printf("[UI] Bildaufbau %u ms, %u Bereiche, %u %% der Flaeche\n", (unsigned)d, (unsigned)g_refrAreas, pct); + // Lage der Bereiche mit ausgeben. Erst daran ist zu erkennen, WELCHER Teil der + // Oberflaeche das Neuzeichnen ausloest - die Groesse allein sagt das nicht. + for (uint8_t i = 0; i < g_refrAreaCnt; i++) + esp_rom_printf(" Bereich %u: x %d..%d, y %d..%d\n", (unsigned)i, + (int)g_refrArea[i].x1, (int)g_refrArea[i].x2, + (int)g_refrArea[i].y1, (int)g_refrArea[i].y2); } static void refr_monitor_install() { @@ -3670,16 +3683,11 @@ void ui_init(ProtocolClient* client) { g_drawer = lv_obj_create(scr); lv_obj_set_size(g_drawer, LV_PCT(100), DISP_VER_RES - 44); lv_obj_set_pos(g_drawer, 0, 44); -#if JC_PANEL_TYPE == WS_PANEL_7H - // Deckend statt halbdurchsichtig - aus demselben Grund wie beim Aufweckdialog: Ein - // durchscheinender Vorhang laesst LVGL die ganze Flaeche darunter mitzeichnen und - // mischen. Auf dunklem Grund sieht ein dunkles Deckend praktisch genauso aus. - lv_obj_set_style_bg_color(g_drawer, lv_color_hex(0x0d0d0d), 0); - lv_obj_set_style_bg_opa(g_drawer, LV_OPA_COVER, 0); -#else + // Bewusst durchscheinend: Der Vorhang legt sich ueber die ganze Seite, und der Inhalt + // dahinter soll sichtbar bleiben. Ein Versuch mit deckendem Vorhang (gegen die + // Zeichenlast) hat den Seiteninhalt verschwinden lassen und ist zurueckgenommen. lv_obj_set_style_bg_color(g_drawer, lv_color_hex(0x000000), 0); lv_obj_set_style_bg_opa(g_drawer, LV_OPA_50, 0); -#endif lv_obj_set_style_border_width(g_drawer, 0, 0); lv_obj_set_style_pad_all(g_drawer, 0, 0); lv_obj_set_style_radius(g_drawer, 0, 0); @@ -3996,10 +4004,14 @@ static void ready_band_update(const MachineState& st) { else if (wOk) { txt = "Wasser bereit — Dampf heizt"; bg = 0x3a2a05; fg = COL_ACCENT; } else { txt = "Heizt auf"; bg = 0x3a2a05; fg = COL_ACCENT; } } - lv_label_set_text(g_readyBandLbl, txt); - lv_obj_set_style_text_color(g_readyBandLbl, fg, 0); - lv_obj_set_style_bg_color(g_readyBand, lv_color_hex(bg), 0); - lv_obj_set_style_bg_opa(g_readyBand, LV_OPA_COVER, 0); + // Das Band spannt sich ueber die volle Breite. Wuerde es bei jeder Zustandsmeldung neu + // gesetzt, machte es allein schon einen Streifen ueber den ganzen Bildschirm ungueltig. + label_set_if_changed(g_readyBandLbl, txt); + label_color_if_changed(g_readyBandLbl, fg); + if (lv_color_to_u32(lv_obj_get_style_bg_color(g_readyBand, LV_PART_MAIN)) != bg) { + lv_obj_set_style_bg_color(g_readyBand, lv_color_hex(bg), 0); + lv_obj_set_style_bg_opa(g_readyBand, LV_OPA_COVER, 0); + } } @@ -4092,7 +4104,7 @@ void ui_update(const MachineState& st) { // WLAN-Symbol bool wifiOk = st.wifiConnected && !st.apMode; - if (g_wifiIcon) lv_obj_set_style_text_color(g_wifiIcon, wifiOk ? COL_OK : (st.apMode ? COL_WARN : COL_TEXT_MUT), 0); + label_color_if_changed(g_wifiIcon, wifiOk ? COL_OK : (st.apMode ? COL_WARN : COL_TEXT_MUT)); // Uhrzeit. Angezeigt wird die der Hauptplatine; faellt sie voruebergehend aus, zaehlt // der P4 die zuletzt bekannte Zeit selbst weiter (siehe clock_text).