|
|
@ -29,6 +29,16 @@ |
|
|
|
#include "../sd/cardreader.h" |
|
|
|
#endif |
|
|
|
MarlinUI ui; |
|
|
|
#if ENABLED(SDSUPPORT) |
|
|
|
#include "../sd/cardreader.h" |
|
|
|
#endif |
|
|
|
#if ENABLED(EXTENSIBLE_UI) |
|
|
|
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u) |
|
|
|
#endif |
|
|
|
|
|
|
|
#define MAX_MESSAGE_LENGTH 63 |
|
|
|
uint8_t MarlinUI::status_message_level; // = 0
|
|
|
|
char MarlinUI::status_message[MAX_MESSAGE_LENGTH + 1]; |
|
|
|
#endif |
|
|
|
|
|
|
|
#if HAS_SPI_LCD |
|
|
@ -86,9 +96,7 @@ |
|
|
|
bool MarlinUI::defer_return_to_status; |
|
|
|
#endif |
|
|
|
|
|
|
|
char MarlinUI::status_message[MAX_MESSAGE_LENGTH + 1]; |
|
|
|
uint8_t MarlinUI::lcd_status_update_delay = 1; // First update one loop delayed
|
|
|
|
uint8_t MarlinUI::status_message_level; // = 0
|
|
|
|
|
|
|
|
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) |
|
|
|
millis_t MarlinUI::next_filament_display; // = 0
|
|
|
@ -475,7 +483,7 @@ void MarlinUI::status_screen() { |
|
|
|
|
|
|
|
void MarlinUI::kill_screen(PGM_P lcd_msg) { |
|
|
|
init(); |
|
|
|
setalertstatusPGM(lcd_msg); |
|
|
|
set_alert_status_P(lcd_msg); |
|
|
|
draw_kill_screen(); |
|
|
|
} |
|
|
|
|
|
|
@ -674,11 +682,11 @@ void MarlinUI::update() { |
|
|
|
if (old_sd_status == 2) |
|
|
|
card.beginautostart(); // Initial boot
|
|
|
|
else |
|
|
|
setstatusPGM(PSTR(MSG_SD_INSERTED)); |
|
|
|
set_status_P(PSTR(MSG_SD_INSERTED)); |
|
|
|
} |
|
|
|
else { |
|
|
|
card.release(); |
|
|
|
if (old_sd_status != 2) setstatusPGM(PSTR(MSG_SD_REMOVED)); |
|
|
|
if (old_sd_status != 2) set_status_P(PSTR(MSG_SD_REMOVED)); |
|
|
|
} |
|
|
|
|
|
|
|
refresh(); |
|
|
@ -1083,110 +1091,118 @@ void MarlinUI::update() { |
|
|
|
|
|
|
|
#endif // HAS_ENCODER_ACTION
|
|
|
|
|
|
|
|
////////////////////////////////////////////
|
|
|
|
/////////////// Status Line ////////////////
|
|
|
|
////////////////////////////////////////////
|
|
|
|
#endif // HAS_SPI_LCD
|
|
|
|
|
|
|
|
void MarlinUI::finishstatus(const bool persist) { |
|
|
|
#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI) |
|
|
|
|
|
|
|
#if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) |
|
|
|
UNUSED(persist); |
|
|
|
#if ENABLED(EXTENSIBLE_UI) |
|
|
|
#include "extensible_ui/ui_api.h" |
|
|
|
#endif |
|
|
|
|
|
|
|
#if ENABLED(LCD_PROGRESS_BAR) |
|
|
|
progress_bar_ms = millis(); |
|
|
|
#if PROGRESS_MSG_EXPIRE > 0 |
|
|
|
expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; |
|
|
|
////////////////////////////////////////////
|
|
|
|
/////////////// Status Line ////////////////
|
|
|
|
////////////////////////////////////////////
|
|
|
|
|
|
|
|
void MarlinUI::finishstatus(const bool persist) { |
|
|
|
|
|
|
|
#if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) |
|
|
|
UNUSED(persist); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) |
|
|
|
next_filament_display = millis() + 5000UL; // Show status message for 5s
|
|
|
|
#endif |
|
|
|
#if ENABLED(LCD_PROGRESS_BAR) |
|
|
|
progress_bar_ms = millis(); |
|
|
|
#if PROGRESS_MSG_EXPIRE > 0 |
|
|
|
expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#if ENABLED(STATUS_MESSAGE_SCROLLING) |
|
|
|
status_scroll_offset = 0; |
|
|
|
#endif |
|
|
|
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) |
|
|
|
next_filament_display = millis() + 5000UL; // Show status message for 5s
|
|
|
|
#endif |
|
|
|
|
|
|
|
refresh(); |
|
|
|
} |
|
|
|
#if ENABLED(STATUS_MESSAGE_SCROLLING) |
|
|
|
status_scroll_offset = 0; |
|
|
|
#endif |
|
|
|
|
|
|
|
bool MarlinUI::has_status() { return (status_message[0] != '\0'); } |
|
|
|
#if ENABLED(EXTENSIBLE_UI) |
|
|
|
ExtUI::onStatusChanged(status_message); |
|
|
|
#endif |
|
|
|
|
|
|
|
void MarlinUI::setstatus(const char * const message, const bool persist) { |
|
|
|
if (status_message_level > 0) return; |
|
|
|
refresh(); |
|
|
|
} |
|
|
|
|
|
|
|
// Here we have a problem. The message is encoded in UTF8, so
|
|
|
|
// arbitrarily cutting it will be a problem. We MUST be sure
|
|
|
|
// that there is no cutting in the middle of a multibyte character!
|
|
|
|
bool MarlinUI::has_status() { return (status_message[0] != '\0'); } |
|
|
|
|
|
|
|
// Get a pointer to the null terminator
|
|
|
|
const char* pend = message + strlen(message); |
|
|
|
void MarlinUI::set_status(const char * const message, const bool persist) { |
|
|
|
if (status_message_level > 0) return; |
|
|
|
|
|
|
|
// If length of supplied UTF8 string is greater than
|
|
|
|
// our buffer size, start cutting whole UTF8 chars
|
|
|
|
while ((pend - message) > MAX_MESSAGE_LENGTH) { |
|
|
|
--pend; |
|
|
|
while (!START_OF_UTF8_CHAR(*pend)) --pend; |
|
|
|
}; |
|
|
|
// Here we have a problem. The message is encoded in UTF8, so
|
|
|
|
// arbitrarily cutting it will be a problem. We MUST be sure
|
|
|
|
// that there is no cutting in the middle of a multibyte character!
|
|
|
|
|
|
|
|
// At this point, we have the proper cut point. Use it
|
|
|
|
uint8_t maxLen = pend - message; |
|
|
|
strncpy(status_message, message, maxLen); |
|
|
|
status_message[maxLen] = '\0'; |
|
|
|
// Get a pointer to the null terminator
|
|
|
|
const char* pend = message + strlen(message); |
|
|
|
|
|
|
|
finishstatus(persist); |
|
|
|
} |
|
|
|
// If length of supplied UTF8 string is greater than
|
|
|
|
// our buffer size, start cutting whole UTF8 chars
|
|
|
|
while ((pend - message) > MAX_MESSAGE_LENGTH) { |
|
|
|
--pend; |
|
|
|
while (!START_OF_UTF8_CHAR(*pend)) --pend; |
|
|
|
}; |
|
|
|
|
|
|
|
#include <stdarg.h> |
|
|
|
// At this point, we have the proper cut point. Use it
|
|
|
|
uint8_t maxLen = pend - message; |
|
|
|
strncpy(status_message, message, maxLen); |
|
|
|
status_message[maxLen] = '\0'; |
|
|
|
|
|
|
|
void MarlinUI::status_printf_P(const uint8_t level, PGM_P const fmt, ...) { |
|
|
|
if (level < status_message_level) return; |
|
|
|
status_message_level = level; |
|
|
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
|
|
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args); |
|
|
|
va_end(args); |
|
|
|
finishstatus(level > 0); |
|
|
|
} |
|
|
|
finishstatus(persist); |
|
|
|
} |
|
|
|
|
|
|
|
void MarlinUI::setstatusPGM(PGM_P const message, int8_t level) { |
|
|
|
if (level < 0) level = status_message_level = 0; |
|
|
|
if (level < status_message_level) return; |
|
|
|
status_message_level = level; |
|
|
|
#include <stdarg.h> |
|
|
|
|
|
|
|
// Here we have a problem. The message is encoded in UTF8, so
|
|
|
|
// arbitrarily cutting it will be a problem. We MUST be sure
|
|
|
|
// that there is no cutting in the middle of a multibyte character!
|
|
|
|
void MarlinUI::status_printf_P(const uint8_t level, PGM_P const fmt, ...) { |
|
|
|
if (level < status_message_level) return; |
|
|
|
status_message_level = level; |
|
|
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
|
|
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args); |
|
|
|
va_end(args); |
|
|
|
finishstatus(level > 0); |
|
|
|
} |
|
|
|
|
|
|
|
// Get a pointer to the null terminator
|
|
|
|
PGM_P pend = message + strlen_P(message); |
|
|
|
void MarlinUI::set_status_P(PGM_P const message, int8_t level) { |
|
|
|
if (level < 0) level = status_message_level = 0; |
|
|
|
if (level < status_message_level) return; |
|
|
|
status_message_level = level; |
|
|
|
|
|
|
|
// If length of supplied UTF8 string is greater than
|
|
|
|
// our buffer size, start cutting whole UTF8 chars
|
|
|
|
while ((pend - message) > MAX_MESSAGE_LENGTH) { |
|
|
|
--pend; |
|
|
|
while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend; |
|
|
|
}; |
|
|
|
// Here we have a problem. The message is encoded in UTF8, so
|
|
|
|
// arbitrarily cutting it will be a problem. We MUST be sure
|
|
|
|
// that there is no cutting in the middle of a multibyte character!
|
|
|
|
|
|
|
|
// At this point, we have the proper cut point. Use it
|
|
|
|
uint8_t maxLen = pend - message; |
|
|
|
strncpy_P(status_message, message, maxLen); |
|
|
|
status_message[maxLen] = '\0'; |
|
|
|
// Get a pointer to the null terminator
|
|
|
|
PGM_P pend = message + strlen_P(message); |
|
|
|
|
|
|
|
finishstatus(level > 0); |
|
|
|
} |
|
|
|
// If length of supplied UTF8 string is greater than
|
|
|
|
// our buffer size, start cutting whole UTF8 chars
|
|
|
|
while ((pend - message) > MAX_MESSAGE_LENGTH) { |
|
|
|
--pend; |
|
|
|
while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend; |
|
|
|
}; |
|
|
|
|
|
|
|
void MarlinUI::setalertstatusPGM(PGM_P const message) { |
|
|
|
setstatusPGM(message, 1); |
|
|
|
#if HAS_LCD_MENU |
|
|
|
return_to_status(); |
|
|
|
#endif |
|
|
|
} |
|
|
|
// At this point, we have the proper cut point. Use it
|
|
|
|
uint8_t maxLen = pend - message; |
|
|
|
strncpy_P(status_message, message, maxLen); |
|
|
|
status_message[maxLen] = '\0'; |
|
|
|
|
|
|
|
#endif // HAS_SPI_LCD
|
|
|
|
finishstatus(level > 0); |
|
|
|
} |
|
|
|
|
|
|
|
#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI) |
|
|
|
void MarlinUI::set_alert_status_P(PGM_P const message) { |
|
|
|
set_status_P(message, 1); |
|
|
|
#if HAS_LCD_MENU |
|
|
|
return_to_status(); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
#include "../module/printcounter.h" |
|
|
|
|
|
|
@ -1202,14 +1218,14 @@ void MarlinUI::setalertstatusPGM(PGM_P const message) { |
|
|
|
msg = paused; |
|
|
|
#if ENABLED(SDSUPPORT) |
|
|
|
else if (IS_SD_PRINTING()) |
|
|
|
return setstatus(card.longest_filename(), true); |
|
|
|
return set_status(card.longest_filename(), true); |
|
|
|
#endif |
|
|
|
else if (print_job_timer.isRunning()) |
|
|
|
msg = printing; |
|
|
|
else |
|
|
|
msg = welcome; |
|
|
|
|
|
|
|
setstatusPGM(msg, -1); |
|
|
|
set_status_P(msg, -1); |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|