♻️ Apply F() to more LCD code (#24228)
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							9a74bcd4cf
						
					
				
				
					commit
					28f8646aa6
				
			| @@ -45,6 +45,7 @@ typedef const char Language_Str[]; | ||||
|  | ||||
| // Set unused languages equal to each other so the | ||||
| // compiler can optimize away the conditionals. | ||||
| #define LCD_LANGUAGE_1 LCD_LANGUAGE | ||||
| #ifndef LCD_LANGUAGE_2 | ||||
|   #define LCD_LANGUAGE_2 LCD_LANGUAGE | ||||
| #endif | ||||
|   | ||||
| @@ -410,7 +410,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); } | ||||
|  | ||||
|   // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line | ||||
|   void lcd_scroll(const lcd_uint_t col, const lcd_uint_t line, FSTR_P const ftxt, const uint8_t len, const int16_t time) { | ||||
|     uint8_t slen = utf8_strlen_P(FTOP(ftxt)); | ||||
|     uint8_t slen = utf8_strlen(ftxt); | ||||
|     if (slen < len) { | ||||
|       lcd_put_u8str_max(col, line, ftxt, len); | ||||
|       for (; slen < len; ++slen) lcd_put_wchar(' '); | ||||
| @@ -437,10 +437,10 @@ void MarlinUI::clear_lcd() { lcd.clear(); } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static void logo_lines(PGM_P const extra) { | ||||
|     int16_t indent = (LCD_WIDTH - 8 - utf8_strlen_P(extra)) / 2; | ||||
|   static void logo_lines(FSTR_P const extra) { | ||||
|     int16_t indent = (LCD_WIDTH - 8 - utf8_strlen(extra)) / 2; | ||||
|     lcd_put_wchar(indent, 0, '\x00'); lcd_put_u8str(F( "------" ));  lcd_put_wchar('\x01'); | ||||
|     lcd_put_u8str(indent, 1, F("|Marlin|"));  lcd_put_u8str_P(extra); | ||||
|     lcd_put_u8str(indent, 1, F("|Marlin|")); lcd_put_u8str(extra); | ||||
|     lcd_put_wchar(indent, 2, '\x02'); lcd_put_u8str(F( "------" ));  lcd_put_wchar('\x03'); | ||||
|   } | ||||
|  | ||||
| @@ -468,7 +468,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); } | ||||
|       // | ||||
|       // Show the Marlin logo, splash line1, and splash line 2 | ||||
|       // | ||||
|       logo_lines(PSTR(" " SHORT_BUILD_VERSION)); | ||||
|       logo_lines(F(" " SHORT_BUILD_VERSION)); | ||||
|       CENTER_OR_SCROLL(MARLIN_WEBSITE_URL, 2000); | ||||
|     } | ||||
|     else { | ||||
| @@ -476,7 +476,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); } | ||||
|       // Show the Marlin logo and short build version | ||||
|       // After a delay show the website URL | ||||
|       // | ||||
|       logo_lines(NUL_STR); | ||||
|       logo_lines(FPSTR(NUL_STR)); | ||||
|       CENTER_OR_SCROLL(SHORT_BUILD_VERSION, 1500); | ||||
|       CENTER_OR_SCROLL(MARLIN_WEBSITE_URL, 1500); | ||||
|       #ifdef STRING_SPLASH_LINE3 | ||||
| @@ -1067,33 +1067,33 @@ 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, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|   void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|     int8_t n = LCD_WIDTH; | ||||
|     lcd_moveto(0, row); | ||||
|     const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, | ||||
|     const int8_t plen = fstr ? utf8_strlen(fstr) : 0, | ||||
|                  vlen = vstr ? utf8_strlen(vstr) : 0; | ||||
|     if (style & SS_CENTER) { | ||||
|       int8_t pad = (LCD_WIDTH - plen - vlen) / 2; | ||||
|       while (--pad >= 0) { lcd_put_wchar(' '); n--; } | ||||
|     } | ||||
|     if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n); | ||||
|     if (plen) n = lcd_put_u8str_ind(fstr, itemIndex, itemString, n); | ||||
|     if (vlen) n -= lcd_put_u8str_max(vstr, n); | ||||
|     for (; n > 0; --n) lcd_put_wchar(' '); | ||||
|   } | ||||
|  | ||||
|   // Draw a generic menu item with pre_char (if selected) and post_char | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) { | ||||
|     lcd_put_wchar(0, row, sel ? pre_char : ' '); | ||||
|     uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2); | ||||
|     uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2); | ||||
|     for (; n; --n) lcd_put_wchar(' '); | ||||
|     lcd_put_wchar(post_char); | ||||
|   } | ||||
|  | ||||
|   // Draw a menu item with a (potentially) editable value | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const inStr, const bool pgm) { | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) { | ||||
|     const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0; | ||||
|     lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' '); | ||||
|     uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen); | ||||
|     uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen); | ||||
|     if (vlen) { | ||||
|       lcd_put_wchar(':'); | ||||
|       for (; n; --n) lcd_put_wchar(' '); | ||||
| @@ -1102,9 +1102,9 @@ void MarlinUI::draw_status_screen() { | ||||
|   } | ||||
|  | ||||
|   // Low-level draw_edit_screen can be used to draw an edit screen from anyplace | ||||
|   void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { | ||||
|   void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) { | ||||
|     ui.encoder_direction_normal(); | ||||
|     uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, itemString, LCD_WIDTH - 1); | ||||
|     uint8_t n = lcd_put_u8str_ind(0, 1, fstr, itemIndex, itemString, LCD_WIDTH - 1); | ||||
|     if (value) { | ||||
|       lcd_put_wchar(':'); n--; | ||||
|       const uint8_t len = utf8_strlen(value) + 1;   // Plus one for a leading space | ||||
| @@ -1115,21 +1115,21 @@ void MarlinUI::draw_status_screen() { | ||||
|   } | ||||
|  | ||||
|   // The Select Screen presents a prompt and two "buttons" | ||||
|   void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { | ||||
|   void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) { | ||||
|     ui.draw_select_screen_prompt(pref, string, suff); | ||||
|     if (no) { | ||||
|       SETCURSOR(0, LCD_HEIGHT - 1); | ||||
|       lcd_put_wchar(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd_put_wchar(yesno ? ' ' : ']'); | ||||
|       lcd_put_wchar(yesno ? ' ' : '['); lcd_put_u8str(no); lcd_put_wchar(yesno ? ' ' : ']'); | ||||
|     } | ||||
|     if (yes) { | ||||
|       SETCURSOR_RJ(utf8_strlen_P(yes) + 2, LCD_HEIGHT - 1); | ||||
|       lcd_put_wchar(yesno ? '[' : ' '); lcd_put_u8str_P(yes); lcd_put_wchar(yesno ? ']' : ' '); | ||||
|       SETCURSOR_RJ(utf8_strlen(yes) + 2, LCD_HEIGHT - 1); | ||||
|       lcd_put_wchar(yesno ? '[' : ' '); lcd_put_u8str(yes); lcd_put_wchar(yesno ? ']' : ' '); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) { | ||||
|       lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' '); | ||||
|       constexpr uint8_t maxlen = LCD_WIDTH - 2; | ||||
|       uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen); | ||||
|   | ||||
| @@ -380,13 +380,10 @@ void MarlinUI::clear_lcd() { | ||||
|   void MarlinUI::_set_contrast() { lcd.setContrast(contrast); } | ||||
| #endif | ||||
|  | ||||
| static void center_text_P(PGM_P pstart, uint8_t y) { | ||||
|   uint8_t len = utf8_strlen_P(pstart); | ||||
|   if (len < LCD_WIDTH) | ||||
|     lcd.setCursor((LCD_WIDTH - len) / 2, y); | ||||
|   else | ||||
|     lcd.setCursor(0, y); | ||||
|   lcd_put_u8str_P(pstart); | ||||
| static void center_text(FSTR_P const fstart, const uint8_t y) { | ||||
|   const uint8_t len = utf8_strlen(fstart); | ||||
|   lcd.setCursor(len < LCD_WIDTH ? (LCD_WIDTH - len) / 2 : 0, y); | ||||
|   lcd_put_u8str(fstart); | ||||
| } | ||||
|  | ||||
| #if ENABLED(SHOW_BOOTSCREEN) | ||||
| @@ -402,8 +399,8 @@ static void center_text_P(PGM_P pstart, uint8_t y) { | ||||
|     lcd.setCursor(indent, 0); lcd.write(TLC); lcd_put_u8str(F("------"));  lcd.write(TRC); | ||||
|     lcd.setCursor(indent, 1); lcd.write(LR);  lcd_put_u8str(F("Marlin"));  lcd.write(LR); | ||||
|     lcd.setCursor(indent, 2); lcd.write(BLC); lcd_put_u8str(F("------"));  lcd.write(BRC); | ||||
|     center_text_P(PSTR(SHORT_BUILD_VERSION), 3); | ||||
|     center_text_P(PSTR(MARLIN_WEBSITE_URL), 4); | ||||
|     center_text(F(SHORT_BUILD_VERSION), 3); | ||||
|     center_text(F(MARLIN_WEBSITE_URL), 4); | ||||
|     picBits = ICON_LOGO; | ||||
|     lcd.print_screen(); | ||||
|   } | ||||
| @@ -420,8 +417,8 @@ void MarlinUI::draw_kill_screen() { | ||||
|   lcd.setCursor(0, 3);  lcd.write(COLOR_ERROR); | ||||
|   lcd.setCursor((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3); | ||||
|   lcd_put_u8str(status_message); | ||||
|   center_text_P(GET_TEXT(MSG_HALTED), 5); | ||||
|   center_text_P(GET_TEXT(MSG_PLEASE_RESET), 6); | ||||
|   center_text(GET_TEXT_F(MSG_HALTED), 5); | ||||
|   center_text(GET_TEXT_F(MSG_PLEASE_RESET), 6); | ||||
|   lcd.print_screen(); | ||||
| } | ||||
|  | ||||
| @@ -940,38 +937,38 @@ 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, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) { | ||||
|   void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) { | ||||
|     if (!PanelDetected) return; | ||||
|     uint8_t n = LCD_WIDTH; | ||||
|     lcd.setCursor(0, row); | ||||
|     if ((style & SS_CENTER) && !valstr) { | ||||
|       int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2; | ||||
|       int8_t pad = (LCD_WIDTH - utf8_strlen(fstr)) / 2; | ||||
|       while (--pad >= 0) { lcd.write(' '); n--; } | ||||
|     } | ||||
|     n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n); | ||||
|     n = lcd_put_u8str_ind(fstr, itemIndex, itemString, n); | ||||
|     if (valstr) n -= lcd_put_u8str_max(valstr, n); | ||||
|     for (; n; --n) lcd.write(' '); | ||||
|     lcd.print_line(); | ||||
|   } | ||||
|  | ||||
|   // Draw a generic menu item with pre_char (if selected) and post_char | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) { | ||||
|     if (!PanelDetected) return; | ||||
|     lcd.setCursor(0, row); | ||||
|     lcd.write(sel ? pre_char : ' '); | ||||
|     uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2); | ||||
|     uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2); | ||||
|     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, PGM_P const pstr, const char * const data, const bool pgm) { | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const data, const bool pgm) { | ||||
|     if (!PanelDetected) return; | ||||
|     const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0; | ||||
|     lcd.setCursor(0, row); | ||||
|     lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' '); | ||||
|     uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen); | ||||
|     uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen); | ||||
|     if (vlen) { | ||||
|       lcd.write(':'); | ||||
|       for (; n; --n) lcd.write(' '); | ||||
| @@ -982,13 +979,13 @@ void MarlinUI::draw_status_screen() { | ||||
|  | ||||
|   // Low-level draw_edit_screen can be used to draw an edit screen from anyplace | ||||
|   // This line moves to the last line of the screen for UBL plot screen on the panel side | ||||
|   void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { | ||||
|   void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) { | ||||
|     if (!PanelDetected) return; | ||||
|     ui.encoder_direction_normal(); | ||||
|     const uint8_t y = TERN0(AUTO_BED_LEVELING_UBL, ui.external_control) ? LCD_HEIGHT - 1 : MIDDLE_Y; | ||||
|     lcd.setCursor(0, y); | ||||
|     lcd.write(COLOR_EDIT); | ||||
|     lcd_put_u8str_P(pstr); | ||||
|     lcd_put_u8str(fstr); | ||||
|     if (value) { | ||||
|       lcd.write(':'); | ||||
|       lcd.setCursor((LCD_WIDTH - 1) - (utf8_strlen(value) + 1), y); // Right-justified, padded by spaces | ||||
| @@ -1000,24 +997,24 @@ void MarlinUI::draw_status_screen() { | ||||
|   } | ||||
|  | ||||
|   // The Select Screen presents a prompt and two "buttons" | ||||
|   void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string, PGM_P const suff) { | ||||
|   void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string, FSTR_P const suff) { | ||||
|     if (!PanelDetected) return; | ||||
|     ui.draw_select_screen_prompt(pref, string, suff); | ||||
|     lcd.write(COLOR_EDIT); | ||||
|     if (no) { | ||||
|       lcd.setCursor(0, MIDDLE_Y); | ||||
|       lcd.write(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd.write(yesno ? ' ' : ']'); | ||||
|       lcd.write(yesno ? ' ' : '['); lcd_put_u8str(no); lcd.write(yesno ? ' ' : ']'); | ||||
|     } | ||||
|     if (yes) { | ||||
|       lcd.setCursor(LCD_WIDTH - utf8_strlen_P(yes) - 3, MIDDLE_Y); | ||||
|       lcd.write(yesno ? '[' : ' '); lcd_put_u8str_P(yes); lcd.write(yesno ? ']' : ' '); | ||||
|       lcd.setCursor(LCD_WIDTH - utf8_strlen(yes) - 3, MIDDLE_Y); | ||||
|       lcd.write(yesno ? '[' : ' '); lcd_put_u8str(yes); lcd.write(yesno ? ']' : ' '); | ||||
|     } | ||||
|     lcd.print_line(); | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) { | ||||
|       if (!PanelDetected) return; | ||||
|       lcd.setCursor(0, row); | ||||
|       lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' '); | ||||
| @@ -1081,7 +1078,7 @@ void MarlinUI::draw_status_screen() { | ||||
|       else | ||||
|         lcd_put_u8str(F(" -----")); | ||||
|  | ||||
|       center_text_P(GET_TEXT(MSG_UBL_FINE_TUNE_MESH), 8); | ||||
|       center_text(GET_TEXT_F(MSG_UBL_FINE_TUNE_MESH), 8); | ||||
|  | ||||
|       lcd.print_screen(); | ||||
|     } | ||||
|   | ||||
| @@ -412,28 +412,28 @@ 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, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|   void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|  | ||||
|     if (mark_as_selected(row, style & SS_INVERT)) { | ||||
|       pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed | ||||
|  | ||||
|       const int plen = pstr ? calculateWidth(pstr) : 0, | ||||
|       const int plen = fstr ? calculateWidth(FTOP(fstr)) : 0, | ||||
|                 vlen = vstr ? utf8_strlen(vstr) : 0; | ||||
|       if (style & SS_CENTER) { | ||||
|         int pad = (LCD_PIXEL_WIDTH - plen - vlen * MENU_FONT_WIDTH) / MENU_FONT_WIDTH / 2; | ||||
|         while (--pad >= 0) n -= lcd_put_wchar(' '); | ||||
|       } | ||||
|  | ||||
|       if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH); | ||||
|       if (plen) n = lcd_put_u8str_ind(fstr, itemIndex, itemString, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH); | ||||
|       if (vlen) n -= lcd_put_u8str_max(vstr, n); | ||||
|       while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Draw a generic menu item | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) { | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char, const char post_char) { | ||||
|     if (mark_as_selected(row, sel)) { | ||||
|       pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 1) * (MENU_FONT_WIDTH); | ||||
|       pixel_len_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 1) * (MENU_FONT_WIDTH); | ||||
|       while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); | ||||
|       lcd_put_wchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char); | ||||
|       lcd_put_wchar(' '); | ||||
| @@ -441,13 +441,13 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|   } | ||||
|  | ||||
|   // Draw a menu item with an editable value | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const inStr, const bool pgm) { | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) { | ||||
|     if (mark_as_selected(row, sel)) { | ||||
|       const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen((char*)inStr)), | ||||
|                     pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), (char*)inStr)); | ||||
|       const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; | ||||
|  | ||||
|       pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH); | ||||
|       pixel_len_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH); | ||||
|       if (vallen) { | ||||
|         lcd_put_wchar(':'); | ||||
|         while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); | ||||
| @@ -457,11 +457,11 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { | ||||
|   void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) { | ||||
|     ui.encoder_direction_normal(); | ||||
|  | ||||
|     const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; | ||||
|     const u8g_uint_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value); | ||||
|     const u8g_uint_t labellen = utf8_strlen(fstr), vallen = utf8_strlen(value); | ||||
|     bool extra_row = labellen * prop > LCD_WIDTH - 2 - vallen * prop; | ||||
|  | ||||
|     #if ENABLED(USE_BIG_EDIT_FONT) | ||||
| @@ -490,7 +490,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|  | ||||
|     // Assume the label is alpha-numeric (with a descender) | ||||
|     bool onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline + EDIT_FONT_DESCENT); | ||||
|     if (onpage) lcd_put_u8str_ind_P(0, baseline, pstr, itemIndex, itemString); | ||||
|     if (onpage) lcd_put_u8str_ind(0, baseline, fstr, itemIndex, itemString); | ||||
|  | ||||
|     // If a value is included, print a colon, then print the value right-justified | ||||
|     if (value) { | ||||
| @@ -508,8 +508,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|     TERN_(USE_BIG_EDIT_FONT, ui.set_font(FONT_MENU)); | ||||
|   } | ||||
|  | ||||
|   inline void draw_boxed_string(const u8g_uint_t x, const u8g_uint_t y, PGM_P const pstr, const bool inv) { | ||||
|     const u8g_uint_t len = utf8_strlen_P(pstr), | ||||
|   inline void draw_boxed_string(const u8g_uint_t x, const u8g_uint_t y, FSTR_P const fstr, const bool inv) { | ||||
|     const u8g_uint_t len = utf8_strlen(fstr), | ||||
|                       by = (y + 1) * (MENU_FONT_HEIGHT); | ||||
|     const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1; | ||||
|     const pixel_len_t bw = len * prop * (MENU_FONT_WIDTH), bx = x * prop * (MENU_FONT_WIDTH); | ||||
| @@ -518,19 +518,19 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|       u8g.drawBox(bx / prop - 1, by - (MENU_FONT_ASCENT), bw + 2, MENU_FONT_HEIGHT); | ||||
|       u8g.setColorIndex(0); | ||||
|     } | ||||
|     lcd_put_u8str_P(bx / prop, by, pstr); | ||||
|     lcd_put_u8str(bx / prop, by, fstr); | ||||
|     if (inv) u8g.setColorIndex(1); | ||||
|   } | ||||
|  | ||||
|   void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { | ||||
|   void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) { | ||||
|     ui.draw_select_screen_prompt(pref, string, suff); | ||||
|     if (no)  draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno); | ||||
|     if (yes) draw_boxed_string(LCD_WIDTH - (utf8_strlen_P(yes) * (USE_WIDE_GLYPH ? 2 : 1) + 1), LCD_HEIGHT - 1, yes, yesno); | ||||
|     if (yes) draw_boxed_string(LCD_WIDTH - (utf8_strlen(yes) * (USE_WIDE_GLYPH ? 2 : 1) + 1), LCD_HEIGHT - 1, yes, yesno); | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { | ||||
|     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_wchar(LCD_STR_FOLDER[0]); | ||||
|   | ||||
| @@ -517,14 +517,14 @@ U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT, | ||||
|       drawCross(x, y, TFT_MARLINBG_COLOR); | ||||
|     } | ||||
|  | ||||
|     const char *str = nullptr; | ||||
|     FSTR_P str = nullptr; | ||||
|     if (calibration_stage < CALIBRATION_SUCCESS) { | ||||
|       // handle current state | ||||
|       switch (calibration_stage) { | ||||
|         case CALIBRATION_TOP_LEFT: str = GET_TEXT(MSG_TOP_LEFT); break; | ||||
|         case CALIBRATION_BOTTOM_LEFT: str = GET_TEXT(MSG_BOTTOM_LEFT); break; | ||||
|         case CALIBRATION_TOP_RIGHT:  str = GET_TEXT(MSG_TOP_RIGHT); break; | ||||
|         case CALIBRATION_BOTTOM_RIGHT: str = GET_TEXT(MSG_BOTTOM_RIGHT); break; | ||||
|         case CALIBRATION_TOP_LEFT: str = GET_TEXT_F(MSG_TOP_LEFT); break; | ||||
|         case CALIBRATION_BOTTOM_LEFT: str = GET_TEXT_F(MSG_BOTTOM_LEFT); break; | ||||
|         case CALIBRATION_TOP_RIGHT:  str = GET_TEXT_F(MSG_TOP_RIGHT); break; | ||||
|         case CALIBRATION_BOTTOM_RIGHT: str = GET_TEXT_F(MSG_BOTTOM_RIGHT); break; | ||||
|         default: break; | ||||
|       } | ||||
|  | ||||
| @@ -534,7 +534,7 @@ U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT, | ||||
|     } | ||||
|     else { | ||||
|       // end calibration | ||||
|       str = calibration_stage == CALIBRATION_SUCCESS ? GET_TEXT(MSG_CALIBRATION_COMPLETED) : GET_TEXT(MSG_CALIBRATION_FAILED); | ||||
|       str = calibration_stage == CALIBRATION_SUCCESS ? GET_TEXT_F(MSG_CALIBRATION_COMPLETED) : GET_TEXT_F(MSG_CALIBRATION_FAILED); | ||||
|       defer_status_screen(false); | ||||
|       touch_calibration.calibration_end(); | ||||
|       TERN_(HAS_TOUCH_BUTTONS, redrawTouchButtons = true); | ||||
|   | ||||
| @@ -74,7 +74,7 @@ inline void DWIN_Text(size_t &i, const char * const string, uint16_t rlimit=0xFF | ||||
|  | ||||
| inline void DWIN_Text(size_t &i, FSTR_P string, uint16_t rlimit=0xFFFF) { | ||||
|   if (!string) return; | ||||
|   const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, _MIN(rlimit, strlen_P((PGM_P)string))); // cast to PGM_P (const char*) measure with strlen_P. | ||||
|   const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, _MIN(rlimit, strlen_P(FTOP(string)))); | ||||
|   if (len == 0) return; | ||||
|   memcpy_P(&DWIN_SendBuf[i+1], string, len); | ||||
|   i += len; | ||||
|   | ||||
| @@ -2944,7 +2944,7 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/ | ||||
|             break; | ||||
|           case LEVELING_VIEW: | ||||
|             if (draw) | ||||
|               Draw_Menu_Item(row, ICON_Mesh, GET_TEXT(MSG_MESH_VIEW), nullptr, true); | ||||
|               Draw_Menu_Item(row, ICON_Mesh, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true); | ||||
|             else { | ||||
|               #if ENABLED(AUTO_BED_LEVELING_UBL) | ||||
|                 if (bedlevel.storage_slot < 0) { | ||||
| @@ -3017,7 +3017,7 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/ | ||||
|             break; | ||||
|           case LEVELING_VIEW_MESH: | ||||
|             if (draw) | ||||
|               Draw_Menu_Item(row, ICON_PrintSize, GET_TEXT(MSG_MESH_VIEW), nullptr, true); | ||||
|               Draw_Menu_Item(row, ICON_PrintSize, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true); | ||||
|             else | ||||
|               Draw_Menu(MeshViewer); | ||||
|             break; | ||||
|   | ||||
| @@ -43,13 +43,13 @@ uint8_t read_byte(uint8_t *byte) { return *byte; } | ||||
| /** | ||||
|  * Add a string, applying substitutions for the following characters: | ||||
|  * | ||||
|  *   $ displays the clipped C-string given by the itemString argument | ||||
|  *   $ displays the clipped C-string given by the inStr argument | ||||
|  *   = 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 | ||||
|  */ | ||||
| void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *itemString/*=nullptr*/) { | ||||
| void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *inStr/*=nullptr*/) { | ||||
|   wchar_t wchar; | ||||
|  | ||||
|   while (*string) { | ||||
| @@ -67,8 +67,8 @@ void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *itemString/* | ||||
|       else | ||||
|         add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED)); | ||||
|     } | ||||
|     else if (ch == '$' && itemString) | ||||
|       add(itemString); | ||||
|     else if (ch == '$' && inStr) | ||||
|       add(inStr); | ||||
|     else if (ch == '@') | ||||
|       add_character(axis_codes[index]); | ||||
|     else | ||||
|   | ||||
| @@ -61,15 +61,20 @@ class DWIN_String { | ||||
|     //static void add(uint8_t character) { add_character(character); eol(); } | ||||
|     static void add(wchar_t character); | ||||
|     static void add(uint8_t *string, uint8_t max_len=MAX_STRING_LENGTH); | ||||
|     static void add(uint8_t *string, const int8_t index, uint8_t *itemString=nullptr); | ||||
|     static void add(uint8_t *string, const int8_t index, uint8_t *inStr=nullptr); | ||||
|     static void set(uint8_t *string)   { set(); add(string); } | ||||
|     static void set(wchar_t character) { set(); add(character); } | ||||
|     static void set(uint8_t *string, int8_t index, const char *itemString=nullptr) { set(); add(string, index, (uint8_t *)itemString); } | ||||
|     static void set(FSTR_P fstring) { set((uint8_t *)fstring); } | ||||
|     static void set(uint8_t *string, int8_t index, const char *inStr=nullptr) { set(); add(string, index, (uint8_t *)inStr); } | ||||
|     static void set(const char *string) { set((uint8_t *)string); } | ||||
|     static void set(const char *string, int8_t index, const char *itemString=nullptr) { set((uint8_t *)string, index, itemString); } | ||||
|     static void set(const char *string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)string, index, inStr); } | ||||
|     static void add(const char *string) { add((uint8_t *)string); } | ||||
|  | ||||
|     static void add(FSTR_P const string, uint8_t max_len=MAX_STRING_LENGTH) { add((uint8_t *)FTOP(string), max_len); } | ||||
|     static void add(FSTR_P const string, int8_t index, uint8_t *inStr=nullptr) { add((uint8_t *)FTOP(string), index, inStr); } | ||||
|     static void set(FSTR_P const string) { set((uint8_t *)FTOP(string)); } | ||||
|     static void set(FSTR_P const string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)FTOP(string), index, inStr); } | ||||
|     static void add(FSTR_P const string) { add((uint8_t *)FTOP(string)); } | ||||
|  | ||||
|     static void trim(const uint8_t character=0x20); | ||||
|     static void rtrim(const uint8_t character=0x20); | ||||
|     static void ltrim(const uint8_t character=0x20); | ||||
|   | ||||
| @@ -311,7 +311,7 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|  | ||||
|   // Draw a static line of text in the same idiom as a menu item | ||||
|  | ||||
|   void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|   void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const 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)) { | ||||
| @@ -320,14 +320,14 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|       dwin_font.fg = Color_White; | ||||
|  | ||||
|       dwin_string.set(); | ||||
|       const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, | ||||
|       const int8_t plen = fstr ? utf8_strlen(fstr) : 0, | ||||
|                    vlen = vstr ? utf8_strlen(vstr) : 0; | ||||
|       if (style & SS_CENTER) { | ||||
|         int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2; | ||||
|         while (--pad) dwin_string.add(' '); | ||||
|       } | ||||
|  | ||||
|       if (plen) dwin_string.add((uint8_t*)pstr, itemIndex, (uint8_t*)itemString); | ||||
|       if (plen) dwin_string.add((uint8_t*)FTOP(fstr), itemIndex, (uint8_t*)FTOP(itemString)); | ||||
|       if (vlen) dwin_string.add((uint8_t*)vstr); | ||||
|       if (style & SS_CENTER) { | ||||
|         int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2; | ||||
| @@ -340,13 +340,13 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|   } | ||||
|  | ||||
|   // Draw a generic menu item | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) { | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, 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; | ||||
|  | ||||
|       dwin_string.set(pstr, itemIndex, itemString); | ||||
|       dwin_string.set(fstr, itemIndex, FTOP(itemString)); | ||||
|  | ||||
|       pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length(); | ||||
|       while (--n > 1) dwin_string.add(' '); | ||||
| @@ -361,15 +361,15 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|   // | ||||
|   // Draw a menu item with an editable value | ||||
|   // | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, 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; | ||||
|  | ||||
|       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen(S(data))); | ||||
|       const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(S(inStr))); | ||||
|  | ||||
|       dwin_string.set(pstr, itemIndex, itemString); | ||||
|       dwin_string.set(fstr, itemIndex, FTOP(itemString)); | ||||
|       if (vallen) dwin_string.add(':'); | ||||
|  | ||||
|       lcd_moveto(1, row); | ||||
| @@ -377,7 +377,7 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|  | ||||
|       if (vallen) { | ||||
|         dwin_font.fg = Color_Yellow; | ||||
|         dwin_string.set(data); | ||||
|         dwin_string.set(inStr); | ||||
|         lcd_moveto(LCD_WIDTH - vallen - 1, row); | ||||
|         lcd_put_dwin_string(); | ||||
|       } | ||||
| @@ -387,13 +387,13 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|   // | ||||
|   // Draw an edit screen with label and current value | ||||
|   // | ||||
|   void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { | ||||
|   void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char* const value/*=nullptr*/) { | ||||
|     ui.encoder_direction_normal(); | ||||
|  | ||||
|     const dwin_coord_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value); | ||||
|     const dwin_coord_t labellen = utf8_strlen(fstr), vallen = utf8_strlen(value); | ||||
|  | ||||
|     dwin_string.set(); | ||||
|     dwin_string.add((uint8_t*)pstr, itemIndex); | ||||
|     dwin_string.add((uint8_t*)FTOP(fstr), itemIndex); | ||||
|     if (vallen) dwin_string.add(':');  // If a value is included, add a colon | ||||
|  | ||||
|     // Assume the label is alpha-numeric (with a descender) | ||||
| @@ -430,19 +430,19 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   inline void draw_boxed_string(const bool yesopt, PGM_P const pstr, const bool inv) { | ||||
|     const uint8_t len = utf8_strlen_P(pstr), | ||||
|   inline void draw_boxed_string(const bool yesopt, FSTR_P const fstr, const bool inv) { | ||||
|     const uint8_t len = utf8_strlen(fstr), | ||||
|                   mar = TERN(DWIN_MARLINUI_PORTRAIT, 1, 4), | ||||
|                   col = yesopt ? LCD_WIDTH - mar - len : mar, | ||||
|                   row = (LCD_HEIGHT >= 8 ? LCD_HEIGHT / 2 + 3 : LCD_HEIGHT - 1); | ||||
|     lcd_moveto(col, row); | ||||
|     DWIN_Draw_Box(1, inv ? Select_Color : Color_Bg_Black, cursor.x - dwin_font.width, cursor.y + 1, dwin_font.width * (len + 2), dwin_font.height + 2); | ||||
|     lcd_put_u8str_P(col, row, pstr); | ||||
|     lcd_put_u8str(col, row, fstr); | ||||
|   } | ||||
|  | ||||
|   void MenuItem_confirm::draw_select_screen( | ||||
|     PGM_P const yes, PGM_P const no, const bool yesno, | ||||
|     PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/ | ||||
|     FSTR_P const yes, FSTR_P const no, const bool yesno, | ||||
|     FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/ | ||||
|   ) { | ||||
|     ui.set_font(DWIN_FONT_MENU); | ||||
|     dwin_font.solid = false; | ||||
| @@ -454,7 +454,7 @@ void MarlinUI::draw_status_message(const bool blink) { | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { | ||||
|     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(); | ||||
|  | ||||
|   | ||||
| @@ -140,12 +140,12 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; | ||||
|  | ||||
|   preheat_t MarlinUI::material_preset[PREHEAT_COUNT];  // Initialized by settings.load() | ||||
|  | ||||
|   PGM_P MarlinUI::get_preheat_label(const uint8_t m) { | ||||
|   FSTR_P MarlinUI::get_preheat_label(const uint8_t m) { | ||||
|     #define _PDEF(N) static PGMSTR(preheat_##N##_label, PREHEAT_##N##_LABEL); | ||||
|     #define _PLBL(N) preheat_##N##_label, | ||||
|     REPEAT_1(PREHEAT_COUNT, _PDEF); | ||||
|     static PGM_P const preheat_labels[PREHEAT_COUNT] PROGMEM = { REPEAT_1(PREHEAT_COUNT, _PLBL) }; | ||||
|     return (PGM_P)pgm_read_ptr(&preheat_labels[m]); | ||||
|     return FPSTR((PGM_P)pgm_read_ptr(&preheat_labels[m])); | ||||
|   } | ||||
|  | ||||
|   void MarlinUI::apply_preheat(const uint8_t m, const uint8_t pmask, const uint8_t e/*=active_extruder*/) { | ||||
| @@ -454,20 +454,20 @@ void MarlinUI::init() { | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       void MarlinUI::draw_select_screen_prompt(PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { | ||||
|         const uint8_t plen = utf8_strlen_P(pref), slen = suff ? utf8_strlen_P(suff) : 0; | ||||
|       void MarlinUI::draw_select_screen_prompt(FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) { | ||||
|         const uint8_t plen = utf8_strlen(pref), slen = suff ? utf8_strlen(suff) : 0; | ||||
|         uint8_t col = 0, row = 0; | ||||
|         if (!string && plen + slen <= LCD_WIDTH) { | ||||
|           col = (LCD_WIDTH - plen - slen) / 2; | ||||
|           row = LCD_HEIGHT > 3 ? 1 : 0; | ||||
|         } | ||||
|         if (LCD_HEIGHT >= 8) row = LCD_HEIGHT / 2 - 2; | ||||
|         wrap_string_P(col, row, pref, true); | ||||
|         wrap_string_P(col, row, FTOP(pref), true); | ||||
|         if (string) { | ||||
|           if (col) { col = 0; row++; } // Move to the start of the next line | ||||
|           wrap_string(col, row, string); | ||||
|         } | ||||
|         if (suff) wrap_string_P(col, row, suff); | ||||
|         if (suff) wrap_string_P(col, row, FTOP(suff)); | ||||
|       } | ||||
|  | ||||
|     #endif // !HAS_GRAPHICAL_TFT | ||||
| @@ -484,17 +484,17 @@ void MarlinUI::init() { | ||||
|  | ||||
|     #if HAS_MARLINUI_MENU && !HAS_ADC_BUTTONS | ||||
|  | ||||
|       void lcd_move_x(); | ||||
|       void lcd_move_y(); | ||||
|       void lcd_move_z(); | ||||
|  | ||||
|       void _reprapworld_keypad_move(const AxisEnum axis, const int16_t dir) { | ||||
|         ui.manual_move.menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; | ||||
|         ui.encoderPosition = dir; | ||||
|         switch (axis) { | ||||
|           case X_AXIS: lcd_move_x(); break; | ||||
|           case Y_AXIS: lcd_move_y(); break; | ||||
|           case Z_AXIS: lcd_move_z(); | ||||
|           case X_AXIS: { void lcd_move_x(); lcd_move_x(); } break; | ||||
|           #if HAS_Y_AXIS | ||||
|             case Y_AXIS: { void lcd_move_y(); lcd_move_y(); } break; | ||||
|           #endif | ||||
|           #if HAS_Z_AXIS | ||||
|             case Z_AXIS: { void lcd_move_z(); lcd_move_z(); } break; | ||||
|           #endif | ||||
|           default: break; | ||||
|         } | ||||
|       } | ||||
| @@ -1651,7 +1651,7 @@ void MarlinUI::init() { | ||||
|  | ||||
|   void MarlinUI::pause_print() { | ||||
|     #if HAS_MARLINUI_MENU | ||||
|       synchronize(GET_TEXT(MSG_PAUSING)); | ||||
|       synchronize(GET_TEXT_F(MSG_PAUSING)); | ||||
|       defer_status_screen(); | ||||
|     #endif | ||||
|  | ||||
| @@ -1855,12 +1855,12 @@ void MarlinUI::init() { | ||||
|  | ||||
|   #if DISABLED(EEPROM_AUTO_INIT) | ||||
|  | ||||
|     static inline PGM_P eeprom_err(const uint8_t msgid) { | ||||
|     static inline FSTR_P eeprom_err(const uint8_t msgid) { | ||||
|       switch (msgid) { | ||||
|         default: | ||||
|         case 0: return GET_TEXT(MSG_ERR_EEPROM_CRC); | ||||
|         case 1: return GET_TEXT(MSG_ERR_EEPROM_INDEX); | ||||
|         case 2: return GET_TEXT(MSG_ERR_EEPROM_VERSION); | ||||
|         case 0: return GET_TEXT_F(MSG_ERR_EEPROM_CRC); | ||||
|         case 1: return GET_TEXT_F(MSG_ERR_EEPROM_INDEX); | ||||
|         case 2: return GET_TEXT_F(MSG_ERR_EEPROM_VERSION); | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @@ -1868,17 +1868,17 @@ void MarlinUI::init() { | ||||
|       #if HAS_MARLINUI_MENU | ||||
|         editable.uint8 = msgid; | ||||
|         goto_screen([]{ | ||||
|           PGM_P const restore_msg = GET_TEXT(MSG_INIT_EEPROM); | ||||
|           char msg[utf8_strlen_P(restore_msg) + 1]; | ||||
|           strcpy_P(msg, restore_msg); | ||||
|           FSTR_P const restore_msg = GET_TEXT_F(MSG_INIT_EEPROM); | ||||
|           char msg[utf8_strlen(restore_msg) + 1]; | ||||
|           strcpy_P(msg, FTOP(restore_msg)); | ||||
|           MenuItem_confirm::select_screen( | ||||
|             GET_TEXT(MSG_BUTTON_RESET), GET_TEXT(MSG_BUTTON_IGNORE), | ||||
|             GET_TEXT_F(MSG_BUTTON_RESET), GET_TEXT_F(MSG_BUTTON_IGNORE), | ||||
|             init_eeprom, return_to_status, | ||||
|             eeprom_err(editable.uint8), msg, PSTR("?") | ||||
|             eeprom_err(editable.uint8), msg, F("?") | ||||
|           ); | ||||
|         }); | ||||
|       #else | ||||
|         set_status(FPSTR(eeprom_err(msgid))); | ||||
|         set_status(eeprom_err(msgid)); | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -520,7 +520,7 @@ public: | ||||
|   #if HAS_PREHEAT | ||||
|     enum PreheatTarget : uint8_t { PT_HOTEND, PT_BED, PT_FAN, PT_CHAMBER, PT_ALL = 0xFF }; | ||||
|     static preheat_t material_preset[PREHEAT_COUNT]; | ||||
|     static PGM_P get_preheat_label(const uint8_t m); | ||||
|     static FSTR_P get_preheat_label(const uint8_t m); | ||||
|     static void apply_preheat(const uint8_t m, const uint8_t pmask, const uint8_t e=active_extruder); | ||||
|     static void preheat_set_fan(const uint8_t m) { TERN_(HAS_FAN, apply_preheat(m, _BV(PT_FAN))); } | ||||
|     static void preheat_hotend(const uint8_t m, const uint8_t e=active_extruder) { TERN_(HAS_HOTEND, apply_preheat(m, _BV(PT_HOTEND))); } | ||||
| @@ -559,7 +559,7 @@ public: | ||||
|     static void set_selection(const bool sel) { selection = sel; } | ||||
|     static bool update_selection(); | ||||
|  | ||||
|     static void synchronize(PGM_P const msg=nullptr); | ||||
|     static void synchronize(FSTR_P const msg=nullptr); | ||||
|  | ||||
|     static screenFunc_t currentScreen; | ||||
|     static bool screen_changed; | ||||
| @@ -605,7 +605,7 @@ public: | ||||
|       static float ubl_mesh_value(); | ||||
|     #endif | ||||
|  | ||||
|     static void draw_select_screen_prompt(PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr); | ||||
|     static void draw_select_screen_prompt(FSTR_P const pref, const char * const string=nullptr, FSTR_P const suff=nullptr); | ||||
|  | ||||
|   #else | ||||
|  | ||||
|   | ||||
| @@ -69,11 +69,11 @@ menuPosition screen_history[6]; | ||||
| uint8_t screen_history_depth = 0; | ||||
|  | ||||
| int8_t MenuItemBase::itemIndex;   // Index number for draw and action | ||||
| PGM_P MenuItemBase::itemString;   // A PSTR for substitution | ||||
| FSTR_P MenuItemBase::itemString;  // A string for substitution | ||||
| chimera_t editable;               // Value Editing | ||||
|  | ||||
| // Menu Edit Items | ||||
| PGM_P        MenuEditItemBase::editLabel; | ||||
| FSTR_P       MenuEditItemBase::editLabel; | ||||
| void*        MenuEditItemBase::editValue; | ||||
| int32_t      MenuEditItemBase::minEditValue, | ||||
|              MenuEditItemBase::maxEditValue; | ||||
| @@ -134,7 +134,7 @@ void MenuEditItemBase::edit_screen(strfunc_t strfunc, loadfunc_t loadfunc) { | ||||
|  | ||||
| // Going to an edit screen sets up some persistent values first | ||||
| void MenuEditItemBase::goto_edit_screen( | ||||
|   PGM_P const el,         // Edit label | ||||
|   FSTR_P const el,        // Edit label | ||||
|   void * const ev,        // Edit value pointer | ||||
|   const int32_t minv,     // Encoder minimum | ||||
|   const int32_t maxv,     // Encoder maximum | ||||
| @@ -232,8 +232,8 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co | ||||
| // Display a "synchronize" screen with a custom message until | ||||
| // all moves are finished. Go back to calling screen when done. | ||||
| // | ||||
| void MarlinUI::synchronize(PGM_P const msg/*=nullptr*/) { | ||||
|   static PGM_P sync_message = msg ?: GET_TEXT(MSG_MOVING); | ||||
| void MarlinUI::synchronize(FSTR_P const fmsg/*=nullptr*/) { | ||||
|   static FSTR_P sync_message = fmsg ?: GET_TEXT_F(MSG_MOVING); | ||||
|   push_current_screen(); | ||||
|   goto_screen([]{ | ||||
|     if (should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, sync_message); | ||||
| @@ -319,12 +319,12 @@ void scroll_screen(const uint8_t limit, const bool is_menu) { | ||||
|     } | ||||
|     if (ui.should_draw()) { | ||||
|       if (do_probe) { | ||||
|         MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_ZPROBE_ZOFFSET), BABYSTEP_TO_STR(probe.offset.z)); | ||||
|         MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_ZPROBE_ZOFFSET), BABYSTEP_TO_STR(probe.offset.z)); | ||||
|         TERN_(BABYSTEP_ZPROBE_GFX_OVERLAY, ui.zoffset_overlay(probe.offset.z)); | ||||
|       } | ||||
|       else { | ||||
|         #if ENABLED(BABYSTEP_HOTEND_Z_OFFSET) | ||||
|           MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_HOTEND_OFFSET_Z), ftostr54sign(hotend_offset[active_extruder].z)); | ||||
|           MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_HOTEND_OFFSET_Z), ftostr54sign(hotend_offset[active_extruder].z)); | ||||
|         #endif | ||||
|       } | ||||
|     } | ||||
| @@ -335,7 +335,7 @@ void scroll_screen(const uint8_t limit, const bool is_menu) { | ||||
| void _lcd_draw_homing() { | ||||
|   if (ui.should_draw()) { | ||||
|     constexpr uint8_t line = (LCD_HEIGHT - 1) / 2; | ||||
|     MenuItem_static::draw(line, GET_TEXT(MSG_LEVEL_BED_HOMING)); | ||||
|     MenuItem_static::draw(line, GET_TEXT_F(MSG_LEVEL_BED_HOMING)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -357,9 +357,9 @@ bool MarlinUI::update_selection() { | ||||
| } | ||||
|  | ||||
| void MenuItem_confirm::select_screen( | ||||
|   PGM_P const yes, PGM_P const no, | ||||
|   FSTR_P const yes, FSTR_P const no, | ||||
|   selectFunc_t yesFunc, selectFunc_t noFunc, | ||||
|   PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/ | ||||
|   FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/ | ||||
| ) { | ||||
|   ui.defer_status_screen(); | ||||
|   const bool ui_selection = !yes ? false : !no || ui.update_selection(), | ||||
|   | ||||
| @@ -54,72 +54,72 @@ class MenuItemBase { | ||||
|     static int8_t itemIndex; | ||||
|  | ||||
|     // An optional pointer for use in display or by the action | ||||
|     static PGM_P itemString; | ||||
|     static FSTR_P itemString; | ||||
|  | ||||
|     // Store the index of the item ahead of use by indexed items | ||||
|     FORCE_INLINE static void init(const int8_t ind=0, PGM_P const pstr=nullptr) { itemIndex = ind; itemString = pstr; } | ||||
|     FORCE_INLINE static void init(const int8_t ind=0, FSTR_P const fstr=nullptr) { itemIndex = ind; itemString = fstr; } | ||||
|  | ||||
|     // Implementation-specific: | ||||
|     // Draw an item either selected (pre_char) or not (space) with post_char | ||||
|     // Menus may set up itemIndex, itemString and pass them to string-building or string-emitting functions | ||||
|     static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char); | ||||
|     static void _draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char); | ||||
|  | ||||
|     // Draw an item either selected ('>') or not (space) with post_char | ||||
|     FORCE_INLINE static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char post_char) { | ||||
|       _draw(sel, row, pstr, '>', post_char); | ||||
|     FORCE_INLINE static void _draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char post_char) { | ||||
|       _draw(sel, row, fstr, '>', post_char); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // STATIC_ITEM(LABEL,...) | ||||
| class MenuItem_static : public MenuItemBase { | ||||
|   public: | ||||
|     static void draw(const uint8_t row, PGM_P const pstr, const uint8_t style=SS_DEFAULT, const char * const vstr=nullptr); | ||||
|     static void draw(const uint8_t row, FSTR_P const fstr, const uint8_t style=SS_DEFAULT, const char * const vstr=nullptr); | ||||
| }; | ||||
|  | ||||
| // BACK_ITEM(LABEL) | ||||
| class MenuItem_back : public MenuItemBase { | ||||
|   public: | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr) { | ||||
|       _draw(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr) { | ||||
|       _draw(sel, row, fstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]); | ||||
|     } | ||||
|     // Back Item action goes back one step in history | ||||
|     FORCE_INLINE static void action(PGM_P const=nullptr) { ui.go_back(); } | ||||
|     FORCE_INLINE static void action(FSTR_P const=nullptr) { ui.go_back(); } | ||||
| }; | ||||
|  | ||||
| // CONFIRM_ITEM(LABEL,Y,N,FY,FN,...), | ||||
| // YESNO_ITEM(LABEL,FY,FN,...) | ||||
| class MenuItem_confirm : public MenuItemBase { | ||||
|   public: | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { | ||||
|       _draw(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, ...) { | ||||
|       _draw(sel, row, fstr, '>', LCD_STR_ARROW_RIGHT[0]); | ||||
|     } | ||||
|     // Implemented for HD44780 and DOGM | ||||
|     // Draw the prompt, buttons, and state | ||||
|     static void draw_select_screen( | ||||
|       PGM_P const yes,            // Right option label | ||||
|       PGM_P const no,             // Left option label | ||||
|       FSTR_P const yes,           // Right option label | ||||
|       FSTR_P const no,            // Left option label | ||||
|       const bool yesno,           // Is "yes" selected? | ||||
|       PGM_P const pref,           // Prompt prefix | ||||
|       FSTR_P const pref,          // Prompt prefix | ||||
|       const char * const string,  // Prompt runtime string | ||||
|       PGM_P const suff            // Prompt suffix | ||||
|       FSTR_P const suff           // Prompt suffix | ||||
|     ); | ||||
|     static void select_screen( | ||||
|       PGM_P const yes, PGM_P const no, | ||||
|       FSTR_P const yes, FSTR_P const no, | ||||
|       selectFunc_t yesFunc, selectFunc_t noFunc, | ||||
|       PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr | ||||
|       FSTR_P const pref, const char * const string=nullptr, FSTR_P const suff=nullptr | ||||
|     ); | ||||
|     static void select_screen( | ||||
|       PGM_P const yes, PGM_P const no, | ||||
|       FSTR_P const yes, FSTR_P const no, | ||||
|       selectFunc_t yesFunc, selectFunc_t noFunc, | ||||
|       PGM_P const pref, FSTR_P const string, PGM_P const suff=nullptr | ||||
|       FSTR_P const pref, FSTR_P const string, FSTR_P const suff=nullptr | ||||
|     ) { | ||||
|       char str[strlen_P(FTOP(string)) + 1]; | ||||
|       strcpy_P(str, FTOP(string)); | ||||
|       select_screen(yes, no, yesFunc, noFunc, pref, str, suff); | ||||
|     } | ||||
|     // Shortcut for prompt with "NO"/ "YES" labels | ||||
|     FORCE_INLINE static void confirm_screen(selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr) { | ||||
|       select_screen(GET_TEXT(MSG_YES), GET_TEXT(MSG_NO), yesFunc, noFunc, pref, string, suff); | ||||
|     FORCE_INLINE static void confirm_screen(selectFunc_t yesFunc, selectFunc_t noFunc, FSTR_P const pref, const char * const string=nullptr, FSTR_P const suff=nullptr) { | ||||
|       select_screen(GET_TEXT_F(MSG_YES), GET_TEXT_F(MSG_NO), yesFunc, noFunc, pref, string, suff); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @@ -148,7 +148,7 @@ class MenuEditItemBase : public MenuItemBase { | ||||
|     // The action() method acts like the instantiator. The entire lifespan | ||||
|     // of a menu item is within its declaration, so all these values decompose | ||||
|     // into behavior and unused items get optimized out. | ||||
|     static PGM_P editLabel; | ||||
|     static FSTR_P editLabel; | ||||
|     static void *editValue; | ||||
|     static int32_t minEditValue, maxEditValue;  // Encoder value range | ||||
|     static screenFunc_t callbackFunc; | ||||
| @@ -157,7 +157,7 @@ class MenuEditItemBase : public MenuItemBase { | ||||
|     typedef const char* (*strfunc_t)(const int32_t); | ||||
|     typedef void (*loadfunc_t)(void *, const int32_t); | ||||
|     static void goto_edit_screen( | ||||
|       PGM_P const el,         // Edit label | ||||
|       FSTR_P const el,        // Edit label | ||||
|       void * const ev,        // Edit value pointer | ||||
|       const int32_t minv,     // Encoder minimum | ||||
|       const int32_t maxv,     // Encoder maximum | ||||
| @@ -170,11 +170,15 @@ class MenuEditItemBase : public MenuItemBase { | ||||
|   public: | ||||
|     // Implementation-specific: | ||||
|     // Draw the current item at specified row with edit data | ||||
|     static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const inStr, const bool pgm=false); | ||||
|     static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm=false); | ||||
|  | ||||
|     static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, FSTR_P const inStr) { | ||||
|       draw(sel, row, fstr, FTOP(inStr), true); | ||||
|     } | ||||
|  | ||||
|     // Implementation-specific: | ||||
|     // This low-level method is good to draw from anywhere | ||||
|     static void draw_edit_screen(PGM_P const pstr, const char * const value); | ||||
|     static void draw_edit_screen(FSTR_P const fstr, const char * const value); | ||||
|  | ||||
|     // This method is for the current menu item | ||||
|     static void draw_edit_screen(const char * const value) { draw_edit_screen(editLabel, value); } | ||||
| @@ -185,7 +189,7 @@ class MenuEditItemBase : public MenuItemBase { | ||||
|   class MenuItem_sdbase { | ||||
|     public: | ||||
|       // Implemented for HD44780 and DOGM | ||||
|       static void draw(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir); | ||||
|       static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, CardReader &theCard, const bool isDir); | ||||
|   }; | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -83,7 +83,7 @@ void menu_backlash(); | ||||
|   void menu_pwm() { | ||||
|     START_MENU(); | ||||
|     BACK_ITEM(MSG_ADVANCED_SETTINGS); | ||||
|     #define EDIT_CURRENT_PWM(LABEL,I) EDIT_ITEM_P(long5, PSTR(LABEL), &stepper.motor_current_setting[I], 100, 2000, stepper.refresh_motor_power) | ||||
|     #define EDIT_CURRENT_PWM(LABEL,I) EDIT_ITEM_F(long5, F(LABEL), &stepper.motor_current_setting[I], 100, 2000, stepper.refresh_motor_power) | ||||
|     #if ANY_PIN(MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y) | ||||
|       EDIT_CURRENT_PWM(STR_A STR_B, 0); | ||||
|     #endif | ||||
| @@ -705,7 +705,7 @@ void menu_advanced_settings() { | ||||
|     CONFIRM_ITEM(MSG_INIT_EEPROM, | ||||
|       MSG_BUTTON_INIT, MSG_BUTTON_CANCEL, | ||||
|       ui.init_eeprom, nullptr, | ||||
|       GET_TEXT(MSG_INIT_EEPROM), (const char *)nullptr, PSTR("?") | ||||
|       GET_TEXT_F(MSG_INIT_EEPROM), (const char *)nullptr, F("?") | ||||
|     ); | ||||
|   #endif | ||||
|  | ||||
|   | ||||
| @@ -168,7 +168,7 @@ static void _lcd_level_bed_corners_get_next_position() { | ||||
|  | ||||
|     TERN_(HAS_MARLINUI_U8GLIB, ui.set_font(FONT_MENU)); // Set up the font for extra info | ||||
|  | ||||
|     MenuItem_static::draw(0, GET_TEXT(MSG_PROBING_POINT), SS_INVERT); // "Probing Mesh" heading | ||||
|     MenuItem_static::draw(0, GET_TEXT_F(MSG_PROBING_POINT), SS_INVERT); // "Probing Mesh" heading | ||||
|  | ||||
|     uint8_t cy = TERN(TFT_COLOR_UI, 3, LCD_HEIGHT - 1), y = LCD_ROW_Y(cy); | ||||
|  | ||||
| @@ -197,10 +197,10 @@ static void _lcd_level_bed_corners_get_next_position() { | ||||
|   void _lcd_draw_raise() { | ||||
|     if (!ui.should_draw()) return; | ||||
|     MenuItem_confirm::select_screen( | ||||
|         GET_TEXT(MSG_BUTTON_DONE), GET_TEXT(MSG_BUTTON_SKIP) | ||||
|         GET_TEXT_F(MSG_BUTTON_DONE), GET_TEXT_F(MSG_BUTTON_SKIP) | ||||
|       , []{ corner_probing_done = true; wait_for_probe = false; } | ||||
|       , []{ wait_for_probe = false; } | ||||
|       , GET_TEXT(MSG_BED_TRAMMING_RAISE) | ||||
|       , GET_TEXT_F(MSG_BED_TRAMMING_RAISE) | ||||
|       , (const char*)nullptr, NUL_STR | ||||
|     ); | ||||
|   } | ||||
| @@ -208,11 +208,11 @@ static void _lcd_level_bed_corners_get_next_position() { | ||||
|   void _lcd_draw_level_prompt() { | ||||
|     if (!ui.should_draw()) return; | ||||
|     MenuItem_confirm::select_screen( | ||||
|         GET_TEXT(TERN(HAS_LEVELING, MSG_BUTTON_LEVEL, MSG_BUTTON_DONE)), | ||||
|         TERN(HAS_LEVELING, GET_TEXT(MSG_BUTTON_BACK), nullptr) | ||||
|         GET_TEXT_F(TERN(HAS_LEVELING, MSG_BUTTON_LEVEL, MSG_BUTTON_DONE)), | ||||
|         TERN(HAS_LEVELING, GET_TEXT_F(MSG_BUTTON_BACK), nullptr) | ||||
|       , []{ queue.inject(TERN(HAS_LEVELING, F("G29N"), FPSTR(G28_STR))); ui.return_to_status(); } | ||||
|       , TERN(HAS_LEVELING, ui.goto_previous_screen_no_defer, []{}) | ||||
|       , GET_TEXT(MSG_BED_TRAMMING_IN_RANGE) | ||||
|       , GET_TEXT_F(MSG_BED_TRAMMING_IN_RANGE) | ||||
|       , (const char*)nullptr, NUL_STR | ||||
|     ); | ||||
|   } | ||||
| @@ -332,15 +332,15 @@ static void _lcd_level_bed_corners_homing() { | ||||
|     bed_corner = 0; | ||||
|     ui.goto_screen([]{ | ||||
|       MenuItem_confirm::select_screen( | ||||
|           GET_TEXT(MSG_BUTTON_NEXT), GET_TEXT(MSG_BUTTON_DONE) | ||||
|           GET_TEXT_F(MSG_BUTTON_NEXT), GET_TEXT_F(MSG_BUTTON_DONE) | ||||
|         , _lcd_goto_next_corner | ||||
|         , []{ | ||||
|             line_to_z(LEVEL_CORNERS_Z_HOP); // Raise Z off the bed when done | ||||
|             TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_was_active)); | ||||
|             ui.goto_previous_screen_no_defer(); | ||||
|           } | ||||
|         , GET_TEXT(TERN(LEVEL_CENTER_TOO, MSG_LEVEL_BED_NEXT_POINT, MSG_NEXT_CORNER)) | ||||
|         , (const char*)nullptr, PSTR("?") | ||||
|         , GET_TEXT_F(TERN(LEVEL_CENTER_TOO, MSG_LEVEL_BED_NEXT_POINT, MSG_NEXT_CORNER)) | ||||
|         , (const char*)nullptr, F("?") | ||||
|       ); | ||||
|     }); | ||||
|     ui.set_selection(true); | ||||
|   | ||||
| @@ -71,12 +71,12 @@ | ||||
|       #if Z_AFTER_PROBING > 0 && DISABLED(MESH_BED_LEVELING) | ||||
|         // Display "Done" screen and wait for moves to complete | ||||
|         line_to_z(Z_AFTER_PROBING); | ||||
|         ui.synchronize(GET_TEXT(MSG_LEVEL_BED_DONE)); | ||||
|         ui.synchronize(GET_TEXT_F(MSG_LEVEL_BED_DONE)); | ||||
|       #endif | ||||
|       ui.goto_previous_screen_no_defer(); | ||||
|       ui.completion_feedback(); | ||||
|     } | ||||
|     if (ui.should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, GET_TEXT(MSG_LEVEL_BED_DONE)); | ||||
|     if (ui.should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, GET_TEXT_F(MSG_LEVEL_BED_DONE)); | ||||
|     ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); | ||||
|   } | ||||
|  | ||||
| @@ -127,7 +127,7 @@ | ||||
|     // | ||||
|     if (ui.should_draw()) { | ||||
|       const float v = current_position.z; | ||||
|       MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_MOVE_Z), ftostr43sign(v + (v < 0 ? -0.0001f : 0.0001f), '+')); | ||||
|       MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_MOVE_Z), ftostr43sign(v + (v < 0 ? -0.0001f : 0.0001f), '+')); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -138,7 +138,7 @@ | ||||
|     if (ui.should_draw()) { | ||||
|       char msg[10]; | ||||
|       sprintf_P(msg, PSTR("%i / %u"), int(manual_probe_index + 1), total_probe_points); | ||||
|       MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_LEVEL_BED_NEXT_POINT), msg); | ||||
|       MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), msg); | ||||
|     } | ||||
|     ui.refresh(LCDVIEW_CALL_NO_REDRAW); | ||||
|     if (!ui.wait_for_move) ui.goto_screen(_lcd_level_bed_get_z); | ||||
| @@ -165,7 +165,7 @@ | ||||
|   // | ||||
|   void _lcd_level_bed_homing_done() { | ||||
|     if (ui.should_draw()) { | ||||
|       MenuItem_static::draw(1, GET_TEXT(MSG_LEVEL_BED_WAITING)); | ||||
|       MenuItem_static::draw(1, GET_TEXT_F(MSG_LEVEL_BED_WAITING)); | ||||
|       // Color UI needs a control to detect a touch | ||||
|       #if BOTH(TOUCH_SCREEN, HAS_GRAPHICAL_TFT) | ||||
|         touch.add_control(CLICK, 0, 0, TFT_WIDTH, TFT_HEIGHT); | ||||
| @@ -243,7 +243,7 @@ void menu_bed_leveling() { | ||||
|  | ||||
|   // Auto Home if not using manual probing | ||||
|   #if NONE(PROBE_MANUALLY, MESH_BED_LEVELING) | ||||
|     if (!is_homed) GCODES_ITEM(MSG_AUTO_HOME, G28_STR); | ||||
|     if (!is_homed) GCODES_ITEM(MSG_AUTO_HOME, FPSTR(G28_STR)); | ||||
|   #endif | ||||
|  | ||||
|   // Level Bed | ||||
| @@ -252,7 +252,7 @@ void menu_bed_leveling() { | ||||
|     SUBMENU(MSG_LEVEL_BED, _lcd_level_bed_continue); | ||||
|   #else | ||||
|     // Automatic leveling can just run the G-code | ||||
|     GCODES_ITEM(MSG_LEVEL_BED, is_homed ? PSTR("G29") : PSTR("G29N")); | ||||
|     GCODES_ITEM(MSG_LEVEL_BED, is_homed ? F("G29") : F("G29N")); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(MESH_EDIT_MENU) | ||||
|   | ||||
| @@ -48,7 +48,7 @@ static void lcd_cancel_object_confirm() { | ||||
|       ui.goto_previous_screen(); | ||||
|     }, | ||||
|     nullptr, | ||||
|     GET_TEXT(MSG_CANCEL_OBJECT), item_num, PSTR("?") | ||||
|     GET_TEXT_F(MSG_CANCEL_OBJECT), item_num, F("?") | ||||
|   ); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -78,7 +78,7 @@ void menu_advanced_settings(); | ||||
|     bar_percent += (int8_t)ui.encoderPosition; | ||||
|     LIMIT(bar_percent, 0, 100); | ||||
|     ui.encoderPosition = 0; | ||||
|     MenuItem_static::draw(0, GET_TEXT(MSG_PROGRESS_BAR_TEST), SS_DEFAULT|SS_INVERT); | ||||
|     MenuItem_static::draw(0, GET_TEXT_F(MSG_PROGRESS_BAR_TEST), SS_DEFAULT|SS_INVERT); | ||||
|     lcd_put_int((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2, bar_percent); lcd_put_wchar('%'); | ||||
|     lcd_moveto(0, LCD_HEIGHT - 1); ui.draw_progress_bar(bar_percent); | ||||
|   } | ||||
| @@ -137,7 +137,7 @@ void menu_advanced_settings(); | ||||
|     #include "../../gcode/queue.h" | ||||
|  | ||||
|     void menu_toolchange_migration() { | ||||
|       PGM_P const msg_migrate = GET_TEXT(MSG_TOOL_MIGRATION_SWAP); | ||||
|       FSTR_P const msg_migrate = GET_TEXT_F(MSG_TOOL_MIGRATION_SWAP); | ||||
|  | ||||
|       START_MENU(); | ||||
|       BACK_ITEM(MSG_CONFIGURATION); | ||||
| @@ -149,7 +149,7 @@ void menu_advanced_settings(); | ||||
|       // Migrate to a chosen extruder | ||||
|       EXTRUDER_LOOP() { | ||||
|         if (e != active_extruder) { | ||||
|           ACTION_ITEM_N_P(e, msg_migrate, []{ | ||||
|           ACTION_ITEM_N_F(e, msg_migrate, []{ | ||||
|             char cmd[12]; | ||||
|             sprintf_P(cmd, PSTR("M217 T%i"), int(MenuItemBase::itemIndex)); | ||||
|             queue.inject(cmd); | ||||
| @@ -199,16 +199,16 @@ void menu_advanced_settings(); | ||||
|     START_MENU(); | ||||
|     BACK_ITEM(MSG_CONFIGURATION); | ||||
|  | ||||
|     GCODES_ITEM(MSG_IDEX_MODE_AUTOPARK,  PSTR("M605S1\nG28X\nG1X0")); | ||||
|     GCODES_ITEM(MSG_IDEX_MODE_AUTOPARK,  F("M605S1\nG28X\nG1X0")); | ||||
|     GCODES_ITEM(MSG_IDEX_MODE_DUPLICATE, need_g28 | ||||
|       ? PSTR("M605S1\nT0\nG28\nM605S2\nG28X\nG1X0")         // If Y or Z is not homed, do a full G28 first | ||||
|       : PSTR("M605S1\nT0\nM605S2\nG28X\nG1X0") | ||||
|       ? F("M605S1\nT0\nG28\nM605S2\nG28X\nG1X0")         // If Y or Z is not homed, do a full G28 first | ||||
|       : F("M605S1\nT0\nM605S2\nG28X\nG1X0") | ||||
|     ); | ||||
|     GCODES_ITEM(MSG_IDEX_MODE_MIRRORED_COPY, need_g28 | ||||
|       ? PSTR("M605S1\nT0\nG28\nM605S2\nG28X\nG1X0\nM605S3") // If Y or Z is not homed, do a full G28 first | ||||
|       : PSTR("M605S1\nT0\nM605S2\nG28 X\nG1X0\nM605S3") | ||||
|       ? F("M605S1\nT0\nG28\nM605S2\nG28X\nG1X0\nM605S3") // If Y or Z is not homed, do a full G28 first | ||||
|       : F("M605S1\nT0\nM605S2\nG28 X\nG1X0\nM605S3") | ||||
|     ); | ||||
|     GCODES_ITEM(MSG_IDEX_MODE_FULL_CTRL, PSTR("M605S0\nG28X")); | ||||
|     GCODES_ITEM(MSG_IDEX_MODE_FULL_CTRL, F("M605S0\nG28X")); | ||||
|  | ||||
|     EDIT_ITEM(float42_52, MSG_IDEX_DUPE_GAP, &duplicate_extruder_x_offset, (X2_MIN_POS) - (X1_MIN_POS), (X_BED_SIZE) - 20); | ||||
|  | ||||
| @@ -246,11 +246,11 @@ void menu_advanced_settings(); | ||||
|       EDIT_ITEM(bool, MSG_BLTOUCH_SPEED_MODE, &bltouch.high_speed_mode); | ||||
|     #endif | ||||
|     #if ENABLED(BLTOUCH_LCD_VOLTAGE_MENU) | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_5V_MODE, MSG_BLTOUCH_5V_MODE, MSG_BUTTON_CANCEL, bltouch._set_5V_mode, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_OD_MODE, MSG_BLTOUCH_OD_MODE, MSG_BUTTON_CANCEL, bltouch._set_OD_mode, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_5V_MODE, MSG_BLTOUCH_5V_MODE, MSG_BUTTON_CANCEL, bltouch._set_5V_mode, nullptr, GET_TEXT_F(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_OD_MODE, MSG_BLTOUCH_OD_MODE, MSG_BUTTON_CANCEL, bltouch._set_OD_mode, nullptr, GET_TEXT_F(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       ACTION_ITEM(MSG_BLTOUCH_MODE_STORE, bltouch._mode_store); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_5V, MSG_BLTOUCH_MODE_STORE_5V, MSG_BUTTON_CANCEL, bltouch.mode_conv_5V, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_OD, MSG_BLTOUCH_MODE_STORE_OD, MSG_BUTTON_CANCEL, bltouch.mode_conv_OD, nullptr, GET_TEXT(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_5V, MSG_BLTOUCH_MODE_STORE_5V, MSG_BUTTON_CANCEL, bltouch.mode_conv_5V, nullptr, GET_TEXT_F(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       CONFIRM_ITEM(MSG_BLTOUCH_MODE_STORE_OD, MSG_BLTOUCH_MODE_STORE_OD, MSG_BUTTON_CANCEL, bltouch.mode_conv_OD, nullptr, GET_TEXT_F(MSG_BLTOUCH_MODE_CHANGE)); | ||||
|       ACTION_ITEM(MSG_BLTOUCH_MODE_ECHO, bltouch_report); | ||||
|     #endif | ||||
|     END_MENU(); | ||||
| @@ -264,10 +264,10 @@ void menu_advanced_settings(); | ||||
|     ui.defer_status_screen(); | ||||
|     START_MENU(); | ||||
|     BACK_ITEM(MSG_CONFIGURATION); | ||||
|     GCODES_ITEM(MSG_TOUCHMI_INIT, PSTR("M851 Z0\nG28\nG1 F200 Z0")); | ||||
|     GCODES_ITEM(MSG_TOUCHMI_INIT, F("M851 Z0\nG28\nG1 F200 Z0")); | ||||
|     SUBMENU(MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); | ||||
|     GCODES_ITEM(MSG_TOUCHMI_SAVE, PSTR("M500\nG1 F200 Z10")); | ||||
|     GCODES_ITEM(MSG_TOUCHMI_ZTEST, PSTR("G28\nG1 F200 Z0")); | ||||
|     GCODES_ITEM(MSG_TOUCHMI_SAVE, F("M500\nG1 F200 Z10")); | ||||
|     GCODES_ITEM(MSG_TOUCHMI_ZTEST, F("G28\nG1 F200 Z0")); | ||||
|     END_MENU(); | ||||
|   } | ||||
|  | ||||
| @@ -329,7 +329,7 @@ void menu_advanced_settings(); | ||||
|     #define MAXTEMP_ALL _MAX(REPEAT(HOTENDS, _MAXTEMP_ITEM) 0) | ||||
|     const uint8_t m = MenuItemBase::itemIndex; | ||||
|     START_MENU(); | ||||
|     STATIC_ITEM_P(ui.get_preheat_label(m), SS_DEFAULT|SS_INVERT); | ||||
|     STATIC_ITEM_F(ui.get_preheat_label(m), SS_DEFAULT|SS_INVERT); | ||||
|     BACK_ITEM(MSG_CONFIGURATION); | ||||
|     #if HAS_FAN | ||||
|       editable.uint8 = uint8_t(ui.material_preset[m].fan_speed); | ||||
| @@ -369,12 +369,12 @@ void menu_advanced_settings(); | ||||
|       #define _DONE_SCRIPT "" | ||||
|     #endif | ||||
|     #define GCODE_LAMBDA_CONF(N) []{ _lcd_custom_menus_configuration_gcode(F(CONFIG_MENU_ITEM_##N##_GCODE _DONE_SCRIPT)); } | ||||
|     #define _CUSTOM_ITEM_CONF(N) ACTION_ITEM_P(PSTR(CONFIG_MENU_ITEM_##N##_DESC), GCODE_LAMBDA_CONF(N)); | ||||
|     #define _CUSTOM_ITEM_CONF(N) ACTION_ITEM_F(F(CONFIG_MENU_ITEM_##N##_DESC), GCODE_LAMBDA_CONF(N)); | ||||
|     #define _CUSTOM_ITEM_CONF_CONFIRM(N)            \ | ||||
|       SUBMENU_P(PSTR(CONFIG_MENU_ITEM_##N##_DESC), []{ \ | ||||
|       SUBMENU_F(F(CONFIG_MENU_ITEM_##N##_DESC), []{ \ | ||||
|           MenuItem_confirm::confirm_screen(         \ | ||||
|             GCODE_LAMBDA_CONF(N), nullptr,          \ | ||||
|             PSTR(CONFIG_MENU_ITEM_##N##_DESC "?")      \ | ||||
|             F(CONFIG_MENU_ITEM_##N##_DESC "?")      \ | ||||
|           );                                        \ | ||||
|         }) | ||||
|  | ||||
| @@ -483,7 +483,7 @@ void menu_configuration() { | ||||
|   #if ENABLED(CUSTOM_MENU_CONFIG) | ||||
|     if (TERN1(CUSTOM_MENU_CONFIG_ONLY_IDLE, !busy)) { | ||||
|       #ifdef CUSTOM_MENU_CONFIG_TITLE | ||||
|         SUBMENU_P(PSTR(CUSTOM_MENU_CONFIG_TITLE), custom_menus_configuration); | ||||
|         SUBMENU_F(F(CUSTOM_MENU_CONFIG_TITLE), custom_menus_configuration); | ||||
|       #else | ||||
|         SUBMENU(MSG_CUSTOM_COMMANDS, custom_menus_configuration); | ||||
|       #endif | ||||
|   | ||||
| @@ -107,12 +107,12 @@ void lcd_delta_settings() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_DELTA_CALIBRATE); | ||||
|   EDIT_ITEM(float52sign, MSG_DELTA_HEIGHT, &delta_height, delta_height - 10, delta_height + 10, _recalc_delta_settings); | ||||
|   #define EDIT_ENDSTOP_ADJ(LABEL,N) EDIT_ITEM_P(float43, PSTR(LABEL), &delta_endstop_adj.N, -5, 0, _recalc_delta_settings) | ||||
|   #define EDIT_ENDSTOP_ADJ(LABEL,N) EDIT_ITEM_F(float43, F(LABEL), &delta_endstop_adj.N, -5, 0, _recalc_delta_settings) | ||||
|   EDIT_ENDSTOP_ADJ("Ex", a); | ||||
|   EDIT_ENDSTOP_ADJ("Ey", b); | ||||
|   EDIT_ENDSTOP_ADJ("Ez", c); | ||||
|   EDIT_ITEM(float52sign, MSG_DELTA_RADIUS, &delta_radius, delta_radius - 5, delta_radius + 5, _recalc_delta_settings); | ||||
|   #define EDIT_ANGLE_TRIM(LABEL,N) EDIT_ITEM_P(float43, PSTR(LABEL), &delta_tower_angle_trim.N, -5, 5, _recalc_delta_settings) | ||||
|   #define EDIT_ANGLE_TRIM(LABEL,N) EDIT_ITEM_F(float43, F(LABEL), &delta_tower_angle_trim.N, -5, 5, _recalc_delta_settings) | ||||
|   EDIT_ANGLE_TRIM("Tx", a); | ||||
|   EDIT_ANGLE_TRIM("Ty", b); | ||||
|   EDIT_ANGLE_TRIM("Tz", c); | ||||
| @@ -129,7 +129,7 @@ void menu_delta_calibrate() { | ||||
|   BACK_ITEM(MSG_MAIN); | ||||
|  | ||||
|   #if ENABLED(DELTA_AUTO_CALIBRATION) | ||||
|     GCODES_ITEM(MSG_DELTA_AUTO_CALIBRATE, PSTR("G33")); | ||||
|     GCODES_ITEM(MSG_DELTA_AUTO_CALIBRATE, F("G33")); | ||||
|     #if ENABLED(EEPROM_SETTINGS) | ||||
|       ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings); | ||||
|       ACTION_ITEM(MSG_LOAD_EEPROM, ui.load_settings); | ||||
|   | ||||
| @@ -45,22 +45,22 @@ | ||||
| static PauseMode _change_filament_mode; // = PAUSE_MODE_PAUSE_PRINT | ||||
| static int8_t _change_filament_extruder; // = 0 | ||||
|  | ||||
| inline PGM_P _change_filament_command() { | ||||
| inline FSTR_P _change_filament_command() { | ||||
|   switch (_change_filament_mode) { | ||||
|     case PAUSE_MODE_LOAD_FILAMENT:    return PSTR("M701 T%d"); | ||||
|     case PAUSE_MODE_LOAD_FILAMENT:    return F("M701 T%d"); | ||||
|     case PAUSE_MODE_UNLOAD_FILAMENT:  return _change_filament_extruder >= 0 | ||||
|                                            ? PSTR("M702 T%d") : PSTR("M702 ;%d"); | ||||
|                                            ? F("M702 T%d") : F("M702 ;%d"); | ||||
|     case PAUSE_MODE_CHANGE_FILAMENT: | ||||
|     case PAUSE_MODE_PAUSE_PRINT: | ||||
|     default: break; | ||||
|   } | ||||
|   return PSTR("M600 B0 T%d"); | ||||
|   return F("M600 B0 T%d"); | ||||
| } | ||||
|  | ||||
| // Initiate Filament Load/Unload/Change at the specified temperature | ||||
| static void _change_filament_with_temp(const uint16_t celsius) { | ||||
|   char cmd[11]; | ||||
|   sprintf_P(cmd, _change_filament_command(), _change_filament_extruder); | ||||
|   sprintf_P(cmd, FTOP(_change_filament_command()), _change_filament_extruder); | ||||
|   thermalManager.setTargetHotend(celsius, _change_filament_extruder); | ||||
|   queue.inject(cmd); | ||||
| } | ||||
| @@ -77,13 +77,13 @@ static void _change_filament_with_custom() { | ||||
| // Menu to choose the temperature and start Filament Change | ||||
| // | ||||
|  | ||||
| inline PGM_P change_filament_header(const PauseMode mode) { | ||||
| inline FSTR_P change_filament_header(const PauseMode mode) { | ||||
|   switch (mode) { | ||||
|     case PAUSE_MODE_LOAD_FILAMENT:   return GET_TEXT(MSG_FILAMENTLOAD); | ||||
|     case PAUSE_MODE_UNLOAD_FILAMENT: return GET_TEXT(MSG_FILAMENTUNLOAD); | ||||
|     case PAUSE_MODE_LOAD_FILAMENT:   return GET_TEXT_F(MSG_FILAMENTLOAD); | ||||
|     case PAUSE_MODE_UNLOAD_FILAMENT: return GET_TEXT_F(MSG_FILAMENTUNLOAD); | ||||
|     default: break; | ||||
|   } | ||||
|   return GET_TEXT(MSG_FILAMENTCHANGE); | ||||
|   return GET_TEXT_F(MSG_FILAMENTCHANGE); | ||||
| } | ||||
|  | ||||
| void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { | ||||
| @@ -91,7 +91,7 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { | ||||
|   _change_filament_extruder = extruder; | ||||
|   const int8_t old_index = MenuItemBase::itemIndex; | ||||
|   START_MENU(); | ||||
|   if (LCD_HEIGHT >= 4) STATIC_ITEM_P(change_filament_header(mode), SS_DEFAULT|SS_INVERT); | ||||
|   if (LCD_HEIGHT >= 4) STATIC_ITEM_F(change_filament_header(mode), SS_DEFAULT|SS_INVERT); | ||||
|   BACK_ITEM(MSG_BACK); | ||||
|   #if HAS_PREHEAT | ||||
|     LOOP_L_N(m, PREHEAT_COUNT) | ||||
| @@ -132,18 +132,18 @@ void menu_change_filament() { | ||||
|  | ||||
|     // Change filament | ||||
|     #if E_STEPPERS == 1 | ||||
|       PGM_P const msg = GET_TEXT(MSG_FILAMENTCHANGE); | ||||
|       FSTR_P const msg = GET_TEXT_F(MSG_FILAMENTCHANGE); | ||||
|       if (thermalManager.targetTooColdToExtrude(active_extruder)) | ||||
|         SUBMENU_P(msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, 0); }); | ||||
|         SUBMENU_F(msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, 0); }); | ||||
|       else | ||||
|         GCODES_ITEM_P(msg, PSTR("M600 B0")); | ||||
|         GCODES_ITEM_F(msg, F("M600 B0")); | ||||
|     #else | ||||
|       PGM_P const msg = GET_TEXT(MSG_FILAMENTCHANGE_E); | ||||
|       FSTR_P const msg = GET_TEXT_F(MSG_FILAMENTCHANGE_E); | ||||
|       LOOP_L_N(s, E_STEPPERS) { | ||||
|         if (thermalManager.targetTooColdToExtrude(s)) | ||||
|           SUBMENU_N_P(s, msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, MenuItemBase::itemIndex); }); | ||||
|           SUBMENU_N_F(s, msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, MenuItemBase::itemIndex); }); | ||||
|         else { | ||||
|           ACTION_ITEM_N_P(s, msg, []{ | ||||
|           ACTION_ITEM_N_F(s, msg, []{ | ||||
|             PGM_P const cmdpstr = PSTR("M600 B0 T%i"); | ||||
|             char cmd[strlen_P(cmdpstr) + 3 + 1]; | ||||
|             sprintf_P(cmd, cmdpstr, int(MenuItemBase::itemIndex)); | ||||
| @@ -157,18 +157,18 @@ void menu_change_filament() { | ||||
|       if (!is_busy) { | ||||
|         // Load filament | ||||
|         #if E_STEPPERS == 1 | ||||
|           PGM_P const msg_load = GET_TEXT(MSG_FILAMENTLOAD); | ||||
|           FSTR_P const msg_load = GET_TEXT_F(MSG_FILAMENTLOAD); | ||||
|           if (thermalManager.targetTooColdToExtrude(active_extruder)) | ||||
|             SUBMENU_P(msg_load, []{ _menu_temp_filament_op(PAUSE_MODE_LOAD_FILAMENT, 0); }); | ||||
|             SUBMENU_F(msg_load, []{ _menu_temp_filament_op(PAUSE_MODE_LOAD_FILAMENT, 0); }); | ||||
|           else | ||||
|             GCODES_ITEM_P(msg_load, PSTR("M701")); | ||||
|             GCODES_ITEM_F(msg_load, F("M701")); | ||||
|         #else | ||||
|           PGM_P const msg_load = GET_TEXT(MSG_FILAMENTLOAD_E); | ||||
|           FSTR_P const msg_load = GET_TEXT_F(MSG_FILAMENTLOAD_E); | ||||
|           LOOP_L_N(s, E_STEPPERS) { | ||||
|             if (thermalManager.targetTooColdToExtrude(s)) | ||||
|               SUBMENU_N_P(s, msg_load, []{ _menu_temp_filament_op(PAUSE_MODE_LOAD_FILAMENT, MenuItemBase::itemIndex); }); | ||||
|               SUBMENU_N_F(s, msg_load, []{ _menu_temp_filament_op(PAUSE_MODE_LOAD_FILAMENT, MenuItemBase::itemIndex); }); | ||||
|             else { | ||||
|               ACTION_ITEM_N_P(s, msg_load, []{ | ||||
|               ACTION_ITEM_N_F(s, msg_load, []{ | ||||
|                 char cmd[12]; | ||||
|                 sprintf_P(cmd, PSTR("M701 T%i"), int(MenuItemBase::itemIndex)); | ||||
|                 queue.inject(cmd); | ||||
| @@ -179,24 +179,24 @@ void menu_change_filament() { | ||||
|  | ||||
|         // Unload filament | ||||
|         #if E_STEPPERS == 1 | ||||
|           PGM_P const msg_unload = GET_TEXT(MSG_FILAMENTUNLOAD); | ||||
|           FSTR_P const msg_unload = GET_TEXT_F(MSG_FILAMENTUNLOAD); | ||||
|           if (thermalManager.targetTooColdToExtrude(active_extruder)) | ||||
|             SUBMENU_P(msg_unload, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, 0); }); | ||||
|             SUBMENU_F(msg_unload, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, 0); }); | ||||
|           else | ||||
|             GCODES_ITEM_P(msg_unload, PSTR("M702")); | ||||
|             GCODES_ITEM_F(msg_unload, F("M702")); | ||||
|         #else | ||||
|           #if ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS) | ||||
|             if (too_cold) | ||||
|               SUBMENU(MSG_FILAMENTUNLOAD_ALL, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, -1); }); | ||||
|             else | ||||
|               GCODES_ITEM(MSG_FILAMENTUNLOAD_ALL, PSTR("M702")); | ||||
|               GCODES_ITEM(MSG_FILAMENTUNLOAD_ALL, F("M702")); | ||||
|           #endif | ||||
|           PGM_P const msg_unload = GET_TEXT(MSG_FILAMENTUNLOAD_E); | ||||
|           FSTR_P const msg_unload = GET_TEXT_F(MSG_FILAMENTUNLOAD_E); | ||||
|           LOOP_L_N(s, E_STEPPERS) { | ||||
|             if (thermalManager.targetTooColdToExtrude(s)) | ||||
|               SUBMENU_N_P(s, msg_unload, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, MenuItemBase::itemIndex); }); | ||||
|               SUBMENU_N_F(s, msg_unload, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, MenuItemBase::itemIndex); }); | ||||
|             else { | ||||
|               ACTION_ITEM_N_P(s, msg_unload, []{ | ||||
|               ACTION_ITEM_N_F(s, msg_unload, []{ | ||||
|                 char cmd[12]; | ||||
|                 sprintf_P(cmd, PSTR("M702 T%i"), int(MenuItemBase::itemIndex)); | ||||
|                 queue.inject(cmd); | ||||
| @@ -221,21 +221,21 @@ void menu_change_filament() { | ||||
|  | ||||
| static uint8_t hotend_status_extruder = 0; | ||||
|  | ||||
| static PGM_P pause_header() { | ||||
| static FSTR_P pause_header() { | ||||
|   switch (pause_mode) { | ||||
|     case PAUSE_MODE_CHANGE_FILAMENT:  return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER); | ||||
|     case PAUSE_MODE_LOAD_FILAMENT:    return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_LOAD); | ||||
|     case PAUSE_MODE_UNLOAD_FILAMENT:  return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_UNLOAD); | ||||
|     case PAUSE_MODE_CHANGE_FILAMENT:  return GET_TEXT_F(MSG_FILAMENT_CHANGE_HEADER); | ||||
|     case PAUSE_MODE_LOAD_FILAMENT:    return GET_TEXT_F(MSG_FILAMENT_CHANGE_HEADER_LOAD); | ||||
|     case PAUSE_MODE_UNLOAD_FILAMENT:  return GET_TEXT_F(MSG_FILAMENT_CHANGE_HEADER_UNLOAD); | ||||
|     default: break; | ||||
|   } | ||||
|   return GET_TEXT(MSG_FILAMENT_CHANGE_HEADER_PAUSE); | ||||
|   return GET_TEXT_F(MSG_FILAMENT_CHANGE_HEADER_PAUSE); | ||||
| } | ||||
|  | ||||
| // Portions from STATIC_ITEM... | ||||
| #define HOTEND_STATUS_ITEM() do { \ | ||||
|   if (_menuLineNr == _thisItemNr) { \ | ||||
|     if (ui.should_draw()) { \ | ||||
|       IF_DISABLED(HAS_GRAPHICAL_TFT, MenuItem_static::draw(_lcdLineNr, GET_TEXT(MSG_FILAMENT_CHANGE_NOZZLE), SS_INVERT)); \ | ||||
|       IF_DISABLED(HAS_GRAPHICAL_TFT, MenuItem_static::draw(_lcdLineNr, GET_TEXT_F(MSG_FILAMENT_CHANGE_NOZZLE), SS_INVERT)); \ | ||||
|       ui.draw_hotend_status(_lcdLineNr, hotend_status_extruder); \ | ||||
|     } \ | ||||
|     if (_skipStatic && encoderLine <= _thisItemNr) { \ | ||||
| @@ -273,39 +273,39 @@ void menu_pause_option() { | ||||
| // | ||||
| // Warning: msg must have three null bytes to delimit lines! | ||||
| // | ||||
| void _lcd_pause_message(PGM_P const msg) { | ||||
|   PGM_P const msg1 = msg; | ||||
| void _lcd_pause_message(FSTR_P const msg) { | ||||
|   PGM_P const msg1 = FTOP(msg); | ||||
|   PGM_P const msg2 = msg1 + strlen_P(msg1) + 1; | ||||
|   PGM_P const msg3 = msg2 + strlen_P(msg2) + 1; | ||||
|   const bool has2 = msg2[0], has3 = msg3[0], | ||||
|              skip1 = !has2 && (LCD_HEIGHT) >= 5; | ||||
|  | ||||
|   START_SCREEN(); | ||||
|   STATIC_ITEM_P(pause_header(), SS_DEFAULT|SS_INVERT);          // 1: Header | ||||
|   STATIC_ITEM_F(pause_header(), SS_DEFAULT|SS_INVERT);          // 1: Header | ||||
|   if (skip1) SKIP_ITEM();                                       // Move a single-line message down | ||||
|   STATIC_ITEM_P(msg1);                                          // 2: Message Line 1 | ||||
|   if (has2) STATIC_ITEM_P(msg2);                                // 3: Message Line 2 | ||||
|   if (has3 && (LCD_HEIGHT) >= 5) STATIC_ITEM_P(msg3);           // 4: Message Line 3 (if LCD has 5 lines) | ||||
|   STATIC_ITEM_F(FPSTR(msg1));                                   // 2: Message Line 1 | ||||
|   if (has2) STATIC_ITEM_F(FPSTR(msg2));                         // 3: Message Line 2 | ||||
|   if (has3 && (LCD_HEIGHT) >= 5) STATIC_ITEM_F(FPSTR(msg3));    // 4: Message Line 3 (if LCD has 5 lines) | ||||
|   if (skip1 + 1 + has2 + has3 < (LCD_HEIGHT) - 2) SKIP_ITEM();  // Push Hotend Status down, if needed | ||||
|   HOTEND_STATUS_ITEM();                                         // 5: Hotend Status | ||||
|   END_SCREEN(); | ||||
| } | ||||
|  | ||||
| void lcd_pause_parking_message()  { _lcd_pause_message(GET_TEXT(MSG_PAUSE_PRINT_PARKING));     } | ||||
| void lcd_pause_changing_message() { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_INIT));    } | ||||
| void lcd_pause_unload_message()   { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_UNLOAD));  } | ||||
| void lcd_pause_heating_message()  { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_HEATING)); } | ||||
| void lcd_pause_heat_message()     { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_HEAT));    } | ||||
| void lcd_pause_insert_message()   { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_INSERT));  } | ||||
| void lcd_pause_load_message()     { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_LOAD));    } | ||||
| void lcd_pause_waiting_message()  { _lcd_pause_message(GET_TEXT(MSG_ADVANCED_PAUSE_WAITING));  } | ||||
| void lcd_pause_resume_message()   { _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_RESUME));  } | ||||
| void lcd_pause_parking_message()  { _lcd_pause_message(GET_TEXT_F(MSG_PAUSE_PRINT_PARKING));     } | ||||
| void lcd_pause_changing_message() { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_INIT));    } | ||||
| void lcd_pause_unload_message()   { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_UNLOAD));  } | ||||
| void lcd_pause_heating_message()  { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_HEATING)); } | ||||
| void lcd_pause_heat_message()     { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_HEAT));    } | ||||
| void lcd_pause_insert_message()   { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_INSERT));  } | ||||
| void lcd_pause_load_message()     { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_LOAD));    } | ||||
| void lcd_pause_waiting_message()  { _lcd_pause_message(GET_TEXT_F(MSG_ADVANCED_PAUSE_WAITING));  } | ||||
| void lcd_pause_resume_message()   { _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_RESUME));  } | ||||
|  | ||||
| void lcd_pause_purge_message() { | ||||
|   #if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE) | ||||
|     _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_CONT_PURGE)); | ||||
|     _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_CONT_PURGE)); | ||||
|   #else | ||||
|     _lcd_pause_message(GET_TEXT(MSG_FILAMENT_CHANGE_PURGE)); | ||||
|     _lcd_pause_message(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE)); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -35,7 +35,7 @@ | ||||
| #endif | ||||
|  | ||||
| #define VALUE_ITEM(MSG, VALUE, STYL)    do{ char msg[21]; strcpy_P(msg, PSTR(": ")); strcpy(msg + 2, VALUE); STATIC_ITEM(MSG, STYL, msg); }while(0) | ||||
| #define VALUE_ITEM_P(MSG, PVALUE, STYL) do{ char msg[21]; strcpy_P(msg, PSTR(": ")); strcpy_P(msg + 2, PSTR(PVALUE)); STATIC_ITEM(MSG, STYL, msg); }while(0) | ||||
| #define VALUE_ITEM_F(MSG, PVALUE, STYL) do{ char msg[21]; strcpy_P(msg, PSTR(": ")); strcpy_P(msg + 2, PSTR(PVALUE)); STATIC_ITEM(MSG, STYL, msg); }while(0) | ||||
|  | ||||
| #if ENABLED(PRINTCOUNTER) | ||||
|  | ||||
| @@ -56,35 +56,35 @@ | ||||
|     VALUE_ITEM(MSG_INFO_COMPLETED_PRINTS, i16tostr3left(stats.finishedPrints), SS_LEFT);    // Completed  : 666 | ||||
|  | ||||
|     STATIC_ITEM(MSG_INFO_PRINT_TIME, SS_LEFT);                                              // Total print Time: | ||||
|     STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.printTime).toString(buffer));       // > 99y 364d 23h 59m 59s | ||||
|     STATIC_ITEM_F(F("> "), SS_LEFT, duration_t(stats.printTime).toString(buffer));       // > 99y 364d 23h 59m 59s | ||||
|  | ||||
|     STATIC_ITEM(MSG_INFO_PRINT_LONGEST, SS_LEFT);                                           // Longest job time: | ||||
|     STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.longestPrint).toString(buffer));    // > 99y 364d 23h 59m 59s | ||||
|     STATIC_ITEM_F(F("> "), SS_LEFT, duration_t(stats.longestPrint).toString(buffer));    // > 99y 364d 23h 59m 59s | ||||
|  | ||||
|     STATIC_ITEM(MSG_INFO_PRINT_FILAMENT, SS_LEFT);                                          // Extruded total: | ||||
|     sprintf_P(buffer, PSTR("%ld.%im") | ||||
|       , long(stats.filamentUsed / 1000) | ||||
|       , int16_t(stats.filamentUsed / 100) % 10 | ||||
|     ); | ||||
|     STATIC_ITEM_P(PSTR("> "), SS_LEFT, buffer);                                             // > 125m | ||||
|     STATIC_ITEM_F(F("> "), SS_LEFT, buffer);                                             // > 125m | ||||
|  | ||||
|     #if SERVICE_INTERVAL_1 > 0 || SERVICE_INTERVAL_2 > 0 || SERVICE_INTERVAL_3 > 0 | ||||
|       strcpy_P(buffer, GET_TEXT(MSG_SERVICE_IN)); | ||||
|     #endif | ||||
|  | ||||
|     #if SERVICE_INTERVAL_1 > 0 | ||||
|       STATIC_ITEM_P(PSTR(SERVICE_NAME_1 " "), SS_LEFT, buffer);                             // Service X in: | ||||
|       STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.nextService1).toString(buffer));  // > 7d 12h 11m 10s | ||||
|       STATIC_ITEM_F(F(SERVICE_NAME_1 " "), SS_LEFT, buffer);                             // Service X in: | ||||
|       STATIC_ITEM_F(F("> "), SS_LEFT, duration_t(stats.nextService1).toString(buffer));  // > 7d 12h 11m 10s | ||||
|     #endif | ||||
|  | ||||
|     #if SERVICE_INTERVAL_2 > 0 | ||||
|       STATIC_ITEM_P(PSTR(SERVICE_NAME_2 " "), SS_LEFT, buffer); | ||||
|       STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.nextService2).toString(buffer)); | ||||
|       STATIC_ITEM_F(F(SERVICE_NAME_2 " "), SS_LEFT, buffer); | ||||
|       STATIC_ITEM_F(F("> "), SS_LEFT, duration_t(stats.nextService2).toString(buffer)); | ||||
|     #endif | ||||
|  | ||||
|     #if SERVICE_INTERVAL_3 > 0 | ||||
|       STATIC_ITEM_P(PSTR(SERVICE_NAME_3 " "), SS_LEFT, buffer); | ||||
|       STATIC_ITEM_P(PSTR("> "), SS_LEFT, duration_t(stats.nextService3).toString(buffer)); | ||||
|       STATIC_ITEM_F(F(SERVICE_NAME_3 " "), SS_LEFT, buffer); | ||||
|       STATIC_ITEM_F(F("> "), SS_LEFT, duration_t(stats.nextService3).toString(buffer)); | ||||
|     #endif | ||||
|  | ||||
|     END_SCREEN(); | ||||
| @@ -103,7 +103,7 @@ void menu_info_thermistors() { | ||||
|   #if HAS_EXTRUDERS | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_0 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E0 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E0 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_0_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_0_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -113,7 +113,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_1 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E1 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E1 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_1_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_1_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -123,7 +123,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_2 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E2 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E2 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_2_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_2_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -133,7 +133,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_3 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E3 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E3 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_3_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_3_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -143,7 +143,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_4 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E4 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E4 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_4_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_4_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -153,7 +153,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_5 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E5 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E5 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_5_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_5_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -163,7 +163,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_6 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E6 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E6 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_6_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_6_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -173,7 +173,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_7 | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR(STR_E7 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F(STR_E7 ": " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(HEATER_7_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(HEATER_7_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_HOTENDS, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -183,7 +183,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_BED | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR("BED: " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F("BED: " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(BED_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(BED_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_BED, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -193,7 +193,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_CHAMBER | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR("CHAM: " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F("CHAM: " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(CHAMBER_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(CHAMBER_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_CHAMBER, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -203,7 +203,7 @@ void menu_info_thermistors() { | ||||
|     #undef THERMISTOR_ID | ||||
|     #define THERMISTOR_ID TEMP_SENSOR_COOLER | ||||
|     #include "../thermistornames.h" | ||||
|     STATIC_ITEM_P(PSTR("COOL: " THERMISTOR_NAME), SS_INVERT); | ||||
|     STATIC_ITEM_F(F("COOL: " THERMISTOR_NAME), SS_INVERT); | ||||
|     PSTRING_ITEM(MSG_INFO_MIN_TEMP, STRINGIFY(COOLER_MINTEMP), SS_LEFT); | ||||
|     PSTRING_ITEM(MSG_INFO_MAX_TEMP, STRINGIFY(COOLER_MAXTEMP), SS_LEFT); | ||||
|     STATIC_ITEM(TERN(WATCH_COOLER, MSG_INFO_RUNAWAY_ON, MSG_INFO_RUNAWAY_OFF), SS_LEFT); | ||||
| @@ -219,9 +219,9 @@ void menu_info_board() { | ||||
|   if (ui.use_click()) return ui.go_back(); | ||||
|  | ||||
|   START_SCREEN(); | ||||
|   STATIC_ITEM_P(PSTR(BOARD_INFO_NAME), SS_DEFAULT|SS_INVERT);      // MyPrinterController | ||||
|   STATIC_ITEM_F(F(BOARD_INFO_NAME), SS_DEFAULT|SS_INVERT);      // MyPrinterController | ||||
|   #ifdef BOARD_WEBSITE_URL | ||||
|     STATIC_ITEM_P(PSTR(BOARD_WEBSITE_URL), SS_LEFT);               // www.my3dprinter.com | ||||
|     STATIC_ITEM_F(F(BOARD_WEBSITE_URL), SS_LEFT);               // www.my3dprinter.com | ||||
|   #endif | ||||
|   PSTRING_ITEM(MSG_INFO_BAUDRATE, STRINGIFY(BAUDRATE), SS_CENTER); // Baud: 250000 | ||||
|   PSTRING_ITEM(MSG_INFO_PROTOCOL, PROTOCOL_VERSION, SS_CENTER);    // Protocol: 1.0 | ||||
| @@ -252,10 +252,10 @@ void menu_info_board() { | ||||
|     if (ui.use_click()) return ui.go_back(); | ||||
|     START_SCREEN(); | ||||
|     STATIC_ITEM(MSG_MARLIN, SS_DEFAULT|SS_INVERT);                // Marlin | ||||
|     STATIC_ITEM_P(PSTR(SHORT_BUILD_VERSION));                   // x.x.x-Branch | ||||
|     STATIC_ITEM_P(PSTR(STRING_DISTRIBUTION_DATE));              // YYYY-MM-DD HH:MM | ||||
|     STATIC_ITEM_P(PSTR(MACHINE_NAME), SS_DEFAULT|SS_INVERT);    // My3DPrinter | ||||
|     STATIC_ITEM_P(PSTR(WEBSITE_URL));                           // www.my3dprinter.com | ||||
|     STATIC_ITEM_F(F(SHORT_BUILD_VERSION));                        // x.x.x-Branch | ||||
|     STATIC_ITEM_F(F(STRING_DISTRIBUTION_DATE));                   // YYYY-MM-DD HH:MM | ||||
|     STATIC_ITEM_F(F(MACHINE_NAME), SS_DEFAULT|SS_INVERT);         // My3DPrinter | ||||
|     STATIC_ITEM_F(F(WEBSITE_URL));                                // www.my3dprinter.com | ||||
|     PSTRING_ITEM(MSG_INFO_EXTRUDERS, STRINGIFY(EXTRUDERS), SS_CENTER); // Extruders: 2 | ||||
|     #if HAS_LEVELING | ||||
|       STATIC_ITEM( | ||||
|   | ||||
| @@ -36,36 +36,36 @@ void lcd_move_z(); | ||||
| // SUBMENU(LABEL, screen_handler) | ||||
| class MenuItem_submenu : public MenuItemBase { | ||||
|   public: | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { | ||||
|       _draw(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, ...) { | ||||
|       _draw(sel, row, fstr, '>', LCD_STR_ARROW_RIGHT[0]); | ||||
|     } | ||||
|     static void action(PGM_P const, const screenFunc_t func) { ui.push_current_screen(); ui.goto_screen(func); } | ||||
|     static void action(FSTR_P const, const screenFunc_t func) { ui.push_current_screen(); ui.goto_screen(func); } | ||||
| }; | ||||
|  | ||||
| // Any menu item that invokes an immediate action | ||||
| class MenuItem_button : public MenuItemBase { | ||||
|   public: | ||||
|     // Button-y Items are selectable lines with no other indicator | ||||
|     static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { | ||||
|       _draw(sel, row, pstr, '>', ' '); | ||||
|     static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, ...) { | ||||
|       _draw(sel, row, fstr, '>', ' '); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // ACTION_ITEM(LABEL, FUNC) | ||||
| class MenuItem_function : public MenuItem_button { | ||||
|   public: | ||||
|     //static void action(PGM_P const, const uint8_t, const menuAction_t func) { (*func)(); }; | ||||
|     static void action(PGM_P const, const menuAction_t func) { if (func) (*func)(); }; | ||||
|     //static void action(FSTR_P const, const uint8_t, const menuAction_t func) { (*func)(); }; | ||||
|     static void action(FSTR_P const, const menuAction_t func) { if (func) (*func)(); }; | ||||
| }; | ||||
|  | ||||
| // GCODES_ITEM(LABEL, GCODES) | ||||
| class MenuItem_gcode : public MenuItem_button { | ||||
|   public: | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) { | ||||
|       _draw(sel, row, pstr, '>', ' '); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, ...) { | ||||
|       _draw(sel, row, fstr, '>', ' '); | ||||
|     } | ||||
|     static void action(PGM_P const, PGM_P const pgcode) { queue.inject(FPSTR(pgcode)); } | ||||
|     static void action(PGM_P const pstr, const uint8_t, PGM_P const pgcode) { action(pstr, pgcode); } | ||||
|     static void action(FSTR_P const, FSTR_P const fgcode) { queue.inject(fgcode); } | ||||
|     static void action(FSTR_P const fstr, const uint8_t, FSTR_P const fgcode) { action(fstr, fgcode); } | ||||
| }; | ||||
|  | ||||
| //////////////////////////////////////////// | ||||
| @@ -82,16 +82,16 @@ class TMenuEditItem : MenuEditItemBase { | ||||
|     static const char* to_string(const int32_t value) { return NAME::strfunc(unscale(value)); } | ||||
|     static void load(void *ptr, const int32_t value)  { *((type_t*)ptr) = unscale(value);     } | ||||
|   public: | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, type_t * const data, ...) { | ||||
|       MenuEditItemBase::draw(sel, row, pstr, NAME::strfunc(*(data))); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, type_t * const data, ...) { | ||||
|       MenuEditItemBase::draw(sel, row, fstr, NAME::strfunc(*(data))); | ||||
|     } | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, type_t (*pget)(), ...) { | ||||
|       MenuEditItemBase::draw(sel, row, pstr, NAME::strfunc(pget())); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, type_t (*pget)(), ...) { | ||||
|       MenuEditItemBase::draw(sel, row, fstr, NAME::strfunc(pget())); | ||||
|     } | ||||
|     // Edit screen for this type of item | ||||
|     static void edit_screen() { MenuEditItemBase::edit_screen(to_string, load); } | ||||
|     static void action( | ||||
|       PGM_P const pstr,                     // Edit label | ||||
|       FSTR_P const fstr,                    // Edit label | ||||
|       type_t * const ptr,                   // Value pointer | ||||
|       const type_t minValue,                // Value range | ||||
|       const type_t maxValue, | ||||
| @@ -101,7 +101,7 @@ class TMenuEditItem : MenuEditItemBase { | ||||
|       // Make sure minv and maxv fit within int32_t | ||||
|       const int32_t minv = _MAX(scale(minValue), INT32_MIN), | ||||
|                     maxv = _MIN(scale(maxValue), INT32_MAX); | ||||
|       goto_edit_screen(pstr, ptr, minv, maxv - minv, scale(*ptr) - minv, | ||||
|       goto_edit_screen(fstr, ptr, minv, maxv - minv, scale(*ptr) - minv, | ||||
|         edit_screen, callback, live); | ||||
|     } | ||||
| }; | ||||
| @@ -168,16 +168,16 @@ DEFINE_MENU_EDIT_ITEM_TYPE(long5_25    ,uint32_t ,ftostr5rj       ,   0.04f ); | ||||
|  | ||||
| class MenuItem_bool : public MenuEditItemBase { | ||||
|   public: | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const bool onoff) { | ||||
|       MenuEditItemBase::draw(sel, row, pstr, onoff ? GET_TEXT(MSG_LCD_ON) : GET_TEXT(MSG_LCD_OFF), true); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, const bool onoff) { | ||||
|       MenuEditItemBase::draw(sel, row, fstr, onoff ? GET_TEXT_F(MSG_LCD_ON) : GET_TEXT_F(MSG_LCD_OFF)); | ||||
|     } | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, bool * const data, ...) { | ||||
|       draw(sel, row, pstr, *data); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, bool * const data, ...) { | ||||
|       draw(sel, row, fstr, *data); | ||||
|     } | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, PGM_P const, bool (*pget)(), ...) { | ||||
|       draw(sel, row, pstr, pget()); | ||||
|     FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, FSTR_P const, bool (*pget)(), ...) { | ||||
|       draw(sel, row, fstr, pget()); | ||||
|     } | ||||
|     static void action(PGM_P const pstr, bool * const ptr, const screenFunc_t callbackFunc=nullptr) { | ||||
|     static void action(FSTR_P const fstr, bool * const ptr, const screenFunc_t callbackFunc=nullptr) { | ||||
|       *ptr ^= true; ui.refresh(); | ||||
|       if (callbackFunc) (*callbackFunc)(); | ||||
|     } | ||||
| @@ -250,16 +250,16 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
|  * | ||||
|  * Examples: | ||||
|  *   BACK_ITEM(MSG_INFO_SCREEN) | ||||
|  *     MenuItem_back::action(plabel, ...) | ||||
|  *     MenuItem_back::draw(sel, row, plabel, ...) | ||||
|  *     MenuItem_back::action(flabel, ...) | ||||
|  *     MenuItem_back::draw(sel, row, flabel, ...) | ||||
|  * | ||||
|  *   ACTION_ITEM(MSG_PAUSE_PRINT, lcd_sdcard_pause) | ||||
|  *     MenuItem_function::action(plabel, lcd_sdcard_pause) | ||||
|  *     MenuItem_function::draw(sel, row, plabel, lcd_sdcard_pause) | ||||
|  *     MenuItem_function::action(flabel, lcd_sdcard_pause) | ||||
|  *     MenuItem_function::draw(sel, row, flabel, lcd_sdcard_pause) | ||||
|  * | ||||
|  *   EDIT_ITEM(int3, MSG_SPEED, &feedrate_percentage, 10, 999) | ||||
|  *     MenuItem_int3::action(plabel, &feedrate_percentage, 10, 999) | ||||
|  *     MenuItem_int3::draw(sel, row, plabel, &feedrate_percentage, 10, 999) | ||||
|  *     MenuItem_int3::action(flabel, &feedrate_percentage, 10, 999) | ||||
|  *     MenuItem_int3::draw(sel, row, flabel, &feedrate_percentage, 10, 999) | ||||
|  */ | ||||
|  | ||||
| #if ENABLED(ENCODER_RATE_MULTIPLIER) | ||||
| @@ -268,19 +268,19 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
|   #define _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER) | ||||
| #endif | ||||
|  | ||||
| #define _MENU_INNER_P(TYPE, USE_MULTIPLIER, PLABEL, V...) do { \ | ||||
|   PGM_P const plabel = PLABEL;                                 \ | ||||
| #define _MENU_INNER_P(TYPE, USE_MULTIPLIER, FLABEL, V...) do { \ | ||||
|   FSTR_P const flabel = FLABEL;                                \ | ||||
|   if (encoderLine == _thisItemNr && ui.use_click()) {          \ | ||||
|     _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER);               \ | ||||
|     MenuItem_##TYPE::action(plabel, ##V);                      \ | ||||
|     MenuItem_##TYPE::action(flabel, ##V);                      \ | ||||
|     if (ui.screen_changed) return;                             \ | ||||
|   }                                                            \ | ||||
|   if (ui.should_draw())                                        \ | ||||
|     MenuItem_##TYPE::draw                                      \ | ||||
|       (encoderLine == _thisItemNr, _lcdLineNr, plabel, ##V);   \ | ||||
|       (encoderLine == _thisItemNr, _lcdLineNr, flabel, ##V);   \ | ||||
| }while(0) | ||||
|  | ||||
| #define _MENU_ITEM_P(TYPE, V...) do { \ | ||||
| #define _MENU_ITEM_F(TYPE, V...) do { \ | ||||
|   if (_menuLineNr == _thisItemNr) {   \ | ||||
|     _skipStatic = false;              \ | ||||
|     _MENU_INNER_P(TYPE, ##V);         \ | ||||
| @@ -289,7 +289,7 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
| }while(0) | ||||
|  | ||||
| // Indexed items set a global index value and optional data | ||||
| #define _MENU_ITEM_N_S_P(TYPE, N, S, V...) do{ \ | ||||
| #define _MENU_ITEM_N_S_F(TYPE, N, S, V...) do{ \ | ||||
|   if (_menuLineNr == _thisItemNr) {            \ | ||||
|     _skipStatic = false;                       \ | ||||
|     MenuItemBase::init(N, S);                  \ | ||||
| @@ -299,7 +299,7 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
| }while(0) | ||||
|  | ||||
| // Indexed items set a global index value | ||||
| #define _MENU_ITEM_N_P(TYPE, N, V...) do{ \ | ||||
| #define _MENU_ITEM_N_F(TYPE, N, V...) do{ \ | ||||
|   if (_menuLineNr == _thisItemNr) {       \ | ||||
|     _skipStatic = false;                  \ | ||||
|     MenuItemBase::itemIndex = N;          \ | ||||
| @@ -309,7 +309,7 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
| }while(0) | ||||
|  | ||||
| // Items with a unique string | ||||
| #define _MENU_ITEM_S_P(TYPE, S, V...) do{ \ | ||||
| #define _MENU_ITEM_S_F(TYPE, S, V...) do{ \ | ||||
|   if (_menuLineNr == _thisItemNr) {       \ | ||||
|     _skipStatic = false;                  \ | ||||
|     MenuItemBase::itemString = S;         \ | ||||
| @@ -321,25 +321,25 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
| // STATIC_ITEM draws a styled string with no highlight. | ||||
| // Parameters: label [, style [, char *value] ] | ||||
|  | ||||
| #define STATIC_ITEM_INNER_P(PLABEL, V...) do{           \ | ||||
| #define STATIC_ITEM_INNER_F(FLABEL, V...) do{           \ | ||||
|   if (_skipStatic && encoderLine <= _thisItemNr) {      \ | ||||
|     ui.encoderPosition += ENCODER_STEPS_PER_MENU_ITEM;  \ | ||||
|     ++encoderLine;                                      \ | ||||
|   }                                                     \ | ||||
|   if (ui.should_draw())                                 \ | ||||
|     MenuItem_static::draw(_lcdLineNr, PLABEL, ##V);     \ | ||||
|     MenuItem_static::draw(_lcdLineNr, FLABEL, ##V);     \ | ||||
| } while(0) | ||||
|  | ||||
| #define STATIC_ITEM_P(PLABEL, V...) do{ \ | ||||
| #define STATIC_ITEM_F(FLABEL, V...) do{ \ | ||||
|   if (_menuLineNr == _thisItemNr)       \ | ||||
|     STATIC_ITEM_INNER_P(PLABEL, ##V);   \ | ||||
|     STATIC_ITEM_INNER_F(FLABEL, ##V);   \ | ||||
|   NEXT_ITEM();                          \ | ||||
| } while(0) | ||||
|  | ||||
| #define STATIC_ITEM_N_P(PLABEL, N, V...) do{ \ | ||||
| #define STATIC_ITEM_N_F(FLABEL, N, V...) do{ \ | ||||
|   if (_menuLineNr == _thisItemNr) {          \ | ||||
|     MenuItemBase::init(N);                   \ | ||||
|     STATIC_ITEM_INNER_P(PLABEL, ##V);        \ | ||||
|     STATIC_ITEM_INNER_F(FLABEL, ##V);        \ | ||||
|   }                                          \ | ||||
|   NEXT_ITEM();                               \ | ||||
| }while(0) | ||||
| @@ -347,124 +347,124 @@ class MenuItem_bool : public MenuEditItemBase { | ||||
| // PSTRING_ITEM is like STATIC_ITEM but it takes | ||||
| // two PSTRs with the style as the last parameter. | ||||
|  | ||||
| #define PSTRING_ITEM_P(PLABEL, PVAL, STYL) do{ \ | ||||
| #define PSTRING_ITEM_F(FLABEL, PVAL, STYL) do{ \ | ||||
|   constexpr int m = 20;                        \ | ||||
|   char msg[m+1];                               \ | ||||
|   msg[0] = ':'; msg[1] = ' ';                  \ | ||||
|   strncpy_P(msg+2, PSTR(PVAL), m-2);           \ | ||||
|   if (msg[m-1] & 0x80) msg[m-1] = '\0';        \ | ||||
|   STATIC_ITEM_P(PLABEL, STYL, msg);            \ | ||||
|   STATIC_ITEM_F(FLABEL, STYL, msg);            \ | ||||
| }while(0) | ||||
|  | ||||
| #define PSTRING_ITEM(LABEL, V...)                     PSTRING_ITEM_P(GET_TEXT(LABEL), ##V) | ||||
| #define PSTRING_ITEM(LABEL, V...)                     PSTRING_ITEM_F(GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define STATIC_ITEM(LABEL, V...)                       STATIC_ITEM_P(GET_TEXT(LABEL), ##V) | ||||
| #define STATIC_ITEM_N(LABEL, N, V...)                STATIC_ITEM_N_P(GET_TEXT(LABEL), N, ##V) | ||||
| #define STATIC_ITEM(LABEL, V...)                       STATIC_ITEM_F(GET_TEXT_F(LABEL), ##V) | ||||
| #define STATIC_ITEM_N(LABEL, N, V...)                STATIC_ITEM_N_F(GET_TEXT_F(LABEL), N, ##V) | ||||
|  | ||||
| #define MENU_ITEM_N_S_P(TYPE, N, S, PLABEL, V...)   _MENU_ITEM_N_S_P(TYPE, N, S, false, PLABEL, ##V) | ||||
| #define MENU_ITEM_N_S(TYPE, N, S, LABEL, V...)       MENU_ITEM_N_S_P(TYPE, N, S, GET_TEXT(LABEL), ##V) | ||||
| #define MENU_ITEM_S_P(TYPE, S, PLABEL, V...)          _MENU_ITEM_S_P(TYPE, S, false, PLABEL, ##V) | ||||
| #define MENU_ITEM_S(TYPE, S, LABEL, V...)              MENU_ITEM_S_P(TYPE, S, GET_TEXT(LABEL), ##V) | ||||
| #define MENU_ITEM_N_P(TYPE, N, PLABEL, V...)          _MENU_ITEM_N_P(TYPE, N, false, PLABEL, ##V) | ||||
| #define MENU_ITEM_N(TYPE, N, LABEL, V...)              MENU_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V) | ||||
| #define MENU_ITEM_P(TYPE, PLABEL, V...)                 _MENU_ITEM_P(TYPE, false, PLABEL, ##V) | ||||
| #define MENU_ITEM(TYPE, LABEL, V...)                     MENU_ITEM_P(TYPE, GET_TEXT(LABEL), ##V) | ||||
| #define MENU_ITEM_N_S_F(TYPE, N, S, FLABEL, V...)   _MENU_ITEM_N_S_F(TYPE, N, S, false, FLABEL, ##V) | ||||
| #define MENU_ITEM_N_S(TYPE, N, S, LABEL, V...)       MENU_ITEM_N_S_F(TYPE, N, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define MENU_ITEM_S_F(TYPE, S, FLABEL, V...)          _MENU_ITEM_S_F(TYPE, S, false, FLABEL, ##V) | ||||
| #define MENU_ITEM_S(TYPE, S, LABEL, V...)              MENU_ITEM_S_F(TYPE, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define MENU_ITEM_N_F(TYPE, N, FLABEL, V...)          _MENU_ITEM_N_F(TYPE, N, false, FLABEL, ##V) | ||||
| #define MENU_ITEM_N(TYPE, N, LABEL, V...)              MENU_ITEM_N_F(TYPE, N, GET_TEXT_F(LABEL), ##V) | ||||
| #define MENU_ITEM_F(TYPE, FLABEL, V...)                 _MENU_ITEM_F(TYPE, false, FLABEL, ##V) | ||||
| #define MENU_ITEM(TYPE, LABEL, V...)                     MENU_ITEM_F(TYPE, GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define BACK_ITEM_P(PLABEL)                              MENU_ITEM_P(back, PLABEL) | ||||
| #define BACK_ITEM_F(FLABEL)                              MENU_ITEM_F(back, FLABEL) | ||||
| #define BACK_ITEM(LABEL)                                   MENU_ITEM(back, LABEL) | ||||
|  | ||||
| #define ACTION_ITEM_N_S_P(N, S, PLABEL, ACTION)      MENU_ITEM_N_S_P(function, N, S, PLABEL, ACTION) | ||||
| #define ACTION_ITEM_N_S(N, S, LABEL, ACTION)       ACTION_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ACTION) | ||||
| #define ACTION_ITEM_S_P(S, PLABEL, ACTION)             MENU_ITEM_S_P(function, S, PLABEL, ACTION) | ||||
| #define ACTION_ITEM_S(S, LABEL, ACTION)              ACTION_ITEM_S_P(S, GET_TEXT(LABEL), ACTION) | ||||
| #define ACTION_ITEM_N_P(N, PLABEL, ACTION)             MENU_ITEM_N_P(function, N, PLABEL, ACTION) | ||||
| #define ACTION_ITEM_N(N, LABEL, ACTION)              ACTION_ITEM_N_P(N, GET_TEXT(LABEL), ACTION) | ||||
| #define ACTION_ITEM_P(PLABEL, ACTION)                    MENU_ITEM_P(function, PLABEL, ACTION) | ||||
| #define ACTION_ITEM(LABEL, ACTION)                     ACTION_ITEM_P(GET_TEXT(LABEL), ACTION) | ||||
| #define ACTION_ITEM_N_S_F(N, S, FLABEL, ACTION)      MENU_ITEM_N_S_F(function, N, S, FLABEL, ACTION) | ||||
| #define ACTION_ITEM_N_S(N, S, LABEL, ACTION)       ACTION_ITEM_N_S_F(N, S, GET_TEXT_F(LABEL), ACTION) | ||||
| #define ACTION_ITEM_S_F(S, FLABEL, ACTION)             MENU_ITEM_S_F(function, S, FLABEL, ACTION) | ||||
| #define ACTION_ITEM_S(S, LABEL, ACTION)              ACTION_ITEM_S_F(S, GET_TEXT_F(LABEL), ACTION) | ||||
| #define ACTION_ITEM_N_F(N, FLABEL, ACTION)             MENU_ITEM_N_F(function, N, FLABEL, ACTION) | ||||
| #define ACTION_ITEM_N(N, LABEL, ACTION)              ACTION_ITEM_N_F(N, GET_TEXT_F(LABEL), ACTION) | ||||
| #define ACTION_ITEM_F(FLABEL, ACTION)                    MENU_ITEM_F(function, FLABEL, ACTION) | ||||
| #define ACTION_ITEM(LABEL, ACTION)                     ACTION_ITEM_F(GET_TEXT_F(LABEL), ACTION) | ||||
|  | ||||
| #define GCODES_ITEM_N_S_P(N, S, PLABEL, GCODES)      MENU_ITEM_N_S_P(gcode, N, S, PLABEL, GCODES) | ||||
| #define GCODES_ITEM_N_S(N, S, LABEL, GCODES)       GCODES_ITEM_N_S_P(N, S, GET_TEXT(LABEL), GCODES) | ||||
| #define GCODES_ITEM_S_P(S, PLABEL, GCODES)             MENU_ITEM_S_P(gcode, S, PLABEL, GCODES) | ||||
| #define GCODES_ITEM_S(S, LABEL, GCODES)              GCODES_ITEM_S_P(S, GET_TEXT(LABEL), GCODES) | ||||
| #define GCODES_ITEM_N_P(N, PLABEL, GCODES)             MENU_ITEM_N_P(gcode, N, PLABEL, GCODES) | ||||
| #define GCODES_ITEM_N(N, LABEL, GCODES)              GCODES_ITEM_N_P(N, GET_TEXT(LABEL), GCODES) | ||||
| #define GCODES_ITEM_P(PLABEL, GCODES)                    MENU_ITEM_P(gcode, PLABEL, GCODES) | ||||
| #define GCODES_ITEM(LABEL, GCODES)                     GCODES_ITEM_P(GET_TEXT(LABEL), GCODES) | ||||
| #define GCODES_ITEM_N_S_F(N, S, FLABEL, GCODES)      MENU_ITEM_N_S_F(gcode, N, S, FLABEL, GCODES) | ||||
| #define GCODES_ITEM_N_S(N, S, LABEL, GCODES)       GCODES_ITEM_N_S_F(N, S, GET_TEXT_F(LABEL), GCODES) | ||||
| #define GCODES_ITEM_S_F(S, FLABEL, GCODES)             MENU_ITEM_S_F(gcode, S, FLABEL, GCODES) | ||||
| #define GCODES_ITEM_S(S, LABEL, GCODES)              GCODES_ITEM_S_F(S, GET_TEXT_F(LABEL), GCODES) | ||||
| #define GCODES_ITEM_N_F(N, FLABEL, GCODES)             MENU_ITEM_N_F(gcode, N, FLABEL, GCODES) | ||||
| #define GCODES_ITEM_N(N, LABEL, GCODES)              GCODES_ITEM_N_F(N, GET_TEXT_F(LABEL), GCODES) | ||||
| #define GCODES_ITEM_F(FLABEL, GCODES)                    MENU_ITEM_F(gcode, FLABEL, GCODES) | ||||
| #define GCODES_ITEM(LABEL, GCODES)                     GCODES_ITEM_F(GET_TEXT_F(LABEL), GCODES) | ||||
|  | ||||
| #define SUBMENU_N_S_P(N, S, PLABEL, DEST)            MENU_ITEM_N_S_P(submenu, N, S, PLABEL, DEST) | ||||
| #define SUBMENU_N_S(N, S, LABEL, DEST)                 SUBMENU_N_S_P(N, S, GET_TEXT(LABEL), DEST) | ||||
| #define SUBMENU_S_P(S, PLABEL, DEST)                   MENU_ITEM_S_P(submenu, S, PLABEL, DEST) | ||||
| #define SUBMENU_S(S, LABEL, DEST)                        SUBMENU_S_P(S, GET_TEXT(LABEL), DEST) | ||||
| #define SUBMENU_N_P(N, PLABEL, DEST)                   MENU_ITEM_N_P(submenu, N, PLABEL, DEST) | ||||
| #define SUBMENU_N(N, LABEL, DEST)                        SUBMENU_N_P(N, GET_TEXT(LABEL), DEST) | ||||
| #define SUBMENU_P(PLABEL, DEST)                          MENU_ITEM_P(submenu, PLABEL, DEST) | ||||
| #define SUBMENU(LABEL, DEST)                               SUBMENU_P(GET_TEXT(LABEL), DEST) | ||||
| #define SUBMENU_N_S_F(N, S, FLABEL, DEST)            MENU_ITEM_N_S_F(submenu, N, S, FLABEL, DEST) | ||||
| #define SUBMENU_N_S(N, S, LABEL, DEST)                 SUBMENU_N_S_F(N, S, GET_TEXT_F(LABEL), DEST) | ||||
| #define SUBMENU_S_F(S, FLABEL, DEST)                   MENU_ITEM_S_F(submenu, S, FLABEL, DEST) | ||||
| #define SUBMENU_S(S, LABEL, DEST)                        SUBMENU_S_F(S, GET_TEXT_F(LABEL), DEST) | ||||
| #define SUBMENU_N_F(N, FLABEL, DEST)                   MENU_ITEM_N_F(submenu, N, FLABEL, DEST) | ||||
| #define SUBMENU_N(N, LABEL, DEST)                        SUBMENU_N_F(N, GET_TEXT_F(LABEL), DEST) | ||||
| #define SUBMENU_F(FLABEL, DEST)                          MENU_ITEM_F(submenu, FLABEL, DEST) | ||||
| #define SUBMENU(LABEL, DEST)                               SUBMENU_F(GET_TEXT_F(LABEL), DEST) | ||||
|  | ||||
| #define EDIT_ITEM_N_S_P(TYPE, N, S, PLABEL, V...)    MENU_ITEM_N_S_P(TYPE, N, S, PLABEL, ##V) | ||||
| #define EDIT_ITEM_N_S(TYPE, N, S, LABEL, V...)       EDIT_ITEM_N_S_P(TYPE, N, S, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_S_P(TYPE, S, PLABEL, V...)           MENU_ITEM_S_P(TYPE, S, PLABEL, ##V) | ||||
| #define EDIT_ITEM_S(TYPE, S, LABEL, V...)              EDIT_ITEM_S_P(TYPE, S, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_N_P(TYPE, N, PLABEL, V...)           MENU_ITEM_N_P(TYPE, N, PLABEL, ##V) | ||||
| #define EDIT_ITEM_N(TYPE, N, LABEL, V...)              EDIT_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_P(TYPE, PLABEL, V...)                  MENU_ITEM_P(TYPE, PLABEL, ##V) | ||||
| #define EDIT_ITEM(TYPE, LABEL, V...)                     EDIT_ITEM_P(TYPE, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_N_S_F(TYPE, N, S, FLABEL, V...)    MENU_ITEM_N_S_F(TYPE, N, S, FLABEL, ##V) | ||||
| #define EDIT_ITEM_N_S(TYPE, N, S, LABEL, V...)       EDIT_ITEM_N_S_F(TYPE, N, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define EDIT_ITEM_S_F(TYPE, S, FLABEL, V...)           MENU_ITEM_S_F(TYPE, S, FLABEL, ##V) | ||||
| #define EDIT_ITEM_S(TYPE, S, LABEL, V...)              EDIT_ITEM_S_F(TYPE, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define EDIT_ITEM_N_F(TYPE, N, FLABEL, V...)           MENU_ITEM_N_F(TYPE, N, FLABEL, ##V) | ||||
| #define EDIT_ITEM_N(TYPE, N, LABEL, V...)              EDIT_ITEM_N_F(TYPE, N, GET_TEXT_F(LABEL), ##V) | ||||
| #define EDIT_ITEM_F(TYPE, FLABEL, V...)                  MENU_ITEM_F(TYPE, FLABEL, ##V) | ||||
| #define EDIT_ITEM(TYPE, LABEL, V...)                     EDIT_ITEM_F(TYPE, GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define EDIT_ITEM_FAST_N_S_P(TYPE, N, S, PLABEL, V...)  _MENU_ITEM_N_S_P(TYPE, N, S, true, PLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST_N_S(TYPE, N, S, LABEL, V...) EDIT_ITEM_FAST_N_S_P(TYPE, N, S, true, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_S_P(TYPE, S, PLABEL, V...)         _MENU_ITEM_S_P(TYPE, S, true, PLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST_S(TYPE, S, LABEL, V...)        EDIT_ITEM_FAST_S_P(TYPE, S, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_N_P(TYPE, N, PLABEL, V...)         _MENU_ITEM_N_P(TYPE, N, true, PLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST_N(TYPE, N, LABEL, V...)        EDIT_ITEM_FAST_N_P(TYPE, N, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_P(TYPE, PLABEL, V...)                _MENU_ITEM_P(TYPE, true, PLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST(TYPE, LABEL, V...)               EDIT_ITEM_FAST_P(TYPE, GET_TEXT(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_N_S_F(TYPE, N, S, FLABEL, V...)  _MENU_ITEM_N_S_F(TYPE, N, S, true, FLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST_N_S(TYPE, N, S, LABEL, V...) EDIT_ITEM_FAST_N_S_F(TYPE, N, S, true, GET_TEXT_F(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_S_F(TYPE, S, FLABEL, V...)         _MENU_ITEM_S_F(TYPE, S, true, FLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST_S(TYPE, S, LABEL, V...)        EDIT_ITEM_FAST_S_F(TYPE, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_N_F(TYPE, N, FLABEL, V...)         _MENU_ITEM_N_F(TYPE, N, true, FLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST_N(TYPE, N, LABEL, V...)        EDIT_ITEM_FAST_N_F(TYPE, N, GET_TEXT_F(LABEL), ##V) | ||||
| #define EDIT_ITEM_FAST_F(TYPE, FLABEL, V...)                _MENU_ITEM_F(TYPE, true, FLABEL, ##V) | ||||
| #define EDIT_ITEM_FAST(TYPE, LABEL, V...)               EDIT_ITEM_FAST_F(TYPE, GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define _CONFIRM_ITEM_INNER_P(PLABEL, V...) do {             \ | ||||
| #define _CONFIRM_ITEM_INNER_F(FLABEL, V...) do {             \ | ||||
|   if (encoderLine == _thisItemNr && ui.use_click()) {        \ | ||||
|     ui.push_current_screen();                                \ | ||||
|     ui.goto_screen([]{MenuItem_confirm::select_screen(V);}); \ | ||||
|     return;                                                  \ | ||||
|   }                                                          \ | ||||
|   if (ui.should_draw()) MenuItem_confirm::draw               \ | ||||
|     (encoderLine == _thisItemNr, _lcdLineNr, PLABEL, ##V);   \ | ||||
|     (encoderLine == _thisItemNr, _lcdLineNr, FLABEL, ##V);   \ | ||||
| }while(0) | ||||
|  | ||||
| // Indexed items set a global index value and optional data | ||||
| #define _CONFIRM_ITEM_P(PLABEL, V...) do { \ | ||||
| #define _CONFIRM_ITEM_F(FLABEL, V...) do { \ | ||||
|   if (_menuLineNr == _thisItemNr) {        \ | ||||
|     _skipStatic = false;                   \ | ||||
|     _CONFIRM_ITEM_INNER_P(PLABEL, ##V);    \ | ||||
|     _CONFIRM_ITEM_INNER_F(FLABEL, ##V);    \ | ||||
|   }                                        \ | ||||
|   NEXT_ITEM();                             \ | ||||
| }while(0) | ||||
|  | ||||
| // Indexed items set a global index value | ||||
| #define _CONFIRM_ITEM_N_S_P(N, S, V...) do{ \ | ||||
| #define _CONFIRM_ITEM_N_S_F(N, S, V...) do{ \ | ||||
|   if (_menuLineNr == _thisItemNr) {         \ | ||||
|     _skipStatic = false;                    \ | ||||
|     MenuItemBase::init(N, S);               \ | ||||
|     _CONFIRM_ITEM_INNER_P(TYPE, ##V);       \ | ||||
|     _CONFIRM_ITEM_INNER_F(TYPE, ##V);       \ | ||||
|   }                                         \ | ||||
|   NEXT_ITEM();                              \ | ||||
| }while(0) | ||||
|  | ||||
| // Indexed items set a global index value | ||||
| #define _CONFIRM_ITEM_N_P(N, V...)              _CONFIRM_ITEM_N_S_P(N, nullptr, V) | ||||
| #define _CONFIRM_ITEM_N_F(N, V...)              _CONFIRM_ITEM_N_S_F(N, nullptr, V) | ||||
|  | ||||
| #define CONFIRM_ITEM_P(PLABEL,A,B,V...)         _CONFIRM_ITEM_P(PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) | ||||
| #define CONFIRM_ITEM(LABEL, V...)                CONFIRM_ITEM_P(GET_TEXT(LABEL), ##V) | ||||
| #define CONFIRM_ITEM_F(FLABEL,A,B,V...)         _CONFIRM_ITEM_F(FLABEL, GET_TEXT_F(A), GET_TEXT_F(B), ##V) | ||||
| #define CONFIRM_ITEM(LABEL, V...)                CONFIRM_ITEM_F(GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define YESNO_ITEM_P(PLABEL, V...)               CONFIRM_ITEM_P(PLABEL, MSG_YES, MSG_NO, ##V) | ||||
| #define YESNO_ITEM(LABEL, V...)                    YESNO_ITEM_P(GET_TEXT(LABEL), ##V) | ||||
| #define YESNO_ITEM_F(FLABEL, V...)               CONFIRM_ITEM_F(FLABEL, MSG_YES, MSG_NO, ##V) | ||||
| #define YESNO_ITEM(LABEL, V...)                    YESNO_ITEM_F(GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define CONFIRM_ITEM_N_S_P(N,S,PLABEL,A,B,V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) | ||||
| #define CONFIRM_ITEM_N_S(N,S,LABEL,V...)         CONFIRM_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) | ||||
| #define CONFIRM_ITEM_N_P(N,PLABEL,A,B,V...)       _CONFIRM_ITEM_N_P(N, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V) | ||||
| #define CONFIRM_ITEM_N(N,LABEL, V...)              CONFIRM_ITEM_N_P(N, GET_TEXT(LABEL), ##V) | ||||
| #define CONFIRM_ITEM_N_S_F(N,S,FLABEL,A,B,V...) _CONFIRM_ITEM_N_S_F(N, S, FLABEL, GET_TEXT_F(A), GET_TEXT_F(B), ##V) | ||||
| #define CONFIRM_ITEM_N_S(N,S,LABEL,V...)         CONFIRM_ITEM_N_S_F(N, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define CONFIRM_ITEM_N_F(N,FLABEL,A,B,V...)       _CONFIRM_ITEM_N_F(N, FLABEL, GET_TEXT_F(A), GET_TEXT_F(B), ##V) | ||||
| #define CONFIRM_ITEM_N(N,LABEL, V...)              CONFIRM_ITEM_N_F(N, GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #define YESNO_ITEM_N_S_P(N,S,PLABEL, V...)      _CONFIRM_ITEM_N_S_P(N, S, PLABEL, MSG_YES, MSG_NO, ##V) | ||||
| #define YESNO_ITEM_N_S(N,S,LABEL, V...)            YESNO_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V) | ||||
| #define YESNO_ITEM_N_P(N,PLABEL, V...)             CONFIRM_ITEM_N_P(N, PLABEL, MSG_YES, MSG_NO, ##V) | ||||
| #define YESNO_ITEM_N(N,LABEL, V...)                  YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V) | ||||
| #define YESNO_ITEM_N_S_F(N,S,FLABEL, V...)      _CONFIRM_ITEM_N_S_F(N, S, FLABEL, MSG_YES, MSG_NO, ##V) | ||||
| #define YESNO_ITEM_N_S(N,S,LABEL, V...)            YESNO_ITEM_N_S_F(N, S, GET_TEXT_F(LABEL), ##V) | ||||
| #define YESNO_ITEM_N_F(N,FLABEL, V...)             CONFIRM_ITEM_N_F(N, FLABEL, MSG_YES, MSG_NO, ##V) | ||||
| #define YESNO_ITEM_N(N,LABEL, V...)                  YESNO_ITEM_N_F(N, GET_TEXT_F(LABEL), ##V) | ||||
|  | ||||
| #if ENABLED(LEVEL_BED_CORNERS) | ||||
|   void _lcd_level_bed_corners(); | ||||
|   | ||||
| @@ -41,14 +41,14 @@ void menu_language() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_MAIN); | ||||
|  | ||||
|   MENU_ITEM_P(function, GET_LANG(LCD_LANGUAGE  )::LANGUAGE, []{ set_lcd_language(0); }); | ||||
|   MENU_ITEM_P(function, GET_LANG(LCD_LANGUAGE_2)::LANGUAGE, []{ set_lcd_language(1); }); | ||||
|   MENU_ITEM_F(function, FPSTR(GET_LANGUAGE_NAME(1)), []{ set_lcd_language(0); }); | ||||
|   MENU_ITEM_F(function, FPSTR(GET_LANGUAGE_NAME(2)), []{ set_lcd_language(1); }); | ||||
|   #if NUM_LANGUAGES > 2 | ||||
|     MENU_ITEM_P(function, GET_LANG(LCD_LANGUAGE_3)::LANGUAGE, []{ set_lcd_language(2); }); | ||||
|     MENU_ITEM_F(function, FPSTR(GET_LANGUAGE_NAME(3)), []{ set_lcd_language(2); }); | ||||
|     #if NUM_LANGUAGES > 3 | ||||
|       MENU_ITEM_P(function, GET_LANG(LCD_LANGUAGE_4)::LANGUAGE, []{ set_lcd_language(3); }); | ||||
|       MENU_ITEM_F(function, FPSTR(GET_LANGUAGE_NAME(4)), []{ set_lcd_language(3); }); | ||||
|       #if NUM_LANGUAGES > 4 | ||||
|         MENU_ITEM_P(function, GET_LANG(LCD_LANGUAGE_5)::LANGUAGE, []{ set_lcd_language(4); }); | ||||
|         MENU_ITEM_F(function, FPSTR(GET_LANGUAGE_NAME(5)), []{ set_lcd_language(4); }); | ||||
|       #endif | ||||
|     #endif | ||||
|   #endif | ||||
|   | ||||
| @@ -124,12 +124,12 @@ void menu_configuration(); | ||||
|       #define _DONE_SCRIPT "" | ||||
|     #endif | ||||
|     #define GCODE_LAMBDA_MAIN(N) []{ _lcd_custom_menu_main_gcode(F(MAIN_MENU_ITEM_##N##_GCODE _DONE_SCRIPT)); } | ||||
|     #define _CUSTOM_ITEM_MAIN(N) ACTION_ITEM_P(PSTR(MAIN_MENU_ITEM_##N##_DESC), GCODE_LAMBDA_MAIN(N)); | ||||
|     #define _CUSTOM_ITEM_MAIN(N) ACTION_ITEM_F(F(MAIN_MENU_ITEM_##N##_DESC), GCODE_LAMBDA_MAIN(N)); | ||||
|     #define _CUSTOM_ITEM_MAIN_CONFIRM(N)          \ | ||||
|       SUBMENU_P(PSTR(MAIN_MENU_ITEM_##N##_DESC), []{ \ | ||||
|       SUBMENU_F(F(MAIN_MENU_ITEM_##N##_DESC), []{ \ | ||||
|           MenuItem_confirm::confirm_screen(       \ | ||||
|             GCODE_LAMBDA_MAIN(N), nullptr,        \ | ||||
|             PSTR(MAIN_MENU_ITEM_##N##_DESC "?")      \ | ||||
|             F(MAIN_MENU_ITEM_##N##_DESC "?")      \ | ||||
|           );                                      \ | ||||
|         }) | ||||
|  | ||||
| @@ -247,10 +247,10 @@ void menu_main() { | ||||
|       if (card_detected) { | ||||
|         if (!card_open) { | ||||
|           #if PIN_EXISTS(SD_DETECT) | ||||
|             GCODES_ITEM(MSG_CHANGE_MEDIA, PSTR("M21"));       // M21 Change Media | ||||
|             GCODES_ITEM(MSG_CHANGE_MEDIA, F("M21"));        // M21 Change Media | ||||
|           #else                                             // - or - | ||||
|             ACTION_ITEM(MSG_RELEASE_MEDIA, []{              // M22 Release Media | ||||
|               queue.inject(PSTR("M22")); | ||||
|               queue.inject(F("M22")); | ||||
|               #if ENABLED(TFT_COLOR_UI) | ||||
|                 // Menu display issue on item removal with multi language selection menu | ||||
|                 if (encoderTopLine > 0) encoderTopLine--; | ||||
| @@ -265,7 +265,7 @@ void menu_main() { | ||||
|         #if PIN_EXISTS(SD_DETECT) | ||||
|           ACTION_ITEM(MSG_NO_MEDIA, nullptr);               // "No Media" | ||||
|         #else | ||||
|           GCODES_ITEM(MSG_ATTACH_MEDIA, PSTR("M21"));         // M21 Attach Media | ||||
|           GCODES_ITEM(MSG_ATTACH_MEDIA, F("M21"));          // M21 Attach Media | ||||
|         #endif | ||||
|       } | ||||
|     }; | ||||
| @@ -279,9 +279,9 @@ void menu_main() { | ||||
|     #if MACHINE_CAN_STOP | ||||
|       SUBMENU(MSG_STOP_PRINT, []{ | ||||
|         MenuItem_confirm::select_screen( | ||||
|           GET_TEXT(MSG_BUTTON_STOP), GET_TEXT(MSG_BACK), | ||||
|           GET_TEXT_F(MSG_BUTTON_STOP), GET_TEXT_F(MSG_BACK), | ||||
|           ui.abort_print, nullptr, | ||||
|           GET_TEXT(MSG_STOP_PRINT), (const char *)nullptr, PSTR("?") | ||||
|           GET_TEXT_F(MSG_STOP_PRINT), (const char *)nullptr, F("?") | ||||
|         ); | ||||
|       }); | ||||
|     #endif | ||||
| @@ -342,7 +342,7 @@ void menu_main() { | ||||
|   #if ENABLED(CUSTOM_MENU_MAIN) | ||||
|     if (TERN1(CUSTOM_MENU_MAIN_ONLY_IDLE, !busy)) { | ||||
|       #ifdef CUSTOM_MENU_MAIN_TITLE | ||||
|         SUBMENU_P(PSTR(CUSTOM_MENU_MAIN_TITLE), custom_menus_main); | ||||
|         SUBMENU_F(F(CUSTOM_MENU_MAIN_TITLE), custom_menus_main); | ||||
|       #else | ||||
|         SUBMENU(MSG_CUSTOM_COMMANDS, custom_menus_main); | ||||
|       #endif | ||||
| @@ -353,7 +353,7 @@ void menu_main() { | ||||
|     #if E_STEPPERS == 1 && DISABLED(FILAMENT_LOAD_UNLOAD_GCODES) | ||||
|       YESNO_ITEM(MSG_FILAMENTCHANGE, | ||||
|         menu_change_filament, nullptr, | ||||
|         GET_TEXT(MSG_FILAMENTCHANGE), (const char *)nullptr, PSTR("?") | ||||
|         GET_TEXT_F(MSG_FILAMENTCHANGE), (const char *)nullptr, F("?") | ||||
|       ); | ||||
|     #else | ||||
|       SUBMENU(MSG_FILAMENTCHANGE, menu_change_filament); | ||||
| @@ -377,13 +377,13 @@ void menu_main() { | ||||
|         CONFIRM_ITEM(MSG_SWITCH_PS_OFF, | ||||
|           MSG_YES, MSG_NO, | ||||
|           ui.poweroff, nullptr, | ||||
|           GET_TEXT(MSG_SWITCH_PS_OFF), (const char *)nullptr, PSTR("?") | ||||
|           GET_TEXT_F(MSG_SWITCH_PS_OFF), (const char *)nullptr, F("?") | ||||
|         ); | ||||
|       #else | ||||
|         ACTION_ITEM(MSG_SWITCH_PS_OFF, ui.poweroff); | ||||
|       #endif | ||||
|     else | ||||
|       GCODES_ITEM(MSG_SWITCH_PS_ON, PSTR("M80")); | ||||
|       GCODES_ITEM(MSG_SWITCH_PS_ON, F("M80")); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) && DISABLED(MEDIA_MENU_AT_TOP) | ||||
| @@ -398,24 +398,24 @@ void menu_main() { | ||||
|       ui.return_to_status(); | ||||
|     }; | ||||
|     #if SERVICE_INTERVAL_1 > 0 | ||||
|       CONFIRM_ITEM_P(PSTR(SERVICE_NAME_1), | ||||
|       CONFIRM_ITEM_F(F(SERVICE_NAME_1), | ||||
|         MSG_BUTTON_RESET, MSG_BUTTON_CANCEL, | ||||
|         []{ _service_reset(1); }, nullptr, | ||||
|         GET_TEXT(MSG_SERVICE_RESET), F(SERVICE_NAME_1), PSTR("?") | ||||
|         GET_TEXT_F(MSG_SERVICE_RESET), F(SERVICE_NAME_1), F("?") | ||||
|       ); | ||||
|     #endif | ||||
|     #if SERVICE_INTERVAL_2 > 0 | ||||
|       CONFIRM_ITEM_P(PSTR(SERVICE_NAME_2), | ||||
|       CONFIRM_ITEM_F(F(SERVICE_NAME_2), | ||||
|         MSG_BUTTON_RESET, MSG_BUTTON_CANCEL, | ||||
|         []{ _service_reset(2); }, nullptr, | ||||
|         GET_TEXT(MSG_SERVICE_RESET), F(SERVICE_NAME_2), PSTR("?") | ||||
|         GET_TEXT_F(MSG_SERVICE_RESET), F(SERVICE_NAME_2), F("?") | ||||
|       ); | ||||
|     #endif | ||||
|     #if SERVICE_INTERVAL_3 > 0 | ||||
|       CONFIRM_ITEM_P(PSTR(SERVICE_NAME_3), | ||||
|       CONFIRM_ITEM_F(F(SERVICE_NAME_3), | ||||
|         MSG_BUTTON_RESET, MSG_BUTTON_CANCEL, | ||||
|         []{ _service_reset(3); }, nullptr, | ||||
|         GET_TEXT(MSG_SERVICE_RESET), F(SERVICE_NAME_3), PSTR("?") | ||||
|         GET_TEXT_F(MSG_SERVICE_RESET), F(SERVICE_NAME_3), F("?") | ||||
|       ); | ||||
|     #endif | ||||
|   #endif | ||||
| @@ -451,9 +451,9 @@ void menu_main() { | ||||
|   #if ENABLED(HOST_SHUTDOWN_MENU_ITEM) && defined(SHUTDOWN_ACTION) | ||||
|     SUBMENU(MSG_HOST_SHUTDOWN, []{ | ||||
|       MenuItem_confirm::select_screen( | ||||
|         GET_TEXT(MSG_BUTTON_PROCEED), GET_TEXT(MSG_BUTTON_CANCEL), | ||||
|         GET_TEXT_F(MSG_BUTTON_PROCEED), GET_TEXT_F(MSG_BUTTON_CANCEL), | ||||
|         []{ ui.return_to_status(); hostui.shutdown(); }, nullptr, | ||||
|         GET_TEXT(MSG_HOST_SHUTDOWN), (const char *)nullptr, PSTR("?") | ||||
|         GET_TEXT_F(MSG_HOST_SHUTDOWN), (const char *)nullptr, F("?") | ||||
|       ); | ||||
|     }); | ||||
|   #endif | ||||
|   | ||||
| @@ -61,10 +61,10 @@ inline void sdcard_start_selected_file() { | ||||
|  | ||||
| class MenuItem_sdfile : public MenuItem_sdbase { | ||||
|   public: | ||||
|     static inline void draw(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard) { | ||||
|       MenuItem_sdbase::draw(sel, row, pstr, theCard, false); | ||||
|     static inline void draw(const bool sel, const uint8_t row, FSTR_P const fstr, CardReader &theCard) { | ||||
|       MenuItem_sdbase::draw(sel, row, fstr, theCard, false); | ||||
|     } | ||||
|     static void action(PGM_P const pstr, CardReader &) { | ||||
|     static void action(FSTR_P const fstr, CardReader &) { | ||||
|       #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) | ||||
|         // Save menu state for the selected file | ||||
|         sd_encoder_position = ui.encoderPosition; | ||||
| @@ -72,30 +72,30 @@ class MenuItem_sdfile : public MenuItem_sdbase { | ||||
|         sd_items = screen_items; | ||||
|       #endif | ||||
|       #if ENABLED(SD_MENU_CONFIRM_START) | ||||
|         MenuItem_submenu::action(pstr, []{ | ||||
|         MenuItem_submenu::action(fstr, []{ | ||||
|           char * const longest = card.longest_filename(); | ||||
|           char buffer[strlen(longest) + 2]; | ||||
|           buffer[0] = ' '; | ||||
|           strcpy(buffer + 1, longest); | ||||
|           MenuItem_confirm::select_screen( | ||||
|             GET_TEXT(MSG_BUTTON_PRINT), GET_TEXT(MSG_BUTTON_CANCEL), | ||||
|             GET_TEXT_F(MSG_BUTTON_PRINT), GET_TEXT_F(MSG_BUTTON_CANCEL), | ||||
|             sdcard_start_selected_file, nullptr, | ||||
|             GET_TEXT(MSG_START_PRINT), buffer, PSTR("?") | ||||
|             GET_TEXT_F(MSG_START_PRINT), buffer, F("?") | ||||
|           ); | ||||
|         }); | ||||
|       #else | ||||
|         sdcard_start_selected_file(); | ||||
|         UNUSED(pstr); | ||||
|         UNUSED(fstr); | ||||
|       #endif | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class MenuItem_sdfolder : public MenuItem_sdbase { | ||||
|   public: | ||||
|     static inline void draw(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard) { | ||||
|       MenuItem_sdbase::draw(sel, row, pstr, theCard, true); | ||||
|     static inline void draw(const bool sel, const uint8_t row, FSTR_P const fstr, CardReader &theCard) { | ||||
|       MenuItem_sdbase::draw(sel, row, fstr, theCard, true); | ||||
|     } | ||||
|     static void action(PGM_P const, CardReader &theCard) { | ||||
|     static void action(FSTR_P const, CardReader &theCard) { | ||||
|       card.cd(theCard.filename); | ||||
|       encoderTopLine = 0; | ||||
|       ui.encoderPosition = 2 * (ENCODER_STEPS_PER_MENU_ITEM); | ||||
| @@ -119,7 +119,7 @@ void menu_media_filelist() { | ||||
|   #if ENABLED(MULTI_VOLUME) | ||||
|     ACTION_ITEM(MSG_BACK, []{ ui.goto_screen(menu_media); }); | ||||
|   #else | ||||
|     BACK_ITEM_P(TERN1(BROWSE_MEDIA_ON_INSERT, screen_history_depth) ? GET_TEXT(MSG_MAIN) : GET_TEXT(MSG_BACK)); | ||||
|     BACK_ITEM_F(TERN1(BROWSE_MEDIA_ON_INSERT, screen_history_depth) ? GET_TEXT_F(MSG_MAIN) : GET_TEXT_F(MSG_BACK)); | ||||
|   #endif | ||||
|   if (card.flag.workDirIsRoot) { | ||||
|     #if !PIN_EXISTS(SD_DETECT) | ||||
| @@ -127,7 +127,7 @@ void menu_media_filelist() { | ||||
|     #endif | ||||
|   } | ||||
|   else if (card.isMounted()) | ||||
|     ACTION_ITEM_P(PSTR(LCD_STR_FOLDER " .."), lcd_sd_updir); | ||||
|     ACTION_ITEM_F(F(LCD_STR_FOLDER " .."), lcd_sd_updir); | ||||
|  | ||||
|   if (ui.should_draw()) for (uint16_t i = 0; i < fileCnt; i++) { | ||||
|     if (_menuLineNr == _thisItemNr) { | ||||
| @@ -146,7 +146,7 @@ void menu_media_filelist() { | ||||
| #if ENABLED(MULTI_VOLUME) | ||||
|   void menu_media_select() { | ||||
|     START_MENU(); | ||||
|     BACK_ITEM_P(TERN1(BROWSE_MEDIA_ON_INSERT, screen_history_depth) ? GET_TEXT(MSG_MAIN) : GET_TEXT(MSG_BACK)); | ||||
|     BACK_ITEM_F(TERN1(BROWSE_MEDIA_ON_INSERT, screen_history_depth) ? GET_TEXT_F(MSG_MAIN) : GET_TEXT_F(MSG_BACK)); | ||||
|     #if ENABLED(VOLUME_SD_ONBOARD) | ||||
|       ACTION_ITEM(MSG_SD_CARD, []{ card.changeMedia(&card.media_driver_sdcard); card.mount(); ui.goto_screen(menu_media_filelist); }); | ||||
|     #endif | ||||
|   | ||||
| @@ -89,15 +89,15 @@ | ||||
|  | ||||
|     char tmp[18]; | ||||
|  | ||||
|     PGM_P const slabel = GET_TEXT(MSG_START_Z); | ||||
|     SUBMENU_P(slabel, []{ _lcd_mixer_gradient_z_edit(false); }); | ||||
|     FSTR_P const slabel = GET_TEXT_F(MSG_START_Z); | ||||
|     SUBMENU_F(slabel, []{ _lcd_mixer_gradient_z_edit(false); }); | ||||
|     MENU_ITEM_ADDON_START_RJ(11); | ||||
|       sprintf_P(tmp, PSTR("%4d.%d mm"), int(mixer.gradient.start_z), int(mixer.gradient.start_z * 10) % 10); | ||||
|       lcd_put_u8str(tmp); | ||||
|     MENU_ITEM_ADDON_END(); | ||||
|  | ||||
|     PGM_P const elabel = GET_TEXT(MSG_END_Z); | ||||
|     SUBMENU_P(elabel, []{ _lcd_mixer_gradient_z_edit(true); }); | ||||
|     FSTR_P const elabel = GET_TEXT_F(MSG_END_Z); | ||||
|     SUBMENU_F(elabel, []{ _lcd_mixer_gradient_z_edit(true); }); | ||||
|     MENU_ITEM_ADDON_START_RJ(11); | ||||
|       sprintf_P(tmp, PSTR("%4d.%d mm"), int(mixer.gradient.end_z), int(mixer.gradient.end_z * 10) % 10); | ||||
|       lcd_put_u8str(tmp); | ||||
| @@ -257,7 +257,7 @@ void menu_mixer() { | ||||
|       ui.return_to_status(); | ||||
|     }, | ||||
|     nullptr, | ||||
|     GET_TEXT(MSG_RESET_VTOOLS), (const char *)nullptr, PSTR("?") | ||||
|     GET_TEXT_F(MSG_RESET_VTOOLS), (const char *)nullptr, F("?") | ||||
|   ); | ||||
|  | ||||
|   #if ENABLED(GRADIENT_MIX) | ||||
|   | ||||
| @@ -57,7 +57,7 @@ | ||||
| // "Motion" > "Move Axis" submenu | ||||
| // | ||||
|  | ||||
| static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { | ||||
| static void _lcd_move_xyz(FSTR_P const name, const AxisEnum axis) { | ||||
|   if (ui.use_click()) return ui.goto_previous_screen_no_defer(); | ||||
|   if (ui.encoderPosition && !ui.manual_move.processing) { | ||||
|     // Get motion limit from software endstops, if any | ||||
| @@ -90,21 +90,21 @@ static void _lcd_move_xyz(PGM_P const name, const AxisEnum axis) { | ||||
|       MenuEditItemBase::draw_edit_screen(name, ui.manual_move.menu_scale >= 0.1f ? (LARGE_AREA_TEST ? ftostr51sign(pos) : ftostr41sign(pos)) : ftostr63(pos)); | ||||
|   } | ||||
| } | ||||
| void lcd_move_x() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_X), X_AXIS); } | ||||
| void lcd_move_x() { _lcd_move_xyz(GET_TEXT_F(MSG_MOVE_X), X_AXIS); } | ||||
| #if HAS_Y_AXIS | ||||
|   void lcd_move_y() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_Y), Y_AXIS); } | ||||
|   void lcd_move_y() { _lcd_move_xyz(GET_TEXT_F(MSG_MOVE_Y), Y_AXIS); } | ||||
| #endif | ||||
| #if HAS_Z_AXIS | ||||
|   void lcd_move_z() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_Z), Z_AXIS); } | ||||
|   void lcd_move_z() { _lcd_move_xyz(GET_TEXT_F(MSG_MOVE_Z), Z_AXIS); } | ||||
| #endif | ||||
| #if HAS_I_AXIS | ||||
|   void lcd_move_i() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_I), I_AXIS); } | ||||
|   void lcd_move_i() { _lcd_move_xyz(GET_TEXT_F(MSG_MOVE_I), I_AXIS); } | ||||
| #endif | ||||
| #if HAS_J_AXIS | ||||
|   void lcd_move_j() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_J), J_AXIS); } | ||||
|   void lcd_move_j() { _lcd_move_xyz(GET_TEXT_F(MSG_MOVE_J), J_AXIS); } | ||||
| #endif | ||||
| #if HAS_K_AXIS | ||||
|   void lcd_move_k() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_K), K_AXIS); } | ||||
|   void lcd_move_k() { _lcd_move_xyz(GET_TEXT_F(MSG_MOVE_K), K_AXIS); } | ||||
| #endif | ||||
|  | ||||
| #if E_MANUAL | ||||
| @@ -123,7 +123,7 @@ void lcd_move_x() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_X), X_AXIS); } | ||||
|     if (ui.should_draw()) { | ||||
|       TERN_(MULTI_E_MANUAL, MenuItemBase::init(eindex)); | ||||
|       MenuEditItemBase::draw_edit_screen( | ||||
|         GET_TEXT(TERN(MULTI_E_MANUAL, MSG_MOVE_EN, MSG_MOVE_E)), | ||||
|         GET_TEXT_F(TERN(MULTI_E_MANUAL, MSG_MOVE_EN, MSG_MOVE_E)), | ||||
|         ftostr41sign(current_position.e | ||||
|           PLUS_TERN0(IS_KINEMATIC, ui.manual_move.offset) | ||||
|           MINUS_TERN0(MANUAL_E_MOVES_RELATIVE, manual_move_e_origin) | ||||
| @@ -195,12 +195,12 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int | ||||
|       char tmp[strlen_P(label) + 10 + 1], numstr[10]; | ||||
|       sprintf_P(tmp, label, dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr)); | ||||
|       #if DISABLED(HAS_GRAPHICAL_TFT) | ||||
|         SUBMENU_P(NUL_STR, []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); | ||||
|         SUBMENU_F(FPSTR(NUL_STR), []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); | ||||
|         MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780)); | ||||
|         lcd_put_u8str(tmp); | ||||
|         MENU_ITEM_ADDON_END(); | ||||
|       #else | ||||
|         SUBMENU_P(tmp, []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); | ||||
|         SUBMENU_F(FPSTR(tmp), []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); | ||||
|       #endif | ||||
|     } | ||||
|   } | ||||
| @@ -219,9 +219,9 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int | ||||
|       if (too_cold) { | ||||
|         ui.goto_screen([]{ | ||||
|           MenuItem_confirm::select_screen( | ||||
|             GET_TEXT(MSG_BUTTON_PROCEED), GET_TEXT(MSG_BACK), | ||||
|             GET_TEXT_F(MSG_BUTTON_PROCEED), GET_TEXT_F(MSG_BACK), | ||||
|             _goto_menu_move_distance_e, nullptr, | ||||
|             GET_TEXT(MSG_HOTEND_TOO_COLD), (const char *)nullptr, PSTR("!") | ||||
|             GET_TEXT_F(MSG_HOTEND_TOO_COLD), (const char *)nullptr, F("!") | ||||
|           ); | ||||
|         }); | ||||
|         return; | ||||
| @@ -266,41 +266,41 @@ void menu_move() { | ||||
|     #endif | ||||
|   } | ||||
|   else | ||||
|     GCODES_ITEM(MSG_AUTO_HOME, G28_STR); | ||||
|     GCODES_ITEM(MSG_AUTO_HOME, FPSTR(G28_STR)); | ||||
|  | ||||
|   #if ANY(SWITCHING_EXTRUDER, SWITCHING_NOZZLE, MAGNETIC_SWITCHING_TOOLHEAD) | ||||
|  | ||||
|     #if EXTRUDERS >= 4 | ||||
|       switch (active_extruder) { | ||||
|         case 0: GCODES_ITEM_N(1, MSG_SELECT_E, PSTR("T1")); break; | ||||
|         case 1: GCODES_ITEM_N(0, MSG_SELECT_E, PSTR("T0")); break; | ||||
|         case 2: GCODES_ITEM_N(3, MSG_SELECT_E, PSTR("T3")); break; | ||||
|         case 3: GCODES_ITEM_N(2, MSG_SELECT_E, PSTR("T2")); break; | ||||
|         case 0: GCODES_ITEM_N(1, MSG_SELECT_E, F("T1")); break; | ||||
|         case 1: GCODES_ITEM_N(0, MSG_SELECT_E, F("T0")); break; | ||||
|         case 2: GCODES_ITEM_N(3, MSG_SELECT_E, F("T3")); break; | ||||
|         case 3: GCODES_ITEM_N(2, MSG_SELECT_E, F("T2")); break; | ||||
|         #if EXTRUDERS == 6 | ||||
|           case 4: GCODES_ITEM_N(5, MSG_SELECT_E, PSTR("T5")); break; | ||||
|           case 5: GCODES_ITEM_N(4, MSG_SELECT_E, PSTR("T4")); break; | ||||
|           case 4: GCODES_ITEM_N(5, MSG_SELECT_E, F("T5")); break; | ||||
|           case 5: GCODES_ITEM_N(4, MSG_SELECT_E, F("T4")); break; | ||||
|         #endif | ||||
|       } | ||||
|     #elif EXTRUDERS == 3 | ||||
|       if (active_extruder < 2) { | ||||
|         if (active_extruder) | ||||
|           GCODES_ITEM_N(0, MSG_SELECT_E, PSTR("T0")); | ||||
|           GCODES_ITEM_N(0, MSG_SELECT_E, F("T0")); | ||||
|         else | ||||
|           GCODES_ITEM_N(1, MSG_SELECT_E, PSTR("T1")); | ||||
|           GCODES_ITEM_N(1, MSG_SELECT_E, F("T1")); | ||||
|       } | ||||
|     #else | ||||
|       if (active_extruder) | ||||
|         GCODES_ITEM_N(0, MSG_SELECT_E, PSTR("T0")); | ||||
|         GCODES_ITEM_N(0, MSG_SELECT_E, F("T0")); | ||||
|       else | ||||
|         GCODES_ITEM_N(1, MSG_SELECT_E, PSTR("T1")); | ||||
|         GCODES_ITEM_N(1, MSG_SELECT_E, F("T1")); | ||||
|     #endif | ||||
|  | ||||
|   #elif ENABLED(DUAL_X_CARRIAGE) | ||||
|  | ||||
|     if (active_extruder) | ||||
|       GCODES_ITEM_N(0, MSG_SELECT_E, PSTR("T0")); | ||||
|       GCODES_ITEM_N(0, MSG_SELECT_E, F("T0")); | ||||
|     else | ||||
|       GCODES_ITEM_N(1, MSG_SELECT_E, PSTR("T1")); | ||||
|       GCODES_ITEM_N(1, MSG_SELECT_E, F("T1")); | ||||
|  | ||||
|   #endif | ||||
|  | ||||
| @@ -338,22 +338,22 @@ void menu_move() { | ||||
|     START_MENU(); | ||||
|     BACK_ITEM(MSG_MOTION); | ||||
|  | ||||
|     GCODES_ITEM(MSG_AUTO_HOME, G28_STR); | ||||
|     GCODES_ITEM_N(X_AXIS, MSG_AUTO_HOME_A, PSTR("G28X")); | ||||
|     GCODES_ITEM(MSG_AUTO_HOME, FPSTR(G28_STR)); | ||||
|     GCODES_ITEM_N(X_AXIS, MSG_AUTO_HOME_A, F("G28X")); | ||||
|     #if HAS_Y_AXIS | ||||
|       GCODES_ITEM_N(Y_AXIS, MSG_AUTO_HOME_A, PSTR("G28Y")); | ||||
|       GCODES_ITEM_N(Y_AXIS, MSG_AUTO_HOME_A, F("G28Y")); | ||||
|     #endif | ||||
|     #if HAS_Z_AXIS | ||||
|       GCODES_ITEM_N(Z_AXIS, MSG_AUTO_HOME_A, PSTR("G28Z")); | ||||
|       GCODES_ITEM_N(Z_AXIS, MSG_AUTO_HOME_A, F("G28Z")); | ||||
|     #endif | ||||
|     #if HAS_I_AXIS | ||||
|       GCODES_ITEM_N(I_AXIS, MSG_AUTO_HOME_A, PSTR("G28" STR_I)); | ||||
|       GCODES_ITEM_N(I_AXIS, MSG_AUTO_HOME_A, F("G28" STR_I)); | ||||
|     #endif | ||||
|     #if HAS_J_AXIS | ||||
|       GCODES_ITEM_N(J_AXIS, MSG_AUTO_HOME_A, PSTR("G28" STR_J)); | ||||
|       GCODES_ITEM_N(J_AXIS, MSG_AUTO_HOME_A, F("G28" STR_J)); | ||||
|     #endif | ||||
|     #if HAS_K_AXIS | ||||
|       GCODES_ITEM_N(K_AXIS, MSG_AUTO_HOME_A, PSTR("G28" STR_K)); | ||||
|       GCODES_ITEM_N(K_AXIS, MSG_AUTO_HOME_A, F("G28" STR_K)); | ||||
|     #endif | ||||
|  | ||||
|     END_MENU(); | ||||
| @@ -390,23 +390,23 @@ void menu_motion() { | ||||
|   #if ENABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU) | ||||
|     SUBMENU(MSG_HOMING, menu_home); | ||||
|   #else | ||||
|     GCODES_ITEM(MSG_AUTO_HOME, G28_STR); | ||||
|     GCODES_ITEM(MSG_AUTO_HOME, FPSTR(G28_STR)); | ||||
|     #if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) | ||||
|       GCODES_ITEM_N(X_AXIS, MSG_AUTO_HOME_A, PSTR("G28X")); | ||||
|       GCODES_ITEM_N(X_AXIS, MSG_AUTO_HOME_A, F("G28X")); | ||||
|       #if HAS_Y_AXIS | ||||
|         GCODES_ITEM_N(Y_AXIS, MSG_AUTO_HOME_A, PSTR("G28Y")); | ||||
|         GCODES_ITEM_N(Y_AXIS, MSG_AUTO_HOME_A, F("G28Y")); | ||||
|       #endif | ||||
|       #if HAS_Z_AXIS | ||||
|         GCODES_ITEM_N(Z_AXIS, MSG_AUTO_HOME_A, PSTR("G28Z")); | ||||
|         GCODES_ITEM_N(Z_AXIS, MSG_AUTO_HOME_A, F("G28Z")); | ||||
|       #endif | ||||
|       #if HAS_I_AXIS | ||||
|         GCODES_ITEM_N(I_AXIS, MSG_AUTO_HOME_A, PSTR("G28" STR_I)); | ||||
|         GCODES_ITEM_N(I_AXIS, MSG_AUTO_HOME_A, F("G28" STR_I)); | ||||
|       #endif | ||||
|       #if HAS_J_AXIS | ||||
|         GCODES_ITEM_N(J_AXIS, MSG_AUTO_HOME_A, PSTR("G28" STR_J)); | ||||
|         GCODES_ITEM_N(J_AXIS, MSG_AUTO_HOME_A, F("G28" STR_J)); | ||||
|       #endif | ||||
|       #if HAS_K_AXIS | ||||
|         GCODES_ITEM_N(K_AXIS, MSG_AUTO_HOME_A, PSTR("G28" STR_K)); | ||||
|         GCODES_ITEM_N(K_AXIS, MSG_AUTO_HOME_A, F("G28" STR_K)); | ||||
|       #endif | ||||
|     #endif | ||||
|   #endif | ||||
| @@ -415,14 +415,14 @@ void menu_motion() { | ||||
|   // Auto-calibration | ||||
|   // | ||||
|   #if ENABLED(CALIBRATION_GCODE) | ||||
|     GCODES_ITEM(MSG_AUTO_CALIBRATE, PSTR("G425")); | ||||
|     GCODES_ITEM(MSG_AUTO_CALIBRATE, F("G425")); | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
|   // Auto Z-Align | ||||
|   // | ||||
|   #if EITHER(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) | ||||
|     GCODES_ITEM(MSG_AUTO_Z_ALIGN, PSTR("G34")); | ||||
|     GCODES_ITEM(MSG_AUTO_Z_ALIGN, F("G34")); | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
| @@ -447,7 +447,7 @@ void menu_motion() { | ||||
|   #elif HAS_LEVELING && DISABLED(SLIM_LCD_MENUS) | ||||
|  | ||||
|     #if DISABLED(PROBE_MANUALLY) | ||||
|       GCODES_ITEM(MSG_LEVEL_BED, PSTR("G29N")); | ||||
|       GCODES_ITEM(MSG_LEVEL_BED, F("G29N")); | ||||
|     #endif | ||||
|  | ||||
|     if (all_axes_homed() && leveling_is_valid()) { | ||||
| @@ -467,13 +467,13 @@ void menu_motion() { | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) | ||||
|     GCODES_ITEM(MSG_M48_TEST, PSTR("G28O\nM48 P10")); | ||||
|     GCODES_ITEM(MSG_M48_TEST, F("G28O\nM48 P10")); | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
|   // Disable Steppers | ||||
|   // | ||||
|   GCODES_ITEM(MSG_DISABLE_STEPPERS, PSTR("M84")); | ||||
|   GCODES_ITEM(MSG_DISABLE_STEPPERS, F("M84")); | ||||
|  | ||||
|   END_MENU(); | ||||
| } | ||||
|   | ||||
| @@ -49,18 +49,18 @@ void Password::menu_password_entry() { | ||||
|   START_MENU(); | ||||
|  | ||||
|   // "Login" or "New Code" | ||||
|   STATIC_ITEM_P(authenticating ? GET_TEXT(MSG_LOGIN_REQUIRED) : GET_TEXT(MSG_EDIT_PASSWORD), SS_CENTER|SS_INVERT); | ||||
|   STATIC_ITEM_F(authenticating ? GET_TEXT_F(MSG_LOGIN_REQUIRED) : GET_TEXT_F(MSG_EDIT_PASSWORD), SS_CENTER|SS_INVERT); | ||||
|  | ||||
|   STATIC_ITEM_P(NUL_STR, SS_CENTER, string); | ||||
|   STATIC_ITEM_F(FPSTR(NUL_STR), SS_CENTER, string); | ||||
|  | ||||
|   #if HAS_MARLINUI_U8GLIB | ||||
|     STATIC_ITEM_P(NUL_STR, SS_CENTER, ""); | ||||
|     STATIC_ITEM_F(FPSTR(NUL_STR), SS_CENTER, ""); | ||||
|   #endif | ||||
|  | ||||
|   // Make the digit edit item look like a sub-menu | ||||
|   PGM_P const label = GET_TEXT(MSG_ENTER_DIGIT); | ||||
|   EDIT_ITEM_P(uint8, label, &editable.uint8, 0, 9, digit_entered); | ||||
|   MENU_ITEM_ADDON_START(utf8_strlen_P(label) + 1); | ||||
|   FSTR_P const label = GET_TEXT_F(MSG_ENTER_DIGIT); | ||||
|   EDIT_ITEM_F(uint8, label, &editable.uint8, 0, 9, digit_entered); | ||||
|   MENU_ITEM_ADDON_START(utf8_strlen(label) + 1); | ||||
|     lcd_put_wchar(' '); | ||||
|     lcd_put_wchar('1' + digit_no); | ||||
|     SETCURSOR_X(LCD_WIDTH - 2); | ||||
|   | ||||
| @@ -62,7 +62,7 @@ void probe_offset_wizard_menu() { | ||||
|   if (LCD_HEIGHT >= 4) | ||||
|     STATIC_ITEM(MSG_MOVE_NOZZLE_TO_BED, SS_CENTER|SS_INVERT); | ||||
|  | ||||
|   STATIC_ITEM_P(PSTR("Z"), SS_CENTER, ftostr42_52(current_position.z)); | ||||
|   STATIC_ITEM_F(F("Z"), SS_CENTER, ftostr42_52(current_position.z)); | ||||
|   STATIC_ITEM(MSG_ZPROBE_ZOFFSET, SS_LEFT, ftostr42_52(calculated_z_offset)); | ||||
|  | ||||
|   SUBMENU(MSG_MOVE_1MM,  []{ _goto_manual_move_z( 1);    }); | ||||
| @@ -75,12 +75,12 @@ void probe_offset_wizard_menu() { | ||||
|                          !UNEAR_ZERO((FINE_MANUAL_MOVE) *  100 - int((FINE_MANUAL_MOVE) *  100)) ? 3 : 2; | ||||
|     sprintf_P(tmp, GET_TEXT(MSG_MOVE_N_MM), dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr)); | ||||
|     #if DISABLED(HAS_GRAPHICAL_TFT) | ||||
|       SUBMENU_P(NUL_STR, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|       SUBMENU_F(FPSTR(NUL_STR), []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|       MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780)); | ||||
|       lcd_put_u8str(tmp); | ||||
|       MENU_ITEM_ADDON_END(); | ||||
|     #else | ||||
|       SUBMENU_P(tmp, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|       SUBMENU_F(tmp, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
| @@ -107,7 +107,7 @@ void probe_offset_wizard_menu() { | ||||
|  | ||||
| void prepare_for_probe_offset_wizard() { | ||||
|   #if defined(PROBE_OFFSET_WIZARD_XY_POS) || !HOMING_Z_WITH_PROBE | ||||
|     if (ui.should_draw()) MenuItem_static::draw(1, GET_TEXT(MSG_PROBE_WIZARD_PROBING)); | ||||
|     if (ui.should_draw()) MenuItem_static::draw(1, GET_TEXT_F(MSG_PROBE_WIZARD_PROBING)); | ||||
|  | ||||
|     if (ui.wait_for_move) return; | ||||
|  | ||||
| @@ -133,7 +133,7 @@ void prepare_for_probe_offset_wizard() { | ||||
|   ui.wait_for_move = true; | ||||
|   current_position += probe.offset_xy; | ||||
|   line_to_current_position(MMM_TO_MMS(XY_PROBE_FEEDRATE)); | ||||
|   ui.synchronize(GET_TEXT(MSG_PROBE_WIZARD_MOVING)); | ||||
|   ui.synchronize(GET_TEXT_F(MSG_PROBE_WIZARD_MOVING)); | ||||
|   ui.wait_for_move = false; | ||||
|  | ||||
|   SET_SOFT_ENDSTOP_LOOSE(true); // Disable soft endstops for free Z movement | ||||
|   | ||||
| @@ -64,7 +64,7 @@ | ||||
|     #if ENABLED(SPINDLE_CHANGE_DIR) | ||||
|       if (!is_enabled) { | ||||
|         editable.state = is_rev; | ||||
|         ACTION_ITEM_P(is_rev ? GET_TEXT(MSG_CUTTER(REVERSE)) : GET_TEXT(MSG_CUTTER(FORWARD)), []{ cutter.set_reverse(!editable.state); }); | ||||
|         ACTION_ITEM_F(is_rev ? GET_TEXT_F(MSG_CUTTER(REVERSE)) : GET_TEXT_F(MSG_CUTTER(FORWARD)), []{ cutter.set_reverse(!editable.state); }); | ||||
|       } | ||||
|     #endif | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,7 @@ | ||||
| #include "../../module/stepper/indirection.h" | ||||
| #include "../../feature/tmc_util.h" | ||||
|  | ||||
| #define TMC_EDIT_STORED_I_RMS(ST,STR) EDIT_ITEM_P(uint16_4, PSTR(STR), &stepper##ST.val_mA, 100, 3000, []{ stepper##ST.refresh_stepper_current(); }) | ||||
| #define TMC_EDIT_STORED_I_RMS(ST,STR) EDIT_ITEM_F(uint16_4, F(STR), &stepper##ST.val_mA, 100, 3000, []{ stepper##ST.refresh_stepper_current(); }) | ||||
|  | ||||
| void menu_tmc_current() { | ||||
|   START_MENU(); | ||||
| @@ -90,7 +90,7 @@ void menu_tmc_current() { | ||||
|  | ||||
| #if ENABLED(HYBRID_THRESHOLD) | ||||
|  | ||||
|   #define TMC_EDIT_STORED_HYBRID_THRS(ST, STR) EDIT_ITEM_P(uint8, PSTR(STR), &stepper##ST.stored.hybrid_thrs, 0, 255, []{ stepper##ST.refresh_hybrid_thrs(); }); | ||||
|   #define TMC_EDIT_STORED_HYBRID_THRS(ST, STR) EDIT_ITEM_F(uint8, F(STR), &stepper##ST.stored.hybrid_thrs, 0, 255, []{ stepper##ST.refresh_hybrid_thrs(); }); | ||||
|  | ||||
|   void menu_tmc_hybrid_thrs() { | ||||
|     START_MENU(); | ||||
| @@ -118,7 +118,7 @@ void menu_tmc_current() { | ||||
|  | ||||
| #if ENABLED(SENSORLESS_HOMING) | ||||
|  | ||||
|   #define TMC_EDIT_STORED_SGT(ST) EDIT_ITEM_P(int4, PSTR(STR_##ST), &stepper##ST.stored.homing_thrs, stepper##ST.sgt_min, stepper##ST.sgt_max, []{ stepper##ST.refresh_homing_thrs(); }); | ||||
|   #define TMC_EDIT_STORED_SGT(ST) EDIT_ITEM_F(int4, F(STR_##ST), &stepper##ST.stored.homing_thrs, stepper##ST.sgt_min, stepper##ST.sgt_max, []{ stepper##ST.refresh_homing_thrs(); }); | ||||
|  | ||||
|   void menu_tmc_homing_thrs() { | ||||
|     START_MENU(); | ||||
| @@ -141,7 +141,7 @@ void menu_tmc_current() { | ||||
|  | ||||
| #if HAS_STEALTHCHOP | ||||
|  | ||||
|   #define TMC_EDIT_STEP_MODE(ST, STR) EDIT_ITEM_P(bool, PSTR(STR), &stepper##ST.stored.stealthChop_enabled, []{ stepper##ST.refresh_stepping_mode(); }) | ||||
|   #define TMC_EDIT_STEP_MODE(ST, STR) EDIT_ITEM_F(bool, F(STR), &stepper##ST.stored.stealthChop_enabled, []{ stepper##ST.refresh_stepping_mode(); }) | ||||
|  | ||||
|   void menu_tmc_step_mode() { | ||||
|     START_MENU(); | ||||
|   | ||||
| @@ -83,7 +83,7 @@ static void tramming_wizard_menu() { | ||||
|  | ||||
|   // Draw a menu item for each tramming point | ||||
|   for (tram_index = 0; tram_index < G35_PROBE_COUNT; tram_index++) | ||||
|     SUBMENU_P((char*)pgm_read_ptr(&tramming_point_name[tram_index]), _menu_single_probe); | ||||
|     SUBMENU_F(FPSTR(pgm_read_ptr(&tramming_point_name[tram_index])), _menu_single_probe); | ||||
|  | ||||
|   ACTION_ITEM(MSG_BUTTON_DONE, []{ | ||||
|     probe.stow(); // Stow before exiting Tramming Wizard | ||||
|   | ||||
| @@ -50,7 +50,7 @@ | ||||
|     #include "../dogm/marlinui_DOGM.h" | ||||
|   #endif | ||||
|  | ||||
|   void _lcd_babystep(const AxisEnum axis, PGM_P const msg) { | ||||
|   void _lcd_babystep(const AxisEnum axis, FSTR_P const fmsg) { | ||||
|     if (ui.use_click()) return ui.goto_previous_screen_no_defer(); | ||||
|     if (ui.encoderPosition) { | ||||
|       const int16_t steps = int16_t(ui.encoderPosition) * ( | ||||
| @@ -66,7 +66,7 @@ | ||||
|     } | ||||
|     if (ui.should_draw()) { | ||||
|       const float mps = planner.mm_per_step[axis]; | ||||
|       MenuEditItemBase::draw_edit_screen(msg, BABYSTEP_TO_STR(mps * babystep.accum)); | ||||
|       MenuEditItemBase::draw_edit_screen(fmsg, BABYSTEP_TO_STR(mps * babystep.accum)); | ||||
|       #if ENABLED(BABYSTEP_DISPLAY_TOTAL) | ||||
|         const bool in_view = TERN1(HAS_MARLINUI_U8GLIB, PAGE_CONTAINS(LCD_PIXEL_HEIGHT - MENU_FONT_HEIGHT, LCD_PIXEL_HEIGHT - 1)); | ||||
|         if (in_view) { | ||||
| @@ -94,12 +94,12 @@ | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(BABYSTEP_XY) | ||||
|     void _lcd_babystep_x() { _lcd_babystep(X_AXIS, GET_TEXT(MSG_BABYSTEP_X)); } | ||||
|     void _lcd_babystep_y() { _lcd_babystep(Y_AXIS, GET_TEXT(MSG_BABYSTEP_Y)); } | ||||
|     void _lcd_babystep_x() { _lcd_babystep(X_AXIS, GET_TEXT_F(MSG_BABYSTEP_X)); } | ||||
|     void _lcd_babystep_y() { _lcd_babystep(Y_AXIS, GET_TEXT_F(MSG_BABYSTEP_Y)); } | ||||
|   #endif | ||||
|  | ||||
|   #if DISABLED(BABYSTEP_ZPROBE_OFFSET) | ||||
|     void _lcd_babystep_z() { _lcd_babystep(Z_AXIS, GET_TEXT(MSG_BABYSTEP_Z)); } | ||||
|     void _lcd_babystep_z() { _lcd_babystep(Z_AXIS, GET_TEXT_F(MSG_BABYSTEP_Z)); } | ||||
|     void lcd_babystep_z()  { _lcd_babystep_go(_lcd_babystep_z); } | ||||
|   #endif | ||||
|  | ||||
|   | ||||
| @@ -67,7 +67,7 @@ inline float rounded_mesh_value() { | ||||
|  * - Draw the graphical overlay, if enabled. | ||||
|  * - Update the 'refresh' state according to the display type | ||||
|  */ | ||||
| void _lcd_mesh_fine_tune(PGM_P const msg) { | ||||
| void _lcd_mesh_fine_tune(FSTR_P const fmsg) { | ||||
|   constexpr float mesh_edit_step = 1.0f / 200.0f; | ||||
|   ui.defer_status_screen(); | ||||
|   if (bedlevel.encoder_diff) { | ||||
| @@ -82,7 +82,7 @@ void _lcd_mesh_fine_tune(PGM_P const msg) { | ||||
|  | ||||
|   if (ui.should_draw()) { | ||||
|     const float rounded_f = rounded_mesh_value(); | ||||
|     MenuEditItemBase::draw_edit_screen(msg, ftostr43sign(rounded_f)); | ||||
|     MenuEditItemBase::draw_edit_screen(fmsg, ftostr43sign(rounded_f)); | ||||
|     TERN_(MESH_EDIT_GFX_OVERLAY, ui.zoffset_overlay(rounded_f)); | ||||
|     TERN_(HAS_GRAPHICAL_TFT, ui.refresh(LCDVIEW_NONE)); | ||||
|   } | ||||
| @@ -95,7 +95,7 @@ void _lcd_mesh_fine_tune(PGM_P const msg) { | ||||
| void MarlinUI::ubl_mesh_edit_start(const_float_t initial) { | ||||
|   TERN_(HAS_GRAPHICAL_TFT, clear_lcd()); | ||||
|   mesh_edit_accumulator = initial; | ||||
|   goto_screen([]{ _lcd_mesh_fine_tune(GET_TEXT(MSG_MESH_EDIT_Z)); }); | ||||
|   goto_screen([]{ _lcd_mesh_fine_tune(GET_TEXT_F(MSG_MESH_EDIT_Z)); }); | ||||
| } | ||||
|  | ||||
| // | ||||
| @@ -176,8 +176,8 @@ void _menu_ubl_height_adjust() { | ||||
| void _lcd_ubl_edit_mesh() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_UBL_TOOLS); | ||||
|   GCODES_ITEM(MSG_UBL_FINE_TUNE_ALL, PSTR("G29P4RT")); | ||||
|   GCODES_ITEM(MSG_UBL_FINE_TUNE_CLOSEST, PSTR("G29P4T")); | ||||
|   GCODES_ITEM(MSG_UBL_FINE_TUNE_ALL, F("G29P4RT")); | ||||
|   GCODES_ITEM(MSG_UBL_FINE_TUNE_CLOSEST, F("G29P4T")); | ||||
|   SUBMENU(MSG_UBL_MESH_HEIGHT_ADJUST, _menu_ubl_height_adjust); | ||||
|   ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status); | ||||
|   END_MENU(); | ||||
| @@ -211,10 +211,10 @@ void _lcd_ubl_edit_mesh() { | ||||
|     #if HAS_PREHEAT | ||||
|       #if HAS_HEATED_BED | ||||
|         #define VALIDATE_MESH_GCODE_ITEM(M) \ | ||||
|           GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, PSTR("G28\nG26CPI" STRINGIFY(M))); | ||||
|           GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPI" STRINGIFY(M))); | ||||
|       #else | ||||
|         #define VALIDATE_MESH_GCODE_ITEM(M) \ | ||||
|           GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, PSTR("G28\nG26CPB0I" STRINGIFY(M))); | ||||
|           GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPB0I" STRINGIFY(M))); | ||||
|       #endif | ||||
|       REPEAT(PREHEAT_COUNT, VALIDATE_MESH_GCODE_ITEM) | ||||
|     #endif | ||||
| @@ -255,7 +255,7 @@ void _lcd_ubl_grid_level() { | ||||
| void _lcd_ubl_mesh_leveling() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_UBL_TOOLS); | ||||
|   GCODES_ITEM(MSG_UBL_3POINT_MESH_LEVELING, PSTR("G29J0")); | ||||
|   GCODES_ITEM(MSG_UBL_3POINT_MESH_LEVELING, F("G29J0")); | ||||
|   SUBMENU(MSG_UBL_GRID_MESH_LEVELING, _lcd_ubl_grid_level); | ||||
|   ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status); | ||||
|   END_MENU(); | ||||
| @@ -284,8 +284,8 @@ void _menu_ubl_fillin() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_UBL_BUILD_MESH_MENU); | ||||
|   EDIT_ITEM(int3, MSG_UBL_FILLIN_AMOUNT, &ubl_fillin_amount, 0, 9, _lcd_ubl_fillin_amount_cmd); | ||||
|   GCODES_ITEM(MSG_UBL_SMART_FILLIN, PSTR("G29P3T0")); | ||||
|   GCODES_ITEM(MSG_UBL_MANUAL_FILLIN, PSTR("G29P2BT0")); | ||||
|   GCODES_ITEM(MSG_UBL_SMART_FILLIN, F("G29P3T0")); | ||||
|   GCODES_ITEM(MSG_UBL_MANUAL_FILLIN, F("G29P2BT0")); | ||||
|   ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status); | ||||
|   END_MENU(); | ||||
| } | ||||
| @@ -318,7 +318,7 @@ void _lcd_ubl_build_mesh() { | ||||
|       #define PREHEAT_BED_GCODE(M) "" | ||||
|     #endif | ||||
|     #define BUILD_MESH_GCODE_ITEM(M) GCODES_ITEM_S(ui.get_preheat_label(M), MSG_UBL_BUILD_MESH_M, \ | ||||
|       PSTR( \ | ||||
|       F( \ | ||||
|         "G28\n" \ | ||||
|         PREHEAT_BED_GCODE(M) \ | ||||
|         "M109I" STRINGIFY(M) "\n" \ | ||||
| @@ -342,11 +342,11 @@ void _lcd_ubl_build_mesh() { | ||||
|   #endif // HAS_PREHEAT | ||||
|  | ||||
|   SUBMENU(MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_custom_mesh); | ||||
|   GCODES_ITEM(MSG_UBL_BUILD_COLD_MESH, PSTR("G29NP1")); | ||||
|   GCODES_ITEM(MSG_UBL_BUILD_COLD_MESH, F("G29NP1")); | ||||
|   SUBMENU(MSG_UBL_FILLIN_MESH, _menu_ubl_fillin); | ||||
|   GCODES_ITEM(MSG_UBL_CONTINUE_MESH, PSTR("G29P1C")); | ||||
|   GCODES_ITEM(MSG_UBL_CONTINUE_MESH, F("G29P1C")); | ||||
|   ACTION_ITEM(MSG_UBL_INVALIDATE_ALL, _lcd_ubl_invalidate); | ||||
|   GCODES_ITEM(MSG_UBL_INVALIDATE_CLOSEST, PSTR("G29I")); | ||||
|   GCODES_ITEM(MSG_UBL_INVALIDATE_CLOSEST, F("G29I")); | ||||
|   ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status); | ||||
|   END_MENU(); | ||||
| } | ||||
| @@ -354,14 +354,14 @@ void _lcd_ubl_build_mesh() { | ||||
| /** | ||||
|  * UBL Load / Save Mesh Commands | ||||
|  */ | ||||
| inline void _lcd_ubl_load_save_cmd(const char loadsave, PGM_P const msg) { | ||||
| inline void _lcd_ubl_load_save_cmd(const char loadsave, FSTR_P const fmsg) { | ||||
|   char ubl_lcd_gcode[40]; | ||||
|   sprintf_P(ubl_lcd_gcode, PSTR("G29%c%i\nM117 "), loadsave, ubl_storage_slot); | ||||
|   sprintf_P(&ubl_lcd_gcode[strlen(ubl_lcd_gcode)], msg, ubl_storage_slot); | ||||
|   sprintf_P(&ubl_lcd_gcode[strlen(ubl_lcd_gcode)], FTOP(fmsg), ubl_storage_slot); | ||||
|   gcode.process_subcommands_now(ubl_lcd_gcode); | ||||
| } | ||||
| void _lcd_ubl_load_mesh_cmd() { _lcd_ubl_load_save_cmd('L', GET_TEXT(MSG_MESH_LOADED)); } | ||||
| void _lcd_ubl_save_mesh_cmd() { _lcd_ubl_load_save_cmd('S', GET_TEXT(MSG_MESH_SAVED)); } | ||||
| void _lcd_ubl_load_mesh_cmd() { _lcd_ubl_load_save_cmd('L', GET_TEXT_F(MSG_MESH_LOADED)); } | ||||
| void _lcd_ubl_save_mesh_cmd() { _lcd_ubl_load_save_cmd('S', GET_TEXT_F(MSG_MESH_SAVED)); } | ||||
|  | ||||
| /** | ||||
|  * UBL Mesh Storage submenu | ||||
| @@ -531,9 +531,9 @@ void _ubl_goto_map_screen() { | ||||
| void _lcd_ubl_output_map() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_UBL_LEVEL_BED); | ||||
|   GCODES_ITEM(MSG_UBL_OUTPUT_MAP_HOST, PSTR("G29T0")); | ||||
|   GCODES_ITEM(MSG_UBL_OUTPUT_MAP_CSV, PSTR("G29T1")); | ||||
|   GCODES_ITEM(MSG_UBL_OUTPUT_MAP_BACKUP, PSTR("G29S-1")); | ||||
|   GCODES_ITEM(MSG_UBL_OUTPUT_MAP_HOST, F("G29T0")); | ||||
|   GCODES_ITEM(MSG_UBL_OUTPUT_MAP_CSV, F("G29T1")); | ||||
|   GCODES_ITEM(MSG_UBL_OUTPUT_MAP_BACKUP, F("G29S-1")); | ||||
|   END_MENU(); | ||||
| } | ||||
|  | ||||
| @@ -550,7 +550,7 @@ void _menu_ubl_tools() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_UBL_LEVEL_BED); | ||||
|   SUBMENU(MSG_UBL_BUILD_MESH_MENU, _lcd_ubl_build_mesh); | ||||
|   GCODES_ITEM(MSG_UBL_MANUAL_MESH, PSTR("G29I999\nG29P2BT0")); | ||||
|   GCODES_ITEM(MSG_UBL_MANUAL_MESH, F("G29I999\nG29P2BT0")); | ||||
|   #if ENABLED(G26_MESH_VALIDATION) | ||||
|     SUBMENU(MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); | ||||
|   #endif | ||||
| @@ -576,12 +576,12 @@ void _menu_ubl_tools() { | ||||
|   void _lcd_ubl_step_by_step() { | ||||
|     START_MENU(); | ||||
|     BACK_ITEM(MSG_UBL_LEVEL_BED); | ||||
|     GCODES_ITEM(MSG_UBL_1_BUILD_COLD_MESH, PSTR("G29NP1")); | ||||
|     GCODES_ITEM(MSG_UBL_2_SMART_FILLIN, PSTR("G29P3T0")); | ||||
|     GCODES_ITEM(MSG_UBL_1_BUILD_COLD_MESH, F("G29NP1")); | ||||
|     GCODES_ITEM(MSG_UBL_2_SMART_FILLIN, F("G29P3T0")); | ||||
|     SUBMENU(MSG_UBL_3_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); | ||||
|     GCODES_ITEM(MSG_UBL_4_FINE_TUNE_ALL, PSTR("G29P4RT")); | ||||
|     GCODES_ITEM(MSG_UBL_4_FINE_TUNE_ALL, F("G29P4RT")); | ||||
|     SUBMENU(MSG_UBL_5_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); | ||||
|     GCODES_ITEM(MSG_UBL_6_FINE_TUNE_ALL, PSTR("G29P4RT")); | ||||
|     GCODES_ITEM(MSG_UBL_6_FINE_TUNE_ALL, F("G29P4RT")); | ||||
|     ACTION_ITEM(MSG_UBL_7_SAVE_MESH, _lcd_ubl_save_mesh_cmd); | ||||
|     END_MENU(); | ||||
|   } | ||||
| @@ -650,9 +650,9 @@ void _lcd_ubl_level_bed() { | ||||
|   START_MENU(); | ||||
|   BACK_ITEM(MSG_MOTION); | ||||
|   if (planner.leveling_active) | ||||
|     GCODES_ITEM(MSG_UBL_DEACTIVATE_MESH, PSTR("G29D")); | ||||
|     GCODES_ITEM(MSG_UBL_DEACTIVATE_MESH, F("G29D")); | ||||
|   else | ||||
|     GCODES_ITEM(MSG_UBL_ACTIVATE_MESH, PSTR("G29A")); | ||||
|     GCODES_ITEM(MSG_UBL_ACTIVATE_MESH, F("G29A")); | ||||
|   #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) | ||||
|     editable.decimal = planner.z_fade_height; | ||||
|     EDIT_ITEM_FAST(float3, MSG_Z_FADE_HEIGHT, &editable.decimal, 0, 100, []{ set_z_fade_height(editable.decimal); }); | ||||
| @@ -667,7 +667,7 @@ void _lcd_ubl_level_bed() { | ||||
|   SUBMENU(MSG_UBL_STORAGE_MESH_MENU, _lcd_ubl_storage_mesh); | ||||
|   SUBMENU(MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map); | ||||
|   SUBMENU(MSG_UBL_TOOLS, _menu_ubl_tools); | ||||
|   GCODES_ITEM(MSG_UBL_INFO_UBL, PSTR("G29W")); | ||||
|   GCODES_ITEM(MSG_UBL_INFO_UBL, F("G29W")); | ||||
|   END_MENU(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -51,7 +51,7 @@ void xatc_wizard_done() { | ||||
|     ui.goto_screen(menu_advanced_settings); | ||||
|   } | ||||
|   if (ui.should_draw()) | ||||
|     MenuItem_static::draw(LCD_HEIGHT >= 4, GET_TEXT(MSG_XATC_DONE)); | ||||
|     MenuItem_static::draw(LCD_HEIGHT >= 4, GET_TEXT_F(MSG_XATC_DONE)); | ||||
|   ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); | ||||
| } | ||||
|  | ||||
| @@ -62,14 +62,14 @@ void xatc_wizard_goto_next_point(); | ||||
| // | ||||
| void xatc_wizard_update_z_offset() { | ||||
|   MenuItem_confirm::select_screen( | ||||
|       GET_TEXT(MSG_YES), GET_TEXT(MSG_NO) | ||||
|       GET_TEXT_F(MSG_YES), GET_TEXT_F(MSG_NO) | ||||
|     , []{ | ||||
|         probe.offset.z = z_offset; | ||||
|         ui.goto_screen(xatc_wizard_done); | ||||
|       } | ||||
|     , xatc_wizard_done | ||||
|     , GET_TEXT(MSG_XATC_UPDATE_Z_OFFSET) | ||||
|     , ftostr42_52(z_offset), PSTR("?") | ||||
|     , GET_TEXT_F(MSG_XATC_UPDATE_Z_OFFSET) | ||||
|     , ftostr42_52(z_offset), F("?") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @@ -93,7 +93,7 @@ void xatc_wizard_menu() { | ||||
|   if (LCD_HEIGHT >= 4) | ||||
|     STATIC_ITEM(MSG_MOVE_NOZZLE_TO_BED, SS_CENTER|SS_INVERT); | ||||
|  | ||||
|   STATIC_ITEM_P(PSTR("Z="), SS_CENTER, ftostr42_52(current_position.z)); | ||||
|   STATIC_ITEM_F(F("Z="), SS_CENTER, ftostr42_52(current_position.z)); | ||||
|   STATIC_ITEM(MSG_ZPROBE_ZOFFSET, SS_LEFT, ftostr42_52(calculated_z_offset)); | ||||
|  | ||||
|   SUBMENU(MSG_MOVE_1MM,  []{ _goto_manual_move_z( 1);    }); | ||||
| @@ -106,12 +106,12 @@ void xatc_wizard_menu() { | ||||
|                          !UNEAR_ZERO((FINE_MANUAL_MOVE) *  100 - int((FINE_MANUAL_MOVE) *  100)) ? 3 : 2; | ||||
|     sprintf_P(tmp, GET_TEXT(MSG_MOVE_N_MM), dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr)); | ||||
|     #if DISABLED(HAS_GRAPHICAL_TFT) | ||||
|       SUBMENU_P(NUL_STR, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|       SUBMENU_F(FPSTR(NUL_STR), []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|       MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780)); | ||||
|       lcd_put_u8str(tmp); | ||||
|       MENU_ITEM_ADDON_END(); | ||||
|     #else | ||||
|       SUBMENU_P(tmp, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|       SUBMENU_F(FPSTR(tmp), []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
| @@ -127,7 +127,7 @@ void xatc_wizard_moving() { | ||||
|   if (ui.should_draw()) { | ||||
|     char msg[10]; | ||||
|     sprintf_P(msg, PSTR("%i / %u"), manual_probe_index + 1, XATC_MAX_POINTS); | ||||
|     MenuEditItemBase::draw_edit_screen(GET_TEXT(MSG_LEVEL_BED_NEXT_POINT), msg); | ||||
|     MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), msg); | ||||
|   } | ||||
|   ui.refresh(LCDVIEW_CALL_NO_REDRAW); | ||||
|   if (!ui.wait_for_move) ui.goto_screen(xatc_wizard_menu); | ||||
| @@ -180,7 +180,7 @@ void xatc_wizard_goto_next_point() { | ||||
| // | ||||
| void xatc_wizard_homing_done() { | ||||
|   if (ui.should_draw()) { | ||||
|     MenuItem_static::draw(1, GET_TEXT(MSG_LEVEL_BED_WAITING)); | ||||
|     MenuItem_static::draw(1, GET_TEXT_F(MSG_LEVEL_BED_WAITING)); | ||||
|  | ||||
|     // Color UI needs a control to detect a touch | ||||
|     #if BOTH(TOUCH_SCREEN, HAS_GRAPHICAL_TFT) | ||||
|   | ||||
| @@ -89,13 +89,13 @@ uint8_t read_byte(uint8_t *byte) { return *byte; } | ||||
| /** | ||||
|  * Add a string, applying substitutions for the following characters: | ||||
|  * | ||||
|  *   $ displays an inserted C-string given by the itemString parameter | ||||
|  *   $ displays an inserted C-string given by the inStr parameter | ||||
|  *   = 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 | ||||
|  */ | ||||
| void TFT_String::add(uint8_t *string, int8_t index, uint8_t *itemString/*=nullptr*/) { | ||||
| void TFT_String::add(uint8_t *string, int8_t index, uint8_t *inStr/*=nullptr*/) { | ||||
|   wchar_t wchar; | ||||
|  | ||||
|   while (*string) { | ||||
| @@ -113,8 +113,8 @@ void TFT_String::add(uint8_t *string, int8_t index, uint8_t *itemString/*=nullpt | ||||
|       else | ||||
|         add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED)); | ||||
|     } | ||||
|     else if (ch == '$' && itemString) | ||||
|       add(itemString); | ||||
|     else if (ch == '$' && inStr) | ||||
|       add(inStr); | ||||
|     else if (ch == '@') | ||||
|       add_character(axis_codes[index]); | ||||
|     else | ||||
|   | ||||
| @@ -86,13 +86,19 @@ class TFT_String { | ||||
|     static void set(); | ||||
|     static void add(uint8_t character) { add_character(character); eol(); } | ||||
|     static void add(uint8_t *string, uint8_t max_len=MAX_STRING_LENGTH); | ||||
|     static void add(uint8_t *string, int8_t index, uint8_t *itemString=nullptr); | ||||
|     static void add(uint8_t *string, int8_t index, uint8_t *inStr=nullptr); | ||||
|     static void set(uint8_t *string) { set(); add(string); }; | ||||
|     static void set(uint8_t *string, int8_t index, const char *itemString=nullptr) { set(); add(string, index, (uint8_t *)itemString); }; | ||||
|     static void set(uint8_t *string, int8_t index, const char *inStr=nullptr) { set(); add(string, index, (uint8_t *)inStr); }; | ||||
|     static void set(const char *string) { set((uint8_t *)string); } | ||||
|     static void set(const char *string, int8_t index, const char *itemString=nullptr) { set((uint8_t *)string, index, itemString); } | ||||
|     static void set(const char *string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)string, index, inStr); } | ||||
|     static void add(const char *string) { add((uint8_t *)string); } | ||||
|  | ||||
|     static void add(FSTR_P const string, uint8_t max_len=MAX_STRING_LENGTH) { add((uint8_t *)FTOP(string), max_len); } | ||||
|     static void add(FSTR_P const string, int8_t index, uint8_t *inStr=nullptr) { add((uint8_t *)FTOP(string), index, inStr); } | ||||
|     static void set(FSTR_P const string) { set((uint8_t *)FTOP(string)); } | ||||
|     static void set(FSTR_P const string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)FTOP(string), index, inStr); } | ||||
|     static void add(FSTR_P const string) { add((uint8_t *)FTOP(string)); } | ||||
|  | ||||
|     static void trim(uint8_t character=0x20); | ||||
|     static void rtrim(uint8_t character=0x20); | ||||
|     static void ltrim(uint8_t character=0x20); | ||||
|   | ||||
| @@ -189,26 +189,26 @@ void Touch::touch(touch_control_t *control) { | ||||
|       #if HAS_HOTEND | ||||
|         if (heater >= 0) { // HotEnd | ||||
|           #if HOTENDS == 1 | ||||
|             MenuItem_int3::action((const char *)GET_TEXT_F(MSG_NOZZLE), &thermalManager.temp_hotend[0].target, 0, thermalManager.hotend_max_target(0), []{ thermalManager.start_watching_hotend(0); }); | ||||
|             MenuItem_int3::action(GET_TEXT_F(MSG_NOZZLE), &thermalManager.temp_hotend[0].target, 0, thermalManager.hotend_max_target(0), []{ thermalManager.start_watching_hotend(0); }); | ||||
|           #else | ||||
|             MenuItemBase::itemIndex = heater; | ||||
|             MenuItem_int3::action((const char *)GET_TEXT_F(MSG_NOZZLE_N), &thermalManager.temp_hotend[heater].target, 0, thermalManager.hotend_max_target(heater), []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); | ||||
|             MenuItem_int3::action(GET_TEXT_F(MSG_NOZZLE_N), &thermalManager.temp_hotend[heater].target, 0, thermalManager.hotend_max_target(heater), []{ thermalManager.start_watching_hotend(MenuItemBase::itemIndex); }); | ||||
|           #endif | ||||
|         } | ||||
|       #endif | ||||
|       #if HAS_HEATED_BED | ||||
|         else if (heater == H_BED) { | ||||
|           MenuItem_int3::action((const char *)GET_TEXT_F(MSG_BED), &thermalManager.temp_bed.target, 0, BED_MAX_TARGET, thermalManager.start_watching_bed); | ||||
|           MenuItem_int3::action(GET_TEXT_F(MSG_BED), &thermalManager.temp_bed.target, 0, BED_MAX_TARGET, thermalManager.start_watching_bed); | ||||
|         } | ||||
|       #endif | ||||
|       #if HAS_HEATED_CHAMBER | ||||
|         else if (heater == H_CHAMBER) { | ||||
|           MenuItem_int3::action((const char *)GET_TEXT_F(MSG_CHAMBER), &thermalManager.temp_chamber.target, 0, CHAMBER_MAX_TARGET, thermalManager.start_watching_chamber); | ||||
|           MenuItem_int3::action(GET_TEXT_F(MSG_CHAMBER), &thermalManager.temp_chamber.target, 0, CHAMBER_MAX_TARGET, thermalManager.start_watching_chamber); | ||||
|         } | ||||
|       #endif | ||||
|       #if HAS_COOLER | ||||
|         else if (heater == H_COOLER) { | ||||
|           MenuItem_int3::action((const char *)GET_TEXT_F(MSG_COOLER), &thermalManager.temp_cooler.target, 0, COOLER_MAX_TARGET, thermalManager.start_watching_cooler); | ||||
|           MenuItem_int3::action(GET_TEXT_F(MSG_COOLER), &thermalManager.temp_cooler.target, 0, COOLER_MAX_TARGET, thermalManager.start_watching_cooler); | ||||
|         } | ||||
|       #endif | ||||
|  | ||||
| @@ -218,19 +218,19 @@ void Touch::touch(touch_control_t *control) { | ||||
|       static uint8_t fan, fan_speed; | ||||
|       fan = 0; | ||||
|       fan_speed = thermalManager.fan_speed[fan]; | ||||
|       MenuItem_percent::action((const char *)GET_TEXT_F(MSG_FIRST_FAN_SPEED), &fan_speed, 0, 255, []{ thermalManager.set_fan_speed(fan, fan_speed); }); | ||||
|       MenuItem_percent::action(GET_TEXT_F(MSG_FIRST_FAN_SPEED), &fan_speed, 0, 255, []{ thermalManager.set_fan_speed(fan, fan_speed); }); | ||||
|       break; | ||||
|     case FEEDRATE: | ||||
|       ui.clear_lcd(); | ||||
|       MenuItem_int3::action((const char *)GET_TEXT_F(MSG_SPEED), &feedrate_percentage, 10, 999); | ||||
|       MenuItem_int3::action(GET_TEXT_F(MSG_SPEED), &feedrate_percentage, 10, 999); | ||||
|       break; | ||||
|     case FLOWRATE: | ||||
|       ui.clear_lcd(); | ||||
|       MenuItemBase::itemIndex = control->data; | ||||
|       #if EXTRUDERS == 1 | ||||
|         MenuItem_int3::action((const char *)GET_TEXT_F(MSG_FLOW), &planner.flow_percentage[MenuItemBase::itemIndex], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); | ||||
|         MenuItem_int3::action(GET_TEXT_F(MSG_FLOW), &planner.flow_percentage[MenuItemBase::itemIndex], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); | ||||
|       #else | ||||
|         MenuItem_int3::action((const char *)GET_TEXT_F(MSG_FLOW_N), &planner.flow_percentage[MenuItemBase::itemIndex], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); | ||||
|         MenuItem_int3::action(GET_TEXT_F(MSG_FLOW_N), &planner.flow_percentage[MenuItemBase::itemIndex], 10, 999, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); | ||||
|       #endif | ||||
|       break; | ||||
|  | ||||
|   | ||||
| @@ -105,12 +105,12 @@ void MarlinUI::draw_kill_screen() { | ||||
|  | ||||
|   line++; | ||||
|   menu_line(line++, COLOR_KILL_SCREEN_BG); | ||||
|   tft_string.set(GET_TEXT(MSG_HALTED)); | ||||
|   tft_string.set(GET_TEXT_F(MSG_HALTED)); | ||||
|   tft_string.trim(); | ||||
|   tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); | ||||
|  | ||||
|   menu_line(line++, COLOR_KILL_SCREEN_BG); | ||||
|   tft_string.set(GET_TEXT(MSG_PLEASE_RESET)); | ||||
|   tft_string.set(GET_TEXT_F(MSG_PLEASE_RESET)); | ||||
|   tft_string.trim(); | ||||
|   tft.add_text(tft_string.center(TFT_WIDTH), 0, COLOR_MENU_TEXT, tft_string); | ||||
|  | ||||
| @@ -352,14 +352,14 @@ void MarlinUI::draw_status_screen() { | ||||
| } | ||||
|  | ||||
| // Low-level draw_edit_screen can be used to draw an edit screen from anyplace | ||||
| void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { | ||||
| void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) { | ||||
|   ui.encoder_direction_normal(); | ||||
|   TERN_(TOUCH_SCREEN, touch.clear()); | ||||
|  | ||||
|   uint16_t line = 1; | ||||
|  | ||||
|   menu_line(line++); | ||||
|   tft_string.set(pstr, itemIndex, itemString); | ||||
|   tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString)); | ||||
|   tft_string.trim(); | ||||
|   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); | ||||
|  | ||||
| @@ -421,7 +421,7 @@ void TFT::draw_edit_screen_buttons() { | ||||
| } | ||||
|  | ||||
| // The Select Screen presents a prompt and two "buttons" | ||||
| void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { | ||||
| void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) { | ||||
|   uint16_t line = 1; | ||||
|  | ||||
|   if (!string) line++; | ||||
| @@ -473,7 +473,7 @@ void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const | ||||
|     #endif | ||||
|  | ||||
|     menu_line(row); | ||||
|     tft_string.set(GET_TEXT(MSG_FILAMENT_CHANGE_NOZZLE)); | ||||
|     tft_string.set(GET_TEXT_F(MSG_FILAMENT_CHANGE_NOZZLE)); | ||||
|     tft_string.add('E'); | ||||
|     tft_string.add((char)('1' + extruder)); | ||||
|     tft_string.add(' '); | ||||
| @@ -693,18 +693,18 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|         drawAxisValue(axis); | ||||
|       } | ||||
|       else { | ||||
|         drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|         drawMessage(GET_TEXT_F(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|       } | ||||
|     #elif HAS_BED_PROBE | ||||
|       // only change probe.offset.z | ||||
|       probe.offset.z += diff; | ||||
|       if (direction < 0 && current_position[axis] < Z_PROBE_OFFSET_RANGE_MIN) { | ||||
|         current_position[axis] = Z_PROBE_OFFSET_RANGE_MIN; | ||||
|         drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|         drawMessage(GET_TEXT_F(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|       } | ||||
|       else if (direction > 0 && current_position[axis] > Z_PROBE_OFFSET_RANGE_MAX) { | ||||
|         current_position[axis] = Z_PROBE_OFFSET_RANGE_MAX; | ||||
|         drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|         drawMessage(GET_TEXT_F(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|       } | ||||
|       else { | ||||
|         drawMessage(""); // clear the error | ||||
| @@ -733,7 +733,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|     #if IS_KINEMATIC | ||||
|       UNUSED(limited); | ||||
|     #else | ||||
|       PGM_P const msg = limited ? GET_TEXT(MSG_LCD_SOFT_ENDSTOPS) : NUL_STR; | ||||
|       FSTR_P const msg = limited ? GET_TEXT_F(MSG_LCD_SOFT_ENDSTOPS) : FPSTR(NUL_STR); | ||||
|       drawMessage(msg); | ||||
|     #endif | ||||
|  | ||||
| @@ -766,7 +766,7 @@ static void z_minus() { moveAxis(Z_AXIS, -1); } | ||||
|  | ||||
|   static void do_home() { | ||||
|     quick_feedback(); | ||||
|     drawMessage(GET_TEXT(MSG_LEVEL_BED_HOMING)); | ||||
|     drawMessage(GET_TEXT_F(MSG_LEVEL_BED_HOMING)); | ||||
|     queue.inject_P(G28_STR); | ||||
|     // Disable touch until home is done | ||||
|     TERN_(TOUCH_SCREEN, touch.disable()); | ||||
|   | ||||
| @@ -347,14 +347,14 @@ void MarlinUI::draw_status_screen() { | ||||
| } | ||||
|  | ||||
| // Low-level draw_edit_screen can be used to draw an edit screen from anyplace | ||||
| void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { | ||||
| void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) { | ||||
|   ui.encoder_direction_normal(); | ||||
|   TERN_(TOUCH_SCREEN, touch.clear()); | ||||
|  | ||||
|   uint16_t line = 1; | ||||
|  | ||||
|   menu_line(line++); | ||||
|   tft_string.set(pstr, itemIndex, itemString); | ||||
|   tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString)); | ||||
|   tft_string.trim(); | ||||
|   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); | ||||
|  | ||||
| @@ -416,7 +416,7 @@ void TFT::draw_edit_screen_buttons() { | ||||
| } | ||||
|  | ||||
| // The Select Screen presents a prompt and two "buttons" | ||||
| void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { | ||||
| void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) { | ||||
|   uint16_t line = 1; | ||||
|  | ||||
|   if (!string) line++; | ||||
| @@ -621,7 +621,7 @@ static void drawCurESelection() { | ||||
|   tft.add_text(tft_string.width(), 0, E_BTN_COLOR, ui8tostr3rj(motionAxisState.e_selection)); | ||||
| } | ||||
|  | ||||
| static void drawMessage(const char *msg) { | ||||
| static void drawMessage(PGM_P const msg) { | ||||
|   tft.canvas(X_MARGIN, TFT_HEIGHT - Y_MARGIN - 29, (TFT_WIDTH / 2) - (BTN_WIDTH / 2) - X_MARGIN, 20); | ||||
|   tft.set_background(COLOR_BACKGROUND); | ||||
|   tft.add_text(0, 0, COLOR_YELLOW, msg); | ||||
| @@ -652,7 +652,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|  | ||||
|   #if ENABLED(PREVENT_COLD_EXTRUSION) | ||||
|     if (axis == E_AXIS && thermalManager.tooColdToExtrude(motionAxisState.e_selection)) { | ||||
|       drawMessage("Too cold"); | ||||
|       drawMessage(PSTR("Too cold")); | ||||
|       return; | ||||
|     } | ||||
|   #endif | ||||
| @@ -675,7 +675,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|           probe.offset.z = new_offs; | ||||
|         else | ||||
|           TERN(BABYSTEP_HOTEND_Z_OFFSET, hotend_offset[active_extruder].z = new_offs, NOOP); | ||||
|         drawMessage(""); // clear the error | ||||
|         drawMessage(NUL_STR); // clear the error | ||||
|         drawAxisValue(axis); | ||||
|       } | ||||
|       else { | ||||
| @@ -693,7 +693,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|         drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|       } | ||||
|       else { | ||||
|         drawMessage(""); // clear the error | ||||
|         drawMessage(NUL_STR); // clear the error | ||||
|       } | ||||
|       drawAxisValue(axis); | ||||
|     #endif | ||||
|   | ||||
| @@ -352,14 +352,14 @@ void MarlinUI::draw_status_screen() { | ||||
| } | ||||
|  | ||||
| // Low-level draw_edit_screen can be used to draw an edit screen from anyplace | ||||
| void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) { | ||||
| void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) { | ||||
|   ui.encoder_direction_normal(); | ||||
|   TERN_(TOUCH_SCREEN, touch.clear()); | ||||
|  | ||||
|   uint16_t line = 1; | ||||
|  | ||||
|   menu_line(line++); | ||||
|   tft_string.set(pstr, itemIndex, itemString); | ||||
|   tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString)); | ||||
|   tft_string.trim(); | ||||
|   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); | ||||
|  | ||||
| @@ -421,7 +421,7 @@ void TFT::draw_edit_screen_buttons() { | ||||
| } | ||||
|  | ||||
| // The Select Screen presents a prompt and two "buttons" | ||||
| void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { | ||||
| void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) { | ||||
|   uint16_t line = 1; | ||||
|  | ||||
|   if (!string) line++; | ||||
| @@ -622,7 +622,7 @@ static void drawCurESelection() { | ||||
|   tft.add_text(tft_string.width(), 0, E_BTN_COLOR, ui8tostr3rj(motionAxisState.e_selection)); | ||||
| } | ||||
|  | ||||
| static void drawMessage(const char *msg) { | ||||
| static void drawMessage(PGM_P const msg) { | ||||
|   tft.canvas(X_MARGIN, TFT_HEIGHT - Y_MARGIN - 34, TFT_HEIGHT / 2, 34); | ||||
|   tft.set_background(COLOR_BACKGROUND); | ||||
|   tft.add_text(0, 0, COLOR_YELLOW, msg); | ||||
| @@ -653,7 +653,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|  | ||||
|   #if ENABLED(PREVENT_COLD_EXTRUSION) | ||||
|     if (axis == E_AXIS && thermalManager.tooColdToExtrude(motionAxisState.e_selection)) { | ||||
|       drawMessage("Too cold"); | ||||
|       drawMessage(PSTR("Too cold")); | ||||
|       return; | ||||
|     } | ||||
|   #endif | ||||
| @@ -676,7 +676,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|           probe.offset.z = new_offs; | ||||
|         else | ||||
|           TERN(BABYSTEP_HOTEND_Z_OFFSET, hotend_offset[active_extruder].z = new_offs, NOOP); | ||||
|         drawMessage(""); // clear the error | ||||
|         drawMessage(NUL_STR); // clear the error | ||||
|         drawAxisValue(axis); | ||||
|       } | ||||
|       else { | ||||
| @@ -694,7 +694,7 @@ static void moveAxis(const AxisEnum axis, const int8_t direction) { | ||||
|         drawMessage(GET_TEXT(MSG_LCD_SOFT_ENDSTOPS)); | ||||
|       } | ||||
|       else { | ||||
|         drawMessage(""); // clear the error | ||||
|         drawMessage(NUL_STR); // clear the error | ||||
|       } | ||||
|       drawAxisValue(axis); | ||||
|     #endif | ||||
|   | ||||
| @@ -130,10 +130,10 @@ void lcd_put_int(const int i) { | ||||
| // | ||||
|  | ||||
| // Draw a generic menu item with pre_char (if selected) and post_char | ||||
| void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) { | ||||
| void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) { | ||||
|   menu_item(row, sel); | ||||
|  | ||||
|   uint8_t *string = (uint8_t *)pstr; | ||||
|   uint8_t *string = (uint8_t *)FTOP(fstr); | ||||
|   MarlinImage image = noImage; | ||||
|   switch (*string) { | ||||
|     case 0x01: image = imgRefresh; break;  // LCD_STR_REFRESH | ||||
| @@ -147,15 +147,15 @@ void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, co | ||||
|     tft.add_image(MENU_ITEM_ICON_X, MENU_ITEM_ICON_Y, image, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); | ||||
|   } | ||||
|  | ||||
|   tft_string.set(string, itemIndex, itemString); | ||||
|   tft_string.set(string, itemIndex, FTOP(itemString)); | ||||
|   tft.add_text(offset, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); | ||||
| } | ||||
|  | ||||
| // Draw a menu item with a (potentially) editable value | ||||
| void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const data, const bool pgm) { | ||||
| void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const data, const bool pgm) { | ||||
|   menu_item(row, sel); | ||||
|  | ||||
|   tft_string.set(pstr, itemIndex, itemString); | ||||
|   tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString)); | ||||
|   tft.add_text(MENU_TEXT_X_OFFSET, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string); | ||||
|   if (data) { | ||||
|     tft_string.set(data); | ||||
| @@ -164,16 +164,16 @@ void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, | ||||
| } | ||||
|  | ||||
| // Draw a static item with no left-right margin required. Centered by default. | ||||
| void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
| void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|   menu_item(row); | ||||
|   tft_string.set(pstr, itemIndex, itemString); | ||||
|   tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString)); | ||||
|   if (vstr) tft_string.add(vstr); | ||||
|   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_YELLOW, tft_string); | ||||
| } | ||||
|  | ||||
| #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|   void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { | ||||
|   void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) { | ||||
|     menu_item(row, sel); | ||||
|     if (isDir) tft.add_image(MENU_ITEM_ICON_X, MENU_ITEM_ICON_Y, imgDirectory, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND); | ||||
|     constexpr uint8_t maxlen = (MENU_ITEM_HEIGHT) - (MENU_TEXT_Y_OFFSET) + 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user