Encapsulate common display code in a singleton (#12395)
* Encapsulate common LCD code in a singleton * Depend more UBL code on UBL_DEVEL_DEBUGGING - Since most users don't need the debugging on at all times, this helps reduce the default build size for UBL by over 2K, a little closer to fitting on 128K boards.
This commit is contained in:
@ -135,35 +135,29 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE void lcd_implementation_status_message(const bool blink) {
|
||||
void MarlinUI::draw_status_message(const bool blink) {
|
||||
|
||||
// Get the UTF8 character count of the string
|
||||
uint8_t slen = utf8_strlen(status_message);
|
||||
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
|
||||
static bool last_blink = false;
|
||||
|
||||
// Get the UTF8 character count of the string
|
||||
uint8_t slen = utf8_strlen(lcd_status_message);
|
||||
|
||||
// If the string fits into the LCD, just print it and do not scroll it
|
||||
if (slen <= LCD_WIDTH) {
|
||||
|
||||
// The string isn't scrolling and may not fill the screen
|
||||
lcd_put_u8str(lcd_status_message);
|
||||
|
||||
// Fill the rest with spaces
|
||||
while (slen < LCD_WIDTH) {
|
||||
lcd_put_wchar(' ');
|
||||
++slen;
|
||||
}
|
||||
// The string fits within the line. Print with no scrolling
|
||||
lcd_put_u8str(status_message);
|
||||
for (; slen < LCD_WIDTH; ++slen) lcd_put_wchar(' ');
|
||||
}
|
||||
else {
|
||||
// String is larger than the available space in screen.
|
||||
// String is longer than the available space
|
||||
|
||||
// Get a pointer to the next valid UTF8 character
|
||||
const char *stat = lcd_status_message + status_scroll_offset;
|
||||
const char *stat = status_message + status_scroll_offset;
|
||||
|
||||
// Get the string remaining length
|
||||
const uint8_t rlen = utf8_strlen(stat);
|
||||
|
||||
// If we have enough characters to display
|
||||
if (rlen >= LCD_WIDTH) {
|
||||
// The remaining string fills the screen - Print it
|
||||
lcd_put_u8str_max(stat, LCD_PIXEL_WIDTH);
|
||||
@ -178,7 +172,7 @@ FORCE_INLINE void lcd_implementation_status_message(const bool blink) {
|
||||
lcd_put_wchar('.');
|
||||
if (--chars) {
|
||||
// Print a second copy of the message
|
||||
lcd_put_u8str_max(lcd_status_message, LCD_PIXEL_WIDTH - ((rlen+2) * MENU_FONT_WIDTH));
|
||||
lcd_put_u8str_max(status_message, LCD_PIXEL_WIDTH - (rlen + 2) * (MENU_FONT_WIDTH));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -188,36 +182,33 @@ FORCE_INLINE void lcd_implementation_status_message(const bool blink) {
|
||||
// Adjust by complete UTF8 characters
|
||||
if (status_scroll_offset < slen) {
|
||||
status_scroll_offset++;
|
||||
while (!START_OF_UTF8_CHAR(lcd_status_message[status_scroll_offset]))
|
||||
while (!START_OF_UTF8_CHAR(status_message[status_scroll_offset]))
|
||||
status_scroll_offset++;
|
||||
}
|
||||
else
|
||||
status_scroll_offset = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#else // !STATUS_MESSAGE_SCROLLING
|
||||
|
||||
UNUSED(blink);
|
||||
|
||||
// Get the UTF8 character count of the string
|
||||
uint8_t slen = utf8_strlen(lcd_status_message);
|
||||
|
||||
// Just print the string to the LCD
|
||||
lcd_put_u8str_max(lcd_status_message, LCD_PIXEL_WIDTH);
|
||||
lcd_put_u8str_max(status_message, LCD_PIXEL_WIDTH);
|
||||
|
||||
// Fill the rest with spaces if there are missing spaces
|
||||
while (slen < LCD_WIDTH) {
|
||||
lcd_put_wchar(' ');
|
||||
++slen;
|
||||
}
|
||||
#endif
|
||||
// Fill the rest with spaces
|
||||
for (; slen < LCD_WIDTH; ++slen) lcd_put_wchar(' ');
|
||||
|
||||
#endif // !STATUS_MESSAGE_SCROLLING
|
||||
}
|
||||
|
||||
void lcd_impl_status_screen_0() {
|
||||
void MarlinUI::draw_status_screen() {
|
||||
|
||||
const bool blink = lcd_blink();
|
||||
const bool blink = get_blink();
|
||||
|
||||
// Status Menu Font
|
||||
lcd_setFont(FONT_STATUSMENU);
|
||||
set_font(FONT_STATUSMENU);
|
||||
|
||||
//
|
||||
// Fan Animation
|
||||
@ -318,11 +309,9 @@ void lcd_impl_status_screen_0() {
|
||||
PROGRESS_BAR_WIDTH, 4
|
||||
);
|
||||
|
||||
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
|
||||
const uint8_t progress_bar_percent = card.percentDone();
|
||||
#endif
|
||||
const uint8_t progress = get_progress();
|
||||
|
||||
if (progress_bar_percent > 1) {
|
||||
if (progress > 1) {
|
||||
|
||||
//
|
||||
// Progress bar solid part
|
||||
@ -331,7 +320,7 @@ void lcd_impl_status_screen_0() {
|
||||
if (PAGE_CONTAINS(50, 51)) // 50-51 (or just 50)
|
||||
u8g.drawBox(
|
||||
PROGRESS_BAR_X + 1, 50,
|
||||
(uint16_t)((PROGRESS_BAR_WIDTH - 2) * progress_bar_percent * 0.01), 2
|
||||
(uint16_t)((PROGRESS_BAR_WIDTH - 2) * progress * 0.01), 2
|
||||
);
|
||||
|
||||
//
|
||||
@ -342,7 +331,7 @@ void lcd_impl_status_screen_0() {
|
||||
if (PAGE_CONTAINS(41, 48)) {
|
||||
// Percent complete
|
||||
lcd_moveto(55, 48);
|
||||
lcd_put_u8str(itostr3(progress_bar_percent));
|
||||
lcd_put_u8str(itostr3(progress));
|
||||
lcd_put_wchar('%');
|
||||
}
|
||||
#endif
|
||||
@ -449,11 +438,11 @@ void lcd_impl_status_screen_0() {
|
||||
#define EXTRAS_BASELINE 50
|
||||
|
||||
if (PAGE_CONTAINS(EXTRAS_BASELINE - (INFO_FONT_HEIGHT - 1), EXTRAS_BASELINE)) {
|
||||
lcd_setFont(FONT_MENU);
|
||||
set_font(FONT_MENU);
|
||||
lcd_moveto(3, EXTRAS_BASELINE);
|
||||
lcd_put_wchar(LCD_STR_FEEDRATE[0]);
|
||||
|
||||
lcd_setFont(FONT_STATUSMENU);
|
||||
set_font(FONT_STATUSMENU);
|
||||
lcd_moveto(12, EXTRAS_BASELINE);
|
||||
lcd_put_u8str(itostr3(feedrate_percentage));
|
||||
lcd_put_wchar('%');
|
||||
@ -467,7 +456,7 @@ void lcd_impl_status_screen_0() {
|
||||
lcd_moveto(102, EXTRAS_BASELINE);
|
||||
lcd_put_u8str(mstring);
|
||||
lcd_put_wchar('%');
|
||||
lcd_setFont(FONT_MENU);
|
||||
set_font(FONT_MENU);
|
||||
lcd_moveto(47, EXTRAS_BASELINE);
|
||||
lcd_put_wchar(LCD_STR_FILAM_DIA[0]); // lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
|
||||
lcd_moveto(93, EXTRAS_BASELINE);
|
||||
@ -485,9 +474,9 @@ void lcd_impl_status_screen_0() {
|
||||
lcd_moveto(0, STATUS_BASELINE);
|
||||
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT)
|
||||
if (PENDING(millis(), previous_lcd_status_ms + 5000UL)) { //Display both Status message line and Filament display on the last line
|
||||
lcd_implementation_status_message(blink);
|
||||
}
|
||||
// Alternate Status message and Filament display
|
||||
if (PENDING(millis(), next_filament_display))
|
||||
draw_status_message(blink);
|
||||
else {
|
||||
lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
|
||||
lcd_put_wchar(':');
|
||||
@ -498,7 +487,7 @@ void lcd_impl_status_screen_0() {
|
||||
lcd_put_wchar('%');
|
||||
}
|
||||
#else
|
||||
lcd_implementation_status_message(blink);
|
||||
draw_status_message(blink);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -230,12 +230,8 @@ void ST7920_Lite_Status_Screen::load_cgram_icon(const uint16_t addr, const void
|
||||
*/
|
||||
void ST7920_Lite_Status_Screen::draw_gdram_icon(uint8_t x, uint8_t y, const void *data) {
|
||||
const uint16_t *p_word = (const uint16_t *)data;
|
||||
if (y > 2) { // Handle display folding
|
||||
y -= 2;
|
||||
x += 8;
|
||||
}
|
||||
--x;
|
||||
--y;
|
||||
// Handle display folding
|
||||
if (y > 1) y -= 2, x += 8;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
set_gdram_address(x, i + y * 16);
|
||||
begin_data();
|
||||
@ -398,24 +394,20 @@ const uint16_t feedrate_icon[] PROGMEM = {
|
||||
|
||||
/************************** MAIN SCREEN *************************************/
|
||||
|
||||
// The ST7920 does not have a degree character, but we
|
||||
// can fake it by writing it to GDRAM.
|
||||
// This function takes as an argument character positions
|
||||
// i.e x is [1-16], while the y position is [1-4]
|
||||
void ST7920_Lite_Status_Screen::draw_degree_symbol(uint8_t x, uint8_t y, bool draw) {
|
||||
/**
|
||||
* The ST7920 has no degree character, so draw it to GDRAM.
|
||||
* This function takes character position xy
|
||||
* i.e., x is [0-15], while the y position is [0-3]
|
||||
*/
|
||||
void ST7920_Lite_Status_Screen::draw_degree_symbol(uint8_t x, uint8_t y, const bool draw) {
|
||||
const uint8_t *p_bytes = degree_symbol;
|
||||
if (y > 2) {
|
||||
// Handle display folding
|
||||
y -= 2;
|
||||
x += 16;
|
||||
}
|
||||
x -= 1;
|
||||
y -= 1;
|
||||
// Handle display folding
|
||||
if (y > 1) y -= 2, x += 16;
|
||||
const bool oddChar = x & 1;
|
||||
const uint8_t x_word = x >> 1;
|
||||
const uint8_t y_top = degree_symbol_y_top;
|
||||
const uint8_t y_bot = y_top + sizeof(degree_symbol)/sizeof(degree_symbol[0]);
|
||||
for(uint8_t i = y_top; i < y_bot; i++) {
|
||||
const uint8_t x_word = x >> 1,
|
||||
y_top = degree_symbol_y_top,
|
||||
y_bot = y_top + sizeof(degree_symbol)/sizeof(degree_symbol[0]);
|
||||
for (uint8_t i = y_top; i < y_bot; i++) {
|
||||
uint8_t byte = pgm_read_byte(p_bytes++);
|
||||
set_gdram_address(x_word, i + y * 16);
|
||||
begin_data();
|
||||
@ -438,14 +430,14 @@ void ST7920_Lite_Status_Screen::draw_static_elements() {
|
||||
load_cgram_icon(CGRAM_ICON_4_ADDR, fan2_icon);
|
||||
|
||||
// Draw the static icons in GDRAM
|
||||
draw_gdram_icon(1, 1, nozzle_icon);
|
||||
draw_gdram_icon(0, 0, nozzle_icon);
|
||||
#if HOTENDS > 1
|
||||
draw_gdram_icon(1,2,nozzle_icon);
|
||||
draw_gdram_icon(1,3,bed_icon);
|
||||
draw_gdram_icon(0, 1, nozzle_icon);
|
||||
draw_gdram_icon(0, 2, bed_icon);
|
||||
#else
|
||||
draw_gdram_icon(1,2,bed_icon);
|
||||
draw_gdram_icon(0, 1, bed_icon);
|
||||
#endif
|
||||
draw_gdram_icon(6,2,feedrate_icon);
|
||||
draw_gdram_icon(5, 1, feedrate_icon);
|
||||
|
||||
// Draw the initial fan icon
|
||||
draw_fan_icon(false);
|
||||
@ -462,15 +454,15 @@ void ST7920_Lite_Status_Screen::draw_static_elements() {
|
||||
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
|
||||
const 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
|
||||
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
|
||||
const uint8_t top = 16 + 1,
|
||||
bottom = 16 + 13,
|
||||
left = 5,
|
||||
width = 3;
|
||||
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?
|
||||
|
||||
@ -557,10 +549,10 @@ static struct {
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange) {
|
||||
switch (line) {
|
||||
case 1: set_ddram_address(DDRAM_LINE_1 + 1); break;
|
||||
case 2: set_ddram_address(DDRAM_LINE_2 + 1); break;
|
||||
case 0: set_ddram_address(DDRAM_LINE_1 + 1); break;
|
||||
case 1: set_ddram_address(DDRAM_LINE_2 + 1); break;
|
||||
case 2: set_ddram_address(DDRAM_LINE_3 + 1); break;
|
||||
case 3: set_ddram_address(DDRAM_LINE_3 + 1); break;
|
||||
case 4: set_ddram_address(DDRAM_LINE_3 + 1); break;
|
||||
}
|
||||
begin_data();
|
||||
write_number(temp);
|
||||
@ -572,27 +564,27 @@ void ST7920_Lite_Status_Screen::draw_temps(uint8_t line, const int16_t temp, con
|
||||
|
||||
if (targetStateChange) {
|
||||
if (!showTarget) write_str(F(" "));
|
||||
draw_degree_symbol(6, line, !showTarget);
|
||||
draw_degree_symbol(10, line, showTarget);
|
||||
draw_degree_symbol(5, line, !showTarget);
|
||||
draw_degree_symbol(9, line, showTarget);
|
||||
}
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_extruder_1_temp(const int16_t temp, const int16_t target, bool forceUpdate) {
|
||||
const bool show_target = target && FAR(temp, target);
|
||||
draw_temps(1, temp, target, show_target, display_state.E1_show_target != show_target || forceUpdate);
|
||||
draw_temps(0, temp, target, show_target, display_state.E1_show_target != show_target || forceUpdate);
|
||||
display_state.E1_show_target = show_target;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate) {
|
||||
const bool show_target = target && FAR(temp, target);
|
||||
draw_temps(2, temp, target, show_target, display_state.E2_show_target != show_target || forceUpdate);
|
||||
draw_temps(1, temp, target, show_target, display_state.E2_show_target != show_target || forceUpdate);
|
||||
display_state.E2_show_target = show_target;
|
||||
}
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
void ST7920_Lite_Status_Screen::draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate) {
|
||||
const bool show_target = target && FAR(temp, target);
|
||||
draw_temps(2
|
||||
draw_temps(1
|
||||
#if HOTENDS > 1
|
||||
+ 1
|
||||
#endif
|
||||
@ -632,44 +624,38 @@ void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint16_t percenta
|
||||
#endif
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
|
||||
void ST7920_Lite_Status_Screen::draw_status_message() {
|
||||
const char *str = ui.status_message;
|
||||
|
||||
set_ddram_address(DDRAM_LINE_4);
|
||||
begin_data();
|
||||
const uint8_t lcd_len = 16;
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
|
||||
uint8_t slen = utf8_strlen(str);
|
||||
|
||||
// If the string fits into the LCD, just print it and do not scroll it
|
||||
if (slen <= lcd_len) {
|
||||
|
||||
// The string isn't scrolling and may not fill the screen
|
||||
if (slen <= LCD_WIDTH) {
|
||||
// String fits the LCD, so just print it
|
||||
write_str(str);
|
||||
|
||||
// Fill the rest with spaces
|
||||
while (slen < lcd_len) {
|
||||
write_byte(' ');
|
||||
++slen;
|
||||
}
|
||||
for (; slen < LCD_WIDTH; ++slen) write_byte(' ');
|
||||
}
|
||||
else {
|
||||
// String is larger than the available space in screen.
|
||||
|
||||
// Get a pointer to the next valid UTF8 character
|
||||
const char *stat = str + status_scroll_offset;
|
||||
const char *stat = str + ui.status_scroll_offset;
|
||||
|
||||
// Get the string remaining length
|
||||
const uint8_t rlen = utf8_strlen(stat);
|
||||
|
||||
// If we have enough characters to display
|
||||
if (rlen >= lcd_len) {
|
||||
if (rlen >= LCD_WIDTH) {
|
||||
// The remaining string fills the screen - Print it
|
||||
write_str(stat, lcd_len);
|
||||
write_str(stat, LCD_WIDTH);
|
||||
}
|
||||
else {
|
||||
// The remaining string does not completely fill the screen
|
||||
write_str(stat); // The string leaves space
|
||||
uint8_t chars = lcd_len - rlen; // Amount of space left in characters
|
||||
uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters
|
||||
|
||||
write_byte('.'); // Always at 1+ spaces left, draw a dot
|
||||
if (--chars) { // Draw a second dot if there's space
|
||||
@ -680,26 +666,21 @@ void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
|
||||
}
|
||||
|
||||
// Adjust by complete UTF8 characters
|
||||
if (status_scroll_offset < slen) {
|
||||
status_scroll_offset++;
|
||||
while (!START_OF_UTF8_CHAR(str[status_scroll_offset]))
|
||||
status_scroll_offset++;
|
||||
if (ui.status_scroll_offset < slen) {
|
||||
ui.status_scroll_offset++;
|
||||
while (!START_OF_UTF8_CHAR(str[ui.status_scroll_offset]))
|
||||
ui.status_scroll_offset++;
|
||||
}
|
||||
else
|
||||
status_scroll_offset = 0;
|
||||
ui.status_scroll_offset = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
// Get the UTF8 character count of the string
|
||||
|
||||
uint8_t slen = utf8_strlen(str);
|
||||
write_str(str, LCD_WIDTH);
|
||||
for (; slen < LCD_WIDTH; ++slen) write_byte(' ');
|
||||
|
||||
// Just print the string to the LCD
|
||||
write_str(str, lcd_len);
|
||||
|
||||
// Fill the rest with spaces if there are missing spaces
|
||||
while (slen < lcd_len) {
|
||||
write_byte(' ');
|
||||
++slen;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -709,7 +690,7 @@ void ST7920_Lite_Status_Screen::draw_position(const float x, const float y, cons
|
||||
begin_data();
|
||||
|
||||
// If position is unknown, flash the labels.
|
||||
const unsigned char alt_label = position_known ? 0 : (lcd_blink() ? ' ' : 0);
|
||||
const unsigned char alt_label = position_known ? 0 : (ui.get_blink() ? ' ' : 0);
|
||||
|
||||
dtostrf(x, -4, 0, str);
|
||||
write_byte(alt_label ? alt_label : 'X');
|
||||
@ -728,7 +709,7 @@ bool ST7920_Lite_Status_Screen::indicators_changed() {
|
||||
// We only add the target temperatures to the checksum
|
||||
// because the actual temps fluctuate so by updating
|
||||
// them only during blinks we gain a bit of stability.
|
||||
const bool blink = lcd_blink();
|
||||
const bool blink = ui.get_blink();
|
||||
const uint16_t feedrate_perc = feedrate_percentage;
|
||||
const uint8_t fs = (((uint16_t)fan_speed[0] + 1) * 100) / 256;
|
||||
const int16_t extruder_1_target = thermalManager.degTargetHotend(0);
|
||||
@ -754,7 +735,7 @@ bool ST7920_Lite_Status_Screen::indicators_changed() {
|
||||
|
||||
void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) {
|
||||
if (forceUpdate || indicators_changed()) {
|
||||
const bool blink = lcd_blink();
|
||||
const bool blink = ui.get_blink();
|
||||
const duration_t elapsed = print_job_timer.duration();
|
||||
const uint16_t feedrate_perc = feedrate_percentage;
|
||||
const uint8_t fs = (((uint16_t)fan_speed[0] + 1) * 100) / 256;
|
||||
@ -783,41 +764,32 @@ void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) {
|
||||
// Update the fan and bed animations
|
||||
if (fs) draw_fan_icon(blink);
|
||||
#if HAS_HEATED_BED
|
||||
if (bed_target > 0)
|
||||
draw_heat_icon(blink, true);
|
||||
else
|
||||
draw_heat_icon(false, false);
|
||||
draw_heat_icon(bed_target > 0 && blink, bed_target > 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::position_changed() {
|
||||
const float x_pos = current_position[X_AXIS],
|
||||
y_pos = current_position[Y_AXIS],
|
||||
z_pos = current_position[Z_AXIS];
|
||||
const float x_pos = current_position[X_AXIS], y_pos = current_position[Y_AXIS], z_pos = current_position[Z_AXIS];
|
||||
const uint8_t checksum = uint8_t(x_pos) ^ uint8_t(y_pos) ^ uint8_t(z_pos);
|
||||
|
||||
static uint8_t last_checksum = 0;
|
||||
if (last_checksum == checksum) return false;
|
||||
last_checksum = checksum;
|
||||
return true;
|
||||
static uint8_t last_checksum = 0, changed = last_checksum != checksum;
|
||||
if (changed) last_checksum = checksum;
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::status_changed() {
|
||||
uint8_t checksum = 0;
|
||||
for (const char *p = lcd_status_message; *p; p++) checksum ^= *p;
|
||||
static uint8_t last_checksum = 0;
|
||||
if (last_checksum == checksum) return false;
|
||||
last_checksum = checksum;
|
||||
return true;
|
||||
for (const char *p = ui.status_message; *p; p++) checksum ^= *p;
|
||||
static uint8_t last_checksum = 0, changed = last_checksum != checksum;
|
||||
if (changed) last_checksum = checksum;
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::blink_changed() {
|
||||
static uint8_t last_blink = 0;
|
||||
const bool blink = lcd_blink();
|
||||
if (last_blink == blink) return false;
|
||||
last_blink = blink;
|
||||
return true;
|
||||
const bool blink = ui.get_blink(), changed = last_blink != blink;
|
||||
if (changed) last_blink = blink;
|
||||
return changed;
|
||||
}
|
||||
|
||||
#ifndef STATUS_EXPIRE_SECONDS
|
||||
@ -831,60 +803,56 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* There is only enough room in the display for either the
|
||||
* status message or the position, not both, so we choose
|
||||
* one or another. Whenever the status message changes,
|
||||
* we show it for a number of consecutive seconds, but
|
||||
* then go back to showing the position as soon as the
|
||||
* head moves, i.e:
|
||||
* There's only enough room for either the status message or the position,
|
||||
* so draw one or the other. When the status message changes, show it for
|
||||
* a few seconds, then return to the position display once the head moves.
|
||||
*
|
||||
* countdown > 1 -- Show status
|
||||
* countdown = 1 -- Show status, until movement
|
||||
* countdown = 0 -- Show position
|
||||
* countdown > 1 -- Show status
|
||||
* countdown = 1 -- Show status, until movement
|
||||
* countdown = 0 -- Show position
|
||||
*
|
||||
* If STATUS_EXPIRE_SECONDS is zero, the position display
|
||||
* will be disabled and only the status will be shown.
|
||||
* If STATUS_EXPIRE_SECONDS is zero, only the status is shown.
|
||||
*/
|
||||
if (forceUpdate || status_changed()) {
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
status_scroll_offset = 0;
|
||||
ui.status_scroll_offset = 0;
|
||||
#endif
|
||||
#if STATUS_EXPIRE_SECONDS
|
||||
countdown = lcd_status_message[0] ? STATUS_EXPIRE_SECONDS : 0;
|
||||
countdown = ui.status_message[0] ? STATUS_EXPIRE_SECONDS : 0;
|
||||
#endif
|
||||
draw_status_message(lcd_status_message);
|
||||
draw_status_message();
|
||||
blink_changed(); // Clear changed flag
|
||||
}
|
||||
#if !STATUS_EXPIRE_SECONDS
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
else
|
||||
draw_status_message(lcd_status_message);
|
||||
draw_status_message();
|
||||
#endif
|
||||
#else
|
||||
else if (countdown > 1 && blink_changed()) {
|
||||
countdown--;
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
draw_status_message(lcd_status_message);
|
||||
#endif
|
||||
}
|
||||
else if (countdown > 0 && blink_changed()) {
|
||||
if (position_changed()) {
|
||||
else if (blink_changed()) {
|
||||
if (countdown > 1) {
|
||||
countdown--;
|
||||
forceUpdate = true;
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
draw_status_message();
|
||||
#endif
|
||||
}
|
||||
else if (countdown > 0) {
|
||||
if (position_changed()) {
|
||||
countdown--;
|
||||
forceUpdate = true;
|
||||
}
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
draw_status_message();
|
||||
#endif
|
||||
}
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
draw_status_message(lcd_status_message);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (countdown == 0 && (forceUpdate || position_changed() ||
|
||||
#if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
|
||||
blink_changed()
|
||||
#endif
|
||||
)) {
|
||||
draw_position(
|
||||
current_position[X_AXIS],
|
||||
current_position[Y_AXIS],
|
||||
current_position[Z_AXIS],
|
||||
draw_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS],
|
||||
#if ENABLED(DISABLE_REDUCED_ACCURACY_WARNING)
|
||||
true
|
||||
#else
|
||||
@ -898,24 +866,16 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
|
||||
void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
|
||||
#if ENABLED(LCD_SET_PROGRESS_MANUALLY) || ENABLED(SDSUPPORT)
|
||||
|
||||
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
|
||||
uint8_t progress_bar_percent = 0;
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
// Progress bar % comes from SD when actively printing
|
||||
if (IS_SD_PRINTING()) progress_bar_percent = card.percentDone();
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
if (!forceUpdate && last_progress == progress_bar_percent) return;
|
||||
last_progress = progress_bar_percent;
|
||||
|
||||
draw_progress_bar(progress_bar_percent);
|
||||
const uint8_t progress = ui.get_progress();
|
||||
if (forceUpdate || last_progress != progress) {
|
||||
last_progress = progress;
|
||||
draw_progress_bar(progress);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@ -966,7 +926,7 @@ void ST7920_Lite_Status_Screen::clear_text_buffer() {
|
||||
ncs();
|
||||
}
|
||||
|
||||
void lcd_impl_status_screen_0() {
|
||||
void MarlinUI::draw_status_screen() {
|
||||
ST7920_Lite_Status_Screen::update(false);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ class ST7920_Lite_Status_Screen {
|
||||
static uint8_t string_checksum(const char *str);
|
||||
|
||||
protected:
|
||||
static void draw_degree_symbol(uint8_t x, uint8_t y, bool draw);
|
||||
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);
|
||||
@ -86,7 +86,7 @@ class ST7920_Lite_Status_Screen {
|
||||
static void draw_fan_speed(const uint8_t value);
|
||||
static void draw_print_time(const duration_t &elapsed);
|
||||
static void draw_feedrate_percentage(const uint16_t percentage);
|
||||
static void draw_status_message(const char *str);
|
||||
static void draw_status_message();
|
||||
static void draw_position(const float x, const float y, const float z, bool position_known = true);
|
||||
|
||||
static bool indicators_changed();
|
||||
|
@ -75,16 +75,16 @@ U8GLIB *pu8g = &u8g;
|
||||
|
||||
#if HAS_LCD_CONTRAST
|
||||
|
||||
int16_t lcd_contrast; // Initialized by settings.load()
|
||||
int16_t MarlinUI::contrast; // Initialized by settings.load()
|
||||
|
||||
void set_lcd_contrast(const int16_t value) {
|
||||
lcd_contrast = constrain(value, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX);
|
||||
u8g.setContrast(lcd_contrast);
|
||||
void MarlinUI::set_contrast(const int16_t value) {
|
||||
contrast = constrain(value, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX);
|
||||
u8g.setContrast(contrast);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void lcd_setFont(const MarlinFont font_nr) {
|
||||
void MarlinUI::set_font(const MarlinFont font_nr) {
|
||||
static char currentfont = 0;
|
||||
if (font_nr != currentfont) {
|
||||
switch ((currentfont = font_nr)) {
|
||||
@ -141,7 +141,7 @@ void lcd_setFont(const MarlinFont font_nr) {
|
||||
|
||||
#endif // SHOW_CUSTOM_BOOTSCREEN
|
||||
|
||||
void lcd_bootscreen() {
|
||||
void MarlinUI::show_bootscreen() {
|
||||
#if ENABLED(SHOW_CUSTOM_BOOTSCREEN)
|
||||
lcd_custom_bootscreen();
|
||||
#endif
|
||||
@ -160,7 +160,7 @@ void lcd_setFont(const MarlinFont font_nr) {
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawBitmapP(offx, offy, (START_BMPWIDTH + 7) / 8, START_BMPHEIGHT, start_bmp);
|
||||
lcd_setFont(FONT_MENU);
|
||||
ui.set_font(FONT_MENU);
|
||||
#ifndef STRING_SPLASH_LINE2
|
||||
const uint8_t txt1X = width - (sizeof(STRING_SPLASH_LINE1) - 1) * (MENU_FONT_WIDTH);
|
||||
u8g.drawStr(txt1X, (height + MENU_FONT_HEIGHT) / 2, STRING_SPLASH_LINE1);
|
||||
@ -181,7 +181,7 @@ void lcd_setFont(const MarlinFont font_nr) {
|
||||
#endif
|
||||
|
||||
// Initialize or re-initialize the LCD
|
||||
void lcd_implementation_init() {
|
||||
void MarlinUI::init_lcd() {
|
||||
|
||||
#if PIN_EXISTS(LCD_BACKLIGHT) // Enable LCD backlight
|
||||
OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH);
|
||||
@ -206,7 +206,7 @@ void lcd_implementation_init() {
|
||||
#endif
|
||||
|
||||
#if HAS_LCD_CONTRAST
|
||||
set_lcd_contrast(lcd_contrast);
|
||||
refresh_contrast();
|
||||
#endif
|
||||
|
||||
#if ENABLED(LCD_SCREEN_ROT_90)
|
||||
@ -221,16 +221,16 @@ void lcd_implementation_init() {
|
||||
}
|
||||
|
||||
// The kill screen is displayed for unrecoverable conditions
|
||||
void lcd_kill_screen() {
|
||||
void MarlinUI::draw_kill_screen() {
|
||||
#if ENABLED(LIGHTWEIGHT_UI)
|
||||
ST7920_Lite_Status_Screen::clear_text_buffer();
|
||||
#endif
|
||||
const uint8_t h4 = u8g.getHeight() / 4;
|
||||
u8g.firstPage();
|
||||
do {
|
||||
lcd_setFont(FONT_MENU);
|
||||
set_font(FONT_MENU);
|
||||
lcd_moveto(0, h4 * 1);
|
||||
lcd_put_u8str(lcd_status_message);
|
||||
lcd_put_u8str(status_message);
|
||||
lcd_moveto(0, h4 * 2);
|
||||
lcd_put_u8str_P(PSTR(MSG_HALTED));
|
||||
lcd_moveto(0, h4 * 3);
|
||||
@ -238,7 +238,7 @@ void lcd_kill_screen() {
|
||||
} while (u8g.nextPage());
|
||||
}
|
||||
|
||||
void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
|
||||
|
||||
#if HAS_LCD_MENU
|
||||
|
||||
@ -246,7 +246,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
|
||||
void lcd_implementation_hotend_status(const uint8_t row, const uint8_t extruder) {
|
||||
void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) {
|
||||
row_y1 = row * (MENU_FONT_HEIGHT) + 1;
|
||||
row_y2 = row_y1 + MENU_FONT_HEIGHT - 1;
|
||||
|
||||
@ -259,7 +259,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
lcd_put_u8str(itostr3(thermalManager.degHotend(extruder)));
|
||||
lcd_put_wchar('/');
|
||||
|
||||
if (lcd_blink() || !thermalManager.is_heater_idle(extruder))
|
||||
if (get_blink() || !thermalManager.is_heater_idle(extruder))
|
||||
lcd_put_u8str(itostr3(thermalManager.degTargetHotend(extruder)));
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
}
|
||||
|
||||
// Draw a static line of text in the same idiom as a menu item
|
||||
void lcd_implementation_drawmenu_static(const uint8_t row, PGM_P pstr, const bool center/*=true*/, const bool invert/*=false*/, const char* valstr/*=NULL*/) {
|
||||
void draw_menu_item_static(const uint8_t row, PGM_P pstr, const bool center/*=true*/, const bool invert/*=false*/, const char* valstr/*=NULL*/) {
|
||||
|
||||
if (mark_as_selected(row, invert)) {
|
||||
|
||||
@ -315,7 +315,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
}
|
||||
|
||||
// Draw a generic menu item
|
||||
void lcd_implementation_drawmenu_generic(const bool isSelected, const uint8_t row, PGM_P pstr, const char pre_char, const char post_char) {
|
||||
void draw_menu_item_generic(const bool isSelected, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) {
|
||||
UNUSED(pre_char);
|
||||
|
||||
if (mark_as_selected(row, isSelected)) {
|
||||
@ -330,7 +330,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
}
|
||||
|
||||
// Draw a menu item with an editable value
|
||||
void _drawmenu_setting_edit_generic(const bool isSelected, const uint8_t row, PGM_P pstr, const char* const data, const bool pgm) {
|
||||
void _drawmenu_setting_edit_generic(const bool isSelected, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
|
||||
if (mark_as_selected(row, isSelected)) {
|
||||
const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
|
||||
uint8_t n = LCD_WIDTH - 2 - vallen;
|
||||
@ -343,7 +343,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_implementation_drawedit(PGM_P const pstr, const char* const value/*=NULL*/) {
|
||||
void draw_edit_screen(PGM_P const pstr, const char* const value/*=NULL*/) {
|
||||
const uint8_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value);
|
||||
|
||||
bool extra_row = labellen > LCD_WIDTH - 2 - vallen;
|
||||
@ -356,12 +356,12 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
if (labellen + vallen + 1 > lcd_edit_width) extra_row = true;
|
||||
lcd_chr_fit = lcd_edit_width + 1;
|
||||
one_chr_width = EDIT_FONT_WIDTH;
|
||||
lcd_setFont(FONT_EDIT);
|
||||
ui.set_font(FONT_EDIT);
|
||||
}
|
||||
else {
|
||||
lcd_chr_fit = LCD_WIDTH;
|
||||
one_chr_width = MENU_FONT_WIDTH;
|
||||
lcd_setFont(FONT_MENU);
|
||||
ui.set_font(FONT_MENU);
|
||||
}
|
||||
#else
|
||||
constexpr uint8_t lcd_chr_fit = LCD_WIDTH,
|
||||
@ -397,7 +397,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
|
||||
void _drawmenu_sd(const bool isSelected, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
|
||||
void draw_sd_menu_item(const bool isSelected, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
|
||||
UNUSED(pstr);
|
||||
|
||||
mark_as_selected(row, isSelected);
|
||||
@ -415,11 +415,11 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ theCard.filename[l]; // rotate, xor
|
||||
if (filename_scroll_hash != name_hash) { // If the hash changed...
|
||||
filename_scroll_hash = name_hash; // Save the new hash
|
||||
filename_scroll_max = MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
|
||||
filename_scroll_pos = 0; // Reset scroll to the start
|
||||
lcd_status_update_delay = 8; // Don't scroll right away
|
||||
ui.filename_scroll_max = MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
|
||||
ui.filename_scroll_pos = 0; // Reset scroll to the start
|
||||
ui.lcd_status_update_delay = 8; // Don't scroll right away
|
||||
}
|
||||
outstr += filename_scroll_pos;
|
||||
outstr += ui.filename_scroll_pos;
|
||||
}
|
||||
#else
|
||||
theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
|
||||
@ -428,8 +428,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
|
||||
if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
|
||||
|
||||
int n;
|
||||
n = lcd_put_u8str_max(outstr, maxlen * (MENU_FONT_WIDTH));
|
||||
uint8_t n = lcd_put_u8str_max(outstr, maxlen * (MENU_FONT_WIDTH));
|
||||
n = maxlen * (MENU_FONT_WIDTH) - n;
|
||||
while (n - MENU_FONT_WIDTH > 0) { n -= lcd_put_wchar(' '); }
|
||||
}
|
||||
@ -446,7 +445,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
|
||||
#define MAP_MAX_PIXELS_X 53
|
||||
#define MAP_MAX_PIXELS_Y 49
|
||||
|
||||
void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
|
||||
void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
|
||||
// Scale the box pixels appropriately
|
||||
uint8_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X),
|
||||
y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y),
|
||||
|
Reference in New Issue
Block a user