From b0ece8f8df130709f97da6c1474cd20cbd9119ed Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 20 Oct 2023 17:21:30 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20MarlinUI=20?= =?UTF-8?q?menu=20tweaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes in prep for #26339 --- Marlin/src/lcd/HD44780/marlinui_HD44780.cpp | 6 +- Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp | 10 +- Marlin/src/lcd/dogm/marlinui_DOGM.cpp | 95 +++++++------ Marlin/src/lcd/e3v2/marlinui/ui_common.cpp | 146 ++++++++++---------- Marlin/src/lcd/lcdprint.cpp | 78 +++++++++++ Marlin/src/lcd/lcdprint.h | 33 ++++- Marlin/src/lcd/menu/menu.h | 2 +- Marlin/src/lcd/menu/menu_configuration.cpp | 12 +- Marlin/src/lcd/tft/ui_common.cpp | 8 +- 9 files changed, 245 insertions(+), 145 deletions(-) diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp index 3206cb6334..716d1341db 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp @@ -1165,12 +1165,12 @@ void MarlinUI::draw_status_screen() { #endif // ADVANCED_PAUSE_FEATURE // Draw a static item with no left-right margin required. Centered by default. - void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { + void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { lcd_moveto(0, row); int8_t n = LCD_WIDTH; const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL); - const int8_t plen = fstr ? utf8_strlen(fstr) : 0, + const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0, vlen = vstr ? utf8_strlen(vstr) : 0; int8_t pad = (center || full) ? n - plen - vlen : 0; @@ -1178,7 +1178,7 @@ void MarlinUI::draw_status_screen() { if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) { lcd_put_u8str(F(" ")); n--; } // Draw as much of the label as fits - if (plen) n -= lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n - vlen); + if (plen) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n - vlen); if (vlen && n > 0) { // SS_FULL: Pad with enough space to justify the value diff --git a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp index 2d621d74cf..1c6e49644b 100644 --- a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp +++ b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp @@ -969,7 +969,7 @@ void MarlinUI::draw_status_screen() { #endif // Draw a static item with no left-right margin required. Centered by default. - void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { + void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { if (!PanelDetected) return; lcd_moveto(0, row); @@ -1004,25 +1004,25 @@ void MarlinUI::draw_status_screen() { } // Draw a generic menu item with pre_char (if selected) and post_char - void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) { + void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char pre_char, const char post_char) { if (!PanelDetected) return; lcd_moveto(0, row); lcd.write(sel ? pre_char : ' '); uint8_t n = LCD_WIDTH - 2; - n -= lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n); + n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n); for (; n; --n) lcd.write(' '); lcd.write(post_char); lcd.print_line(); } // Draw a menu item with a (potentially) editable value - void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) { + void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) { if (!PanelDetected) return; const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0; lcd_moveto(0, row); lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' '); uint8_t n = LCD_WIDTH - 2 - vlen; - n -= lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n); + n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n); if (vlen) { lcd.write(':'); for (; n; --n) lcd.write(' '); diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index c2671b1b75..6c15572f04 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -411,63 +411,62 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop // Draw a static line of text in the same idiom as a menu item void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { + if (!mark_as_selected(row, style & SS_INVERT)) return; - if (mark_as_selected(row, style & SS_INVERT)) { - pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed + pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed - const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL); - const int pwide = ftpl ? calculateWidth(ftpl) : 0, - vlen = vstr ? utf8_strlen(vstr) : 0; - int pad = (center || full) ? ((LCD_PIXEL_WIDTH) - pwide - vlen * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH) : 0; + const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL); + const int pwide = ftpl ? calculateWidth(ftpl) : 0, + vlen = vstr ? utf8_strlen(vstr) : 0; + int pad = (center || full) ? ((LCD_PIXEL_WIDTH) - pwide - vlen * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH) : 0; - // SS_CENTER: Pad with half of the unused space first - if (center) for (int lpad = pad / 2; lpad > 0; --lpad) n -= lcd_put_u8str(F(" ")); + // SS_CENTER: Pad with half of the unused space first + if (center) for (int lpad = pad / 2; lpad > 0; --lpad) n -= lcd_put_u8str(F(" ")); - // Draw as much of the label as fits - if (pwide) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH); + // Draw as much of the label as fits + if (pwide) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH); - if (vlen) { - // SS_FULL: Pad with enough space to justify the value - if (full && !center && n > MENU_FONT_WIDTH) { - // Move the leading colon from the value to the label - if (*vstr == ':') { n -= lcd_put_u8str(F(":")); vstr++; } - // Move spaces to the padding - while (*vstr == ' ') { vstr++; pad++; } - // Pad in-between - for (; pad > 0; --pad) n -= lcd_put_u8str(F(" ")); - } - n -= lcd_put_u8str_max(vstr, n); + if (vlen) { + // SS_FULL: Pad with enough space to justify the value + if (full && !center && n > MENU_FONT_WIDTH) { + // Move the leading colon from the value to the label + if (*vstr == ':') { n -= lcd_put_u8str(F(":")); vstr++; } + // Move spaces to the padding + while (*vstr == ' ') { vstr++; pad++; } + // Pad in-between + for (; pad > 0; --pad) n -= lcd_put_u8str(F(" ")); } - while (n > MENU_FONT_WIDTH) n -= lcd_put_u8str(F(" ")); + n -= lcd_put_u8str_max(vstr, n); } + while (n > MENU_FONT_WIDTH) n -= lcd_put_u8str(F(" ")); } // Draw a generic menu item void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) { - if (mark_as_selected(row, sel)) { - uint8_t n = LCD_WIDTH - 1; - n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n); - for (; n; --n) lcd_put_u8str(F(" ")); - lcd_put_lchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char); - lcd_put_u8str(F(" ")); - } + if (!mark_as_selected(row, sel)) return; + + uint8_t n = LCD_WIDTH - 1; + n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n); + for (; n; --n) lcd_put_u8str(F(" ")); + lcd_put_lchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char); + lcd_put_u8str(F(" ")); } // Draw a menu item with an editable value void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) { - if (mark_as_selected(row, sel)) { - const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)), - pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr)); - const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; + if (!mark_as_selected(row, sel)) return; - uint8_t n = LCD_WIDTH - 2 - vallen * prop; - n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n); - if (vallen) { - lcd_put_u8str(F(":")); - for (; n; --n) lcd_put_u8str(F(" ")); - lcd_moveto(LCD_PIXEL_WIDTH - _MAX((MENU_FONT_WIDTH) * vallen, pixelwidth + 2), row_y2); - if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr); - } + const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)), + pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr)); + const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; + + uint8_t n = LCD_WIDTH - 2 - vallen * prop; + n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n); + if (vallen) { + lcd_put_u8str(F(":")); + for (; n; --n) lcd_put_u8str(F(" ")); + lcd_moveto(LCD_PIXEL_WIDTH - _MAX((MENU_FONT_WIDTH) * vallen, pixelwidth + 2), row_y2); + if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr); } } @@ -545,13 +544,13 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop #if HAS_MEDIA void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) { - if (mark_as_selected(row, sel)) { - const uint8_t maxlen = LCD_WIDTH - isDir; - if (isDir) lcd_put_lchar(LCD_STR_FOLDER[0]); - const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH); - pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw); - for (; n > MENU_FONT_WIDTH; n -= MENU_FONT_WIDTH) lcd_put_u8str(F(" ")); - } + if (!mark_as_selected(row, sel)) return; + + const uint8_t maxlen = LCD_WIDTH - isDir; + if (isDir) lcd_put_lchar(LCD_STR_FOLDER[0]); + const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH); + pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw); + for (; n > MENU_FONT_WIDTH; n -= MENU_FONT_WIDTH) lcd_put_u8str(F(" ")); } #endif // HAS_MEDIA diff --git a/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp b/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp index 27e5b38bd0..c0bf0a75d6 100644 --- a/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp +++ b/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp @@ -308,91 +308,91 @@ void MarlinUI::draw_status_message(const bool blink) { void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { // Call mark_as_selected to draw a bigger selection box // and draw the text without a background - if (mark_as_selected(row, (bool)(style & SS_INVERT), true)) { - ui.set_font(DWIN_FONT_MENU); - dwin_font.solid = false; - dwin_font.fg = COLOR_WHITE; + if (!mark_as_selected(row, (bool)(style & SS_INVERT), true)) return; - dwin_string.set(); + ui.set_font(DWIN_FONT_MENU); + dwin_font.solid = false; + dwin_font.fg = COLOR_WHITE; - const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL); - const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0, - vlen = vstr ? utf8_strlen(vstr) : 0; - int8_t pad = (center || full) ? (LCD_WIDTH) - 1 - plen - vlen : 0; + dwin_string.set(); - // SS_CENTER: Pad with half of the unused space first - if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) dwin_string.add(' '); + const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL); + const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0, + vlen = vstr ? utf8_strlen(vstr) : 0; + int8_t pad = (center || full) ? (LCD_WIDTH) - 1 - plen - vlen : 0; - // Append the templated label string - if (plen) { - dwin_string.add(ftpl, itemIndex, itemStringC, itemStringF); - pad -= dwin_string.length - plen; - } + // SS_CENTER: Pad with half of the unused space first + if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) dwin_string.add(' '); - // SS_FULL: Pad with enough space to justify the value - if (vlen) { - if (full && !center) { - // Move the leading colon from the value to the label - if (*vstr == ':') { dwin_string.add(':'); vstr++; } - // Move spaces to the padding - while (*vstr == ' ') { vstr++; pad++; } - // Pad in-between - for (; pad > 0; --pad) dwin_string.add(' '); - } - // Append the value - dwin_string.add(vstr); - } - - // SS_CENTER: Pad the rest of the string - if (center) for (int8_t rpad = pad - (pad / 2); rpad > 0; --rpad) dwin_string.add(' '); - - lcd_moveto(1, row); - lcd_put_dwin_string(); + // Append the templated label string + if (plen) { + dwin_string.add(ftpl, itemIndex, itemStringC, itemStringF); + pad -= dwin_string.length - plen; } + + // SS_FULL: Pad with enough space to justify the value + if (vlen) { + if (full && !center) { + // Move the leading colon from the value to the label + if (*vstr == ':') { dwin_string.add(':'); vstr++; } + // Move spaces to the padding + while (*vstr == ' ') { vstr++; pad++; } + // Pad in-between + for (; pad > 0; --pad) dwin_string.add(' '); + } + // Append the value + dwin_string.add(vstr); + } + + // SS_CENTER: Pad the rest of the string + if (center) for (int8_t rpad = pad - (pad / 2); rpad > 0; --rpad) dwin_string.add(' '); + + lcd_moveto(1, row); + lcd_put_dwin_string(); } // Draw a generic menu item void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) { - if (mark_as_selected(row, sel)) { - ui.set_font(DWIN_FONT_MENU); - dwin_font.solid = false; - dwin_font.fg = COLOR_WHITE; + if (!mark_as_selected(row, sel)) return; - dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF); + ui.set_font(DWIN_FONT_MENU); + dwin_font.solid = false; + dwin_font.fg = COLOR_WHITE; - pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length; - while (--n > 1) dwin_string.add(' '); + dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF); - dwin_string.add(post_char); + pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length; + while (--n > 1) dwin_string.add(' '); - lcd_moveto(1, row); - lcd_put_dwin_string(); - } + dwin_string.add(post_char); + + lcd_moveto(1, row); + lcd_put_dwin_string(); } // // Draw a menu item with an editable value // void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) { - if (mark_as_selected(row, sel)) { - ui.set_font(DWIN_FONT_MENU); - dwin_font.solid = false; - dwin_font.fg = COLOR_WHITE; + if (!mark_as_selected(row, sel)) return; - const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(S(inStr))); + ui.set_font(DWIN_FONT_MENU); + dwin_font.solid = false; + dwin_font.fg = COLOR_WHITE; - dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF); - if (vallen) dwin_string.add(':'); + const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(S(inStr))); - lcd_moveto(1, row); + dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF); + if (vallen) dwin_string.add(':'); + + lcd_moveto(1, row); + lcd_put_dwin_string(); + + if (vallen) { + dwin_font.fg = COLOR_YELLOW; + dwin_string.set(inStr); + lcd_moveto(LCD_WIDTH - vallen - 1, row); lcd_put_dwin_string(); - - if (vallen) { - dwin_font.fg = COLOR_YELLOW; - dwin_string.set(inStr); - lcd_moveto(LCD_WIDTH - vallen - 1, row); - lcd_put_dwin_string(); - } } } @@ -464,21 +464,21 @@ void MarlinUI::draw_status_message(const bool blink) { #if HAS_MEDIA void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) { - if (mark_as_selected(row, sel)) { - dwin_string.set(); + if (!mark_as_selected(row, sel)) return; - uint8_t maxlen = LCD_WIDTH - 1; - if (isDir) { - dwin_string.add(LCD_STR_FOLDER " "); - maxlen -= 2; - } + dwin_string.set(); - dwin_string.add(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen); - uint8_t n = maxlen - dwin_string.length; - while (n > 0) { dwin_string.add(' '); --n; } - lcd_moveto(1, row); - lcd_put_dwin_string(); + uint8_t maxlen = LCD_WIDTH - 1; + if (isDir) { + dwin_string.add(LCD_STR_FOLDER " "); + maxlen -= 2; } + + dwin_string.add(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen); + uint8_t n = maxlen - dwin_string.length; + while (n > 0) { dwin_string.add(' '); --n; } + lcd_moveto(1, row); + lcd_put_dwin_string(); } #endif // HAS_MEDIA diff --git a/Marlin/src/lcd/lcdprint.cpp b/Marlin/src/lcd/lcdprint.cpp index bdf2513121..70e4e73269 100644 --- a/Marlin/src/lcd/lcdprint.cpp +++ b/Marlin/src/lcd/lcdprint.cpp @@ -31,6 +31,84 @@ #include "marlinui.h" #include "lcdprint.h" +/** + * expand_u8str_P + * + * Expand a string with optional substitutions: + * + * $ displays the clipped string given by fstr or cstr + * { displays '0'....'10' for indexes 0 - 10 + * ~ displays '1'....'11' for indexes 0 - 10 + * * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL) + * @ displays an axis name such as XYZUVW, or E for an extruder + * + * Return the number of characters emitted + */ +lcd_uint_t expand_u8str_P(char * const outstr, PGM_P const ptpl, const int8_t ind, const char *cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) { + const uint8_t prop = USE_WIDE_GLYPH ? 2 : 1; + const uint8_t *p = (uint8_t*)ptpl; + char *o = outstr; + int8_t n = maxlen; + while (n > 0) { + lchar_t wc; + p = get_utf8_value_cb(p, read_byte_rom, wc); + if (!wc) break; + if (wc == '{' || wc == '~' || wc == '*') { + if (ind >= 0) { + if (wc == '*') { *o++ = 'E'; n--; } + if (n) { + int8_t inum = ind + ((wc == '{') ? 0 : LCD_FIRST_TOOL); + if (inum >= 10) { + *o++ = ('0' + (inum / 10)); n--; + inum %= 10; + } + if (n) { *o++ = '0' + inum; n--; } + } + } + else { + PGM_P const b = ind == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED); + strncpy_P(o, b, n); + n -= utf8_strlen_P(b); + o += strlen(o); + } + if (n > 0) { + strncpy_P(o, (PGM_P)p, n); + n -= utf8_strlen(o); + o += strlen(o); + break; + } + } + else if (wc == '$' && fstr) { + strncpy_P(o, FTOP(fstr), n); + n -= utf8_strlen_P(FTOP(fstr)); + o += strlen(o); + } + else if (wc == '$' && cstr) { + strncpy(o, cstr, n); + n -= utf8_strlen(o); + o += strlen(o); + } + else if (wc == '@') { + *o++ = AXIS_CHAR(ind); + *o = '\0'; + n--; + } + else if (wc > 255 && prop == 2) { + // Wide glyph support incomplete + *((uint16_t*)o) = wc; + o += 2; + *o = '\0'; + n--; + } + else { + *o++ = wc; + *o = '\0'; + n--; + } + } + return maxlen - n; +} + /** * lcd_put_u8str_P * diff --git a/Marlin/src/lcd/lcdprint.h b/Marlin/src/lcd/lcdprint.h index 9ba5147918..87032201fb 100644 --- a/Marlin/src/lcd/lcdprint.h +++ b/Marlin/src/lcd/lcdprint.h @@ -205,14 +205,37 @@ inline int lcd_put_u8str(const lcd_uint_t col, const lcd_uint_t row, FSTR_P cons return lcd_put_u8str_P(col, row, FTOP(fstr)); } +/** + * @brief Expand a string with optional substitution + * @details Expand a string with optional substitutions: + * $ : the clipped string given by fstr or cstr + * { : '0'....'10' for indexes 0 - 10 + * ~ : '1'....'11' for indexes 0 - 10 + * * : 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL) + * @ : an axis name such as XYZUVW, or E for an extruder + * + * @param *outstr The output destination buffer + * @param ptpl A ROM string (template) + * @param ind An index value to use for = ~ * substitution + * @param cstr An SRAM C-string to use for $ substitution + * @param fstr A ROM F-string to use for $ substitution + * @param maxlen The maximum size of the string (in pixels on GLCD) + * @return the output width (in pixels on GLCD) + */ +lcd_uint_t expand_u8str_P(char * const outstr, PGM_P const ptpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH); + +inline lcd_uint_t expand_u8str(char * const outstr, FSTR_P const ftpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) { + return expand_u8str_P(outstr, FTOP(ftpl), ind, cstr, fstr, maxlen); +} + /** * @brief Draw a string with optional substitution * @details Print a string with optional substitutions: - * $ displays the clipped string given by fstr or cstr - * { displays '0'....'10' for indexes 0 - 10 - * ~ displays '1'....'11' for indexes 0 - 10 - * * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL) - * @ displays an axis name such as XYZUVW, or E for an extruder + * $ : the clipped string given by fstr or cstr + * { : '0'....'10' for indexes 0 - 10 + * ~ : '1'....'11' for indexes 0 - 10 + * * : 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL) + * @ : an axis name such as XYZUVW, or E for an extruder * * @param ptpl A ROM string (template) * @param ind An index value to use for = ~ * substitution diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index d4cbfd7a73..9bb785e927 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -76,7 +76,7 @@ class MenuItemBase { // STATIC_ITEM(LABEL,...) class MenuItem_static : public MenuItemBase { public: - static void draw(const uint8_t row, FSTR_P const fstr, const uint8_t style=SS_DEFAULT, const char *vstr=nullptr); + static void draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style=SS_DEFAULT, const char *vstr=nullptr); }; // BACK_ITEM(LABEL) diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index 4677d63b69..293067b15c 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -78,7 +78,7 @@ void menu_advanced_settings(); #if ENABLED(LCD_PROGRESS_BAR_TEST) - static void progress_bar_test() { + static void screen_progress_bar_test() { static int8_t bar_percent = 0; if (ui.use_click()) { ui.goto_previous_screen(); @@ -93,8 +93,8 @@ void menu_advanced_settings(); lcd_moveto(0, LCD_HEIGHT - 1); ui.draw_progress_bar(bar_percent); } - void _progress_bar_test() { - ui.goto_screen(progress_bar_test); + void _goto_progress_bar_test() { + ui.goto_screen(screen_progress_bar_test); TERN_(HAS_MARLINUI_HD44780, ui.set_custom_characters(CHARSET_INFO)); } @@ -108,7 +108,7 @@ void menu_advanced_settings(); #define STOP_MINMAX(A,I) STOP_ITEM(A,I,MIN,"Min") STOP_ITEM(A,I,MAX,"Max") #define FIL_ITEM(N) PSTRING_ITEM_N_P(N-1, MSG_FILAMENT_EN, (READ(FIL_RUNOUT##N##_PIN) != FIL_RUNOUT##N##_STATE) ? PSTR("PRESENT") : PSTR("out"), SS_FULL); - static void endstop_test() { + static void screen_endstop_test() { if (ui.use_click()) { ui.goto_previous_screen(); //endstops.enable_globally(false); @@ -148,11 +148,11 @@ void menu_advanced_settings(); BACK_ITEM(MSG_CONFIGURATION); #if ENABLED(LCD_PROGRESS_BAR_TEST) - SUBMENU(MSG_PROGRESS_BAR_TEST, _progress_bar_test); + SUBMENU(MSG_PROGRESS_BAR_TEST, _goto_progress_bar_test); #endif #if ENABLED(LCD_ENDSTOP_TEST) - SUBMENU(MSG_ENDSTOP_TEST, endstop_test); + SUBMENU(MSG_ENDSTOP_TEST, screen_endstop_test); #endif END_MENU(); diff --git a/Marlin/src/lcd/tft/ui_common.cpp b/Marlin/src/lcd/tft/ui_common.cpp index 5f426294dc..d4d398b935 100644 --- a/Marlin/src/lcd/tft/ui_common.cpp +++ b/Marlin/src/lcd/tft/ui_common.cpp @@ -339,10 +339,10 @@ void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, c } // Draw a menu item with a (potentially) editable value -void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) { +void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) { menu_item(row, sel); - tft_string.set(fstr, itemIndex, itemStringC, itemStringF); + tft_string.set(ftpl, itemIndex, itemStringC, itemStringF); tft.add_text(MENU_TEXT_X, MENU_TEXT_Y, COLOR_MENU_TEXT, tft_string); if (inStr) { tft_string.set(inStr); @@ -351,10 +351,10 @@ void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr } // Draw a static item with no left-right margin required. Centered by default. -void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { +void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) { menu_item(row); - tft_string.set(fstr, itemIndex, itemStringC, itemStringF); + tft_string.set(ftpl, itemIndex, itemStringC, itemStringF); const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL); if (!full || !vstr) {