From f98f4ac7eaab5f509da5cd94420821f23fe7aeea Mon Sep 17 00:00:00 2001
From: Marcio Teixeira <marcio@alephobjects.com>
Date: Tue, 16 Oct 2018 15:58:29 -0600
Subject: [PATCH] Fix and improve EXTENSIBLE_UI (#12117)

- Add methods to access print counter data
- Clean up some inconsistent method names
- Clear lcd status after filament change
- Implement `lcd_reset_status` so it works like UltraLCD
---
 Marlin/src/core/utility.cpp                   |  2 +-
 Marlin/src/core/utility.h                     |  2 +-
 Marlin/src/feature/pause.cpp                  |  4 ++
 Marlin/src/gcode/eeprom/M500-M504.cpp         |  3 +
 .../lib/{dummy.cpp => example.cpp}            | 25 ++++++--
 Marlin/src/lcd/extensible_ui/ui_api.cpp       | 63 ++++++++++++++-----
 Marlin/src/lcd/extensible_ui/ui_api.h         | 17 +++--
 7 files changed, 90 insertions(+), 26 deletions(-)
 rename Marlin/src/lcd/extensible_ui/lib/{dummy.cpp => example.cpp} (75%)

diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp
index ba374f7593b..e143cc9709b 100644
--- a/Marlin/src/core/utility.cpp
+++ b/Marlin/src/core/utility.cpp
@@ -48,7 +48,7 @@ void safe_delay(millis_t ms) {
 
 #endif // EEPROM_SETTINGS
 
-#if ENABLED(ULTRA_LCD) || ENABLED(DEBUG_LEVELING_FEATURE)
+#if ENABLED(ULTRA_LCD) || ENABLED(DEBUG_LEVELING_FEATURE) || ENABLED(EXTENSIBLE_UI)
 
   char conv[8] = { 0 };
 
diff --git a/Marlin/src/core/utility.h b/Marlin/src/core/utility.h
index f4f2e7cf806..05ba721def3 100644
--- a/Marlin/src/core/utility.h
+++ b/Marlin/src/core/utility.h
@@ -45,7 +45,7 @@ void safe_delay(millis_t ms);
   FORCE_INLINE bool is_bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
 #endif
 
-#if ENABLED(ULTRA_LCD) || ENABLED(DEBUG_LEVELING_FEATURE)
+#if ENABLED(ULTRA_LCD) || ENABLED(DEBUG_LEVELING_FEATURE) || ENABLED(EXTENSIBLE_UI)
 
   // Convert uint8_t to string with 123 format
   char* i8tostr3(const uint8_t x);
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index d7fe9c7e05d..58a9c9d64a0 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -595,6 +595,10 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
       --did_pause_print;
     }
   #endif
+
+  #if ENABLED(ULTRA_LCD)
+    lcd_reset_status();
+  #endif
 }
 
 #endif // ADVANCED_PAUSE_FEATURE
diff --git a/Marlin/src/gcode/eeprom/M500-M504.cpp b/Marlin/src/gcode/eeprom/M500-M504.cpp
index 07099c31491..e37b4d47d86 100644
--- a/Marlin/src/gcode/eeprom/M500-M504.cpp
+++ b/Marlin/src/gcode/eeprom/M500-M504.cpp
@@ -58,6 +58,9 @@ void GcodeSuite::M501() {
       CHAT_PORT
     #endif
   );
+  #if ENABLED(EXTENSIBLE_UI)
+    UI::onLoadSettings();
+  #endif
 }
 
 /**
diff --git a/Marlin/src/lcd/extensible_ui/lib/dummy.cpp b/Marlin/src/lcd/extensible_ui/lib/example.cpp
similarity index 75%
rename from Marlin/src/lcd/extensible_ui/lib/dummy.cpp
rename to Marlin/src/lcd/extensible_ui/lib/example.cpp
index 9a712907910..d11c85d6fa1 100644
--- a/Marlin/src/lcd/extensible_ui/lib/dummy.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/example.cpp
@@ -28,11 +28,25 @@
 // To implement a new UI, complete the functions below and
 // read or update Marlin's state using the methods in the
 // UI methods in "../ui_api.h"
+//
+// Although it may be possible to access other state
+// variables from Marlin, using the API here possibly
+// helps ensure future compatibility.
 
 namespace UI {
-  void onStartup() {}
-  void onUpdate() {}
-  void onPrinterKilled(const char* lcd_msg) {}
+  void onStartup() {
+    /* Initialize the display module here. The following
+     * routines are available for access to the GPIO pins:
+     *
+     *   SET_OUTPUT(pin)
+     *   SET_INPUT_PULLUP(pin)
+     *   SET_INPUT(pin)
+     *   WRITE(pin,value)
+     *   READ(pin)
+     */
+  }
+  void onIdle() {}
+  void onPrinterKilled(const char* msg) {}
   void onMediaInserted();
   void onMediaError();
   void onMediaRemoved();
@@ -41,9 +55,10 @@ namespace UI {
   void onPrintTimerPaused() {}
   void onPrintTimerStopped() {}
   void onFilamentRunout() {}
-  void onStatusChanged(const char* lcd_msg) {}
-  void onStatusChanged(progmem_str lcd_msg) {}
+  void onStatusChanged(const char* msg) {}
+  void onStatusChanged(progmem_str msg) {}
   void onFactoryReset() {}
+  void onLoadSettings() {}
   void onStoreSettings() {}
 }
 
diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extensible_ui/ui_api.cpp
index cb39c6b0a3e..26b38b1f25e 100644
--- a/Marlin/src/lcd/extensible_ui/ui_api.cpp
+++ b/Marlin/src/lcd/extensible_ui/ui_api.cpp
@@ -27,9 +27,7 @@
 #include "../../module/motion.h"
 #include "../../module/planner.h"
 #include "../../module/probe.h"
-#include "../../module/printcounter.h"
 #include "../../module/temperature.h"
-#include "../../sd/cardreader.h"
 #include "../../libs/duration_t.h"
 
 #if DO_SWITCH_EXTRUDER || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
@@ -37,6 +35,7 @@
 #endif
 
 #if ENABLED(SDSUPPORT)
+  #include "../../sd/cardreader.h"
   #include "../../feature/emergency_parser.h"
 
   bool abort_sd_printing; // =false
@@ -44,6 +43,11 @@
   constexpr bool abort_sd_printing = false;
 #endif
 
+#if ENABLED(PRINTCOUNTER)
+  #include "../../core/utility.h"
+  #include "../../module/printcounter.h"
+#endif
+
 #include "ui_api.h"
 
 #if ENABLED(BACKLASH_GCODE)
@@ -272,16 +276,16 @@ namespace UI {
     }
   #endif
 
-  float getMinFeedrate_mm_s()                             { return planner.settings.min_feedrate_mm_s; }
-  float getMinTravelFeedrate_mm_s()                       { return planner.settings.min_travel_feedrate_mm_s; }
-  float getPrintingAcceleration_mm_s2()                   { return planner.settings.acceleration; }
-  float getRetractAcceleration_mm_s2()                    { return planner.settings.retract_acceleration; }
-  float getTravelAcceleration_mm_s2()                     { return planner.settings.travel_acceleration; }
-  void setMinFeedrate_mm_s(const float fr)                { planner.settings.min_feedrate_mm_s = fr; }
-  void setMinTravelFeedrate_mm_s(const float fr)          { planner.settings.min_travel_feedrate_mm_s = fr; }
-  void setPrintingAcceleration_mm_per_s2(const float acc) { planner.settings.acceleration = acc; }
-  void setRetractAcceleration_mm_s2(const float acc)      { planner.settings.retract_acceleration = acc; }
-  void setTravelAcceleration_mm_s2(const float acc)       { planner.settings.travel_acceleration = acc; }
+  float getMinFeedrate_mm_s()                         { return planner.settings.min_feedrate_mm_s; }
+  float getMinTravelFeedrate_mm_s()                   { return planner.settings.min_travel_feedrate_mm_s; }
+  float getPrintingAcceleration_mm_s2()               { return planner.settings.acceleration; }
+  float getRetractAcceleration_mm_s2()                { return planner.settings.retract_acceleration; }
+  float getTravelAcceleration_mm_s2()                 { return planner.settings.travel_acceleration; }
+  void setMinFeedrate_mm_s(const float fr)            { planner.settings.min_feedrate_mm_s = fr; }
+  void setMinTravelFeedrate_mm_s(const float fr)      { planner.settings.min_travel_feedrate_mm_s = fr; }
+  void setPrintingAcceleration_mm_s2(const float acc) { planner.settings.acceleration = acc; }
+  void setRetractAcceleration_mm_s2(const float acc)  { planner.settings.retract_acceleration = acc; }
+  void setTravelAcceleration_mm_s2(const float acc)   { planner.settings.travel_acceleration = acc; }
 
   #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
     float getZOffset_mm() {
@@ -364,6 +368,18 @@ namespace UI {
     return elapsed.value;
   }
 
+  #if ENABLED(PRINTCOUNTER)
+    char* getTotalPrints_str(char buffer[21])    { strcpy(buffer,itostr3left(print_job_timer.getStats().totalPrints));    return buffer; }
+    char* getFinishedPrints_str(char buffer[21]) { strcpy(buffer,itostr3left(print_job_timer.getStats().finishedPrints)); return buffer; }
+    char* getTotalPrintTime_str(char buffer[21]) { duration_t(print_job_timer.getStats().printTime).toString(buffer);     return buffer; }
+    char* getLongestPrint_str(char buffer[21])   { duration_t(print_job_timer.getStats().printTime).toString(buffer);     return buffer; }
+    char* getFilamentUsed_str(char buffer[21])   {
+      printStatistics stats = print_job_timer.getStats();
+      sprintf_P(buffer, PSTR("%ld.%im"), long(stats.filamentUsed / 1000), int16_t(stats.filamentUsed / 100) % 10);
+      return buffer;
+    }
+  #endif
+
   float getFeedRate_percent() {
     return feedrate_percentage;
   }
@@ -564,7 +580,7 @@ void lcd_init() {
   UI::onStartup();
 }
 
-void lcd_update()                                                                {
+void lcd_update() {
   #if ENABLED(SDSUPPORT)
     static bool last_sd_status;
     const bool sd_status = IS_SD_INSERTED;
@@ -585,7 +601,7 @@ void lcd_update()
       }
     }
   #endif // SDSUPPORT
-  UI::onUpdate();
+  UI::onIdle();
 }
 
 bool lcd_hasstatus()                                                             { return true; }
@@ -594,8 +610,25 @@ void lcd_reset_alert_level()
 void lcd_refresh()                                                               {}
 void lcd_setstatus(const char * const message, const bool persist /* = false */) { UI::onStatusChanged(message); }
 void lcd_setstatusPGM(const char * const message, int8_t level /* = 0 */)        { UI::onStatusChanged((progmem_str)message); }
-void lcd_reset_status()                                                          {}
 void lcd_setalertstatusPGM(const char * const message)                           { lcd_setstatusPGM(message, 0); }
+void lcd_reset_status() {
+  static const char paused[] PROGMEM = MSG_PRINT_PAUSED;
+  static const char printing[] PROGMEM = MSG_PRINTING;
+  static const char welcome[] PROGMEM = WELCOME_MSG;
+  PGM_P msg;
+  if (print_job_timer.isPaused())
+    msg = paused;
+  #if ENABLED(SDSUPPORT)
+    else if (card.sdprinting)
+      return lcd_setstatus(card.longest_filename(), true);
+  #endif
+  else if (print_job_timer.isRunning())
+    msg = printing;
+  else
+    msg = welcome;
+
+  lcd_setstatusPGM(msg, -1);
+}
 void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) {
   char buff[64];
   va_list args;
diff --git a/Marlin/src/lcd/extensible_ui/ui_api.h b/Marlin/src/lcd/extensible_ui/ui_api.h
index 34e2ea75bda..15a68f929dc 100644
--- a/Marlin/src/lcd/extensible_ui/ui_api.h
+++ b/Marlin/src/lcd/extensible_ui/ui_api.h
@@ -49,13 +49,21 @@ namespace UI {
   float getAxisMaxAcceleration_mm_s2(const axis_t axis);
   float getMinFeedrate_mm_s();
   float getMinTravelFeedrate_mm_s();
-  float getPrintingAcceleration_mm_per_s2();
-  float getRetractAcceleration_mm_per_s2();
-  float getTravelAcceleration_mm_per_s2();
+  float getPrintingAcceleration_mm_s2();
+  float getRetractAcceleration_mm_s2();
+  float getTravelAcceleration_mm_s2();
   float getFeedRate_percent();
   uint8_t getProgress_percent();
   uint32_t getProgress_seconds_elapsed();
 
+  #if ENABLED(PRINTCOUNTER)
+    char *getTotalPrints_str(char buffer[21]);
+    char *getFinishedPrints_str(char buffer[21]);
+    char *getTotalPrintTime_str(char buffer[21]);
+    char *getLongestPrint_str(char buffer[21]);
+    char *getFilamentUsed_str(char buffer[21]);
+  #endif
+
   void setTargetTemp_celsius(const uint8_t extruder, float temp);
   void setFan_percent(const uint8_t fan, const float percent);
   void setAxisPosition_mm(const axis_t axis, float position, float _feedrate_mm_s);
@@ -157,7 +165,7 @@ namespace UI {
   // module and will be called by Marlin.
 
   void onStartup();
-  void onUpdate();
+  void onIdle();
   void onMediaInserted();
   void onMediaError();
   void onMediaRemoved();
@@ -171,4 +179,5 @@ namespace UI {
   void onStatusChanged(progmem_str msg);
   void onFactoryReset();
   void onStoreSettings();
+  void onLoadSettings();
 };