From 1959c49d9c30a47ccf898dd277ef385f7277ff51 Mon Sep 17 00:00:00 2001 From: raw-designs Date: Fri, 4 Sep 2026 12:21:36 +0200 Subject: [PATCH] feat(P4): Signalpunkt am Kurvenende, kleiner und ohne Beschnitt (1.11.2) Der Punkt sass mittig auf dem letzten Messwert und damit auf der rechten Kante der Kurvenflaeche - seine rechte Haelfte lag ausserhalb und wurde abgeschnitten. Er sitzt jetzt vollstaendig innerhalb; der Schein darf weiterhin darueber hinausreichen. Der Punkt ist auf etwa zwei Drittel verkleinert. Das Pulsieren ist neu choreografiert: Der Punkt selbst atmet leicht, der Schein macht das Gegenteil - zieht der Punkt sich zusammen, geht der Schein auf. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Wx7wu7uXXgRzp1zHUhtUa6 --- P4_Display_Firmware/Changelog.txt | 9 +++++++ P4_Display_Firmware/config.h | 2 +- P4_Display_Firmware/ui.cpp | 39 ++++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index 1e5bd70..b11daba 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,12 @@ +Version 1.11.2: +- Der Punkt am Kurvenende sitzt jetzt vollständig innerhalb der Kurvenfläche, statt mittig + auf dem letzten Messwert und damit halb außerhalb. Rechts wird nichts mehr abgeschnitten. + Der Schein darf weiterhin darüber hinausreichen. +- Der Punkt ist auf etwa zwei Drittel verkleinert. +- Neues Pulsieren als Signalpunkt: Der Punkt selbst atmet leicht, und der Schein macht das + Gegenteil. Zieht der Punkt sich zusammen, geht der Schein auf; wird der Punkt wieder + größer, zieht der Schein sich zurück. + Version 1.11.1: - Der Punkt am rechten Ende der Verlaufskurven war angeschnitten, und von seinem Schein war nichts zu sehen: Das Diagramm beschnitt beides an seiner eigenen Kante. Punkt und Schein diff --git a/P4_Display_Firmware/config.h b/P4_Display_Firmware/config.h index cc004b3..24c87cd 100644 --- a/P4_Display_Firmware/config.h +++ b/P4_Display_Firmware/config.h @@ -126,7 +126,7 @@ // ------------------------------------------------------------------------------------- // Firmware // ------------------------------------------------------------------------------------- -#define DISPLAY_FW_VERSION "1.11.1" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) +#define DISPLAY_FW_VERSION "1.11.2" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) // ------------------------------------------------------------------------------------- // Protokoll diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index 20fcc87..661a17e 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -190,7 +190,8 @@ static bool g_tempColored = false; // Temperaturzahl in der Zustandsfarbe // Punkt am juengsten Messwert. Er pulsiert leicht und traegt einen weichen Schein - das // ist die einzige Stelle der Oberflaeche, an der etwas dauerhaft in Bewegung ist, und // deshalb bleibt er klein und langsam. -#define SPARK_DOT_SIZE 14 +#define SPARK_DOT_SIZE 10 // groesster Durchmesser des Punktes +#define SPARK_DOT_MIN 7 // kleinster - dazwischen atmet er #define SPARK_DOT_PULS_MS 1100 static lv_obj_t* g_sparkW = nullptr; // Verlaufskurven der Darstellung TD_VERLAUF static lv_obj_t* g_sparkD = nullptr; @@ -198,6 +199,8 @@ static lv_chart_series_t* g_sparkSerW = nullptr; static lv_chart_series_t* g_sparkSerD = nullptr; static lv_obj_t* g_sparkDotW = nullptr; // pulsierender Punkt am juengsten Messwert static lv_obj_t* g_sparkDotD = nullptr; +static int32_t g_dotCxW = 0, g_dotCyW = 0; // Mitte des Punktes in der Kurvenflaeche +static int32_t g_dotCxD = 0, g_dotCyD = 0; static lv_obj_t* g_readyBand = nullptr; // Zustandsband der Darstellung TD_BAND static lv_obj_t* g_readyBandLbl = nullptr; static lv_obj_t* g_tempRow = nullptr; // Container; Inhalt wird je Design (neu) aufgebaut @@ -1201,6 +1204,8 @@ static bool spark_anker(lv_obj_t* ch, lv_chart_series_t* ser, int32_t* anker, in return true; } +static void spark_dot_apply(lv_obj_t* d, int32_t groesse); // weiter unten + // Punkt am juengsten Messwert an seine Stelle setzen (rechter Rand, Hoehe nach Wert). static void spark_dot_place(lv_obj_t* ch, lv_chart_series_t* ser, lv_obj_t* dot, int32_t mn, int32_t mx) { @@ -1215,11 +1220,16 @@ static void spark_dot_place(lv_obj_t* ch, lv_chart_series_t* ser, lv_obj_t* dot, int32_t w = lv_obj_get_content_width(ch); int32_t h = lv_obj_get_content_height(ch); if (w <= 0 || h <= 0) return; + // Der Punkt bleibt vollstaendig innerhalb der Kurvenflaeche. Saesse seine Mitte genau + // auf dem letzten Messwert - also auf der rechten Kante -, laege seine rechte Haelfte + // ausserhalb und wuerde abgeschnitten. Der Schein darf weiterhin hinausreichen. int32_t r = SPARK_DOT_SIZE / 2; int32_t y = h - (int32_t)(((int64_t)(v - mn) * h) / (mx - mn)); if (y < r) y = r; if (y > h - r) y = h - r; - lv_obj_align(dot, LV_ALIGN_TOP_LEFT, w - r, y - r); // Mitte auf dem letzten Punkt + if (dot == g_sparkDotW) { g_dotCxW = w - r; g_dotCyW = y; } + else { g_dotCxD = w - r; g_dotCyD = y; } + spark_dot_apply(dot, lv_obj_get_width(dot)); lv_obj_remove_flag(dot, LV_OBJ_FLAG_HIDDEN); } @@ -1260,11 +1270,24 @@ static void spark_ranges_fit() { } } -// Weiches Pulsieren des Punktes: Nur der Schein atmet, der Punkt selbst bleibt ruhig. -static void spark_dot_puls_cb(void* var, int32_t v) { +// Punkt in seiner aktuellen Groesse an seine Stelle setzen. Die Mitte ist gemerkt, denn +// beim Atmen aendert sich die Groesse - ohne Nachfuehren wanderte der Punkt davon. +static void spark_dot_apply(lv_obj_t* d, int32_t groesse) { + if (!d) return; + const int32_t cx = (d == g_sparkDotW) ? g_dotCxW : g_dotCxD; + const int32_t cy = (d == g_sparkDotW) ? g_dotCyW : g_dotCyD; + lv_obj_set_size(d, groesse, groesse); + lv_obj_align(d, LV_ALIGN_TOP_LEFT, cx - groesse / 2, cy - groesse / 2); +} + +// Signalpunkt: Der Punkt selbst atmet leicht, und der Schein macht genau das Gegenteil. +// Zieht der Punkt sich zusammen, geht der Schein auf; wird der Punkt wieder gross, zieht +// der Schein sich zurueck. Das wirkt wie ein Signal, das ausgesendet wird. +static void spark_dot_puls_cb(void* var, int32_t v) { // v laeuft 0 .. 100 lv_obj_t* d = (lv_obj_t*)var; - lv_obj_set_style_shadow_width(d, 8 + v / 3, 0); // 8 .. 41 - lv_obj_set_style_shadow_opa(d, (lv_opa_t)(60 + v + v / 2), 0); // 60 .. 210 + spark_dot_apply(d, SPARK_DOT_MIN + ((SPARK_DOT_SIZE - SPARK_DOT_MIN) * v) / 100); + lv_obj_set_style_shadow_width(d, 30 - (22 * v) / 100, 0); // 30 .. 8 + lv_obj_set_style_shadow_opa(d, (lv_opa_t)(200 - (150 * v) / 100), 0); // 200 .. 50 } static void spark_dot_puls(lv_obj_t* dot) { lv_anim_t a; lv_anim_init(&a); @@ -1317,8 +1340,8 @@ static lv_obj_t* tempSpark(lv_obj_t* parent, lv_color_t col, lv_chart_series_t** lv_obj_set_style_bg_color(*dot, lv_color_white(), 0); lv_obj_set_style_bg_opa(*dot, LV_OPA_COVER, 0); lv_obj_set_style_shadow_color(*dot, lv_color_white(), 0); - lv_obj_set_style_shadow_width(*dot, 14, 0); - lv_obj_set_style_shadow_opa(*dot, 120, 0); + lv_obj_set_style_shadow_width(*dot, 18, 0); + lv_obj_set_style_shadow_opa(*dot, 130, 0); lv_obj_set_style_shadow_spread(*dot, 1, 0); lv_obj_remove_flag(*dot, LV_OBJ_FLAG_CLICKABLE); lv_obj_remove_flag(*dot, LV_OBJ_FLAG_SCROLLABLE); -- 2.54.0