diff --git a/Marlin/src/gcode/eeprom/M500-M504.cpp b/Marlin/src/gcode/eeprom/M500-M504.cpp index 12e323bd7b..e21e125066 100644 --- a/Marlin/src/gcode/eeprom/M500-M504.cpp +++ b/Marlin/src/gcode/eeprom/M500-M504.cpp @@ -25,18 +25,11 @@ #include "../../core/serial.h" #include "../../inc/MarlinConfig.h" -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extensible_ui/ui_api.h" -#endif - /** * M500: Store settings in EEPROM */ void GcodeSuite::M500() { (void)settings.save(); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onStoreSettings(); - #endif } /** @@ -44,9 +37,6 @@ void GcodeSuite::M500() { */ void GcodeSuite::M501() { (void)settings.load(); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onLoadSettings(); - #endif } /** @@ -54,9 +44,6 @@ void GcodeSuite::M501() { */ void GcodeSuite::M502() { (void)settings.reset(); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onFactoryReset(); - #endif } #if DISABLED(DISABLE_M503) diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp index c8927725c5..57a6e96904 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp @@ -1038,9 +1038,7 @@ 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); + ui.draw_select_screen_prompt(pref, string, 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); diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp index 1ab6b18cf2..4a33045592 100644 --- a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp +++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp @@ -439,9 +439,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop } 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); + ui.draw_select_screen_prompt(pref, string, 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); } diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index d16cd44d47..5677ecbae9 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -753,12 +753,27 @@ #ifndef MSG_START_PRINT #define MSG_START_PRINT _UxGT("Start print") #endif +#ifndef MSG_BUTTON_NEXT + #define MSG_BUTTON_NEXT _UxGT("Next") +#endif +#ifndef MSG_BUTTON_INIT + #define MSG_BUTTON_INIT _UxGT("Init") +#endif +#ifndef MSG_BUTTON_STOP + #define MSG_BUTTON_STOP _UxGT("Stop") +#endif #ifndef MSG_BUTTON_PRINT #define MSG_BUTTON_PRINT _UxGT("Print") #endif +#ifndef MSG_BUTTON_RESET + #define MSG_BUTTON_RESET _UxGT("Reset") +#endif #ifndef MSG_BUTTON_CANCEL #define MSG_BUTTON_CANCEL _UxGT("Cancel") #endif +#ifndef MSG_BUTTON_DONE + #define MSG_BUTTON_DONE _UxGT("Done") +#endif #ifndef MSG_PAUSE_PRINT #define MSG_PAUSE_PRINT _UxGT("Pause print") #endif diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index 1a053ad850..ba6957ddaf 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -268,6 +268,8 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co #if HAS_GRAPHICAL_LCD drawing_screen = false; #endif + + set_ui_selection(false); } } @@ -436,12 +438,21 @@ 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) { +// +// Selection screen presents a prompt and two options +// +bool ui_selection; // = false +void set_ui_selection(const bool sel) { ui_selection = sel; } +void do_select_screen(PGM_P const yes, PGM_P const no, selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string/*=NULL*/, PGM_P const suff/*=NULL*/) { if (ui.encoderPosition) { - yesno = int16_t(ui.encoderPosition) > 0; + ui_selection = int16_t(ui.encoderPosition) > 0; ui.encoderPosition = 0; } - draw_select_screen(yes, no, yesno, pref, string, suff); + const bool got_click = ui.use_click(); + if (got_click || ui.should_draw()) { + draw_select_screen(yes, no, ui_selection, pref, string, suff); + if (got_click) { ui_selection ? yesFunc() : noFunc(); } + } } #endif // HAS_LCD_MENU diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index acc51a2ae0..de3bd210fb 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -65,12 +65,15 @@ DECLARE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01f ); // 123 ///////// Menu Item Draw Functions ///////// //////////////////////////////////////////// -void draw_edit_screen(PGM_P const pstr, const char* const value=NULL); +typedef void (*selectFunc_t)(); 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 set_ui_selection(const bool sel); +void do_select_screen(PGM_P const yes, PGM_P const no, selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string=NULL, PGM_P const suff=NULL); +inline void do_select_screen_yn(selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string=NULL, PGM_P const suff=NULL) { + do_select_screen(PSTR(MSG_YES), PSTR(MSG_NO), yesFunc, noFunc, pref, string, suff); } + +void draw_edit_screen(PGM_P const pstr, const char* const value=NULL); 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); diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 05396f8507..9d99d03962 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -604,16 +604,13 @@ void menu_backlash(); #include "../../module/configuration_store.h" - static void lcd_init_eeprom() { - ui.completion_feedback(settings.init_eeprom()); - ui.goto_previous_screen(); - } - static void lcd_init_eeprom_confirm() { - START_MENU(); - MENU_BACK(MSG_ADVANCED_SETTINGS); - MENU_ITEM(function, MSG_INIT_EEPROM, lcd_init_eeprom); - END_MENU(); + do_select_screen( + PSTR(MSG_BUTTON_INIT), PSTR(MSG_BUTTON_CANCEL), + []{ ui.completion_feedback(settings.init_eeprom()); }, + ui.goto_previous_screen, + PSTR(MSG_INIT_EEPROM), NULL, PSTR("?") + ); } #endif diff --git a/Marlin/src/lcd/menu/menu_bed_corners.cpp b/Marlin/src/lcd/menu/menu_bed_corners.cpp index b36d8dd3b1..de24ed5a56 100644 --- a/Marlin/src/lcd/menu/menu_bed_corners.cpp +++ b/Marlin/src/lcd/menu/menu_bed_corners.cpp @@ -50,13 +50,6 @@ static_assert(LEVEL_CORNERS_Z_HOP >= 0, "LEVEL_CORNERS_Z_HOP must be >= 0. Pleas static bool leveling_was_active = false; #endif -static inline void _lcd_level_bed_corners_back() { - #if HAS_LEVELING - set_bed_leveling_enabled(leveling_was_active); - #endif - ui.goto_previous_screen_no_defer(); -} - /** * Level corners, starting in the front-left corner. */ @@ -94,17 +87,23 @@ static inline void _lcd_goto_next_corner() { } static inline void menu_level_bed_corners() { - START_MENU(); - MENU_ITEM(function, - #if ENABLED(LEVEL_CENTER_TOO) - MSG_LEVEL_BED_NEXT_POINT - #else - MSG_NEXT_CORNER - #endif - , _lcd_goto_next_corner + do_select_screen( + PSTR(MSG_BUTTON_NEXT), PSTR(MSG_BUTTON_DONE), + _lcd_goto_next_corner, + []{ + #if HAS_LEVELING + set_bed_leveling_enabled(leveling_was_active); + #endif + ui.goto_previous_screen_no_defer(); + }, + PSTR( + #if ENABLED(LEVEL_CENTER_TOO) + MSG_LEVEL_BED_NEXT_POINT + #else + MSG_NEXT_CORNER + #endif + ), NULL, PSTR("?") ); - MENU_ITEM(function, MSG_BACK, _lcd_level_bed_corners_back); - END_MENU(); } static inline void _lcd_level_bed_corners_homing() { @@ -112,6 +111,7 @@ static inline void _lcd_level_bed_corners_homing() { if (all_axes_homed()) { bed_corner = 0; ui.goto_screen(menu_level_bed_corners); + set_ui_selection(true); _lcd_goto_next_corner(); } } diff --git a/Marlin/src/lcd/menu/menu_job_recovery.cpp b/Marlin/src/lcd/menu/menu_job_recovery.cpp index 6d584948c4..f819052977 100644 --- a/Marlin/src/lcd/menu/menu_job_recovery.cpp +++ b/Marlin/src/lcd/menu/menu_job_recovery.cpp @@ -44,6 +44,8 @@ static void lcd_power_loss_recovery_cancel() { ui.return_to_status(); } +// TODO: Display long filename with Cancel/Resume buttons +// Requires supporting methods in PLR class. void menu_job_recovery() { ui.defer_status_screen(); START_MENU(); diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index 52178b873c..ef160f6100 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -101,10 +101,7 @@ } void menu_abort_confirm() { - START_MENU(); - MENU_BACK(MSG_MAIN); - MENU_ITEM(function, MSG_STOP_PRINT, lcd_abort_job); - END_MENU(); + do_select_screen(PSTR(MSG_BUTTON_STOP), PSTR(MSG_BACK), lcd_abort_job, ui.goto_previous_screen, PSTR(MSG_STOP_PRINT), NULL, PSTR("?")); } #endif // MACHINE_CAN_STOP diff --git a/Marlin/src/lcd/menu/menu_mixer.cpp b/Marlin/src/lcd/menu/menu_mixer.cpp index 8e5b6f4d0f..77124d1146 100644 --- a/Marlin/src/lcd/menu/menu_mixer.cpp +++ b/Marlin/src/lcd/menu/menu_mixer.cpp @@ -250,17 +250,17 @@ void lcd_mixer_mix_edit() { // // Reset All V-Tools // -inline void _lcd_reset_vtools() { - LCD_MESSAGEPGM(MSG_VTOOLS_RESET); - ui.return_to_status(); - mixer.reset_vtools(); -} - void menu_mixer_vtools_reset_confirm() { - START_MENU(); - MENU_BACK(MSG_BACK); - MENU_ITEM(function, MSG_RESET_VTOOLS, _lcd_reset_vtools); - END_MENU(); + do_select_screen( + PSTR(MSG_BUTTON_RESET), PSTR(MSG_BUTTON_CANCEL), + []{ + mixer.reset_vtools(); + LCD_MESSAGEPGM(MSG_VTOOLS_RESET); + ui.return_to_status(); + }, + ui.goto_previous_screen, + PSTR(MSG_RESET_VTOOLS), NULL, PSTR("?") + ); } void menu_mixer() { diff --git a/Marlin/src/lcd/menu/menu_sdcard.cpp b/Marlin/src/lcd/menu/menu_sdcard.cpp index 274643841f..d574dc150e 100644 --- a/Marlin/src/lcd/menu/menu_sdcard.cpp +++ b/Marlin/src/lcd/menu/menu_sdcard.cpp @@ -81,17 +81,12 @@ inline void sdcard_start_selected_file() { #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(); - } + do_select_screen( + PSTR(MSG_BUTTON_PRINT), PSTR(MSG_BUTTON_CANCEL), + sdcard_start_selected_file, ui.goto_previous_screen, + PSTR(MSG_START_PRINT " "), card.longest_filename(), PSTR("?") + ); } #endif @@ -106,7 +101,6 @@ class MenuItem_sdfile { sd_items = screen_items; #endif #if ENABLED(SD_MENU_CONFIRM_START) - do_print_file = false; MenuItem_submenu::action(menu_sd_confirm); #else sdcard_start_selected_file(); diff --git a/Marlin/src/lcd/menu/menu_service.cpp b/Marlin/src/lcd/menu/menu_service.cpp index 05d43f5fd0..3ab890d7bb 100644 --- a/Marlin/src/lcd/menu/menu_service.cpp +++ b/Marlin/src/lcd/menu/menu_service.cpp @@ -31,52 +31,32 @@ #include "menu.h" #include "../../module/printcounter.h" -inline void _lcd_reset_service(const int index) { - print_job_timer.resetServiceInterval(index); - BUZZ(200, 404); - ui.reset_status(); - ui.return_to_status(); +inline void _menu_service(const int index, PGM_P const name) { + char sram[30]; + strncpy_P(sram, name, 29); + do_select_screen( + PSTR(MSG_BUTTON_RESET), PSTR(MSG_BUTTON_CANCEL), + []{ + print_job_timer.resetServiceInterval(index); + ui.completion_feedback(true); + ui.reset_status(); + ui.return_to_status(); + }, + ui.goto_previous_screen, + PSTR(MSG_SERVICE_RESET), sram, PSTR("?") + ); } #if SERVICE_INTERVAL_1 > 0 - void menu_action_reset_service1() { _lcd_reset_service(1); } + void menu_service1() { _menu_service(1, PSTR(SERVICE_NAME_1)); } #endif #if SERVICE_INTERVAL_2 > 0 - void menu_action_reset_service2() { _lcd_reset_service(2); } + void menu_service2() { _menu_service(2, PSTR(SERVICE_NAME_2)); } #endif #if SERVICE_INTERVAL_3 > 0 - void menu_action_reset_service3() { _lcd_reset_service(3); } -#endif - -inline void _menu_service(const int index) { - START_MENU(); - MENU_BACK(MSG_MAIN); - switch (index) { - #if SERVICE_INTERVAL_1 > 0 - case 1: MENU_ITEM(function, MSG_SERVICE_RESET, menu_action_reset_service1); break; - #endif - #if SERVICE_INTERVAL_2 > 0 - case 2: MENU_ITEM(function, MSG_SERVICE_RESET, menu_action_reset_service2); break; - #endif - #if SERVICE_INTERVAL_3 > 0 - case 3: MENU_ITEM(function, MSG_SERVICE_RESET, menu_action_reset_service3); break; - #endif - } - END_MENU(); -} - -#if SERVICE_INTERVAL_1 > 0 - void menu_service1() { _menu_service(1); } -#endif - -#if SERVICE_INTERVAL_2 > 0 - void menu_service2() { _menu_service(2); } -#endif - -#if SERVICE_INTERVAL_3 > 0 - void menu_service3() { _menu_service(3); } + void menu_service3() { _menu_service(3, PSTR(SERVICE_NAME_3)); } #endif #endif // HAS_LCD_MENU && HAS_SERVICE_INTERVALS && PRINTCOUNTER diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index cf1f8f98ea..0d4b88d2c3 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -192,24 +192,39 @@ millis_t next_button_update_ms; #endif - void wrap_string(uint8_t y, const char * const string) { - uint8_t x = LCD_WIDTH; + void _wrap_string(uint8_t &x, uint8_t &y, const char * const string, read_byte_cb_t cb_read_byte) { + SETCURSOR(x, y); 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); + p = get_utf8_value_cb(p, cb_read_byte, &ch); if (!ch) break; lcd_put_wchar(ch); x++; + if (x >= LCD_WIDTH) { + x = 0; y++; + SETCURSOR(0, y); + } } } } + void MarlinUI::draw_select_screen_prompt(PGM_P const pref, const char * const string/*=NULL*/, PGM_P const suff/*=NULL*/) { + const uint8_t plen = utf8_strlen_P(pref), slen = suff ? utf8_strlen_P(suff) : 0; + uint8_t x = 0, y = 0; + if (!string && plen + slen <= LCD_WIDTH) { + x = (LCD_WIDTH - plen - slen) / 2; + y = LCD_HEIGHT > 3 ? 1 : 0; + } + wrap_string_P(x, y, pref); + if (string) { + if (x) { x = 0; y++; } // Move to the start of the next line + wrap_string(x, y, string); + } + if (suff) wrap_string_P(x, y, suff); + } + #endif // HAS_LCD_MENU void MarlinUI::init() { diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h index be694ddfe4..2ea7f45279 100644 --- a/Marlin/src/lcd/ultralcd.h +++ b/Marlin/src/lcd/ultralcd.h @@ -72,7 +72,11 @@ #define LCDWRITE(c) lcd_put_wchar(c) #endif - void wrap_string(uint8_t y, const char * const string); + #include "fontutils.h" + + void _wrap_string(uint8_t &x, uint8_t &y, const char * const string, read_byte_cb_t cb_read_byte); + inline void wrap_string_P(uint8_t &x, uint8_t &y, PGM_P const pstr) { _wrap_string(x, y, pstr, read_byte_rom); } + inline void wrap_string(uint8_t &x, uint8_t &y, const char * const string) { _wrap_string(x, y, string, read_byte_ram); } #if ENABLED(SDSUPPORT) #include "../sd/cardreader.h" @@ -457,6 +461,8 @@ public: static void ubl_plot(const uint8_t x, const uint8_t inverted_y); #endif + static void draw_select_screen_prompt(PGM_P const pref, const char * const string=NULL, PGM_P const suff=NULL); + #elif HAS_SPI_LCD static constexpr bool lcd_clicked = false; diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index 0552f555a5..a766d91b6e 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -64,6 +64,10 @@ #include "../feature/bedlevel/bedlevel.h" #endif +#if ENABLED(EXTENSIBLE_UI) + #include "../lcd/extensible_ui/ui_api.h" +#endif + #if HAS_SERVOS #include "servo.h" #endif @@ -1120,6 +1124,10 @@ void MarlinSettings::postprocess() { store_mesh(ubl.storage_slot); #endif + #if ENABLED(EXTENSIBLE_UI) + if (!eeprom_error) ExtUI::onStoreSettings(); + #endif + return !eeprom_error; } @@ -1874,7 +1882,13 @@ void MarlinSettings::postprocess() { } bool MarlinSettings::load() { - if (validate()) return _load(); + if (validate()) { + const bool success = _load(); + #if ENABLED(EXTENSIBLE_UI) + if (success) ExtUI::onLoadSettings(); + #endif + return success; + } reset(); return true; } @@ -2290,6 +2304,10 @@ void MarlinSettings::reset() { DEBUG_ECHO_START(); DEBUG_ECHOLNPGM("Hardcoded Default Settings Loaded"); + + #if ENABLED(EXTENSIBLE_UI) + ExtUI::onFactoryReset(); + #endif } #if DISABLED(DISABLE_M503)