Confirm before starting SD print (#13616)
This commit is contained in:
		| @@ -771,6 +771,8 @@ | ||||
|   // Since the FAT gets out of order with usage, SDCARD_SORT_ALPHA is recommended. | ||||
|   #define SDCARD_RATHERRECENTFIRST | ||||
|  | ||||
|   #define SD_MENU_CONFIRM_START             // Confirm the selected SD file before printing | ||||
|  | ||||
|   //#define MENU_ADDAUTOSTART               // Add a menu option to run auto#.g files | ||||
|  | ||||
|   #define EVENT_GCODE_SD_STOP "G28XY"       // G-code to run on Stop Print (e.g., "G28XY" or "G27") | ||||
|   | ||||
| @@ -1679,7 +1679,7 @@ | ||||
| // Get LCD character width/height, which may be overridden by pins, configs, etc. | ||||
| #ifndef LCD_WIDTH | ||||
|   #if HAS_GRAPHICAL_LCD | ||||
|     #define LCD_WIDTH 22 | ||||
|     #define LCD_WIDTH 21 | ||||
|   #elif ENABLED(ULTIPANEL) | ||||
|     #define LCD_WIDTH 20 | ||||
|   #elif HAS_SPI_LCD | ||||
|   | ||||
| @@ -1037,6 +1037,16 @@ void MarlinUI::draw_status_screen() { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void 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) { | ||||
|     SETCURSOR(0, 0); lcd_put_u8str_P(pref); | ||||
|     if (string) wrap_string(1, string); | ||||
|     if (suff) lcd_put_u8str_P(suff); | ||||
|     SETCURSOR(0, LCD_HEIGHT - 1); | ||||
|     lcd_put_wchar(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd_put_wchar(yesno ? ' ' : ']'); | ||||
|     SETCURSOR_RJ(utf8_strlen_P(yes) + 2, LCD_HEIGHT - 1); | ||||
|     lcd_put_wchar(yesno ? '[' : ' '); lcd_put_u8str_P(yes); lcd_put_wchar(yesno ? ']' : ' '); | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) { | ||||
|   | ||||
| @@ -97,7 +97,7 @@ static void fontgroup_drawwchar(font_group_t *group, const font_t *fnt_default, | ||||
|  * @param utf8_msg : the UTF-8 string | ||||
|  * @param cb_read_byte : how to read the utf8_msg, from RAM or ROM (call read_byte_ram or pgm_read_byte) | ||||
|  * @param userdata : User's data | ||||
|  * @param cb_draw_ram : the callback function of userdata to draw a !RAM! string (actural it is to draw a one byte string in RAM) | ||||
|  * @param cb_draw_ram : the callback function of userdata to draw a !RAM! string (actually it is to draw a one byte string in RAM) | ||||
|  * | ||||
|  * @return N/A | ||||
|  * | ||||
|   | ||||
| @@ -401,6 +401,27 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   inline void draw_boxed_string(const uint8_t x, const uint8_t y, PGM_P const pstr, const bool inv) { | ||||
|     const uint8_t len = utf8_strlen_P(pstr), bw = len * (MENU_FONT_WIDTH), | ||||
|                   bx = x * (MENU_FONT_WIDTH), by = (y + 1) * (MENU_FONT_HEIGHT); | ||||
|     if (inv) { | ||||
|       u8g.setColorIndex(1); | ||||
|       u8g.drawBox(bx - 1, by - (MENU_FONT_ASCENT) + 1, bw + 2, MENU_FONT_HEIGHT - 1); | ||||
|       u8g.setColorIndex(0); | ||||
|     } | ||||
|     lcd_moveto(bx, by); | ||||
|     lcd_put_u8str_P(pstr); | ||||
|     if (inv) u8g.setColorIndex(1); | ||||
|   } | ||||
|  | ||||
|   void 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) { | ||||
|     SETCURSOR(0, 0); lcd_put_u8str_P(pref); | ||||
|     if (string) wrap_string(1, string); | ||||
|     if (suff) lcd_put_u8str_P(suff); | ||||
|     draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno); | ||||
|     draw_boxed_string(LCD_WIDTH - (utf8_strlen_P(yes) + 1), LCD_HEIGHT - 1, yes, yesno); | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) { | ||||
|   | ||||
| @@ -10,8 +10,8 @@ | ||||
| #include "../inc/MarlinConfig.h" | ||||
|  | ||||
| #if ENABLED(ULTRA_LCD) | ||||
| #include "ultralcd.h" | ||||
| #include "../Marlin.h" | ||||
|   #include "ultralcd.h" | ||||
|   #include "../Marlin.h" | ||||
| #endif | ||||
|  | ||||
| #include "fontutils.h" | ||||
|   | ||||
| @@ -52,6 +52,12 @@ | ||||
| #ifndef WELCOME_MSG | ||||
|   #define WELCOME_MSG                         MACHINE_NAME _UxGT(" Ready.") | ||||
| #endif | ||||
| #ifndef MSG_YES | ||||
|   #define MSG_YES                             _UxGT("YES") | ||||
| #endif | ||||
| #ifndef MSG_NO | ||||
|   #define MSG_NO                              _UxGT("NO") | ||||
| #endif | ||||
| #ifndef MSG_BACK | ||||
|   #define MSG_BACK                            _UxGT("Back") | ||||
| #endif | ||||
| @@ -744,6 +750,15 @@ | ||||
| #ifndef MSG_TUNE | ||||
|   #define MSG_TUNE                            _UxGT("Tune") | ||||
| #endif | ||||
| #ifndef MSG_START_PRINT | ||||
|   #define MSG_START_PRINT                     _UxGT("Start print") | ||||
| #endif | ||||
| #ifndef MSG_BUTTON_PRINT | ||||
|   #define MSG_BUTTON_PRINT                    _UxGT("Print") | ||||
| #endif | ||||
| #ifndef MSG_BUTTON_CANCEL | ||||
|   #define MSG_BUTTON_CANCEL                   _UxGT("Cancel") | ||||
| #endif | ||||
| #ifndef MSG_PAUSE_PRINT | ||||
|   #define MSG_PAUSE_PRINT                     _UxGT("Pause print") | ||||
| #endif | ||||
|   | ||||
| @@ -62,8 +62,7 @@ void MarlinGame::init_game(const uint8_t init_state, const screenFunc_t screen) | ||||
| } | ||||
|  | ||||
| void MarlinGame::exit_game() { | ||||
|   ui.goto_previous_screen(); | ||||
|   ui.defer_status_screen(false); | ||||
|   ui.goto_previous_screen_no_defer(); | ||||
| } | ||||
|  | ||||
| #endif // HAS_GAMES | ||||
|   | ||||
| @@ -436,4 +436,12 @@ void _lcd_draw_homing() { | ||||
|   void _lcd_toggle_bed_leveling() { set_bed_leveling_enabled(!planner.leveling_active); } | ||||
| #endif | ||||
|  | ||||
| void do_select_screen(PGM_P const yes, PGM_P const no, bool &yesno, PGM_P const pref, const char * const string, PGM_P const suff) { | ||||
|   if (ui.encoderPosition) { | ||||
|     yesno = int32_t(ui.encoderPosition) > 0; | ||||
|     ui.encoderPosition = 0; | ||||
|   } | ||||
|   draw_select_screen(yes, no, yesno, pref, string, suff); | ||||
| } | ||||
|  | ||||
| #endif // HAS_LCD_MENU | ||||
|   | ||||
| @@ -64,6 +64,11 @@ DECLARE_MENU_EDIT_TYPE(uint32_t, long5,       ftostr5rj,       0.01f );   // 123 | ||||
| //////////////////////////////////////////// | ||||
|  | ||||
| void draw_edit_screen(PGM_P const pstr, const char* const value=NULL); | ||||
| void 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 do_select_screen(PGM_P const yes, PGM_P const no, bool &yesno, PGM_P const pref, const char * const string=NULL, PGM_P const suff=NULL); | ||||
| inline void do_select_screen_yn(bool &yesno, PGM_P const pref, const char * const string, PGM_P const suff) { | ||||
|   do_select_screen(PSTR(MSG_YES), PSTR(MSG_NO), yesno, pref, string, suff); | ||||
| } | ||||
| void draw_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char); | ||||
| void draw_menu_item_static(const uint8_t row, PGM_P const pstr, const bool center=true, const bool invert=false, const char *valstr=NULL); | ||||
| void _draw_menu_item_edit(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm); | ||||
|   | ||||
| @@ -72,15 +72,41 @@ void lcd_sd_updir() { | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| inline void sdcard_start_selected_file() { | ||||
|   card.openAndPrintFile(card.filename); | ||||
|   ui.return_to_status(); | ||||
|   ui.reset_status(); | ||||
| } | ||||
|  | ||||
| #if ENABLED(SD_MENU_CONFIRM_START) | ||||
|  | ||||
|   bool do_print_file; | ||||
|   void menu_sd_confirm() { | ||||
|     if (ui.should_draw()) | ||||
|       do_select_screen(PSTR(MSG_BUTTON_PRINT), PSTR(MSG_BUTTON_CANCEL), do_print_file, PSTR(MSG_START_PRINT " "), card.longest_filename(), PSTR("?")); | ||||
|  | ||||
|     if (ui.use_click()) { | ||||
|       if (do_print_file) | ||||
|         sdcard_start_selected_file(); | ||||
|       else | ||||
|         ui.goto_previous_screen(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| class MenuItem_sdfile { | ||||
|   public: | ||||
|     static void action(CardReader &theCard) { | ||||
|       #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE) | ||||
|         last_sdfile_encoderPosition = ui.encoderPosition;  // Save which file was selected for later use | ||||
|       #endif | ||||
|       card.openAndPrintFile(theCard.filename); | ||||
|       ui.return_to_status(); | ||||
|       ui.reset_status(); | ||||
|       #if ENABLED(SD_MENU_CONFIRM_START) | ||||
|         do_print_file = false; | ||||
|         MenuItem_submenu::action(menu_sd_confirm); | ||||
|       #else | ||||
|         sdcard_start_selected_file(); | ||||
|       #endif | ||||
|     } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -192,7 +192,25 @@ millis_t next_button_update_ms; | ||||
|  | ||||
|   #endif | ||||
|  | ||||
| #endif | ||||
|   void wrap_string(uint8_t y, const char * const string) { | ||||
|     uint8_t x = LCD_WIDTH; | ||||
|     if (string) { | ||||
|       uint8_t *p = (uint8_t*)string; | ||||
|       for (;;) { | ||||
|         if (x >= LCD_WIDTH) { | ||||
|           x = 0; | ||||
|           SETCURSOR(0, y++); | ||||
|         } | ||||
|         wchar_t ch; | ||||
|         p = get_utf8_value_cb(p, read_byte_ram, &ch); | ||||
|         if (!ch) break; | ||||
|         lcd_put_wchar(ch); | ||||
|         x++; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #endif // HAS_LCD_MENU | ||||
|  | ||||
| void MarlinUI::init() { | ||||
|  | ||||
|   | ||||
| @@ -56,22 +56,24 @@ | ||||
|     uint8_t get_ADC_keyValue(); | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_GRAPHICAL_LCD | ||||
|     #define SETCURSOR(col, row) lcd_moveto(col * (MENU_FONT_WIDTH), (row + 1) * (MENU_FONT_HEIGHT)) | ||||
|     #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH), (row + 1) * (MENU_FONT_HEIGHT)) | ||||
|     #define LCDPRINT(p) u8g.print(p) | ||||
|     #define LCDWRITE(c) u8g.print(c) | ||||
|   #else | ||||
|     #define SETCURSOR(col, row) lcd_moveto(col, row) | ||||
|     #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_WIDTH - (len), row) | ||||
|     #define LCDPRINT(p) lcd_put_u8str(p) | ||||
|     #define LCDWRITE(c) lcd_put_wchar(c) | ||||
|   #endif | ||||
|  | ||||
|   #define LCD_UPDATE_INTERVAL 100 | ||||
|  | ||||
|   #if HAS_LCD_MENU | ||||
|  | ||||
|     #if HAS_GRAPHICAL_LCD | ||||
|       #define SETCURSOR(col, row) lcd_moveto(col * (MENU_FONT_WIDTH), (row + 1) * (MENU_FONT_HEIGHT)) | ||||
|       #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH), (row + 1) * (MENU_FONT_HEIGHT)) | ||||
|       #define LCDPRINT(p) u8g.print(p) | ||||
|       #define LCDWRITE(c) u8g.print(c) | ||||
|     #else | ||||
|       #define SETCURSOR(col, row) lcd_moveto(col, row) | ||||
|       #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_WIDTH - (len), row) | ||||
|       #define LCDPRINT(p) lcd_put_u8str(p) | ||||
|       #define LCDWRITE(c) lcd_put_wchar(c) | ||||
|     #endif | ||||
|  | ||||
|     void wrap_string(uint8_t y, const char * const string); | ||||
|  | ||||
|     #if ENABLED(SDSUPPORT) | ||||
|       #include "../sd/cardreader.h" | ||||
|     #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user