♻️ Set Progress without LCD (#24767)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
EvilGremlin
2022-10-09 18:30:47 +03:00
committed by Scott Lahteine
parent b0f02b8f9e
commit 8481264566
34 changed files with 626 additions and 487 deletions

View File

@ -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

View File

@ -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

View File

@ -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;