Browse Source

🚸 Update ProUI Plot graph (#26539)

Andrew 1 year ago
parent
commit
56ac5d03ed

+ 10 - 3
Marlin/src/inc/Warnings.cpp

@@ -792,10 +792,17 @@
 #endif
 
 /**
- * ProUI Boot Screen Duration
+ * ProUI Extras
  */
-#if ENABLED(DWIN_LCD_PROUI) && BOOTSCREEN_TIMEOUT > 2000
-  #warning "For ProUI the original BOOTSCREEN_TIMEOUT of 1100 is recommended."
+#if ENABLED(DWIN_LCD_PROUI)
+  #if BOOTSCREEN_TIMEOUT > 2000
+    #warning "For ProUI the original BOOTSCREEN_TIMEOUT of 1100 is recommended."
+  #endif
+  #if HAS_PID_HEATING && NONE(PID_AUTOTUNE_MENU, PID_EDIT_MENU)
+    #warning "For ProUI PID_AUTOTUNE_MENU and PID_EDIT_MENU is recommended for PID tuning."
+  #elif ENABLED(MPCTEMP) && NONE(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU)
+    #warning "For ProUI MPC_EDIT_MENU and MPC_AUTOTUNE_MENU is recommended for MPC tuning."
+  #endif
 #endif
 
 /**

+ 122 - 52
Marlin/src/lcd/e3v2/proui/dwin.cpp

@@ -735,7 +735,7 @@ void _drawIconBlink(bool &flag, const bool sensor, const uint8_t icon1, const ui
 void _drawZOffsetIcon() {
   #if HAS_LEVELING
     static bool _leveling_active = false;
-    _drawIconBlink(_leveling_active, planner.leveling_active, ICON_Zoffset, ICON_SetZOffset, 186, 416);
+    _drawIconBlink(_leveling_active, planner.leveling_active, ICON_Zoffset, ICON_SetZOffset, 187, 416);
   #else
     DWINUI::drawIcon(ICON_Zoffset, 187, 416);
   #endif
@@ -763,9 +763,9 @@ void _drawFeedrate() {
 }
 
 void _drawXYZPosition(const bool force) {
-  _update_axis_value(X_AXIS,  27, 459, force);
-  _update_axis_value(Y_AXIS, 112, 459, force);
-  _update_axis_value(Z_AXIS, 197, 459, force);
+  _update_axis_value(X_AXIS,  27, 457, force);
+  _update_axis_value(Y_AXIS, 112, 457, force);
+  _update_axis_value(Z_AXIS, 197, 457, force);
 }
 
 void updateVariable() {
@@ -778,7 +778,18 @@ void updateVariable() {
                _new_hotend_target = _hotendtarget != ht;
     if (_new_hotend_temp) _hotendtemp = hc;
     if (_new_hotend_target) _hotendtarget = ht;
-  #endif
+
+    // if hotend is near target or heating, ICON indicates hot
+    if (thermalManager.degHotendNear(0, ht) || thermalManager.isHeatingHotend(0)) {
+      dwinDrawBox(1, hmiData.colorBackground, 10, 383, 20, 20);
+      DWINUI::drawIcon(ICON_SetEndTemp, 10, 383);
+    }
+    else {
+      dwinDrawBox(1, hmiData.colorBackground, 10, 383, 20, 20);
+      DWINUI::drawIcon(ICON_HotendTemp, 10, 383);
+    }
+  #endif // HAS_HOTEND
+
   #if HAS_HEATED_BED
     static celsius_t _bedtemp = 0, _bedtarget = 0;
     const celsius_t bc = thermalManager.wholeDegBed(),
@@ -787,7 +798,18 @@ void updateVariable() {
                _new_bed_target = _bedtarget != bt;
     if (_new_bed_temp) _bedtemp = bc;
     if (_new_bed_target) _bedtarget = bt;
-  #endif
+
+    // if bed is near target, heating, or if degrees > 44, ICON indicates hot
+    if (thermalManager.degBedNear(bt) || thermalManager.isHeatingBed() || (bc > 44)) {
+      dwinDrawBox(1, hmiData.colorBackground, 10, 416, 20, 20);
+      DWINUI::drawIcon(ICON_BedTemp, 10, 416);
+    }
+    else {
+      dwinDrawBox(1, hmiData.colorBackground, 10, 416, 20, 20);
+      DWINUI::drawIcon(ICON_SetBedTemp, 10, 416);
+    }
+  #endif // HAS_HEATED_BED
+
   #if HAS_FAN
     static uint8_t _fanspeed = 0;
     const bool _new_fanspeed = _fanspeed != thermalManager.fan_speed[0];
@@ -1022,9 +1044,9 @@ void dwinDrawDashboard() {
   dwinDrawRectangle(1, hmiData.colorBackground, 0, STATUS_Y + 21, DWIN_WIDTH, DWIN_HEIGHT - 1);
   dwinDrawRectangle(1, hmiData.colorSplitLine, 0, 449, DWIN_WIDTH, 451);
 
-  DWINUI::drawIcon(ICON_MaxSpeedX,  10, 456);
-  DWINUI::drawIcon(ICON_MaxSpeedY,  95, 456);
-  DWINUI::drawIcon(ICON_MaxSpeedZ, 180, 456);
+  DWINUI::drawIcon(ICON_MaxSpeedX,  10, 454);
+  DWINUI::drawIcon(ICON_MaxSpeedY,  95, 454);
+  DWINUI::drawIcon(ICON_MaxSpeedZ, 180, 454);
   _drawXYZPosition(true);
 
   #if HAS_HOTEND
@@ -1033,7 +1055,7 @@ void dwinDrawDashboard() {
     DWINUI::drawString(DWIN_FONT_STAT, hmiData.colorIndicator, hmiData.colorBackground, 25 + 3 * STAT_CHR_W + 5, 384, F("/"));
     DWINUI::drawInt(DWIN_FONT_STAT, hmiData.colorIndicator, hmiData.colorBackground, 3, 25 + 4 * STAT_CHR_W + 6, 384, thermalManager.degTargetHotend(0));
 
-    DWINUI::drawIcon(ICON_StepE, 112, 417);
+    DWINUI::drawIcon(ICON_StepE, 113, 416);
     DWINUI::drawInt(DWIN_FONT_STAT, hmiData.colorIndicator, hmiData.colorBackground, 3, 116 + 2 * STAT_CHR_W, 417, planner.flow_percentage[0]);
     DWINUI::drawString(DWIN_FONT_STAT, hmiData.colorIndicator, hmiData.colorBackground, 116 + 5 * STAT_CHR_W + 2, 417, F("%"));
   #endif
@@ -1269,6 +1291,16 @@ void eachMomentUpdate() {
         TERN_(PIDTEMPBED, if (hmiValue.tempControl == PIDTEMPBED_START) plot.update(thermalManager.wholeDegBed()));
       }
       TERN_(MPCTEMP, if (checkkey == ID_MPCProcess) plot.update(thermalManager.wholeDegHotend(0)));
+      #if ENABLED(PROUI_ITEM_PLOT)
+        if (checkkey == ID_PlotProcess) {
+          TERN_(PIDTEMP, if (hmiValue.tempControl == PIDTEMP_START) { plot.update(thermalManager.wholeDegHotend(0)); })
+          TERN_(PIDTEMPBED, if (hmiValue.tempControl == PIDTEMPBED_START) { plot.update(thermalManager.wholeDegBed()); })
+          TERN_(MPCTEMP, if (hmiValue.tempControl == MPCTEMP_START) { plot.update(thermalManager.wholeDegHotend(0)); })
+          if (hmiFlag.abort_flag || hmiFlag.pause_flag || print_job_timer.isPaused()) {
+            hmiReturnScreen();
+          }
+        }
+      #endif
     #endif
   }
 
@@ -1402,29 +1434,32 @@ void dwinHandleScreen() {
     case ID_SetIntNoDraw: hmiSetNoDraw(); break;
     case ID_PrintProcess: hmiPrinting(); break;
     case ID_Popup:        hmiPopup(); break;
-    case ID_Leveling:     break;
     #if HAS_LOCKSCREEN
       case ID_Locked:     hmiLockScreen(); break;
     #endif
-    case ID_PrintDone:
+
     TERN_(HAS_ESDIAG, case ID_ESDiagProcess:)
+    TERN_(PROUI_ITEM_PLOT, case ID_PlotProcess:)
+    case ID_PrintDone:
     case ID_WaitResponse: hmiWaitForUser(); break;
+
+    TERN_(HAS_BED_PROBE, case ID_Leveling:)
     case ID_Homing:
     case ID_PIDProcess:
-    case ID_NothingToDo:  break;
+    case ID_NothingToDo:
     default: break;
   }
 }
 
 bool idIsPopUp() {    // If ID is popup...
   switch (checkkey) {
+    TERN_(HAS_BED_PROBE, case ID_Leveling:)
+    TERN_(HAS_ESDIAG, case ID_ESDiagProcess:)
     case ID_NothingToDo:
     case ID_WaitResponse:
     case ID_Popup:
     case ID_Homing:
-    case ID_Leveling:
     case ID_PIDProcess:
-    TERN_(HAS_ESDIAG, case ID_ESDiagProcess:)
       return true;
     default: break;
   }
@@ -1439,8 +1474,9 @@ void hmiSaveProcessID(const uint8_t id) {
     case ID_Popup:
     case ID_WaitResponse:
     case ID_PrintDone:
-    case ID_Leveling:
+    TERN_(HAS_BED_PROBE, case ID_Leveling:)
     TERN_(HAS_ESDIAG, case ID_ESDiagProcess:)
+    TERN_(PROUI_ITEM_PLOT, case ID_PlotProcess:)
       wait_for_user = true;
     default: break;
   }
@@ -1515,7 +1551,7 @@ void dwinLevelingDone() {
 
   celsius_t _maxtemp, _target;
   void dwinDrawPIDMPCPopup() {
-    constexpr frame_rect_t gfrm = { 40, 180, DWIN_WIDTH - 80, 120 };
+    constexpr frame_rect_t gfrm = { 30, 150, DWIN_WIDTH - 60, 160 };
     DWINUI::clearMainArea();
     drawPopupBkgd();
 
@@ -1523,50 +1559,27 @@ void dwinLevelingDone() {
       default: return;
       #if ENABLED(MPC_AUTOTUNE)
         case MPCTEMP_START:
-          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 100, GET_TEXT_F(MSG_MPC_AUTOTUNE));
-          DWINUI::drawString(hmiData.colorPopupTxt, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("MPC target:    Celsius"));
-          break;
-      #endif
-      #if ANY(PIDTEMP, PIDTEMPBED)
-        TERN_(PIDTEMP,    case PIDTEMP_START:)
-        TERN_(PIDTEMPBED, case PIDTEMPBED_START:)
-          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 100, GET_TEXT_F(MSG_PID_AUTOTUNE));
-          DWINUI::drawString(hmiData.colorPopupTxt, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("PID target:    Celsius"));
-          break;
-      #endif
-    }
-
-    switch (hmiValue.tempControl) {
-      default: break;
-      #if ANY(PIDTEMP, MPC_AUTOTUNE)
-        TERN_(PIDTEMP,      case PIDTEMP_START:)
-        TERN_(MPC_AUTOTUNE, case MPCTEMP_START:)
-          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 120, F("for Nozzle is running."));
-          break;
-      #endif
-      #if ENABLED(PIDTEMPBED)
-        case PIDTEMPBED_START:
-          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 120, F("for BED is running."));
-          break;
-      #endif
-    }
-
-    switch (hmiValue.tempControl) {
-      default: break;
-      #if ENABLED(MPC_AUTOTUNE)
-        case MPCTEMP_START:
+          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 70, GET_TEXT_F(MSG_MPC_AUTOTUNE));
+          DWINUI::drawString(hmiData.colorPopupTxt, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("MPC target:     Celsius"));
+          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 92, F("for NOZZLE is running."));
           _maxtemp = thermalManager.hotend_maxtemp[0];
           _target = 200;
           break;
       #endif
       #if ENABLED(PIDTEMP)
         case PIDTEMP_START:
+          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 70, GET_TEXT_F(MSG_PID_AUTOTUNE));
+          DWINUI::drawString(hmiData.colorPopupTxt, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("PID target:     Celsius"));
+          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 92, F("for NOZZLE is running."));
           _maxtemp = thermalManager.hotend_maxtemp[0];
           _target = hmiData.hotendPidT;
           break;
       #endif
       #if ENABLED(PIDTEMPBED)
         case PIDTEMPBED_START:
+          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 70, GET_TEXT_F(MSG_PID_AUTOTUNE));
+          DWINUI::drawString(hmiData.colorPopupTxt, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("PID target:     Celsius"));
+          DWINUI::drawCenteredString(hmiData.colorPopupTxt, 92, F("for BED is running."));
           _maxtemp = BED_MAXTEMP;
           _target = hmiData.bedPidT;
           break;
@@ -1574,9 +1587,58 @@ void dwinLevelingDone() {
     }
 
     plot.draw(gfrm, _maxtemp, _target);
-    DWINUI::drawInt(hmiData.colorPopupTxt, 3, gfrm.x + 90, gfrm.y - DWINUI::fontHeight() - 4, _target);
+    DWINUI::drawInt(false, 2, hmiData.colorStatusTxt, hmiData.colorPopupTxt, 3, gfrm.x + 92, gfrm.y - DWINUI::fontHeight() - 6, _target);
   }
 
+  // Plot Temperature Graph (PID Tuning Graph)
+  #if ENABLED(PROUI_ITEM_PLOT)
+
+    void dwinDrawPlot(tempcontrol_t result) {
+      hmiValue.tempControl = result;
+      constexpr frame_rect_t gfrm = {30, 135, DWIN_WIDTH - 60, 160};
+      DWINUI::clearMainArea();
+      drawPopupBkgd();
+      hmiSaveProcessID(ID_PlotProcess);
+
+      switch (result) {
+        #if ENABLED(MPCTEMP)
+          case MPCTEMP_START:
+        #elif ENABLED(PIDTEMP)
+          case PIDTEMP_START:
+        #endif
+            title.showCaption(GET_TEXT_F(MSG_HOTEND_TEMP_GRAPH));
+            DWINUI::drawCenteredString(3, hmiData.colorPopupTxt, 75, F("Nozzle Temperature"));
+            _maxtemp = thermalManager.hotend_max_target(0);
+            _target = thermalManager.degTargetHotend(0);
+            break;
+        #if ENABLED(PIDTEMPBED)
+          case PIDTEMPBED_START:
+            title.showCaption(GET_TEXT_F(MSG_BED_TEMP_GRAPH));
+            DWINUI::drawCenteredString(3, hmiData.colorPopupTxt, 75, F("Bed Temperature"));
+            _maxtemp = BED_MAX_TARGET;
+            _target = thermalManager.degTargetBed();
+            break;
+        #endif
+        default: break;
+      }
+
+      dwinDrawString(false, 2, hmiData.colorPopupTxt, hmiData.colorPopupBg, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("Target:     Celsius"));
+      plot.draw(gfrm, _maxtemp, _target);
+      DWINUI::drawInt(false, 2, hmiData.colorStatusTxt, hmiData.colorPopupBg, 3, gfrm.x + 80, gfrm.y - DWINUI::fontHeight() - 4, _target);
+      DWINUI::drawButton(BTN_Continue, 86, 305);
+      dwinUpdateLCD();
+    }
+
+    void drawHPlot() {
+      TERN_(PIDTEMP, dwinDrawPlot(PIDTEMP_START);)
+      TERN_(MPCTEMP, dwinDrawPlot(MPCTEMP_START);)
+    }
+    void drawBPlot() {
+      TERN_(PIDTEMPBED, dwinDrawPlot(PIDTEMPBED_START);)
+    }
+
+  #endif // PROUI_ITEM_PLOT
+
 #endif // PROUI_TUNING_GRAPH
 
 #if PROUI_PID_TUNE
@@ -2993,7 +3055,7 @@ frame_rect_t selrect(frame_rect_t) {
 
 void drawPrepareMenu() {
   checkkey = ID_Menu;
-  if (SET_MENU_R(prepareMenu, selrect({133, 1, 28, 13}), MSG_PREPARE, 10 + PREHEAT_COUNT)) {
+  if (SET_MENU_R(prepareMenu, selrect({133, 1, 28, 13}), MSG_PREPARE, 12 + PREHEAT_COUNT)) {
     BACK_ITEM(gotoMainMenu);
     MENU_ITEM(ICON_FilMan, MSG_FILAMENT_MAN, onDrawSubMenu, drawFilamentManMenu);
     MENU_ITEM(ICON_Axis, MSG_MOVE_AXIS, onDrawMoveSubMenu, drawMoveMenu);
@@ -3023,6 +3085,10 @@ void drawPrepareMenu() {
       REPEAT_1(PREHEAT_COUNT, _ITEM_PREHEAT)
     #endif
     MENU_ITEM(ICON_Cool, MSG_COOLDOWN, onDrawCooldown, doCoolDown);
+    #if ALL(PROUI_TUNING_GRAPH, PROUI_ITEM_PLOT)
+      MENU_ITEM(ICON_PIDNozzle, MSG_HOTEND_TEMP_GRAPH, onDrawMenuItem, drawHPlot);
+      MENU_ITEM(ICON_PIDBed, MSG_BED_TEMP_GRAPH, onDrawMenuItem, drawBPlot);
+    #endif
     MENU_ITEM(ICON_Language, MSG_UI_LANGUAGE, onDrawLanguage, setLanguage);
   }
   ui.reset_status(true);
@@ -3304,7 +3370,7 @@ void drawFilSetMenu() {
 
 void drawTuneMenu() {
   checkkey = ID_Menu;
-  if (SET_MENU_R(tuneMenu, selrect({73, 2, 28, 12}), MSG_TUNE, 18)) {
+  if (SET_MENU_R(tuneMenu, selrect({73, 2, 28, 12}), MSG_TUNE, 20)) {
     BACK_ITEM(gotoPrintProcess);
     EDIT_ITEM(ICON_Speed, MSG_SPEED, onDrawSpeedItem, setSpeed, &feedrate_percentage);
     #if HAS_HOTEND
@@ -3350,6 +3416,10 @@ void drawTuneMenu() {
     #if ENABLED(EDITABLE_DISPLAY_TIMEOUT)
       EDIT_ITEM(ICON_Brightness, MSG_SCREEN_TIMEOUT, onDrawPIntMenu, setTimer, &ui.backlight_timeout_minutes);
     #endif
+    #if ALL(PROUI_TUNING_GRAPH, PROUI_ITEM_PLOT)
+      MENU_ITEM(ICON_PIDNozzle, MSG_HOTEND_TEMP_GRAPH, onDrawMenuItem, drawHPlot);
+      MENU_ITEM(ICON_PIDBed, MSG_BED_TEMP_GRAPH, onDrawMenuItem, drawBPlot);
+    #endif
     #if ENABLED(CASE_LIGHT_MENU)
       EDIT_ITEM(ICON_CaseLight, MSG_CASE_LIGHT, onDrawChkbMenu, setCaseLight, &caselight.on);
       #if CASELIGHT_USES_BRIGHTNESS

+ 1 - 0
Marlin/src/lcd/e3v2/proui/dwin.h

@@ -67,6 +67,7 @@ enum processID : uint8_t {
   ID_WaitResponse,
   ID_Homing,
   ID_PIDProcess,
+  ID_PlotProcess,
   ID_MPCProcess,
   ID_NothingToDo
 };

+ 3 - 0
Marlin/src/lcd/e3v2/proui/dwin_defines.h

@@ -106,6 +106,9 @@
 #if ANY(PROUI_PID_TUNE, MPC_AUTOTUNE) && DISABLED(DISABLE_TUNING_GRAPH)
   #define PROUI_TUNING_GRAPH 1
 #endif
+#if PROUI_TUNING_GRAPH
+  #define PROUI_ITEM_PLOT     // Plot temp graph viewer
+#endif
 #define HAS_GCODE_PREVIEW 1   // Preview G-code model thumbnail
 #define HAS_CUSTOM_COLORS 1   // Change display colors
 #define HAS_ESDIAG 1          // View End-stop/Runout switch continuity

+ 25 - 23
Marlin/src/lcd/e3v2/proui/plot.cpp

@@ -39,40 +39,42 @@
 #include "../../marlinui.h"
 #include "plot.h"
 
-#define Plot_Bg_Color RGB( 1, 12,  8)
+#define plotBgColor RGB(1, 12, 8)
 
 Plot plot;
 
-uint16_t graphpoints, r, x2, y2 = 0;
-frame_rect_t graphframe = {0};
-float scale = 0;
+Plot::PlotData Plot::data;
 
-void Plot::draw(const frame_rect_t &frame, const_celsius_float_t max, const_float_t ref/*=0*/) {
-  graphframe = frame;
-  graphpoints = 0;
-  scale = frame.h / max;
-  x2 = frame.x + frame.w - 1;
-  y2 = frame.y + frame.h - 1;
-  r = round((y2) - ref * scale);
-  DWINUI::drawBox(1, Plot_Bg_Color, frame);
+void Plot::draw(const frame_rect_t &frame, const_celsius_float_t max, const_celsius_float_t ref/*=0*/) {
+  data.graphframe = frame;
+  data.graphpoints = 0;
+  data.scale = frame.h / max;
+  data.x2 = frame.x + frame.w - 1;
+  data.y2 = frame.y + frame.h - 1;
+  data.r = LROUND((data.y2) - ref * data.scale);
+  DWINUI::drawBox(1, plotBgColor, frame);
   for (uint8_t i = 1; i < 4; i++) if (i * 60 < frame.w) dwinDrawVLine(COLOR_LINE, i * 60 + frame.x, frame.y, frame.h);
   DWINUI::drawBox(0, COLOR_WHITE, DWINUI::extendFrame(frame, 1));
-  dwinDrawHLine(COLOR_RED, frame.x, r, frame.w);
+  dwinDrawHLine(COLOR_RED, frame.x, data.r, frame.w);
 }
 
-void Plot::update(const_float_t value) {
-  if (!scale) return;
-  const uint16_t y = round((y2) - value * scale);
-  if (graphpoints < graphframe.w) {
-    dwinDrawPoint(COLOR_YELLOW, 1, 1, graphpoints + graphframe.x, y);
+void Plot::update(const_celsius_float_t value) {
+  if (!data.scale) return;
+  const uint16_t y = LROUND((data.y2) - value * data.scale);
+  if (data.graphpoints < data.graphframe.w) {
+    if (data.graphpoints < 1)
+      dwinDrawPoint(COLOR_YELLOW, 1, 1, data.graphframe.x, y);
+    else
+      dwinDrawLine(COLOR_YELLOW, data.graphpoints + data.graphframe.x - 1, data.yP, data.graphpoints + data.graphframe.x, y);
   }
   else {
-    dwinFrameAreaMove(1, 0, 1, Plot_Bg_Color, graphframe.x, graphframe.y, x2, y2);
-    if ((graphpoints % 60) == 0) dwinDrawVLine(COLOR_LINE, x2 - 1, graphframe.y + 1, graphframe.h - 2);
-    dwinDrawPoint(COLOR_RED, 1, 1, x2 - 1, r);
-    dwinDrawPoint(COLOR_YELLOW, 1, 1, x2 - 1, y);
+    dwinFrameAreaMove(1, 0, 1, plotBgColor, data.graphframe.x, data.graphframe.y, data.x2, data.y2);
+    if ((data.graphpoints % 60) == 0) dwinDrawVLine(COLOR_LINE, data.x2 - 1, data.graphframe.y + 1, data.graphframe.h - 2);
+    dwinDrawPoint(COLOR_RED, 1, 1, data.x2 - 1, data.r);
+    dwinDrawLine(COLOR_YELLOW, data.x2 - 2, data.yP, data.x2 - 1, y);
   }
-  graphpoints++;
+  data.yP = y;
+  data.graphpoints++;
   TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
 }
 

+ 9 - 2
Marlin/src/lcd/e3v2/proui/plot.h

@@ -32,8 +32,15 @@
 
 class Plot {
 public:
-  static void draw(const frame_rect_t &frame, const_celsius_float_t max, const_float_t ref=0);
-  static void update(const_float_t value);
+  static void draw(const frame_rect_t &frame, const_celsius_float_t max, const_celsius_float_t ref=0);
+  static void update(const_celsius_float_t value);
+
+private:
+  static struct PlotData {
+    uint16_t graphpoints, r, x2, y2, yP = 0;
+    frame_rect_t graphframe = {0};
+    float scale = 0;
+  } data;
 };
 
 extern Plot plot;

+ 2 - 0
Marlin/src/lcd/language/language_en.h

@@ -448,6 +448,8 @@ namespace LanguageNarrow_en {
   LSTR MSG_CONTRAST                       = _UxGT("LCD Contrast");
   LSTR MSG_BRIGHTNESS                     = _UxGT("LCD Brightness");
   LSTR MSG_SCREEN_TIMEOUT                 = _UxGT("LCD Timeout (m)");
+  LSTR MSG_HOTEND_TEMP_GRAPH              = _UxGT("Hotend Temp Graph");
+  LSTR MSG_BED_TEMP_GRAPH                 = _UxGT("Bed Temp Graph");
   LSTR MSG_BRIGHTNESS_OFF                 = _UxGT("Backlight Off");
   LSTR MSG_STORE_EEPROM                   = _UxGT("Store Settings");
   LSTR MSG_LOAD_EEPROM                    = _UxGT("Load Settings");

+ 27 - 12
buildroot/share/dwin/bin/DWIN_ICO.py

@@ -247,16 +247,16 @@ class Entry():
         return rawdata
 
 _iconNames = {
-    0 : 'ICON_LOGO',
-    1 : 'ICON_Print_0',
-    2 : 'ICON_Print_1',
-    3 : 'ICON_Prepare_0',
-    4 : 'ICON_Prepare_1',
-    5 : 'ICON_Control_0',
-    6 : 'ICON_Control_1',
-    7 : 'ICON_Leveling_0',
-    8 : 'ICON_Leveling_1',
-    9 : 'ICON_HotendTemp',
+     0 : 'ICON_LOGO',
+     1 : 'ICON_Print_0',
+     2 : 'ICON_Print_1',
+     3 : 'ICON_Prepare_0',
+     4 : 'ICON_Prepare_1',
+     5 : 'ICON_Control_0',
+     6 : 'ICON_Control_1',
+     7 : 'ICON_Leveling_0',
+     8 : 'ICON_Leveling_1',
+     9 : 'ICON_HotendTemp',
     10 : 'ICON_BedTemp',
     11 : 'ICON_Speed',
     12 : 'ICON_Zoffset',
@@ -338,5 +338,20 @@ _iconNames = {
     88 : 'ICON_Confirm_C',
     89 : 'ICON_Confirm_E',
     90 : 'ICON_Info_0',
-    91 : 'ICON_Info_1'
-    }
+    91 : 'ICON_Info_1',
+    93 : 'ICON_Printer_0',
+  #94 : 'ICON_Printer_1',
+   200 : 'ICON_Checkbox_F',
+   201 : 'ICON_Checkbox_T',
+   202 : 'ICON_Fade',
+   203 : 'ICON_Mesh',
+   204 : 'ICON_Tilt',
+   205 : 'ICON_Brightness',
+   206 : 'ICON_Probe',
+   249 : 'ICON_AxisD',
+   250 : 'ICON_AxisBR',
+   251 : 'ICON_AxisTR',
+   252 : 'ICON_AxisBL',
+   253 : 'ICON_AxisTL',
+   254 : 'ICON_AxisC'
+}