♻️ Set Progress without LCD (#24767)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
		
				
					committed by
					
						
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							b0f02b8f9e
						
					
				
				
					commit
					8481264566
				
			@@ -1403,9 +1403,6 @@
 | 
			
		||||
  // On the Info Screen, display XY with one decimal place when possible
 | 
			
		||||
  //#define LCD_DECIMAL_SMALL_XY
 | 
			
		||||
 | 
			
		||||
  // Add an 'M73' G-code to set the current percentage
 | 
			
		||||
  //#define LCD_SET_PROGRESS_MANUALLY
 | 
			
		||||
 | 
			
		||||
  // Show the E position (filament used) during printing
 | 
			
		||||
  //#define LCD_SHOW_E_TOTAL
 | 
			
		||||
 | 
			
		||||
@@ -1426,37 +1423,43 @@
 | 
			
		||||
      //#define LED_USER_PRESET_STARTUP       // Have the printer display the user preset color on startup
 | 
			
		||||
    #endif
 | 
			
		||||
    #if ENABLED(NEO2_COLOR_PRESETS)
 | 
			
		||||
      #define NEO2_USER_PRESET_RED        255  // User defined RED value
 | 
			
		||||
      #define NEO2_USER_PRESET_GREEN      128  // User defined GREEN value
 | 
			
		||||
      #define NEO2_USER_PRESET_BLUE         0  // User defined BLUE value
 | 
			
		||||
      #define NEO2_USER_PRESET_WHITE      255  // User defined WHITE value
 | 
			
		||||
      #define NEO2_USER_PRESET_BRIGHTNESS 255  // User defined intensity
 | 
			
		||||
      //#define NEO2_USER_PRESET_STARTUP       // Have the printer display the user preset color on startup for the second strip
 | 
			
		||||
      #define NEO2_USER_PRESET_RED        255 // User defined RED value
 | 
			
		||||
      #define NEO2_USER_PRESET_GREEN      128 // User defined GREEN value
 | 
			
		||||
      #define NEO2_USER_PRESET_BLUE         0 // User defined BLUE value
 | 
			
		||||
      #define NEO2_USER_PRESET_WHITE      255 // User defined WHITE value
 | 
			
		||||
      #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity
 | 
			
		||||
      //#define NEO2_USER_PRESET_STARTUP      // Have the printer display the user preset color on startup for the second strip
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
#endif // HAS_DISPLAY || DWIN_LCD_PROUI
 | 
			
		||||
 | 
			
		||||
// Add the G-code 'M73' to set / report the current job progress
 | 
			
		||||
//#define SET_PROGRESS_MANUALLY
 | 
			
		||||
#if ENABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
  //#define SET_PROGRESS_PERCENT          // Add 'P' parameter to set percentage done, otherwise use Marlin's estimate
 | 
			
		||||
  //#define SET_REMAINING_TIME            // Add 'R' parameter to set remaining time, otherwise use Marlin's estimate
 | 
			
		||||
  //#define SET_INTERACTION_TIME          // Add 'C' parameter to set time until next filament change or other user interaction
 | 
			
		||||
  #if ENABLED(SET_INTERACTION_TIME)
 | 
			
		||||
    #define SHOW_INTERACTION_TIME         // Display time until next user interaction ('C' = filament change)
 | 
			
		||||
  #endif
 | 
			
		||||
  //#define M73_REPORT                    // Report progress to host with 'M73'
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// LCD Print Progress options
 | 
			
		||||
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #if CAN_SHOW_REMAINING_TIME
 | 
			
		||||
    //#define SHOW_REMAINING_TIME         // Display estimated time to completion
 | 
			
		||||
    #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
      //#define USE_M73_REMAINING_TIME    // Use remaining time from M73 command instead of estimation
 | 
			
		||||
      //#define ROTATE_PROGRESS_DISPLAY   // Display (P)rogress, (E)lapsed, and (R)emaining time
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
// LCD Print Progress options, multiple can be rotated depending on screen layout
 | 
			
		||||
#if HAS_DISPLAY && EITHER(SDSUPPORT, SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #define SHOW_PROGRESS_PERCENT           // Show print progress percentage (doesn't affect progress bar)
 | 
			
		||||
  #define SHOW_ELAPSED_TIME               // Display elapsed printing time (prefix 'E')
 | 
			
		||||
  //#define SHOW_REMAINING_TIME           // Display estimated time to completion (prefix 'R')
 | 
			
		||||
 | 
			
		||||
  #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI)
 | 
			
		||||
    //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
 | 
			
		||||
  #endif
 | 
			
		||||
  //#define PRINT_PROGRESS_SHOW_DECIMALS  // Show/report progress with decimal digits, not all UIs support this
 | 
			
		||||
 | 
			
		||||
  #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
 | 
			
		||||
    //#define LCD_PROGRESS_BAR            // Show a progress bar on HD44780 LCDs for SD printing
 | 
			
		||||
    #if ENABLED(LCD_PROGRESS_BAR)
 | 
			
		||||
      #define PROGRESS_BAR_BAR_TIME 2000  // (ms) Amount of time to show the bar
 | 
			
		||||
      #define PROGRESS_BAR_MSG_TIME 3000  // (ms) Amount of time to show the status message
 | 
			
		||||
      #define PROGRESS_MSG_EXPIRE   0     // (ms) Amount of time to retain the status message (0=forever)
 | 
			
		||||
      #define PROGRESS_MSG_EXPIRE      0  // (ms) Amount of time to retain the status message (0=forever)
 | 
			
		||||
      //#define PROGRESS_MSG_ONCE         // Show the message for MSG_TIME then clear it
 | 
			
		||||
      //#define LCD_PROGRESS_BAR_TEST     // Add a menu item to test the progress bar
 | 
			
		||||
    #endif
 | 
			
		||||
@@ -1799,14 +1802,8 @@
 | 
			
		||||
#endif // HAS_MARLINUI_U8GLIB
 | 
			
		||||
 | 
			
		||||
#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
 | 
			
		||||
  // Show SD percentage next to the progress bar
 | 
			
		||||
  //#define SHOW_SD_PERCENT
 | 
			
		||||
 | 
			
		||||
  // Enable to save many cycles by drawing a hollow frame on Menu Screens
 | 
			
		||||
  #define MENU_HOLLOW_FRAME
 | 
			
		||||
 | 
			
		||||
  // Swap the CW/CCW indicators in the graphics overlay
 | 
			
		||||
  //#define OVERLAY_GFX_REVERSE
 | 
			
		||||
  #define MENU_HOLLOW_FRAME           // Enable to save many cycles by drawing a hollow frame on Menu Screens
 | 
			
		||||
  //#define OVERLAY_GFX_REVERSE       // Swap the CW/CCW indicators in the graphics overlay
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@@ -2064,7 +2061,7 @@
 | 
			
		||||
 */
 | 
			
		||||
//#define LIN_ADVANCE
 | 
			
		||||
#if ENABLED(LIN_ADVANCE)
 | 
			
		||||
  //#define EXTRA_LIN_ADVANCE_K // Add a second linear advance constant, configurable with M900.
 | 
			
		||||
  //#define EXTRA_LIN_ADVANCE_K // Add a second linear advance constant, configurable with M900 L.
 | 
			
		||||
  #define LIN_ADVANCE_K 0.22    // Unit: mm compression per 1mm/s extruder speed
 | 
			
		||||
  //#define LA_DEBUG            // Print debug information to serial during operation. Disable for production use.
 | 
			
		||||
  //#define EXPERIMENTAL_SCURVE // Allow S-Curve Acceleration to be used with LA.
 | 
			
		||||
@@ -4058,7 +4055,7 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Mechanical Gantry Calibration
 | 
			
		||||
 * Modern replacement for the Prusa TMC_Z_CALIBRATION.
 | 
			
		||||
 * Modern replacement for the Průša TMC_Z_CALIBRATION.
 | 
			
		||||
 * Adds capability to work with any adjustable current drivers.
 | 
			
		||||
 * Implemented as G34 because M915 is deprecated.
 | 
			
		||||
 * @section calibrate
 | 
			
		||||
 
 | 
			
		||||
@@ -347,7 +347,7 @@ void startOrResumeJob() {
 | 
			
		||||
    TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
 | 
			
		||||
    TERN_(CANCEL_OBJECTS, cancelable.reset());
 | 
			
		||||
    TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0);
 | 
			
		||||
    #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
 | 
			
		||||
    #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
      ui.reset_remaining_time();
 | 
			
		||||
    #endif
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -561,8 +561,8 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
 | 
			
		||||
        case 48: M48(); break;                                    // M48: Z probe repeatability test
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
        case 73: M73(); break;                                    // M73: Set progress percentage (for display on LCD)
 | 
			
		||||
      #if ENABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
        case 73: M73(); break;                                    // M73: Set progress percentage
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      case 75: M75(); break;                                      // M75: Start print timer
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@
 | 
			
		||||
 * M43  - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins (Requires PINS_DEBUGGING)
 | 
			
		||||
 * M48  - Measure Z Probe repeatability: M48 P<points> X<pos> Y<pos> V<level> E<engage> L<legs> S<chizoid>. (Requires Z_MIN_PROBE_REPEATABILITY_TEST)
 | 
			
		||||
 *
 | 
			
		||||
 * M73  - Set the progress percentage. (Requires LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
 * M73  - Set the progress percentage. (Requires SET_PROGRESS_MANUALLY)
 | 
			
		||||
 * M75  - Start the print job timer.
 | 
			
		||||
 * M76  - Pause the print job timer.
 | 
			
		||||
 * M77  - Stop the print job timer.
 | 
			
		||||
@@ -677,7 +677,7 @@ private:
 | 
			
		||||
    static void M48();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #if ENABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
    static void M73();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -142,7 +142,7 @@ void GcodeSuite::M115() {
 | 
			
		||||
    cap_line(F("LEVELING_DATA"), ENABLED(HAS_LEVELING));
 | 
			
		||||
 | 
			
		||||
    // BUILD_PERCENT (M73)
 | 
			
		||||
    cap_line(F("BUILD_PERCENT"), ENABLED(LCD_SET_PROGRESS_MANUALLY));
 | 
			
		||||
    cap_line(F("BUILD_PERCENT"), ENABLED(SET_PROGRESS_PERCENT));
 | 
			
		||||
 | 
			
		||||
    // SOFTWARE_POWER (M80, M81)
 | 
			
		||||
    cap_line(F("SOFTWARE_POWER"), ENABLED(PSU_CONTROL));
 | 
			
		||||
 
 | 
			
		||||
@@ -22,21 +22,35 @@
 | 
			
		||||
 | 
			
		||||
#include "../../inc/MarlinConfig.h"
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
#if ENABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
 | 
			
		||||
#include "../gcode.h"
 | 
			
		||||
#include "../../lcd/marlinui.h"
 | 
			
		||||
#include "../../sd/cardreader.h"
 | 
			
		||||
#include "../../libs/numtostr.h"
 | 
			
		||||
 | 
			
		||||
#if ENABLED(DWIN_LCD_PROUI)
 | 
			
		||||
  #include "../../lcd/e3v2/proui/dwin.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(M73_REPORT)
 | 
			
		||||
  #define M73_REPORT_PRUSA
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * M73: Set percentage complete (for display on LCD)
 | 
			
		||||
 *
 | 
			
		||||
 * Example:
 | 
			
		||||
 *   M73 P25 ; Set progress to 25%
 | 
			
		||||
 *   M73 P25.63 ; Set progress to 25.63%
 | 
			
		||||
 *   M73 R456   ; Set remaining time to 456 minutes
 | 
			
		||||
 *   M73 C12    ; Set next interaction countdown to 12 minutes
 | 
			
		||||
 *   M73        ; Report current values
 | 
			
		||||
 *
 | 
			
		||||
 * Use a shorter-than-Průša report format:
 | 
			
		||||
 * M73 Percent done: ---%; Time left: -----m; Change: -----m;
 | 
			
		||||
 *
 | 
			
		||||
 * When PRINT_PROGRESS_SHOW_DECIMALS is enabled - reports percent with 100 / 23.4 / 3.45 format
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M73() {
 | 
			
		||||
 | 
			
		||||
@@ -46,17 +60,39 @@ void GcodeSuite::M73() {
 | 
			
		||||
 | 
			
		||||
  #else
 | 
			
		||||
 | 
			
		||||
    if (parser.seenval('P'))
 | 
			
		||||
      ui.set_progress((PROGRESS_SCALE) > 1
 | 
			
		||||
        ? parser.value_float() * (PROGRESS_SCALE)
 | 
			
		||||
        : parser.value_byte()
 | 
			
		||||
      );
 | 
			
		||||
    #if ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
      if (parser.seenval('P'))
 | 
			
		||||
        ui.set_progress((PROGRESS_SCALE) > 1
 | 
			
		||||
          ? parser.value_float() * (PROGRESS_SCALE)
 | 
			
		||||
          : parser.value_byte()
 | 
			
		||||
        );
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(USE_M73_REMAINING_TIME)
 | 
			
		||||
    #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
      if (parser.seenval('R')) ui.set_remaining_time(60 * parser.value_ulong());
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(SET_INTERACTION_TIME)
 | 
			
		||||
      if (parser.seenval('C')) ui.set_interaction_time(60 * parser.value_ulong());
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(M73_REPORT)
 | 
			
		||||
  {
 | 
			
		||||
    SERIAL_ECHO_MSG(
 | 
			
		||||
        TERN(M73_REPORT_PRUSA, "M73 Percent done: ", "Progress: ")
 | 
			
		||||
      , TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui.get_progress_percent())
 | 
			
		||||
      #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
        , TERN(M73_REPORT_PRUSA, "; Print time remaining in mins: ", "%; Time left: "), ui.remaining_time / 60
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(SET_INTERACTION_TIME)
 | 
			
		||||
        , TERN(M73_REPORT_PRUSA, "; Change in mins: ", "m; Change: "), ui.interaction_time / 60
 | 
			
		||||
      #endif
 | 
			
		||||
      , TERN(M73_REPORT_PRUSA, ";", "m")
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // LCD_SET_PROGRESS_MANUALLY
 | 
			
		||||
#endif // SET_PROGRESS_MANUALLY
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
  #include "../queue.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EITHER(LCD_SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE)
 | 
			
		||||
#if EITHER(SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE)
 | 
			
		||||
  #include "../../lcd/marlinui.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +84,7 @@ void GcodeSuite::M1001() {
 | 
			
		||||
  process_subcommands_now(F("M77"));
 | 
			
		||||
 | 
			
		||||
  // Set the progress bar "done" state
 | 
			
		||||
  TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress_done());
 | 
			
		||||
  TERN_(SET_PROGRESS_PERCENT, ui.set_progress_done());
 | 
			
		||||
 | 
			
		||||
  // Announce SD file completion
 | 
			
		||||
  {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ void GcodeSuite::M23() {
 | 
			
		||||
  for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
 | 
			
		||||
  card.openFileRead(parser.string_arg);
 | 
			
		||||
 | 
			
		||||
  TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(0));
 | 
			
		||||
  TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // SDSUPPORT
 | 
			
		||||
 
 | 
			
		||||
@@ -529,10 +529,6 @@
 | 
			
		||||
  #define HAS_MANUAL_MOVE_MENU 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, IS_DWIN_MARLINUI, DWIN_CREALITY_LCD_JYERSUI)
 | 
			
		||||
  #define CAN_SHOW_REMAINING_TIME 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_MARLINUI_U8GLIB
 | 
			
		||||
  #ifndef LCD_PIXEL_WIDTH
 | 
			
		||||
    #define LCD_PIXEL_WIDTH 128
 | 
			
		||||
 
 | 
			
		||||
@@ -599,10 +599,16 @@
 | 
			
		||||
  #undef MENU_ADDAUTOSTART
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
#if EITHER(SDSUPPORT, SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #define HAS_PRINT_PROGRESS 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if DISABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #undef SET_REMAINING_TIME
 | 
			
		||||
  #undef SET_INTERACTION_TIME
 | 
			
		||||
  #undef M73_REPORT
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ANY(HAS_MARLINUI_MENU, ULTIPANEL_FEEDMULTIPLY, SOFT_RESET_ON_KILL)
 | 
			
		||||
  #define HAS_ENCODER_ACTION 1
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -587,7 +587,7 @@
 | 
			
		||||
#elif defined(MKS_LCD12864)
 | 
			
		||||
  #error "MKS_LCD12864 is now MKS_LCD12864A or MKS_LCD12864B."
 | 
			
		||||
#elif defined(DOGM_SD_PERCENT)
 | 
			
		||||
  #error "DOGM_SD_PERCENT is now SHOW_SD_PERCENT."
 | 
			
		||||
  #error "DOGM_SD_PERCENT is now SHOW_PROGRESS_PERCENT."
 | 
			
		||||
#elif defined(NEOPIXEL_BKGD_LED_INDEX)
 | 
			
		||||
  #error "NEOPIXEL_BKGD_LED_INDEX is now NEOPIXEL_BKGD_INDEX_FIRST."
 | 
			
		||||
#elif defined(TEMP_SENSOR_1_AS_REDUNDANT)
 | 
			
		||||
@@ -646,6 +646,12 @@
 | 
			
		||||
  #error "TOUCH_IDLE_SLEEP (seconds) is now TOUCH_IDLE_SLEEP_MINS (minutes)."
 | 
			
		||||
#elif defined(LCD_BACKLIGHT_TIMEOUT)
 | 
			
		||||
  #error "LCD_BACKLIGHT_TIMEOUT (seconds) is now LCD_BACKLIGHT_TIMEOUT_MINS (minutes)."
 | 
			
		||||
#elif defined(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #error "LCD_SET_PROGRESS_MANUALLY is now SET_PROGRESS_MANUALLY."
 | 
			
		||||
#elif defined(USE_M73_REMAINING_TIME)
 | 
			
		||||
  #error "USE_M73_REMAINING_TIME is now SET_REMAINING_TIME."
 | 
			
		||||
#elif defined(SHOW_SD_PERCENT)
 | 
			
		||||
  #error "SHOW_SD_PERCENT is now SHOW_PROGRESS_PERCENT."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// L64xx stepper drivers have been removed
 | 
			
		||||
@@ -894,8 +900,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
 | 
			
		||||
 * Progress Bar
 | 
			
		||||
 */
 | 
			
		||||
#if ENABLED(LCD_PROGRESS_BAR)
 | 
			
		||||
  #if NONE(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
    #error "LCD_PROGRESS_BAR requires SDSUPPORT or LCD_SET_PROGRESS_MANUALLY."
 | 
			
		||||
  #if NONE(SDSUPPORT, SET_PROGRESS_MANUALLY)
 | 
			
		||||
    #error "LCD_PROGRESS_BAR requires SDSUPPORT or SET_PROGRESS_MANUALLY."
 | 
			
		||||
  #elif NONE(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
 | 
			
		||||
    #error "LCD_PROGRESS_BAR only applies to HD44780 character LCD and TFTGLCD_PANEL_(SPI|I2C)."
 | 
			
		||||
  #elif HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
 | 
			
		||||
@@ -905,12 +911,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
 | 
			
		||||
  #elif PROGRESS_MSG_EXPIRE < 0
 | 
			
		||||
    #error "PROGRESS_MSG_EXPIRE must be greater than or equal to 0."
 | 
			
		||||
  #endif
 | 
			
		||||
#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, EXTENSIBLE_UI, HAS_DWIN_E3V2, IS_DWIN_MARLINUI)
 | 
			
		||||
  #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_*, OR EXTENSIBLE_UI."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(USE_M73_REMAINING_TIME) && DISABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #error "USE_M73_REMAINING_TIME requires LCD_SET_PROGRESS_MANUALLY"
 | 
			
		||||
#if ENABLED(SET_PROGRESS_MANUALLY) && NONE(SET_PROGRESS_PERCENT, SET_REMAINING_TIME, SET_INTERACTION_TIME)
 | 
			
		||||
  #error "SET_PROGRESS_MANUALLY requires at least one of SET_PROGRESS_PERCENT, SET_REMAINING_TIME, SET_INTERACTION_TIME to be enabled."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_LCDPRINT && LCD_HEIGHT < 4 && ANY(SHOW_PROGRESS_PERCENT, SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME)
 | 
			
		||||
  #error "Displays with fewer than 4 rows of text can't show progress values."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !HAS_MARLINUI_MENU && ENABLED(SD_REPRINT_LAST_SELECTED_FILE)
 | 
			
		||||
@@ -4038,10 +4046,6 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
 | 
			
		||||
  #error "COOLANT_FLOOD requires COOLANT_FLOOD_PIN to be defined."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if NONE(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, IS_DWIN_MARLINUI) && ENABLED(PRINT_PROGRESS_SHOW_DECIMALS)
 | 
			
		||||
  #error "PRINT_PROGRESS_SHOW_DECIMALS currently requires a Graphical LCD."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_ADC_BUTTONS && defined(ADC_BUTTON_DEBOUNCE_DELAY) && ADC_BUTTON_DEBOUNCE_DELAY < 16
 | 
			
		||||
  #error "ADC_BUTTON_DEBOUNCE_DELAY must be greater than 16."
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -612,20 +612,6 @@ FORCE_INLINE void _draw_bed_status(const bool blink) {
 | 
			
		||||
  _draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
  FORCE_INLINE void _draw_print_progress() {
 | 
			
		||||
    const uint8_t progress = ui.get_progress_percent();
 | 
			
		||||
    lcd_put_u8str(F(TERN(SDSUPPORT, "SD", "P:")));
 | 
			
		||||
    if (progress)
 | 
			
		||||
      lcd_put_u8str(ui8tostr3rj(progress));
 | 
			
		||||
    else
 | 
			
		||||
      lcd_put_u8str(F("---"));
 | 
			
		||||
    lcd_put_lchar('%');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LCD_PROGRESS_BAR)
 | 
			
		||||
 | 
			
		||||
  void MarlinUI::draw_progress_bar(const uint8_t percent) {
 | 
			
		||||
@@ -733,6 +719,56 @@ void MarlinUI::draw_status_message(const bool blink) {
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if HAS_PRINT_PROGRESS
 | 
			
		||||
  #define TPOFFSET (LCD_WIDTH - 1)
 | 
			
		||||
  static uint8_t timepos = TPOFFSET - 6;
 | 
			
		||||
  static char buffer[14];
 | 
			
		||||
  static lcd_uint_t pc, pr;
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(SHOW_PROGRESS_PERCENT)
 | 
			
		||||
    void MarlinUI::drawPercent() {
 | 
			
		||||
      const uint8_t progress = ui.get_progress_percent();
 | 
			
		||||
      if (progress) {
 | 
			
		||||
        lcd_moveto(pc, pr);
 | 
			
		||||
        lcd_put_u8str(F(TERN(IS_SD_PRINTING, "SD", "P:")));
 | 
			
		||||
        lcd_put_u8str(TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui8tostr3rj(progress)));
 | 
			
		||||
        lcd_put_lchar('%');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
    void MarlinUI::drawRemain() {
 | 
			
		||||
      const duration_t remaint = ui.get_remaining_time();
 | 
			
		||||
      if (printJobOngoing()) {
 | 
			
		||||
        timepos = TPOFFSET - remaint.toDigital(buffer);
 | 
			
		||||
        lcd_put_lchar(TERN(LCD_INFO_SCREEN_STYLE, 11, timepos), 2, 'R');
 | 
			
		||||
        lcd_put_u8str(buffer);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_INTERACTION_TIME)
 | 
			
		||||
    void MarlinUI::drawInter() {
 | 
			
		||||
      const duration_t interactt = ui.interaction_time;
 | 
			
		||||
      if (printingIsActive() && interactt.value) {
 | 
			
		||||
        timepos = TPOFFSET - interactt.toDigital(buffer);
 | 
			
		||||
        lcd_put_lchar(TERN(LCD_INFO_SCREEN_STYLE, 11, timepos), 2, 'C');
 | 
			
		||||
        lcd_put_u8str(buffer);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_ELAPSED_TIME)
 | 
			
		||||
    void MarlinUI::drawElapsed() {
 | 
			
		||||
      const duration_t elapsedt = print_job_timer.duration();
 | 
			
		||||
      if (printJobOngoing()) {
 | 
			
		||||
        timepos = TPOFFSET - elapsedt.toDigital(buffer);
 | 
			
		||||
        lcd_put_lchar(TERN(LCD_INFO_SCREEN_STYLE, 11, timepos), 2, 'E');
 | 
			
		||||
        //lcd_put_lchar(timepos, 2, LCD_STR_CLOCK[0]);
 | 
			
		||||
        lcd_put_u8str(buffer);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
#endif // HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  LCD_INFO_SCREEN_STYLE 0 : Classic Status Screen
 | 
			
		||||
 *
 | 
			
		||||
@@ -765,35 +801,6 @@ void MarlinUI::draw_status_message(const bool blink) {
 | 
			
		||||
 *  |01234567890123456789|
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
inline uint8_t draw_elapsed_or_remaining_time(uint8_t timepos, const bool blink) {
 | 
			
		||||
  char buffer[14];
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
    const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && printingIsActive();
 | 
			
		||||
    if (show_remain) {
 | 
			
		||||
      #if ENABLED(USE_M73_REMAINING_TIME)
 | 
			
		||||
        duration_t remaining = ui.get_remaining_time();
 | 
			
		||||
      #else
 | 
			
		||||
        uint8_t progress = ui.get_progress_percent();
 | 
			
		||||
        uint32_t elapsed = print_job_timer.duration();
 | 
			
		||||
        duration_t remaining = (progress > 0) ? ((elapsed * 25600 / progress) >> 8) - elapsed : 0;
 | 
			
		||||
      #endif
 | 
			
		||||
      timepos -= remaining.toDigital(buffer);
 | 
			
		||||
      lcd_put_lchar(timepos, 2, 'R');
 | 
			
		||||
    }
 | 
			
		||||
  #else
 | 
			
		||||
    constexpr bool show_remain = false;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  if (!show_remain) {
 | 
			
		||||
    duration_t elapsed = print_job_timer.duration();
 | 
			
		||||
    timepos -= elapsed.toDigital(buffer);
 | 
			
		||||
    lcd_put_lchar(timepos, 2, LCD_STR_CLOCK[0]);
 | 
			
		||||
  }
 | 
			
		||||
  lcd_put_u8str(buffer);
 | 
			
		||||
  return timepos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinUI::draw_status_screen() {
 | 
			
		||||
 | 
			
		||||
  const bool blink = get_blink();
 | 
			
		||||
@@ -856,8 +863,8 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
      #if LCD_WIDTH < 20
 | 
			
		||||
 | 
			
		||||
        #if HAS_PRINT_PROGRESS
 | 
			
		||||
          lcd_moveto(0, 2);
 | 
			
		||||
          _draw_print_progress();
 | 
			
		||||
          pc = 0, pr = 2;
 | 
			
		||||
          rotate_progress();
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
      #else // LCD_WIDTH >= 20
 | 
			
		||||
@@ -940,12 +947,11 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
      lcd_put_u8str(i16tostr3rj(feedrate_percentage));
 | 
			
		||||
      lcd_put_lchar('%');
 | 
			
		||||
 | 
			
		||||
      const uint8_t timepos = draw_elapsed_or_remaining_time(LCD_WIDTH - 1, blink);
 | 
			
		||||
 | 
			
		||||
      #if LCD_WIDTH >= 20
 | 
			
		||||
        lcd_moveto(timepos - 7, 2);
 | 
			
		||||
 | 
			
		||||
        #if HAS_PRINT_PROGRESS
 | 
			
		||||
          _draw_print_progress();
 | 
			
		||||
          pc = timepos - 7, pr = 2;
 | 
			
		||||
          rotate_progress();
 | 
			
		||||
        #else
 | 
			
		||||
          char c;
 | 
			
		||||
          uint16_t per;
 | 
			
		||||
@@ -1016,7 +1022,7 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
    // ========== Line 3 ==========
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // SD Percent, Hotend 2, or Bed
 | 
			
		||||
    // Progress percent, Hotend 2, or Bed
 | 
			
		||||
    //
 | 
			
		||||
    lcd_moveto(0, 2);
 | 
			
		||||
    #if HOTENDS > 2
 | 
			
		||||
@@ -1025,24 +1031,17 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
      _draw_bed_status(blink);
 | 
			
		||||
    #elif HAS_PRINT_PROGRESS
 | 
			
		||||
      #define DREW_PRINT_PROGRESS 1
 | 
			
		||||
      _draw_print_progress();
 | 
			
		||||
      pc = 0, pr = 2;
 | 
			
		||||
      rotate_progress();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Elapsed Time or SD Percent
 | 
			
		||||
    // All progress strings
 | 
			
		||||
    //
 | 
			
		||||
    lcd_moveto(LCD_WIDTH - 9, 2);
 | 
			
		||||
 | 
			
		||||
    #if HAS_PRINT_PROGRESS && !DREW_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
      _draw_print_progress();
 | 
			
		||||
 | 
			
		||||
    #else
 | 
			
		||||
 | 
			
		||||
      (void)draw_elapsed_or_remaining_time(LCD_WIDTH - 4, blink);
 | 
			
		||||
 | 
			
		||||
      pc = LCD_WIDTH - 9, pr = 2;
 | 
			
		||||
      rotate_progress();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
  #endif // LCD_INFO_SCREEN_STYLE 1
 | 
			
		||||
 | 
			
		||||
  // ========= Last Line ========
 | 
			
		||||
 
 | 
			
		||||
@@ -606,7 +606,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 | 
			
		||||
    const uint8_t progress = ui._get_progress();
 | 
			
		||||
    #if ENABLED(SDSUPPORT)
 | 
			
		||||
      lcd_put_u8str(F("SD"));
 | 
			
		||||
    #elif ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
    #elif ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
      lcd_put_u8str(F("P:"));
 | 
			
		||||
    #endif
 | 
			
		||||
    if (progress)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,9 +40,7 @@
 | 
			
		||||
 | 
			
		||||
#include "../../gcode/parser.h" // for units (and volumetric)
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LCD_SHOW_E_TOTAL)
 | 
			
		||||
  #include "../../MarlinCore.h" // for printingIsActive()
 | 
			
		||||
#endif
 | 
			
		||||
#include "../../MarlinCore.h" // for printingIsActive()
 | 
			
		||||
 | 
			
		||||
#if ENABLED(FILAMENT_LCD_DISPLAY)
 | 
			
		||||
  #include "../../feature/filwidth.h"
 | 
			
		||||
@@ -445,6 +443,55 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 | 
			
		||||
    lcd_put_u8str(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Prepare strings for progress display
 | 
			
		||||
#if HAS_PRINT_PROGRESS
 | 
			
		||||
  #define _PRGR_INFO_X(len) (LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH))
 | 
			
		||||
  #define PCENTERED 1  // center percent value over progress bar, else align to the right
 | 
			
		||||
  static uint8_t lastProgress = 0xFF;
 | 
			
		||||
  static u8g_uint_t progress_bar_solid_width = 0;
 | 
			
		||||
  #if ENABLED(SHOW_PROGRESS_PERCENT)
 | 
			
		||||
    static char progress_string[5];
 | 
			
		||||
    static u8g_uint_t progress_x_pos;
 | 
			
		||||
    void MarlinUI::drawPercent() {
 | 
			
		||||
      if (progress_string[0]) {
 | 
			
		||||
        lcd_put_u8str(progress_x_pos, EXTRAS_BASELINE, progress_string);
 | 
			
		||||
        lcd_put_lchar('%');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
    static char remaining_string[10];
 | 
			
		||||
    static u8g_uint_t remaining_x_pos = 0;
 | 
			
		||||
    void MarlinUI::drawRemain() {
 | 
			
		||||
      if (printJobOngoing()){
 | 
			
		||||
        lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("R:"));
 | 
			
		||||
        lcd_put_u8str(remaining_x_pos, EXTRAS_BASELINE, remaining_string);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_INTERACTION_TIME)
 | 
			
		||||
    static char interaction_string[10];
 | 
			
		||||
    static u8g_uint_t interaction_x_pos = 0;
 | 
			
		||||
    void MarlinUI::drawInter() {
 | 
			
		||||
      if (printingIsActive() && interaction_string[0]) {
 | 
			
		||||
        lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("C:"));
 | 
			
		||||
        lcd_put_u8str(interaction_x_pos, EXTRAS_BASELINE, interaction_string);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_ELAPSED_TIME)
 | 
			
		||||
    static char elapsed_string[10];
 | 
			
		||||
    static u8g_uint_t elapsed_x_pos = 0;
 | 
			
		||||
    static uint8_t lastElapsed;
 | 
			
		||||
    void MarlinUI::drawElapsed() {
 | 
			
		||||
      if (printJobOngoing()) {
 | 
			
		||||
        lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("E:"));
 | 
			
		||||
        lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
#endif // HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Draw the Status Screen for a 128x64 DOGM (U8glib) display.
 | 
			
		||||
 *
 | 
			
		||||
@@ -459,30 +506,6 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
    static char wstring[5], mstring[4];
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if HAS_PRINT_PROGRESS
 | 
			
		||||
    #if DISABLED(SHOW_SD_PERCENT)
 | 
			
		||||
      #define _SD_INFO_X(len) (PROGRESS_BAR_X + (PROGRESS_BAR_WIDTH) / 2 - (len) * (MENU_FONT_WIDTH) / 2)
 | 
			
		||||
    #else
 | 
			
		||||
      #define _SD_INFO_X(len) (LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH))
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(SHOW_SD_PERCENT)
 | 
			
		||||
      static char progress_string[5];
 | 
			
		||||
    #endif
 | 
			
		||||
    static uint8_t lastElapsed = 0xFF, lastProgress = 0xFF;
 | 
			
		||||
    static u8g_uint_t elapsed_x_pos = 0, progress_bar_solid_width = 0;
 | 
			
		||||
    static char elapsed_string[16];
 | 
			
		||||
    #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
      static u8g_uint_t estimation_x_pos = 0;
 | 
			
		||||
      static char estimation_string[10];
 | 
			
		||||
      #if BOTH(SHOW_SD_PERCENT, ROTATE_PROGRESS_DISPLAY)
 | 
			
		||||
        static u8g_uint_t progress_x_pos = 0;
 | 
			
		||||
        static uint8_t progress_state = 0;
 | 
			
		||||
        static bool prev_blink = 0;
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
 | 
			
		||||
 | 
			
		||||
  // At the first page, generate new display values
 | 
			
		||||
@@ -523,61 +546,59 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
    // Progress / elapsed / estimation updates and string formatting to avoid float math on each LCD draw
 | 
			
		||||
    #if HAS_PRINT_PROGRESS
 | 
			
		||||
      const progress_t progress = TERN(HAS_PRINT_PROGRESS_PERMYRIAD, get_progress_permyriad, get_progress_percent)();
 | 
			
		||||
      duration_t elapsed = print_job_timer.duration();
 | 
			
		||||
      const uint8_t p = progress & 0xFF, ev = elapsed.value & 0xFF;
 | 
			
		||||
      duration_t elapsedt = print_job_timer.duration();
 | 
			
		||||
      const uint8_t p = progress & 0xFF, ev = elapsedt.value & 0xFF;
 | 
			
		||||
      if (p != lastProgress) {
 | 
			
		||||
        lastProgress = p;
 | 
			
		||||
 | 
			
		||||
        progress_bar_solid_width = u8g_uint_t((PROGRESS_BAR_WIDTH - 2) * (progress / (PROGRESS_SCALE)) * 0.01f);
 | 
			
		||||
 | 
			
		||||
        #if ENABLED(SHOW_SD_PERCENT)
 | 
			
		||||
          if (progress == 0) {
 | 
			
		||||
        #if ENABLED(SHOW_PROGRESS_PERCENT)
 | 
			
		||||
          if (progress == 0)
 | 
			
		||||
            progress_string[0] = '\0';
 | 
			
		||||
            #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
              estimation_string[0] = '\0';
 | 
			
		||||
              estimation_x_pos = _SD_INFO_X(0);
 | 
			
		||||
            #endif
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
            strcpy(progress_string, TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE))));
 | 
			
		||||
 | 
			
		||||
          #if BOTH(SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY) // Tri-state progress display mode
 | 
			
		||||
            progress_x_pos = _SD_INFO_X(strlen(progress_string) + 1);
 | 
			
		||||
          #endif
 | 
			
		||||
          progress_x_pos = TERN(PCENTERED, 77, _PRGR_INFO_X(strlen(progress_string) + 1));
 | 
			
		||||
        #endif
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      constexpr bool can_show_days = DISABLED(SHOW_SD_PERCENT) || ENABLED(ROTATE_PROGRESS_DISPLAY);
 | 
			
		||||
      if (ev != lastElapsed) {
 | 
			
		||||
        lastElapsed = ev;
 | 
			
		||||
        const uint8_t len = elapsed.toDigital(elapsed_string, can_show_days && elapsed.value >= 60*60*24L);
 | 
			
		||||
        elapsed_x_pos = _SD_INFO_X(len);
 | 
			
		||||
      #if ENABLED(SHOW_INTERACTION_TIME)
 | 
			
		||||
        if (!(interaction_time)) {
 | 
			
		||||
          interaction_string[0] = '\0';
 | 
			
		||||
          interaction_x_pos = _PRGR_INFO_X(0);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          const duration_t interactt = ui.interaction_time;
 | 
			
		||||
          interactt.toDigital(interaction_string, interactt.value >= 60*60*24L);
 | 
			
		||||
          interaction_x_pos = _PRGR_INFO_X(strlen(interaction_string));
 | 
			
		||||
        }
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
        #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
          if (!(ev & 0x3)) {
 | 
			
		||||
            uint32_t timeval = (0
 | 
			
		||||
              #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
 | 
			
		||||
                + get_remaining_time()
 | 
			
		||||
              #endif
 | 
			
		||||
            );
 | 
			
		||||
            if (!timeval && progress > 0) timeval = elapsed.value * (100 * (PROGRESS_SCALE) - progress) / progress;
 | 
			
		||||
            if (!timeval) {
 | 
			
		||||
              estimation_string[0] = '\0';
 | 
			
		||||
              estimation_x_pos = _SD_INFO_X(0);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
              duration_t estimation = timeval;
 | 
			
		||||
              const uint8_t len = estimation.toDigital(estimation_string, can_show_days && estimation.value >= 60*60*24L);
 | 
			
		||||
              estimation_x_pos = _SD_INFO_X(len + !BOTH(SHOW_SD_PERCENT, ROTATE_PROGRESS_DISPLAY));
 | 
			
		||||
            }
 | 
			
		||||
      #if ENABLED(SHOW_ELAPSED_TIME)
 | 
			
		||||
        if (ev != lastElapsed) {
 | 
			
		||||
          lastElapsed = ev;
 | 
			
		||||
          const uint8_t len = elapsedt.toDigital(elapsed_string, elapsedt.value >= 60*60*24L);
 | 
			
		||||
          elapsed_x_pos = _PRGR_INFO_X(len);
 | 
			
		||||
        }
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
        if (!(ev & 0x3)) {
 | 
			
		||||
          uint32_t timeval = get_remaining_time();
 | 
			
		||||
          if (!timeval) {
 | 
			
		||||
            remaining_string[0] = '\0';
 | 
			
		||||
            remaining_x_pos = _PRGR_INFO_X(0);
 | 
			
		||||
          }
 | 
			
		||||
        #endif
 | 
			
		||||
      }
 | 
			
		||||
          else {
 | 
			
		||||
            const duration_t remaint = timeval;
 | 
			
		||||
            const uint8_t len = remaint.toDigital(remaining_string, remaint.value >= 60*60*24L);
 | 
			
		||||
            remaining_x_pos = _PRGR_INFO_X(len);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const bool blink = get_blink();
 | 
			
		||||
 | 
			
		||||
  // Status Menu Font
 | 
			
		||||
  set_font(FONT_STATUSMENU);
 | 
			
		||||
 | 
			
		||||
@@ -634,6 +655,8 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
      u8g.drawBitmapP(STATUS_CHAMBER_X, chambery, STATUS_CHAMBER_BYTEWIDTH, chamberh, CHAMBER_BITMAP(CHAMBER_ALT()));
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  const bool blink = ui.get_blink();
 | 
			
		||||
 | 
			
		||||
  #if DO_DRAW_FAN
 | 
			
		||||
    #if STATUS_FAN_FRAMES > 2
 | 
			
		||||
      static bool old_blink;
 | 
			
		||||
@@ -664,8 +687,7 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
  if (PAGE_UNDER(6 + 1 + 12 + 1 + 6 + 1)) {
 | 
			
		||||
    // Extruders
 | 
			
		||||
    #if DO_DRAW_HOTENDS
 | 
			
		||||
      LOOP_L_N(e, MAX_HOTEND_DRAW)
 | 
			
		||||
        _draw_hotend_status((heater_id_t)e, blink);
 | 
			
		||||
      LOOP_L_N(e, MAX_HOTEND_DRAW) _draw_hotend_status((heater_id_t)e, blink);
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    // Laser / Spindle
 | 
			
		||||
@@ -757,74 +779,18 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
  #endif // SDSUPPORT
 | 
			
		||||
 | 
			
		||||
  #if HAS_PRINT_PROGRESS
 | 
			
		||||
    //
 | 
			
		||||
    // Progress bar frame
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    if (PAGE_CONTAINS(PROGRESS_BAR_Y, PROGRESS_BAR_Y + 3))
 | 
			
		||||
      u8g.drawFrame(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_WIDTH, 4);
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Progress bar solid part
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    if (PAGE_CONTAINS(PROGRESS_BAR_Y + 1, PROGRESS_BAR_Y + 2))
 | 
			
		||||
      u8g.drawBox(PROGRESS_BAR_X + 1, PROGRESS_BAR_Y + 1, progress_bar_solid_width, 2);
 | 
			
		||||
 | 
			
		||||
    if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1)) {
 | 
			
		||||
 | 
			
		||||
      #if ALL(SHOW_SD_PERCENT, SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY)
 | 
			
		||||
 | 
			
		||||
        if (prev_blink != blink) {
 | 
			
		||||
          prev_blink = blink;
 | 
			
		||||
          if (++progress_state >= 3) progress_state = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (progress_state == 0) {
 | 
			
		||||
          if (progress_string[0]) {
 | 
			
		||||
            lcd_put_u8str(progress_x_pos, EXTRAS_BASELINE, progress_string);
 | 
			
		||||
            lcd_put_lchar('%');
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else if (progress_state == 2 && estimation_string[0]) {
 | 
			
		||||
          lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("R:"));
 | 
			
		||||
          lcd_put_u8str(estimation_x_pos, EXTRAS_BASELINE, estimation_string);
 | 
			
		||||
        }
 | 
			
		||||
        else if (elapsed_string[0]) {
 | 
			
		||||
          lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, F("E:"));
 | 
			
		||||
          lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      #else // !SHOW_SD_PERCENT || !SHOW_REMAINING_TIME || !ROTATE_PROGRESS_DISPLAY
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // SD Percent Complete
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
        #if ENABLED(SHOW_SD_PERCENT)
 | 
			
		||||
          if (progress_string[0]) {
 | 
			
		||||
            lcd_put_u8str(55, EXTRAS_BASELINE, progress_string); // Percent complete
 | 
			
		||||
            lcd_put_lchar('%');
 | 
			
		||||
          }
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // Elapsed Time
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
        #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
          if (blink && estimation_string[0]) {
 | 
			
		||||
            lcd_put_lchar(estimation_x_pos, EXTRAS_BASELINE, 'R');
 | 
			
		||||
            lcd_put_u8str(estimation_string);
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
        #endif
 | 
			
		||||
            lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string);
 | 
			
		||||
 | 
			
		||||
      #endif // !SHOW_SD_PERCENT || !SHOW_REMAINING_TIME || !ROTATE_PROGRESS_DISPLAY
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  #endif // HAS_PRINT_PROGRESS
 | 
			
		||||
    // Progress strings
 | 
			
		||||
    if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1))
 | 
			
		||||
      ui.rotate_progress();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // XYZ Coordinates
 | 
			
		||||
 
 | 
			
		||||
@@ -40,12 +40,38 @@
 | 
			
		||||
// Lightweight Status Screen for Graphical Display
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
/** One hotend layout
 | 
			
		||||
 *  ------------------
 | 
			
		||||
 *  |⟱ xxx➜xxx° ✱xxx%
 | 
			
		||||
 *  |_ xxx➜xxx° Fxxx%
 | 
			
		||||
 *  ||||||||||R•xxx:xx
 | 
			
		||||
 *  |  status string
 | 
			
		||||
 *  ------------------
 | 
			
		||||
 *
 | 
			
		||||
 *  hotend temp | fan speed
 | 
			
		||||
 *  bed temp    | feedrate
 | 
			
		||||
 *  progress bar| progress time
 | 
			
		||||
 *       status string
 | 
			
		||||
 *
 | 
			
		||||
 * ****************************
 | 
			
		||||
 *  Two hotends layout
 | 
			
		||||
 *  ------------------
 | 
			
		||||
 *  |⟱ xxx➜xxx° ✱xxx%
 | 
			
		||||
 *  |⟱ xxx➜xxx°|||||||
 | 
			
		||||
 *  |_ xxx➜xxx°Rxxx:xx
 | 
			
		||||
 *  |  status string
 | 
			
		||||
 *  ------------------
 | 
			
		||||
 *
 | 
			
		||||
 *  hotend temp | fan speed
 | 
			
		||||
 *  hotend temp | progress bar
 | 
			
		||||
 *  bed temp    | progress time
 | 
			
		||||
 *       status string
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "../../inc/MarlinConfigPre.h"
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LIGHTWEIGHT_UI)
 | 
			
		||||
 | 
			
		||||
#include "status_screen_lite_ST7920.h"
 | 
			
		||||
 | 
			
		||||
#include "../marlinui.h"
 | 
			
		||||
#include "../fontutils.h"
 | 
			
		||||
#include "../lcdprint.h"
 | 
			
		||||
@@ -53,12 +79,13 @@
 | 
			
		||||
#include "../../module/motion.h"
 | 
			
		||||
#include "../../module/printcounter.h"
 | 
			
		||||
#include "../../module/temperature.h"
 | 
			
		||||
#include "../../libs/numtostr.h"
 | 
			
		||||
 | 
			
		||||
#if ENABLED(SDSUPPORT)
 | 
			
		||||
  #include "../../sd/cardreader.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LCD_SHOW_E_TOTAL)
 | 
			
		||||
#if ENABLED(LCD_SHOW_E_TOTAL) || HAS_PRINT_PROGRESS
 | 
			
		||||
  #include "../../MarlinCore.h" // for printingIsActive
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -72,6 +99,9 @@
 | 
			
		||||
#define DDRAM_LINE_3   0x08
 | 
			
		||||
#define DDRAM_LINE_4   0x18
 | 
			
		||||
 | 
			
		||||
#include "status_screen_lite_ST7920.h"
 | 
			
		||||
extern ST7920_Lite_Status_Screen lightUI;
 | 
			
		||||
 | 
			
		||||
ST7920_Lite_Status_Screen::st7920_state_t ST7920_Lite_Status_Screen::current_bits;
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::cmd(const uint8_t cmd) {
 | 
			
		||||
@@ -442,72 +472,6 @@ void ST7920_Lite_Status_Screen::draw_static_elements() {
 | 
			
		||||
  draw_fan_icon(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Although this is undocumented, the ST7920 allows the character
 | 
			
		||||
 * data buffer (DDRAM) to be used in conjunction with the graphics
 | 
			
		||||
 * bitmap buffer (CGRAM). The contents of the graphics buffer is
 | 
			
		||||
 * XORed with the data from the character generator. This allows
 | 
			
		||||
 * us to make the progress bar out of graphical data (the bar) and
 | 
			
		||||
 * text data (the percentage).
 | 
			
		||||
 */
 | 
			
		||||
void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) {
 | 
			
		||||
  #if HOTENDS == 1
 | 
			
		||||
    // If we have only one extruder, draw a long progress bar on the third line
 | 
			
		||||
    constexpr uint8_t top     = 1,         // Top in pixels
 | 
			
		||||
                      bottom  = 13,        // Bottom in pixels
 | 
			
		||||
                      left    = 12,        // Left edge, in 16-bit words
 | 
			
		||||
                      width   = 4;         // Width of progress bar, in 16-bit words
 | 
			
		||||
  #else
 | 
			
		||||
    constexpr uint8_t top     = 16 + 1,
 | 
			
		||||
                      bottom  = 16 + 13,
 | 
			
		||||
                      left    = 5,
 | 
			
		||||
                      width   = 3;
 | 
			
		||||
  #endif
 | 
			
		||||
  const uint8_t char_pcnt  = 100 / width; // How many percent does each 16-bit word represent?
 | 
			
		||||
 | 
			
		||||
  // Draw the progress bar as a bitmap in CGRAM
 | 
			
		||||
  LOOP_S_LE_N(y, top, bottom) {
 | 
			
		||||
    set_gdram_address(left, y);
 | 
			
		||||
    begin_data();
 | 
			
		||||
    LOOP_L_N(x, width) {
 | 
			
		||||
      uint16_t gfx_word = 0x0000;
 | 
			
		||||
      if ((x + 1) * char_pcnt <= value)
 | 
			
		||||
        gfx_word = 0xFFFF;                                              // Draw completely filled bytes
 | 
			
		||||
      else if ((x * char_pcnt) < value)
 | 
			
		||||
        gfx_word = int(0x8000) >> (value % char_pcnt) * 16 / char_pcnt; // Draw partially filled bytes
 | 
			
		||||
 | 
			
		||||
      // Draw the frame around the progress bar
 | 
			
		||||
      if (y == top || y == bottom)
 | 
			
		||||
        gfx_word = 0xFFFF;        // Draw top/bottom border
 | 
			
		||||
      else if (x == width - 1)
 | 
			
		||||
        gfx_word |= 0x0001;       // Draw right border
 | 
			
		||||
      else if (x == 0)
 | 
			
		||||
        gfx_word |= 0x8000;       // Draw left border
 | 
			
		||||
      write_word(gfx_word);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Draw the percentage as text in DDRAM
 | 
			
		||||
  #if HOTENDS == 1
 | 
			
		||||
    set_ddram_address(DDRAM_LINE_3 + 4);
 | 
			
		||||
    begin_data();
 | 
			
		||||
    write_byte(' ');
 | 
			
		||||
  #else
 | 
			
		||||
    set_ddram_address(DDRAM_LINE_2 + left);
 | 
			
		||||
    begin_data();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Draw centered
 | 
			
		||||
  if (value > 9) {
 | 
			
		||||
    write_number(value, 4);
 | 
			
		||||
    write_str(F("% "));
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    write_number(value, 3);
 | 
			
		||||
    write_str(F("%  "));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::draw_fan_icon(const bool whichIcon) {
 | 
			
		||||
  set_ddram_address(DDRAM_LINE_1 + 5);
 | 
			
		||||
  begin_data();
 | 
			
		||||
@@ -592,22 +556,8 @@ void ST7920_Lite_Status_Screen::draw_fan_speed(const uint8_t value) {
 | 
			
		||||
  write_byte('%');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::draw_print_time(const duration_t &elapsed, char suffix) {
 | 
			
		||||
  #if HOTENDS == 1
 | 
			
		||||
    set_ddram_address(DDRAM_LINE_3);
 | 
			
		||||
  #else
 | 
			
		||||
    set_ddram_address(DDRAM_LINE_3 + 5);
 | 
			
		||||
  #endif
 | 
			
		||||
  char str[7];
 | 
			
		||||
  int str_length = elapsed.toDigital(str);
 | 
			
		||||
  str[str_length++] = suffix;
 | 
			
		||||
  begin_data();
 | 
			
		||||
  write_str(str, str_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint16_t percentage) {
 | 
			
		||||
  // We only have enough room for the feedrate when
 | 
			
		||||
  // we have one extruder
 | 
			
		||||
  // We only have enough room for the feedrate when we have one extruder
 | 
			
		||||
  #if HOTENDS == 1
 | 
			
		||||
    set_ddram_address(DDRAM_LINE_2 + 6);
 | 
			
		||||
    begin_data();
 | 
			
		||||
@@ -631,11 +581,9 @@ void ST7920_Lite_Status_Screen::draw_status_message() {
 | 
			
		||||
      write_str(str);
 | 
			
		||||
      while (slen < TEXT_MODE_LCD_WIDTH) { write_byte(' '); ++slen; }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      // String is larger than the available space in screen.
 | 
			
		||||
    else {  // String is larger than the available space in ST7920_Lite_Status_Screen::
 | 
			
		||||
 | 
			
		||||
      // Get a pointer to the next valid UTF8 character
 | 
			
		||||
      // and the string remaining length
 | 
			
		||||
      // Get a pointer to the next valid UTF8 character and the string remaining length
 | 
			
		||||
      uint8_t rlen;
 | 
			
		||||
      const char *stat = ui.status_and_len(rlen);
 | 
			
		||||
      write_str(stat, TEXT_MODE_LCD_WIDTH);
 | 
			
		||||
@@ -643,12 +591,12 @@ void ST7920_Lite_Status_Screen::draw_status_message() {
 | 
			
		||||
      // If the remaining string doesn't completely fill the screen
 | 
			
		||||
      if (rlen < TEXT_MODE_LCD_WIDTH) {
 | 
			
		||||
        uint8_t chars = TEXT_MODE_LCD_WIDTH - rlen; // Amount of space left in characters
 | 
			
		||||
        write_byte(' ');                        // Always at 1+ spaces left, draw a space
 | 
			
		||||
        if (--chars) {                          // Draw a second space if there's room
 | 
			
		||||
        write_byte(' ');                            // Always at 1+ spaces left, draw a space
 | 
			
		||||
        if (--chars) {                              // Draw a second space if there's room
 | 
			
		||||
          write_byte(' ');
 | 
			
		||||
          if (--chars) {                        // Draw a third space if there's room
 | 
			
		||||
          if (--chars) {                            // Draw a third space if there's room
 | 
			
		||||
            write_byte(' ');
 | 
			
		||||
            if (--chars) write_str(str, chars); // Print a second copy of the message
 | 
			
		||||
            if (--chars) write_str(str, chars);     // Print a second copy of the message
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -715,11 +663,155 @@ bool ST7920_Lite_Status_Screen::indicators_changed() {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Process progress strings
 | 
			
		||||
#if HAS_PRINT_PROGRESS
 | 
			
		||||
  static char screenstr[8];
 | 
			
		||||
 | 
			
		||||
  char * ST7920_Lite_Status_Screen::prepare_time_string(const duration_t &time, char prefix) {
 | 
			
		||||
    static char str[6];
 | 
			
		||||
    memset(&screenstr, 0x20, 8); // fill with spaces to avoid artifacts, not doing right-justification to save cycles
 | 
			
		||||
    screenstr[0] = prefix;
 | 
			
		||||
    TERN_(HOTENDS == 1, screenstr[1] = 0x07;)  // add bullet • separator when there is space
 | 
			
		||||
    int str_length = time.toDigital(str);
 | 
			
		||||
    memcpy(&screenstr[TERN(HOTENDS == 1, 2, 1)], str, str_length); //memcpy because we can't have terminator
 | 
			
		||||
    return screenstr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void ST7920_Lite_Status_Screen::draw_progress_string(uint8_t addr, const char *str) {
 | 
			
		||||
    set_ddram_address(addr);
 | 
			
		||||
    begin_data();
 | 
			
		||||
    write_str(str, TERN(HOTENDS == 1, 8, 6));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #define PPOS (DDRAM_LINE_3 + TERN(HOTENDS == 1, 4, 5)) // progress string position, in 16-bit words
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(SHOW_PROGRESS_PERCENT)
 | 
			
		||||
    void MarlinUI::drawPercent() { lightUI.drawPercent(); }
 | 
			
		||||
    void ST7920_Lite_Status_Screen::drawPercent() {
 | 
			
		||||
      #define LSHIFT TERN(HOTENDS == 1, 0, 1)
 | 
			
		||||
      const uint8_t progress = ui.get_progress_percent();
 | 
			
		||||
      memset(&screenstr, 0x20, 8); // fill with spaces to avoid artifacts
 | 
			
		||||
      if (progress){
 | 
			
		||||
        memcpy(&screenstr[2 - LSHIFT], \
 | 
			
		||||
                  TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui8tostr3rj(progress)), \
 | 
			
		||||
                  TERN(PRINT_PROGRESS_SHOW_DECIMALS, 4, 3));
 | 
			
		||||
        screenstr[(TERN(PRINT_PROGRESS_SHOW_DECIMALS, 6, 5) - LSHIFT)] = '%';
 | 
			
		||||
        draw_progress_string(PPOS, screenstr);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
    void MarlinUI::drawRemain() { lightUI.drawRemain(); }
 | 
			
		||||
    void ST7920_Lite_Status_Screen::drawRemain() {
 | 
			
		||||
      const duration_t remaint = TERN0(SET_REMAINING_TIME, ui.get_remaining_time());
 | 
			
		||||
      if (printJobOngoing() && remaint.value) {
 | 
			
		||||
        draw_progress_string( PPOS, prepare_time_string(remaint, 'R'));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_INTERACTION_TIME)
 | 
			
		||||
    void MarlinUI::drawInter() { lightUI.drawInter(); }
 | 
			
		||||
    void ST7920_Lite_Status_Screen::drawInter() {
 | 
			
		||||
      const duration_t interactt = ui.interaction_time;
 | 
			
		||||
      if (printingIsActive() && interactt.value) {
 | 
			
		||||
        draw_progress_string( PPOS, prepare_time_string(interactt, 'C'));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_ELAPSED_TIME)
 | 
			
		||||
    void MarlinUI::drawElapsed() { lightUI.drawElapsed(); }
 | 
			
		||||
    void ST7920_Lite_Status_Screen::drawElapsed() {
 | 
			
		||||
      if (printJobOngoing()) {
 | 
			
		||||
        const duration_t elapsedt = print_job_timer.duration();
 | 
			
		||||
        draw_progress_string( PPOS, prepare_time_string(elapsedt, 'E'));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Although this is undocumented, the ST7920 allows the character
 | 
			
		||||
   * data buffer (DDRAM) to be used in conjunction with the graphics
 | 
			
		||||
   * bitmap buffer (CGRAM). The contents of the graphics buffer is
 | 
			
		||||
   * XORed with the data from the character generator. This allows
 | 
			
		||||
   * us to make the progress bar out of graphical data (the bar) and
 | 
			
		||||
   * text data (the percentage).
 | 
			
		||||
   */
 | 
			
		||||
  void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) {
 | 
			
		||||
    #if HOTENDS == 1
 | 
			
		||||
      // If we have only one extruder, draw a long progress bar on the third line
 | 
			
		||||
      constexpr uint8_t top     = 1,         // Top in pixels
 | 
			
		||||
                        bottom  = 13,        // Bottom in pixels
 | 
			
		||||
                        left    = 8,         // Left edge, in 16-bit words
 | 
			
		||||
                        width   = 4;         // Width of progress bar, in 16-bit words
 | 
			
		||||
    #else
 | 
			
		||||
      constexpr uint8_t top     = 16 + 1,
 | 
			
		||||
                        bottom  = 16 + 13,
 | 
			
		||||
                        left    = 5,
 | 
			
		||||
                        width   = 3;
 | 
			
		||||
    #endif
 | 
			
		||||
    const uint8_t char_pcnt  = 100 / width; // How many percent does each 16-bit word represent?
 | 
			
		||||
 | 
			
		||||
    // Draw the progress bar as a bitmap in CGRAM
 | 
			
		||||
    // This drawing is a mess and only produce readable result around 25% steps
 | 
			
		||||
    // i.e. 74-76% look fine [||||||||||||||||||||||||        ], but 73% look like this: [||||||||||||||||       |        ]
 | 
			
		||||
    // meaning partially filled bytes produce only single vertical line, and i bet they're not supposed to!
 | 
			
		||||
    LOOP_S_LE_N(y, top, bottom) {
 | 
			
		||||
      set_gdram_address(left, y);
 | 
			
		||||
      begin_data();
 | 
			
		||||
      LOOP_L_N(x, width) {
 | 
			
		||||
        uint16_t gfx_word = 0x0000;
 | 
			
		||||
        if ((x + 1) * char_pcnt <= value)
 | 
			
		||||
          gfx_word = 0xFFFF;                                              // Draw completely filled bytes
 | 
			
		||||
        else if ((x * char_pcnt) < value)
 | 
			
		||||
          gfx_word = int16_t(0x8000) >> (value % char_pcnt) * 16 / char_pcnt; // Draw partially filled bytes
 | 
			
		||||
 | 
			
		||||
        // Draw the frame around the progress bar
 | 
			
		||||
        if (y == top || y == bottom)
 | 
			
		||||
          gfx_word = 0xFFFF;        // Draw top/bottom border
 | 
			
		||||
        else if (x == width - 1)
 | 
			
		||||
          gfx_word |= 0x0001;       // Draw right border
 | 
			
		||||
        else if (x == 0)
 | 
			
		||||
          gfx_word |= 0x8000;       // Draw left border
 | 
			
		||||
        write_word(gfx_word);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // // Draw the percentage as text in DDRAM
 | 
			
		||||
    // #if HOTENDS == 1
 | 
			
		||||
    //   set_ddram_address(DDRAM_LINE_3 + 4);
 | 
			
		||||
    //   begin_data();
 | 
			
		||||
    //   write_byte(' ');
 | 
			
		||||
    // #else
 | 
			
		||||
    //   set_ddram_address(DDRAM_LINE_2 + left);
 | 
			
		||||
    //   begin_data();
 | 
			
		||||
    // #endif
 | 
			
		||||
 | 
			
		||||
    // // Draw centered
 | 
			
		||||
    // if (value > 9)
 | 
			
		||||
    //   write_number(value, 4);
 | 
			
		||||
    // else
 | 
			
		||||
    //   write_number(value, 3);
 | 
			
		||||
    // write_str(F("%  "));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
 | 
			
		||||
 | 
			
		||||
    // Since the progress bar involves writing
 | 
			
		||||
    // quite a few bytes to GDRAM, only do this
 | 
			
		||||
    // when an update is actually necessary.
 | 
			
		||||
 | 
			
		||||
    const uint8_t progress = ui.get_progress_percent();
 | 
			
		||||
    static uint8_t last_progress = 0;
 | 
			
		||||
    if (forceUpdate || last_progress != progress/2) {
 | 
			
		||||
      last_progress = progress/2;     // Because progress bar turns out only 62||46px wide, we only need to redraw it every 2%
 | 
			
		||||
      draw_progress_bar(progress);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif // HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) {
 | 
			
		||||
  if (forceUpdate || indicators_changed()) {
 | 
			
		||||
    const bool       blink              = ui.get_blink();
 | 
			
		||||
    const duration_t elapsed            = print_job_timer.duration();
 | 
			
		||||
    duration_t       remaining          = TERN0(USE_M73_REMAINING_TIME, ui.get_remaining_time());
 | 
			
		||||
    const uint16_t   feedrate_perc      = feedrate_percentage;
 | 
			
		||||
    const celsius_t  extruder_1_temp    = thermalManager.wholeDegHotend(0),
 | 
			
		||||
                     extruder_1_target  = thermalManager.degTargetHotend(0);
 | 
			
		||||
@@ -736,30 +828,20 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) {
 | 
			
		||||
    TERN_(HAS_MULTI_HOTEND, draw_extruder_2_temp(extruder_2_temp, extruder_2_target, forceUpdate));
 | 
			
		||||
    TERN_(HAS_HEATED_BED, draw_bed_temp(bed_temp, bed_target, forceUpdate));
 | 
			
		||||
 | 
			
		||||
    // Update the fan and bed animations
 | 
			
		||||
    uint8_t spd = thermalManager.fan_speed[0];
 | 
			
		||||
    #if ENABLED(ADAPTIVE_FAN_SLOWING)
 | 
			
		||||
      if (!blink && thermalManager.fan_speed_scaler[0] < 128)
 | 
			
		||||
        spd = thermalManager.scaledFanSpeed(0, spd);
 | 
			
		||||
    #endif
 | 
			
		||||
    draw_fan_speed(thermalManager.pwmToPercent(spd));
 | 
			
		||||
 | 
			
		||||
    // Draw elapsed/remaining time
 | 
			
		||||
    const bool show_remaining = ENABLED(SHOW_REMAINING_TIME) && (DISABLED(ROTATE_PROGRESS_DISPLAY) || blink);
 | 
			
		||||
    if (show_remaining && !remaining.second()) {
 | 
			
		||||
      const auto progress = ui.get_progress_percent();
 | 
			
		||||
      if (progress)
 | 
			
		||||
        remaining = elapsed.second() * (100 - progress) / progress;
 | 
			
		||||
    }
 | 
			
		||||
    if (show_remaining && remaining.second())
 | 
			
		||||
      draw_print_time(remaining, 'R');
 | 
			
		||||
    else
 | 
			
		||||
      draw_print_time(elapsed);
 | 
			
		||||
    if (spd) draw_fan_icon(blink);
 | 
			
		||||
    TERN_(HAS_HEATED_BED, draw_heat_icon(bed_target > 0 && blink, bed_target > 0));
 | 
			
		||||
 | 
			
		||||
    draw_feedrate_percentage(feedrate_perc);
 | 
			
		||||
 | 
			
		||||
    // Update the fan and bed animations
 | 
			
		||||
    if (spd) draw_fan_icon(blink);
 | 
			
		||||
    TERN_(HAS_HEATED_BED, draw_heat_icon(bed_target > 0 && blink, bed_target > 0));
 | 
			
		||||
    // Update and draw progress strings
 | 
			
		||||
    TERN_(HAS_PRINT_PROGRESS, ui.rotate_progress());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -839,27 +921,6 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
 | 
			
		||||
  #if EITHER(LCD_SET_PROGRESS_MANUALLY, SDSUPPORT)
 | 
			
		||||
 | 
			
		||||
    // Since the progress bar involves writing
 | 
			
		||||
    // quite a few bytes to GDRAM, only do this
 | 
			
		||||
    // when an update is actually necessary.
 | 
			
		||||
 | 
			
		||||
    static uint8_t last_progress = 0;
 | 
			
		||||
    const uint8_t progress = ui.get_progress_percent();
 | 
			
		||||
    if (forceUpdate || last_progress != progress) {
 | 
			
		||||
      last_progress = progress;
 | 
			
		||||
      draw_progress_bar(progress);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  #else
 | 
			
		||||
 | 
			
		||||
    UNUSED(forceUpdate);
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ST7920_Lite_Status_Screen::update(const bool forceUpdate) {
 | 
			
		||||
  cs();
 | 
			
		||||
  update_indicators(forceUpdate);
 | 
			
		||||
@@ -902,7 +963,7 @@ void ST7920_Lite_Status_Screen::clear_text_buffer() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinUI::draw_status_screen() {
 | 
			
		||||
  ST7920_Lite_Status_Screen::update(false);
 | 
			
		||||
  lightUI.update(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This method is called before each screen update and
 | 
			
		||||
@@ -912,9 +973,9 @@ void MarlinUI::lcd_in_status(const bool inStatus) {
 | 
			
		||||
  static bool lastInStatus = false;
 | 
			
		||||
  if (lastInStatus == inStatus) return;
 | 
			
		||||
  if ((lastInStatus = inStatus))
 | 
			
		||||
    ST7920_Lite_Status_Screen::on_entry();
 | 
			
		||||
    lightUI.on_entry();
 | 
			
		||||
  else
 | 
			
		||||
    ST7920_Lite_Status_Screen::on_exit();
 | 
			
		||||
    lightUI.on_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // LIGHTWEIGHT_UI
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,6 @@ class ST7920_Lite_Status_Screen {
 | 
			
		||||
  protected:
 | 
			
		||||
    static void draw_degree_symbol(uint8_t x, uint8_t y, const bool draw);
 | 
			
		||||
    static void draw_static_elements();
 | 
			
		||||
    static void draw_progress_bar(const uint8_t value);
 | 
			
		||||
    static void draw_fan_icon(const bool whichIcon);
 | 
			
		||||
    static void draw_heat_icon(const bool whichIcon, const bool heating);
 | 
			
		||||
    static void draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange);
 | 
			
		||||
@@ -83,7 +82,12 @@ class ST7920_Lite_Status_Screen {
 | 
			
		||||
    static void draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate=false);
 | 
			
		||||
    static void draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate=false);
 | 
			
		||||
    static void draw_fan_speed(const uint8_t value);
 | 
			
		||||
    static void draw_print_time(const duration_t &elapsed, char suffix=' ');
 | 
			
		||||
    #if HAS_PRINT_PROGRESS
 | 
			
		||||
      static void draw_progress_bar(const uint8_t value);
 | 
			
		||||
      static char* prepare_time_string(const duration_t &time, char prefix=' ');
 | 
			
		||||
      static void draw_progress_string(uint8_t addr, const char *str);
 | 
			
		||||
      static void update_progress(const bool forceUpdate);
 | 
			
		||||
    #endif
 | 
			
		||||
    static void draw_feedrate_percentage(const uint16_t percentage);
 | 
			
		||||
    static void draw_status_message();
 | 
			
		||||
    static void draw_position(const xyze_pos_t &pos, bool position_known=true);
 | 
			
		||||
@@ -96,11 +100,18 @@ class ST7920_Lite_Status_Screen {
 | 
			
		||||
    static void update_indicators(const bool forceUpdate);
 | 
			
		||||
    static void update_position(const bool forceUpdate, bool resetChecksum);
 | 
			
		||||
    static void update_status_or_position(bool forceUpdate);
 | 
			
		||||
    static void update_progress(const bool forceUpdate);
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
    static void update(const bool forceUpdate);
 | 
			
		||||
    static void on_entry();
 | 
			
		||||
    static void on_exit();
 | 
			
		||||
    static void clear_text_buffer();
 | 
			
		||||
    #if HAS_PRINT_PROGRESS
 | 
			
		||||
      static void drawPercent();
 | 
			
		||||
      static void drawRemain();
 | 
			
		||||
      static void drawInter();
 | 
			
		||||
      static void drawElapsed();
 | 
			
		||||
    #endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern ST7920_Lite_Status_Screen lightUI;
 | 
			
		||||
 
 | 
			
		||||
@@ -733,7 +733,7 @@ void CrealityDWINClass::Draw_Print_Screen() {
 | 
			
		||||
  Update_Status_Bar(true);
 | 
			
		||||
  Draw_Print_ProgressBar();
 | 
			
		||||
  Draw_Print_ProgressElapsed();
 | 
			
		||||
  TERN_(USE_M73_REMAINING_TIME, Draw_Print_ProgressRemain());
 | 
			
		||||
  TERN_(SET_REMAINING_TIME, Draw_Print_ProgressRemain());
 | 
			
		||||
  Draw_Print_Filename(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -759,7 +759,7 @@ void CrealityDWINClass::Draw_Print_ProgressBar() {
 | 
			
		||||
  DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_percent, Percent_Color), Color_Bg_Black, 133, 133, F("%"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLED(USE_M73_REMAINING_TIME)
 | 
			
		||||
#if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
 | 
			
		||||
  void CrealityDWINClass::Draw_Print_ProgressRemain() {
 | 
			
		||||
    uint16_t remainingtime = ui.get_remaining_time();
 | 
			
		||||
@@ -4565,8 +4565,8 @@ void CrealityDWINClass::Start_Print(bool sd) {
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      strcpy_P(filename, PSTR("Host Print"));
 | 
			
		||||
    TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(0));
 | 
			
		||||
    TERN_(USE_M73_REMAINING_TIME, ui.set_remaining_time(0));
 | 
			
		||||
    TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0));
 | 
			
		||||
    TERN_(SET_REMAINING_TIME, ui.set_remaining_time(0));
 | 
			
		||||
    Draw_Print_Screen();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -4575,8 +4575,8 @@ void CrealityDWINClass::Stop_Print() {
 | 
			
		||||
  printing = false;
 | 
			
		||||
  sdprint = false;
 | 
			
		||||
  thermalManager.cooldown();
 | 
			
		||||
  TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress(100 * (PROGRESS_SCALE)));
 | 
			
		||||
  TERN_(USE_M73_REMAINING_TIME, ui.set_remaining_time(0));
 | 
			
		||||
  TERN_(SET_PROGRESS_PERCENT, ui.set_progress(100 * (PROGRESS_SCALE)));
 | 
			
		||||
  TERN_(SET_REMAINING_TIME, ui.set_remaining_time(0));
 | 
			
		||||
  Draw_Print_confirm();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -4653,7 +4653,7 @@ void CrealityDWINClass::Screen_Update() {
 | 
			
		||||
    if (process == Print) {
 | 
			
		||||
      Draw_Print_ProgressBar();
 | 
			
		||||
      Draw_Print_ProgressElapsed();
 | 
			
		||||
      TERN_(USE_M73_REMAINING_TIME, Draw_Print_ProgressRemain());
 | 
			
		||||
      TERN_(SET_REMAINING_TIME, Draw_Print_ProgressRemain());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -188,7 +188,7 @@ public:
 | 
			
		||||
  static void Draw_Print_Screen();
 | 
			
		||||
  static void Draw_Print_Filename(const bool reset=false);
 | 
			
		||||
  static void Draw_Print_ProgressBar();
 | 
			
		||||
  #if ENABLED(USE_M73_REMAINING_TIME)
 | 
			
		||||
  #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
    static void Draw_Print_ProgressRemain();
 | 
			
		||||
  #endif
 | 
			
		||||
  static void Draw_Print_ProgressElapsed();
 | 
			
		||||
 
 | 
			
		||||
@@ -374,11 +374,11 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(DWIN_MARLINUI_PORTRAIT)
 | 
			
		||||
 | 
			
		||||
    // Portrait mode only shows one value at a time, and will rotate if ROTATE_PROGRESS_DISPLAY
 | 
			
		||||
    // Portrait mode only shows one value at a time, and will rotate if many are enabled
 | 
			
		||||
    dwin_string.set();
 | 
			
		||||
    char prefix = ' ';
 | 
			
		||||
    #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
      if (TERN1(ROTATE_PROGRESS_DISPLAY, blink) && print_job_timer.isRunning()) {
 | 
			
		||||
      if (blink && print_job_timer.isRunning()) {
 | 
			
		||||
        time = get_remaining_time();
 | 
			
		||||
        prefix = 'R';
 | 
			
		||||
      }
 | 
			
		||||
@@ -447,7 +447,7 @@ void MarlinUI::draw_status_screen() {
 | 
			
		||||
      //if (pb_solid < old_solid)
 | 
			
		||||
        DWIN_Draw_Rectangle(1, Color_Bg_Black, pb_left + 1 + pb_solid, pb_top + 1, pb_right - 1, pb_bottom - 1); // Erase the rest
 | 
			
		||||
 | 
			
		||||
      #if ENABLED(SHOW_SD_PERCENT)
 | 
			
		||||
      #if ENABLED(SHOW_PROGRESS_PERCENT)
 | 
			
		||||
        dwin_string.set(TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE))));
 | 
			
		||||
        dwin_string.add('%');
 | 
			
		||||
        DWIN_Draw_String(
 | 
			
		||||
 
 | 
			
		||||
@@ -43,8 +43,8 @@
 | 
			
		||||
#if DISABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU)
 | 
			
		||||
  #warning "INDIVIDUAL_AXIS_HOMING_SUBMENU is recommended with ProUI."
 | 
			
		||||
#endif
 | 
			
		||||
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #warning "LCD_SET_PROGRESS_MANUALLY is recommended with ProUI."
 | 
			
		||||
#if DISABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #warning "SET_PROGRESS_MANUALLY is recommended with ProUI."
 | 
			
		||||
#endif
 | 
			
		||||
#if DISABLED(STATUS_MESSAGE_SCROLLING)
 | 
			
		||||
  #warning "STATUS_MESSAGE_SCROLLING is recommended with ProUI."
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ const uint16_t VPList_Main[] PROGMEM = {
 | 
			
		||||
  VP_XPos, VP_YPos, VP_ZPos,
 | 
			
		||||
  VP_Fan0_Percentage,
 | 
			
		||||
  VP_Feedrate_Percentage,
 | 
			
		||||
  #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #if ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
    VP_PrintProgress_Percentage,
 | 
			
		||||
  #endif
 | 
			
		||||
  0x0000
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ const uint16_t VPList_Main[] PROGMEM = {
 | 
			
		||||
  VP_XPos, VP_YPos, VP_ZPos,
 | 
			
		||||
  VP_Fan0_Percentage,
 | 
			
		||||
  VP_Feedrate_Percentage,
 | 
			
		||||
  #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #if ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
    VP_PrintProgress_Percentage,
 | 
			
		||||
  #endif
 | 
			
		||||
  0x0000
 | 
			
		||||
 
 | 
			
		||||
@@ -135,7 +135,7 @@ const uint16_t VPList_Main[] PROGMEM = {
 | 
			
		||||
  VP_XPos, VP_YPos, VP_ZPos,
 | 
			
		||||
  VP_Fan0_Percentage,
 | 
			
		||||
  VP_Feedrate_Percentage,
 | 
			
		||||
  #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #if ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
    VP_PrintProgress_Percentage,
 | 
			
		||||
  #endif
 | 
			
		||||
  0x0000
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@
 | 
			
		||||
  #include "../../../feature/powerloss.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
 | 
			
		||||
#if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
  #include "../../marlinui.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +244,7 @@ void disp_fan_speed() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void disp_print_time() {
 | 
			
		||||
  #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
 | 
			
		||||
  #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
    const uint32_t r = ui.get_remaining_time();
 | 
			
		||||
    sprintf_P(public_buf_l, PSTR("%02d:%02d R"), r / 3600, (r % 3600) / 60);
 | 
			
		||||
  #else
 | 
			
		||||
 
 | 
			
		||||
@@ -164,6 +164,9 @@ namespace ExtUI {
 | 
			
		||||
  #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
    inline uint32_t getProgress_seconds_remaining() { return ui.get_remaining_time(); }
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SHOW_INTERACTION_TIME)
 | 
			
		||||
    inline uint32_t getInteraction_seconds_remaining() { return ui.interaction_time; }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if HAS_LEVELING
 | 
			
		||||
    bool getLevelingActive();
 | 
			
		||||
 
 | 
			
		||||
@@ -79,11 +79,16 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
 | 
			
		||||
  statusResetFunc_t MarlinUI::status_reset_callback; // = nullptr
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
  MarlinUI::progress_t MarlinUI::progress_override; // = 0
 | 
			
		||||
  #if ENABLED(USE_M73_REMAINING_TIME)
 | 
			
		||||
#if ENABLED(SET_PROGRESS_MANUALLY)
 | 
			
		||||
  #if ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
    MarlinUI::progress_t MarlinUI::progress_override; // = 0
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
    uint32_t MarlinUI::remaining_time;
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SET_INTERACTION_TIME)
 | 
			
		||||
    uint32_t MarlinUI::interaction_time;
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_MULTI_LANGUAGE
 | 
			
		||||
@@ -153,7 +158,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
 | 
			
		||||
  bool MarlinUI::lcd_clicked;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI)
 | 
			
		||||
#if LCD_WITH_BLINK
 | 
			
		||||
 | 
			
		||||
  bool MarlinUI::get_blink() {
 | 
			
		||||
    static uint8_t blink = 0;
 | 
			
		||||
@@ -1677,19 +1682,6 @@ void MarlinUI::init() {
 | 
			
		||||
    print_job_timer.start(); // Also called by M24
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #if HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
    MarlinUI::progress_t MarlinUI::_get_progress() {
 | 
			
		||||
      return (
 | 
			
		||||
        TERN0(LCD_SET_PROGRESS_MANUALLY, (progress_override & PROGRESS_MASK))
 | 
			
		||||
        #if ENABLED(SDSUPPORT)
 | 
			
		||||
          ?: TERN(HAS_PRINT_PROGRESS_PERMYRIAD, card.permyriadDone(), card.percentDone())
 | 
			
		||||
        #endif
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if HAS_TOUCH_BUTTONS
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
@@ -1723,6 +1715,38 @@ void MarlinUI::init() {
 | 
			
		||||
 | 
			
		||||
#endif // HAS_DISPLAY
 | 
			
		||||
 | 
			
		||||
#if HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
  MarlinUI::progress_t MarlinUI::_get_progress() {
 | 
			
		||||
    return (
 | 
			
		||||
      TERN0(SET_PROGRESS_PERCENT, (progress_override & PROGRESS_MASK))
 | 
			
		||||
      #if ENABLED(SDSUPPORT)
 | 
			
		||||
        ?: TERN(HAS_PRINT_PROGRESS_PERMYRIAD, card.permyriadDone(), card.percentDone())
 | 
			
		||||
      #endif
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #if LCD_WITH_BLINK
 | 
			
		||||
    typedef void (*PrintProgress_t)();
 | 
			
		||||
    void MarlinUI::rotate_progress() { // Renew and redraw all enabled progress strings
 | 
			
		||||
      const PrintProgress_t progFunc[] = {
 | 
			
		||||
        OPTITEM(SHOW_PROGRESS_PERCENT, drawPercent)
 | 
			
		||||
        OPTITEM(SHOW_ELAPSED_TIME, drawElapsed)
 | 
			
		||||
        OPTITEM(SHOW_REMAINING_TIME, drawRemain)
 | 
			
		||||
        OPTITEM(SHOW_INTERACTION_TIME, drawInter)
 | 
			
		||||
      };
 | 
			
		||||
      static bool prev_blink;
 | 
			
		||||
      static uint8_t i;
 | 
			
		||||
      if (prev_blink != get_blink()) {
 | 
			
		||||
        prev_blink = get_blink();
 | 
			
		||||
        if (++i >= COUNT(progFunc)) i = 0;
 | 
			
		||||
        (*progFunc[i])();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
#endif // HAS_PRINT_PROGRESS
 | 
			
		||||
 | 
			
		||||
#if ENABLED(SDSUPPORT)
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(EXTENSIBLE_UI)
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,6 @@
 | 
			
		||||
#include "../sd/cardreader.h"
 | 
			
		||||
#include "../module/motion.h"
 | 
			
		||||
#include "../libs/buzzer.h"
 | 
			
		||||
 | 
			
		||||
#include "buttons.h"
 | 
			
		||||
 | 
			
		||||
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
 | 
			
		||||
@@ -36,7 +35,7 @@
 | 
			
		||||
  #define MULTI_E_MANUAL 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAS_DISPLAY
 | 
			
		||||
#if HAS_PRINT_PROGRESS
 | 
			
		||||
  #include "../module/printcounter.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -86,6 +85,7 @@ typedef bool (*statusResetFunc_t)();
 | 
			
		||||
#endif // HAS_WIRED_LCD
 | 
			
		||||
 | 
			
		||||
#if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI)
 | 
			
		||||
  #define LCD_WITH_BLINK 1
 | 
			
		||||
  #define LCD_UPDATE_INTERVAL TERN(HAS_TOUCH_BUTTONS, 50, 100)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -303,19 +303,19 @@ public:
 | 
			
		||||
      #define PROGRESS_SCALE 1U
 | 
			
		||||
      #define PROGRESS_MASK 0x7F
 | 
			
		||||
    #endif
 | 
			
		||||
    #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
 | 
			
		||||
    #if ENABLED(SET_PROGRESS_PERCENT)
 | 
			
		||||
      static progress_t progress_override;
 | 
			
		||||
      static void set_progress(const progress_t p) { progress_override = _MIN(p, 100U * (PROGRESS_SCALE)); }
 | 
			
		||||
      static void set_progress_done() { progress_override = (PROGRESS_MASK + 1U) + 100U * (PROGRESS_SCALE); }
 | 
			
		||||
      static void progress_reset() { if (progress_override & (PROGRESS_MASK + 1U)) set_progress(0); }
 | 
			
		||||
    #endif
 | 
			
		||||
    #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
    #if EITHER(SHOW_REMAINING_TIME, SET_PROGRESS_MANUALLY)
 | 
			
		||||
      static uint32_t _calculated_remaining_time() {
 | 
			
		||||
        const duration_t elapsed = print_job_timer.duration();
 | 
			
		||||
        const progress_t progress = _get_progress();
 | 
			
		||||
        return progress ? elapsed.value * (100 * (PROGRESS_SCALE) - progress) / progress : 0;
 | 
			
		||||
      }
 | 
			
		||||
      #if ENABLED(USE_M73_REMAINING_TIME)
 | 
			
		||||
      #if ENABLED(SET_REMAINING_TIME)
 | 
			
		||||
        static uint32_t remaining_time;
 | 
			
		||||
        FORCE_INLINE static void set_remaining_time(const uint32_t r) { remaining_time = r; }
 | 
			
		||||
        FORCE_INLINE static uint32_t get_remaining_time() { return remaining_time ?: _calculated_remaining_time(); }
 | 
			
		||||
@@ -323,12 +323,32 @@ public:
 | 
			
		||||
      #else
 | 
			
		||||
        FORCE_INLINE static uint32_t get_remaining_time() { return _calculated_remaining_time(); }
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(SET_INTERACTION_TIME)
 | 
			
		||||
        static uint32_t interaction_time;
 | 
			
		||||
        FORCE_INLINE static void set_interaction_time(const uint32_t r) { interaction_time = r; }
 | 
			
		||||
        FORCE_INLINE static void reset_interaction_time() { set_interaction_time(0); }
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    static progress_t _get_progress();
 | 
			
		||||
    #if HAS_PRINT_PROGRESS_PERMYRIAD
 | 
			
		||||
      FORCE_INLINE static uint16_t get_progress_permyriad() { return _get_progress(); }
 | 
			
		||||
    #endif
 | 
			
		||||
    static uint8_t get_progress_percent() { return uint8_t(_get_progress() / (PROGRESS_SCALE)); }
 | 
			
		||||
    #if LCD_WITH_BLINK
 | 
			
		||||
      #if ENABLED(SHOW_PROGRESS_PERCENT)
 | 
			
		||||
        static void drawPercent();
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(SHOW_ELAPSED_TIME)
 | 
			
		||||
        static void drawElapsed();
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(SHOW_REMAINING_TIME)
 | 
			
		||||
        static void drawRemain();
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(SHOW_INTERACTION_TIME)
 | 
			
		||||
        static void drawInter();
 | 
			
		||||
      #endif
 | 
			
		||||
      static void rotate_progress();
 | 
			
		||||
    #endif
 | 
			
		||||
  #else
 | 
			
		||||
    static constexpr uint8_t get_progress_percent() { return 0; }
 | 
			
		||||
  #endif
 | 
			
		||||
@@ -390,7 +410,7 @@ public:
 | 
			
		||||
      static void poweroff();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI)
 | 
			
		||||
    #if LCD_WITH_BLINK
 | 
			
		||||
      static bool get_blink();
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,7 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co
 | 
			
		||||
 | 
			
		||||
    TERN_(HAS_TOUCH_BUTTONS, repeat_delay = BUTTON_DELAY_MENU);
 | 
			
		||||
 | 
			
		||||
    TERN_(LCD_SET_PROGRESS_MANUALLY, progress_reset());
 | 
			
		||||
    TERN_(SET_PROGRESS_PERCENT, progress_reset());
 | 
			
		||||
 | 
			
		||||
    #if BOTH(DOUBLECLICK_FOR_Z_BABYSTEPPING, BABYSTEPPING)
 | 
			
		||||
      static millis_t doubleclick_expire_ms = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -73,10 +73,10 @@ const char* i8tostr3rj(const int8_t x) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if HAS_PRINT_PROGRESS_PERMYRIAD
 | 
			
		||||
  // Convert unsigned 16-bit permyriad to percent with 100 / 23 / 23.4 / 3.45 format
 | 
			
		||||
  // Convert unsigned 16-bit permyriad to percent with 100 / 23.4 / 3.45 format
 | 
			
		||||
  const char* permyriadtostr4(const uint16_t xx) {
 | 
			
		||||
    if (xx >= 10000)
 | 
			
		||||
      return "100";
 | 
			
		||||
      return " 100"; // space to keep 4-width alignment
 | 
			
		||||
    else if (xx >= 1000) {
 | 
			
		||||
      conv[3] = DIGIMOD(xx, 1000);
 | 
			
		||||
      conv[4] = DIGIMOD(xx, 100);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user