diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index cc928baff9..4117d3f382 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -822,7 +822,7 @@ void idle(bool no_stepper_sleep/*=false*/) { TERN_(USE_BEEPER, buzzer.tick()); // Handle UI input / draw events - TERN(HAS_DWIN_E3V2_BASIC, DWIN_Update(), ui.update()); + TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update()); // Run i2c Position Encoders #if ENABLED(I2C_POSITION_ENCODERS) @@ -1571,11 +1571,7 @@ void setup() { #endif #if HAS_DWIN_E3V2_BASIC - SETUP_LOG("E3V2 Init"); - Encoder_Configuration(); - HMI_Init(); - HMI_SetLanguageCache(); - HMI_StartFrame(true); + SETUP_RUN(DWIN_InitScreen()); #endif #if HAS_SERVICE_INTERVALS && !HAS_DWIN_E3V2_BASIC diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 79780021cf..636ac32042 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -407,6 +407,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool #endif TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR))); + TERN_(DWIN_LCD_PROUI, DWIN_Print_Pause()); // Indicate that the printer is paused ++did_pause_print; @@ -709,7 +710,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_ TERN_(HAS_FILAMENT_SENSOR, runout.reset()); - TERN_(HAS_STATUS_MESSAGE, ui.reset_status()); + TERN(DWIN_LCD_PROUI, DWIN_Print_Resume(), ui.reset_status()); TERN_(HAS_MARLINUI_MENU, ui.return_to_status()); TERN_(DWIN_LCD_PROUI, HMI_ReturnScreen()); } diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp index 309d21fe53..3767cef3cf 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -105,6 +105,7 @@ void GcodeSuite::G29() { if (!ui.wait_for_move) { queue.inject(parser.seen_test('N') ? F("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : F("G29S2")); TERN_(EXTENSIBLE_UI, ExtUI::onMeshLevelingStart()); + TERN_(DWIN_LCD_PROUI, DWIN_MeshLevelingStart()); return; } state = MeshNext; @@ -127,6 +128,7 @@ void GcodeSuite::G29() { // Save Z for the previous mesh position mbl.set_zigzag_z(mbl_probe_index - 1, current_position.z); TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, current_position.z)); + TERN_(DWIN_LCD_PROUI, DWIN_MeshUpdate(_MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS), current_position.z)); SET_SOFT_ENDSTOP_LOOSE(false); } // If there's another point to sample, move there with optional lift. diff --git a/Marlin/src/gcode/config/M302.cpp b/Marlin/src/gcode/config/M302.cpp index e271dcd469..9f4d569d7b 100644 --- a/Marlin/src/gcode/config/M302.cpp +++ b/Marlin/src/gcode/config/M302.cpp @@ -27,6 +27,10 @@ #include "../gcode.h" #include "../../module/temperature.h" +#if ENABLED(DWIN_LCD_PROUI) + #include "../../lcd/e3v2/proui/dwin_defines.h" +#endif + /** * M302: Allow cold extrudes, or set the minimum extrude temperature * @@ -47,6 +51,7 @@ void GcodeSuite::M302() { if (seen_S) { thermalManager.extrude_min_temp = parser.value_celsius(); thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0); + TERN_(DWIN_LCD_PROUI, HMI_data.ExtMinT = thermalManager.extrude_min_temp); } if (parser.seen('P')) diff --git a/Marlin/src/gcode/sd/M524.cpp b/Marlin/src/gcode/sd/M524.cpp index e715915565..001a1e1842 100644 --- a/Marlin/src/gcode/sd/M524.cpp +++ b/Marlin/src/gcode/sd/M524.cpp @@ -27,15 +27,27 @@ #include "../gcode.h" #include "../../sd/cardreader.h" +#if ENABLED(DWIN_LCD_PROUI) + #include "../../lcd/e3v2/proui/dwin.h" +#endif + /** * M524: Abort the current SD print job (started with M24) */ void GcodeSuite::M524() { - if (IS_SD_PRINTING()) - card.abortFilePrintSoon(); - else if (card.isMounted()) - card.closefile(); + #if ENABLED(DWIN_LCD_PROUI) + + HMI_flag.abort_flag = true; // The LCD will handle it + + #else + + if (IS_SD_PRINTING()) + card.abortFilePrintSoon(); + else if (card.isMounted()) + card.closefile(); + + #endif } diff --git a/Marlin/src/gcode/stats/M75-M78.cpp b/Marlin/src/gcode/stats/M75-M78.cpp index 01630adc50..0ed1e66930 100644 --- a/Marlin/src/gcode/stats/M75-M78.cpp +++ b/Marlin/src/gcode/stats/M75-M78.cpp @@ -39,8 +39,8 @@ void GcodeSuite::M75() { startOrResumeJob(); #if ENABLED(DWIN_LCD_PROUI) - DWIN_Print_Header(parser.string_arg && parser.string_arg[0] ? parser.string_arg : GET_TEXT(MSG_HOST_START_PRINT)); DWIN_Print_Started(false); + if (!IS_SD_PRINTING()) DWIN_Print_Header(parser.string_arg && parser.string_arg[0] ? parser.string_arg : GET_TEXT(MSG_HOST_START_PRINT)); #endif } @@ -50,6 +50,7 @@ void GcodeSuite::M75() { void GcodeSuite::M76() { print_job_timer.pause(); TERN_(HOST_PAUSE_M76, hostui.pause()); + TERN_(DWIN_LCD_PROUI, DWIN_Print_Pause()); } /** diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 9d9fddc8c1..33d9e46220 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -479,6 +479,9 @@ #if EITHER(HAS_DWIN_E3V2_BASIC, DWIN_CREALITY_LCD_JYERSUI) #define HAS_DWIN_E3V2 1 #endif +#if ENABLED(DWIN_LCD_PROUI) + #define DO_LIST_BIN_FILES 1 +#endif // E3V2 extras #if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI @@ -513,7 +516,7 @@ #endif #endif -#if ANY(HAS_WIRED_LCD, EXTENSIBLE_UI, DWIN_CREALITY_LCD_JYERSUI) +#if ANY(HAS_WIRED_LCD, EXTENSIBLE_UI, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI) #define HAS_DISPLAY 1 #endif diff --git a/Marlin/src/lcd/e3v2/common/encoder.h b/Marlin/src/lcd/e3v2/common/encoder.h index e5d9645ed4..3ab8c3bf42 100644 --- a/Marlin/src/lcd/e3v2/common/encoder.h +++ b/Marlin/src/lcd/e3v2/common/encoder.h @@ -45,12 +45,32 @@ typedef enum { ENCODER_DIFF_ENTER = 3 // click } EncoderState; +#define ENCODER_WAIT_MS 20 + // Encoder initialization void Encoder_Configuration(); // Analyze encoder value and return state EncoderState Encoder_ReceiveAnalyze(); +inline EncoderState get_encoder_state() { + static millis_t Encoder_ms = 0; + const millis_t ms = millis(); + if (PENDING(ms, Encoder_ms)) return ENCODER_DIFF_NO; + const EncoderState state = Encoder_ReceiveAnalyze(); + if (state != ENCODER_DIFF_NO) Encoder_ms = ms + ENCODER_WAIT_MS; + return state; +} + +template +inline bool Apply_Encoder(const EncoderState &encoder_diffState, T &valref) { + if (encoder_diffState == ENCODER_DIFF_CW) + valref += EncoderRate.encoderMoveValue; + else if (encoder_diffState == ENCODER_DIFF_CCW) + valref -= EncoderRate.encoderMoveValue; + return encoder_diffState == ENCODER_DIFF_ENTER; +} + /*********************** Encoder LED ***********************/ #if PIN_EXISTS(LCD_LED) diff --git a/Marlin/src/lcd/e3v2/creality/dwin.cpp b/Marlin/src/lcd/e3v2/creality/dwin.cpp index f20260e43d..7dc06d00f2 100644 --- a/Marlin/src/lcd/e3v2/creality/dwin.cpp +++ b/Marlin/src/lcd/e3v2/creality/dwin.cpp @@ -471,15 +471,6 @@ void Draw_Back_First(const bool is_sel=true) { if (is_sel) Draw_Menu_Cursor(0); } -template -inline bool Apply_Encoder(const EncoderState &encoder_diffState, T &valref) { - if (encoder_diffState == ENCODER_DIFF_CW) - valref += EncoderRate.encoderMoveValue; - else if (encoder_diffState == ENCODER_DIFF_CCW) - valref -= EncoderRate.encoderMoveValue; - return encoder_diffState == ENCODER_DIFF_ENTER; -} - // // Draw Menus // @@ -1296,15 +1287,6 @@ void Goto_MainMenu() { TERN(HAS_ONESTEP_LEVELING, ICON_Leveling, ICON_StartInfo)(); } -inline EncoderState get_encoder_state() { - static millis_t Encoder_ms = 0; - const millis_t ms = millis(); - if (PENDING(ms, Encoder_ms)) return ENCODER_DIFF_NO; - const EncoderState state = Encoder_ReceiveAnalyze(); - if (state != ENCODER_DIFF_NO) Encoder_ms = ms + ENCODER_WAIT_MS; - return state; -} - void HMI_Plan_Move(const feedRate_t fr_mm_s) { if (!planner.is_full()) { planner.synchronize(); @@ -4086,6 +4068,13 @@ void HMI_Init() { HMI_SetLanguage(); } +void DWIN_InitScreen() { + Encoder_Configuration(); + HMI_Init(); + HMI_SetLanguageCache(); + HMI_StartFrame(true); +} + void DWIN_Update() { EachMomentUpdate(); // Status update HMI_SDCardUpdate(); // SD card update diff --git a/Marlin/src/lcd/e3v2/creality/dwin.h b/Marlin/src/lcd/e3v2/creality/dwin.h index 3122a6fcba..3ccb70e52f 100644 --- a/Marlin/src/lcd/e3v2/creality/dwin.h +++ b/Marlin/src/lcd/e3v2/creality/dwin.h @@ -236,6 +236,7 @@ void HMI_MaxJerk(); // Maximum jerk speed submenu void HMI_Step(); // Transmission ratio void HMI_Init(); +void DWIN_InitScreen(); void DWIN_Update(); void EachMomentUpdate(); void DWIN_HandleScreen(); diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp index 9e08854aed..0a392cd563 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp @@ -21,19 +21,18 @@ */ /** - * Enhanced DWIN implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.11.2 - * date: 2022/01/19 - * - * Based on the original code provided by Creality under GPL + * Version: 3.15.2 + * Date: 2022/03/01 */ -#include "../../../inc/MarlinConfigPre.h" +#include "../../../inc/MarlinConfig.h" #if ENABLED(DWIN_LCD_PROUI) #include "dwin.h" +#include "menus.h" #include "dwin_popup.h" #include "../../fontutils.h" @@ -65,6 +64,10 @@ #include "../../../feature/host_actions.h" #endif +#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) && DISABLED(PROBE_MANUALLY) + #define HAS_ONESTEP_LEVELING 1 +#endif + #if HAS_MESH || HAS_ONESTEP_LEVELING #include "../../../feature/bedlevel/bedlevel.h" #endif @@ -77,8 +80,14 @@ #include "../../../feature/bltouch.h" #endif -#if EITHER(BABYSTEP_ZPROBE_OFFSET, JUST_BABYSTEP) - #include "../../../feature/babystep.h" +#if ANY(BABYSTEPPING, HAS_BED_PROBE, HAS_WORKSPACE_OFFSET) + #define HAS_ZOFFSET_ITEM 1 + #if !HAS_BED_PROBE && ENABLED(BABYSTEPPING) + #define JUST_BABYSTEP 1 + #endif + #if EITHER(BABYSTEP_ZPROBE_OFFSET, JUST_BABYSTEP) + #include "../../../feature/babystep.h" + #endif #endif #if ENABLED(POWER_LOSS_RECOVERY) @@ -171,7 +180,7 @@ enum SelectItem : uint8_t { PAGE_PRINT = 0, PAGE_PREPARE, PAGE_CONTROL, - PAGE_INFO_LEV_ADV, + PAGE_ADVANCE, PAGE_COUNT, PRINT_SETUP = 0, @@ -192,14 +201,13 @@ typedef struct { select_t select_page{0}, select_file{0}, select_print{0}; uint8_t index_file = MROWS; -bool dwin_abort_flag = false; // Flag to reset feedrate, return to Home bool hash_changed = true; // Flag to know if message status was changed -constexpr float default_max_feedrate[] = DEFAULT_MAX_FEEDRATE; -constexpr float default_max_acceleration[] = DEFAULT_MAX_ACCELERATION; +constexpr float max_feedrate_edit_values[] = DEFAULT_MAX_FEEDRATE; +constexpr float max_acceleration_edit_values[] = DEFAULT_MAX_ACCELERATION; #if HAS_CLASSIC_JERK - constexpr float default_max_jerk[] = { DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_EJERK }; + constexpr float max_jerk_edit_values[] = { DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_EJERK }; #endif static uint8_t _percent_done = 0; @@ -208,18 +216,6 @@ static uint32_t _remain_time = 0; // Additional Aux Host Support static bool sdprint = false; -#if ENABLED(PAUSE_HEAT) - #if HAS_HOTEND - celsius_t resume_hotend_temp = 0; - #endif - #if HAS_HEATED_BED - celsius_t resume_bed_temp = 0; - #endif - #if HAS_FAN - uint16_t resume_fan = 0; - #endif -#endif - #if HAS_ZOFFSET_ITEM float dwin_zoffset = 0, last_zoffset = 0; #endif @@ -348,31 +344,13 @@ void ICON_Control() { ICON_Button(select_page.now == PAGE_CONTROL, ICON_Control_0, ico, txt, GET_TEXT_F(MSG_CONTROL)); } -// -// Main Menu: "Info" -// -void ICON_StartInfo() { - constexpr frame_rect_t ico = { 145, 226, 110, 100 }; - constexpr text_info_t txt = { 91, { 405, TERN(USE_STOCK_DWIN_SET, 446, 447) }, 27, 15 }; - ICON_Button(select_page.now == PAGE_INFO_LEV_ADV, ICON_Info_0, ico, txt, GET_TEXT_F(MSG_BUTTON_INFO)); -} - -// -// Main Menu: "Level" -// -void ICON_Leveling() { - constexpr frame_rect_t ico = { 145, 226, 110, 100 }; - constexpr text_info_t txt = { 211, { 405, TERN(USE_STOCK_DWIN_SET, 446, 447) }, 27, 15 }; - ICON_Button(select_page.now == PAGE_INFO_LEV_ADV, ICON_Leveling_0, ico, txt, GET_TEXT_F(MSG_BUTTON_LEVEL)); -} - // // Main Menu: "Advanced Settings" // void ICON_AdvSettings() { constexpr frame_rect_t ico = { 145, 226, 110, 100 }; constexpr text_info_t txt = { 91, { 405, TERN(USE_STOCK_DWIN_SET, 446, 447) }, 27, 15 }; - ICON_Button(select_page.now == PAGE_INFO_LEV_ADV, ICON_Info_0, ico, txt, GET_TEXT_F(MSG_BUTTON_ADVANCED)); + ICON_Button(select_page.now == PAGE_ADVANCE, ICON_Info_0, ico, txt, GET_TEXT_F(MSG_BUTTON_ADVANCED)); } // @@ -415,14 +393,6 @@ void ICON_Stop() { // Drawing routines //----------------------------------------------------------------------------- -void Draw_Menu_Cursor(const int8_t line) { - DWIN_Draw_Rectangle(1, HMI_data.Cursor_color, 0, MBASE(line) - 18, 14, MBASE(line + 1) - 20); -} - -void Erase_Menu_Cursor(const int8_t line) { - DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, MBASE(line) - 18, 14, MBASE(line + 1) - 20); -} - void Move_Highlight(const int8_t from, const int8_t newline) { Erase_Menu_Cursor(newline - from); Draw_Menu_Cursor(newline); @@ -430,7 +400,7 @@ void Move_Highlight(const int8_t from, const int8_t newline) { void Add_Menu_Line() { Move_Highlight(1, MROWS); - DWIN_Draw_Line(HMI_data.SplitLine_Color, 16, MBASE(MROWS + 1) - 20, 256, MBASE(MROWS + 1) - 19); + DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(MROWS + 1), 240); } void Scroll_Menu(const uint8_t dir) { @@ -449,21 +419,6 @@ void Erase_Menu_Text(const uint8_t line) { DWIN_Draw_Rectangle(1, HMI_data.Background_Color, LBLX, MBASE(line) - 14, 271, MBASE(line) + 28); } -void Draw_Menu_Line(const uint8_t line, const uint8_t icon=0, const char * const label=nullptr, bool more=false) { - if (icon) DWINUI::Draw_Icon(icon, ICOX, MBASE(line) - 3); - if (label) DWINUI::Draw_String(LBLX, MBASE(line) - 1, (char*)label); - if (more) DWINUI::Draw_Icon(ICON_More, VALX + 16, MBASE(line) - 3); - DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240); -} - -void Draw_Chkb_Line(const uint8_t line, const bool checked) { - DWINUI::Draw_Checkbox(HMI_data.Text_Color, HMI_data.Background_Color, VALX + 16, MBASE(line) - 1, checked); -} - -void Draw_Menu_IntValue(uint16_t bcolor, const uint8_t line, uint8_t iNum, const uint16_t value=0) { - DWINUI::Draw_Int(HMI_data.Text_Color, bcolor, iNum , VALX, MBASE(line) - 1, value); -} - // Draw "Back" line at the top void Draw_Back_First(const bool is_sel=true) { Draw_Menu_Line(0, ICON_Back); @@ -474,24 +429,6 @@ void Draw_Back_First(const bool is_sel=true) { if (is_sel) Draw_Menu_Cursor(0); } -inline EncoderState get_encoder_state() { - static millis_t Encoder_ms = 0; - const millis_t ms = millis(); - if (PENDING(ms, Encoder_ms)) return ENCODER_DIFF_NO; - const EncoderState state = Encoder_ReceiveAnalyze(); - if (state != ENCODER_DIFF_NO) Encoder_ms = ms + ENCODER_WAIT_MS; - return state; -} - -template -inline bool Apply_Encoder(const EncoderState &encoder_diffState, T &valref) { - if (encoder_diffState == ENCODER_DIFF_CW) - valref += EncoderRate.encoderMoveValue; - else if (encoder_diffState == ENCODER_DIFF_CCW) - valref -= EncoderRate.encoderMoveValue; - return encoder_diffState == ENCODER_DIFF_ENTER; -} - //PopUps void Popup_window_PauseOrStop() { if (HMI_IsChinese()) { @@ -530,9 +467,10 @@ void Popup_window_PauseOrStop() { #if HAS_HOTEND || HAS_HEATED_BED void DWIN_Popup_Temperature(const bool toohigh) { - DWINUI::ClearMenuArea(); - Draw_Popup_Bkgd(); + HMI_SaveProcessID(WaitResponse); if (HMI_IsChinese()) { + DWINUI::ClearMenuArea(); + Draw_Popup_Bkgd(); if (toohigh) { DWINUI::Draw_Icon(ICON_TempTooHigh, 102, 165); DWIN_Frame_AreaCopy(1, 103, 371, 237, 386, 52, 285); @@ -545,23 +483,14 @@ void Popup_window_PauseOrStop() { DWIN_Frame_AreaCopy(1, 189, 389, 271, 402, 95, 310); } } - else { - DWIN_Draw_Popup(toohigh ? ICON_TempTooHigh : ICON_TempTooLow, F("Nozzle or Bed temperature"), toohigh ? F("is too high") : F("is too low")); - } + else DWIN_Show_Popup(toohigh ? ICON_TempTooHigh : ICON_TempTooLow, F("Nozzle or Bed temperature"), toohigh ? F("is too high") : F("is too low"), BTN_Continue); } #endif // Draw status line -void DWIN_DrawStatusLine(const uint16_t color, const uint16_t bgcolor, const char *text, const bool center = true) { - DWIN_Draw_Rectangle(1, bgcolor, 0, STATUS_Y, DWIN_WIDTH, STATUS_Y + 20); - if (text) { - if (center) DWINUI::Draw_CenteredString(color, STATUS_Y + 2, text); - else DWINUI::Draw_String(color, 0, STATUS_Y + 2, text); - } - DWIN_UpdateLCD(); -} -void DWIN_DrawStatusLine(const char *text, const bool center = true) { - DWIN_DrawStatusLine(HMI_data.StatusTxt_Color, HMI_data.StatusBg_Color, text, center); +void DWIN_DrawStatusLine(const char *text) { + DWIN_Draw_Rectangle(1, HMI_data.StatusBg_Color, 0, STATUS_Y, DWIN_WIDTH, STATUS_Y + 20); + if (text) DWINUI::Draw_CenteredString(HMI_data.StatusTxt_Color, STATUS_Y + 2, text); } // Clear & reset status line @@ -582,17 +511,15 @@ void DWIN_CheckStatusMessage() { }; void DWIN_DrawStatusMessage() { - const uint8_t max_status_chars = DWIN_WIDTH / DWINUI::fontWidth(); - #if ENABLED(STATUS_MESSAGE_SCROLLING) // Get the UTF8 character count of the string uint8_t slen = utf8_strlen(ui.status_message); // If the string fits the status line do not scroll it - if (slen <= max_status_chars) { + if (slen <= LCD_WIDTH) { if (hash_changed) { - DWIN_DrawStatusLine(HMI_data.StatusTxt_Color, HMI_data.StatusBg_Color, ui.status_message); + DWIN_DrawStatusLine(ui.status_message); hash_changed = false; } } @@ -605,16 +532,16 @@ void DWIN_DrawStatusMessage() { const char *stat = MarlinUI::status_and_len(rlen); DWIN_Draw_Rectangle(1, HMI_data.StatusBg_Color, 0, STATUS_Y, DWIN_WIDTH, STATUS_Y + 20); DWINUI::MoveTo(0, STATUS_Y + 2); - DWINUI::Draw_String(stat, max_status_chars); + DWINUI::Draw_String(HMI_data.StatusTxt_Color, stat, LCD_WIDTH); // If the string doesn't completely fill the line... - if (rlen < max_status_chars) { - DWINUI::Draw_Char('.'); // Always at 1+ spaces left, draw a dot - uint8_t chars = max_status_chars - rlen; // Amount of space left in characters + if (rlen < LCD_WIDTH) { + DWINUI::Draw_Char(HMI_data.StatusTxt_Color, '.'); // Always at 1+ spaces left, draw a dot + uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters if (--chars) { // Draw a second dot if there's space - DWINUI::Draw_Char('.'); + DWINUI::Draw_Char(HMI_data.StatusTxt_Color, '.'); if (--chars) - DWINUI::Draw_String(ui.status_message, chars); // Print a second copy of the message + DWINUI::Draw_String(HMI_data.StatusTxt_Color, ui.status_message, chars); // Print a second copy of the message } } MarlinUI::advance_status_scroll(); @@ -623,8 +550,8 @@ void DWIN_DrawStatusMessage() { #else if (hash_changed) { - ui.status_message[max_status_chars] = 0; - DWIN_DrawStatusLine(HMI_data.StatusTxt_Color, HMI_data.StatusBg_Color, ui.status_message); + ui.status_message[LCD_WIDTH] = 0; + DWIN_DrawStatusLine(ui.status_message); hash_changed = false; } @@ -643,7 +570,7 @@ void Draw_Print_Labels() { } void Draw_Print_ProgressBar() { - DWINUI::Draw_IconWB(ICON_Bar, 15, 93); + DWIN_ICON_Show(true, false, false, ICON, ICON_Bar, 15, 93); DWIN_Draw_Rectangle(1, HMI_data.Barfill_Color, 16 + _percent_done * 240 / 100, 93, 256, 113); DWINUI::Draw_Int(HMI_data.PercentTxt_Color, HMI_data.Background_Color, 3, 117, 133, _percent_done); DWINUI::Draw_String(HMI_data.PercentTxt_Color, 142, 133, F("%")); @@ -663,10 +590,21 @@ void Draw_Print_ProgressRemain() { } void ICON_ResumeOrPause() { - if (printingIsPaused() || HMI_flag.pause_flag || HMI_flag.pause_action) - ICON_Resume(); - else - ICON_Pause(); + if (checkkey == PrintProcess) printingIsPaused() ? ICON_Resume() : ICON_Pause(); +} + +// Update filename on print +void DWIN_Print_Header(const char *text = nullptr) { + static char headertxt[31] = ""; // Print header text + if (text) { + const int8_t size = _MIN(30U, strlen_P(text)); + LOOP_L_N(i, size) headertxt[i] = text[i]; + headertxt[size] = '\0'; + } + if (checkkey == PrintProcess || checkkey == PrintDone) { + DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, 60, DWIN_WIDTH, 60+16); + DWINUI::Draw_CenteredString(60, headertxt); + } } void Draw_PrintProcess() { @@ -685,17 +623,16 @@ void Draw_PrintProcess() { ICON_Tune(); ICON_ResumeOrPause(); ICON_Stop(); - DWIN_UpdateLCD(); } void Goto_PrintProcess() { - if (checkkey == PrintProcess) { + if (checkkey == PrintProcess) ICON_ResumeOrPause(); - DWIN_UpdateLCD(); - return; + else { + checkkey = PrintProcess; + Draw_PrintProcess(); } - checkkey = PrintProcess; - Draw_PrintProcess(); + DWIN_UpdateLCD(); } void Draw_PrintDone() { @@ -713,8 +650,16 @@ void Draw_PrintDone() { Draw_Print_ProgressElapsed(); Draw_Print_ProgressRemain(); // show print done confirm - DWINUI::Draw_IconWB(HMI_IsChinese() ? ICON_Confirm_C : ICON_Confirm_E, 86, 273); - DWIN_UpdateLCD(); + DWINUI::Draw_Button(BTN_Confirm, 86, 273); +} + +void Goto_PrintDone() { + wait_for_user = true; + if (checkkey != PrintDone) { + checkkey = PrintDone; + Draw_PrintDone(); + DWIN_UpdateLCD(); + } } void Draw_Main_Menu() { @@ -724,18 +669,18 @@ void Draw_Main_Menu() { else Title.ShowCaption(MACHINE_NAME); DWINUI::Draw_Icon(ICON_LOGO, 71, 52); // CREALITY logo + DWIN_ResetStatusLine(); ICON_Print(); ICON_Prepare(); ICON_Control(); ICON_AdvSettings(); - DWIN_UpdateLCD(); } void Goto_Main_Menu() { if (checkkey == MainMenu) return; checkkey = MainMenu; - ui.reset_status(true); Draw_Main_Menu(); + DWIN_UpdateLCD(); } // Draw X, Y, Z and blink if in an un-homed or un-trusted state @@ -751,9 +696,9 @@ void _update_axis_value(const AxisEnum axis, const uint16_t x, const uint16_t y, if (force || changed || draw_qmark || draw_empty) { if (blink && draw_qmark) - DWINUI::Draw_String(HMI_data.Coordinate_Color, HMI_data.Background_Color, x, y, F(" - ? -")); + DWINUI::Draw_String(HMI_data.Coordinate_Color, HMI_data.Background_Color, x, y, F(" - ? -")); else if (blink && draw_empty) - DWINUI::Draw_String(HMI_data.Coordinate_Color, HMI_data.Background_Color, x, y, F(" ")); + DWINUI::Draw_String(HMI_data.Coordinate_Color, HMI_data.Background_Color, x, y, F(" ")); else DWINUI::Draw_Signed_Float(HMI_data.Coordinate_Color, HMI_data.Background_Color, 3, 2, x, y, p); } @@ -766,9 +711,9 @@ void _draw_xyz_position(const bool force) { if (force || blink != _blink) { _blink = blink; //SERIAL_ECHOPGM(" (blink)"); - _update_axis_value(X_AXIS, 35, 459, blink, true); - _update_axis_value(Y_AXIS, 120, 459, blink, true); - _update_axis_value(Z_AXIS, 205, 459, blink, true); + _update_axis_value(X_AXIS, 27, 459, blink, true); + _update_axis_value(Y_AXIS, 112, 459, blink, true); + _update_axis_value(Z_AXIS, 197, 459, blink, true); } //SERIAL_EOL(); } @@ -852,7 +797,7 @@ void update_variable() { static float _offset = 0; if (BABY_Z_VAR != _offset) { _offset = BABY_Z_VAR; - DWINUI::Draw_Signed_Float(DWIN_FONT_STAT, HMI_data.Indicator_Color, HMI_data.Background_Color, 2, 2, 210, 417, _offset); + DWINUI::Draw_Signed_Float(DWIN_FONT_STAT, HMI_data.Indicator_Color, HMI_data.Background_Color, 2, 2, 204, 417, _offset); } #if HAS_MESH @@ -908,15 +853,6 @@ void make_name_without_ext(char *dst, char *src, size_t maxlen=MENU_CHAR_LIMIT) void HMI_SDCardInit() { card.cdroot(); } -// Initialize or re-initialize the LCD -void MarlinUI::init_lcd() { DWIN_Startup(); } - -void MarlinUI::refresh() { /* Nothing to see here */ } - -#if HAS_LCD_BRIGHTNESS - void MarlinUI::_set_brightness() { DWIN_LCD_Brightness(backlight ? brightness : 0); } -#endif - #if ENABLED(SCROLL_LONG_FILENAMES) char shift_name[LONG_FILENAME_LENGTH + 1]; @@ -966,7 +902,8 @@ void Draw_SDItem(const uint16_t item, int16_t row=-1) { // Draw the file/folder with name aligned left char str[strlen(name) + 1]; make_name_without_ext(str, name); - Draw_Menu_Line(row, card.flag.filenameIsDir ? ICON_Folder : ICON_File, str); + const uint8_t icon = card.flag.filenameIsDir ? ICON_Folder : card.fileIsBinary() ? ICON_Binary : ICON_File; + Draw_Menu_Line(row, icon, str); } #if ENABLED(SCROLL_LONG_FILENAMES) @@ -1045,11 +982,8 @@ void HMI_SDCardUpdate() { Redraw_SD_List(); } else if (sdprint && card.isPrinting() && printingIsActive()) { - // TODO: Move card removed abort handling - // to CardReader::manage_media. - card.abortFilePrintSoon(); wait_for_heatup = wait_for_user = false; - dwin_abort_flag = true; // Reset feedrate, return to Home + HMI_flag.abort_flag = true; // Abort print } } DWIN_UpdateLCD(); @@ -1057,10 +991,10 @@ void HMI_SDCardUpdate() { } // -// The status area is always on-screen, except during -// full-screen modal dialogs. (TODO: Keep alive during dialogs) +// The Dashboard is always on-screen, except during +// full-screen modal dialogs. // -void Draw_Status_Area(const bool with_update) { +void DWIN_Draw_Dashboard() { DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, STATUS_Y + 21, DWIN_WIDTH, DWIN_HEIGHT - 1); @@ -1095,7 +1029,7 @@ void Draw_Status_Area(const bool with_update) { DWINUI::Draw_Icon(planner.leveling_active ? ICON_SetZOffset : ICON_Zoffset, 187, 416); #endif - DWINUI::Draw_Signed_Float(DWIN_FONT_STAT, HMI_data.Indicator_Color, HMI_data.Background_Color, 2, 2, 210, 417, BABY_Z_VAR); + DWINUI::Draw_Signed_Float(DWIN_FONT_STAT, HMI_data.Indicator_Color, HMI_data.Background_Color, 2, 2, 204, 417, BABY_Z_VAR); DWIN_Draw_Rectangle(1, HMI_data.SplitLine_Color, 0, 449, DWIN_WIDTH, 451); @@ -1104,16 +1038,6 @@ void Draw_Status_Area(const bool with_update) { DWINUI::Draw_Icon(ICON_MaxSpeedZ, 180, 456); _draw_xyz_position(true); - if (with_update) { - DWIN_UpdateLCD(); - delay(5); - } -} - -void HMI_StartFrame(const bool with_update) { - Goto_Main_Menu(); - DWIN_DrawStatusLine(nullptr); - Draw_Status_Area(with_update); } void Draw_Info_Menu() { @@ -1143,8 +1067,6 @@ void Draw_Info_Menu() { DWINUI::Draw_Icon(ICON_PrintSize + i, ICOX, 99 + i * 73); DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MBASE(2) + i * 73, 240); } - - DWIN_UpdateLCD(); } void Draw_Print_File_Menu() { @@ -1166,7 +1088,7 @@ void HMI_MainMenu() { case PAGE_PRINT: ICON_Print(); break; case PAGE_PREPARE: ICON_Print(); ICON_Prepare(); break; case PAGE_CONTROL: ICON_Prepare(); ICON_Control(); break; - case PAGE_INFO_LEV_ADV: ICON_Control(); ICON_AdvSettings(); break; + case PAGE_ADVANCE: ICON_Control(); ICON_AdvSettings(); break; } } } @@ -1176,7 +1098,7 @@ void HMI_MainMenu() { case PAGE_PRINT: ICON_Print(); ICON_Prepare(); break; case PAGE_PREPARE: ICON_Prepare(); ICON_Control(); break; case PAGE_CONTROL: ICON_Control(); ICON_AdvSettings(); break; - case PAGE_INFO_LEV_ADV: ICON_AdvSettings(); break; + case PAGE_ADVANCE: ICON_AdvSettings(); break; } } } @@ -1185,14 +1107,12 @@ void HMI_MainMenu() { case PAGE_PRINT: checkkey = SelectFile; card.mount(); + delay(300); Draw_Print_File_Menu(); break; - case PAGE_PREPARE: Draw_Prepare_Menu(); break; - case PAGE_CONTROL: Draw_Control_Menu(); break; - - case PAGE_INFO_LEV_ADV: Draw_AdvancedSettings_Menu(); break; + case PAGE_ADVANCE: Draw_AdvancedSettings_Menu(); break; } } DWIN_UpdateLCD(); @@ -1277,7 +1197,7 @@ void HMI_SelectFile() { else if (encoder_diffState == ENCODER_DIFF_ENTER) { if (select_file.now == 0) { // Back select_page.set(PAGE_PRINT); - Goto_Main_Menu(); + return Goto_Main_Menu(); } else if (hasUpDir && select_file.now == 1) { // CD-Up SDCard_Up(); @@ -1301,16 +1221,10 @@ void HMI_SelectFile() { HMI_flag.heat_flag = true; HMI_flag.print_finish = false; - card.openAndPrintFile(card.filename); - - #if HAS_FAN - // All fans on for Ender 3 v2 ? - // The slicer should manage this for us. - //for (uint8_t i = 0; i < FAN_COUNT; i++) - // thermalManager.fan_speed[i] = 255; - #endif - - DWIN_Print_Started(true); + if (card.fileIsBinary()) + return DWIN_Popup_Confirm(ICON_Error, F("Please check filenames"), F("Only G-code can be printed")); + else + return Goto_ConfirmToPrint(); } } @@ -1318,6 +1232,16 @@ void HMI_SelectFile() { DWIN_UpdateLCD(); } +// Pause or Stop popup +void onClick_PauseOrStop() { + switch (select_print.now) { + case PRINT_PAUSE_RESUME: if (HMI_flag.select_flag) HMI_flag.pause_flag = true; break; // confirm pause + case PRINT_STOP: if (HMI_flag.select_flag) HMI_flag.abort_flag = true; break; // stop confirmed then abort print + default: break; + } + return Goto_PrintProcess(); +} + // Printing void HMI_Printing() { EncoderState encoder_diffState = get_encoder_state(); @@ -1345,93 +1269,20 @@ void HMI_Printing() { switch (select_print.now) { case PRINT_SETUP: Draw_Tune_Menu(); break; case PRINT_PAUSE_RESUME: - if (HMI_flag.pause_flag) { - ICON_Pause(); - #if DISABLED(ADVANCED_PAUSE_FEATURE) - char cmd[40]; - cmd[0] = '\0'; - #if BOTH(HAS_HEATED_BED, PAUSE_HEAT) - if (resume_bed_temp) sprintf_P(cmd, PSTR("M190 S%i\n"), resume_bed_temp); - #endif - #if BOTH(HAS_HOTEND, PAUSE_HEAT) - if (resume_hotend_temp) sprintf_P(&cmd[strlen(cmd)], PSTR("M109 S%i\n"), resume_hotend_temp); - #endif - #if HAS_FAN - if (resume_fan) thermalManager.fan_speed[0] = resume_fan; - #endif - strcat_P(cmd, M24_STR); - queue.inject(cmd); - #endif + if (printingIsPaused()) { // if printer is already in pause + ui.resume_print(); + break; } - else { - HMI_flag.select_flag = true; - checkkey = PauseOrStop; - Popup_window_PauseOrStop(); - } - break; - + else + return Goto_Popup(Popup_window_PauseOrStop, onClick_PauseOrStop); case PRINT_STOP: - HMI_flag.select_flag = true; - checkkey = PauseOrStop; - Popup_window_PauseOrStop(); - break; - + return Goto_Popup(Popup_window_PauseOrStop, onClick_PauseOrStop); default: break; } } DWIN_UpdateLCD(); } -// Print done -void HMI_PrintDone() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - if (encoder_diffState == ENCODER_DIFF_ENTER) { - dwin_abort_flag = true; // Reset feedrate, return to Home - Goto_Main_Menu(); // Return to Main menu after print done - } -} - -// Pause or Stop popup -void HMI_PauseOrStop() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - - if (encoder_diffState == ENCODER_DIFF_CW) - Draw_Select_Highlight(false); - else if (encoder_diffState == ENCODER_DIFF_CCW) - Draw_Select_Highlight(true); - else if (encoder_diffState == ENCODER_DIFF_ENTER) { - if (select_print.now == PRINT_PAUSE_RESUME) { - if (HMI_flag.select_flag) { - HMI_flag.pause_action = true; - ICON_Resume(); - queue.inject(F("M25")); - } - else { - // cancel pause - } - Goto_PrintProcess(); - } - else if (select_print.now == PRINT_STOP) { - if (HMI_flag.select_flag) { - checkkey = MainMenu; - if (HMI_flag.home_flag) planner.synchronize(); // Wait for planner moves to finish! - wait_for_heatup = wait_for_user = false; // Stop waiting for heating/user - card.abortFilePrintSoon(); // Let the main loop handle SD abort - dwin_abort_flag = true; // Reset feedrate, return to Home - #ifdef ACTION_ON_CANCEL - hostui.cancel(); - #endif - DWIN_Draw_Popup(ICON_BLTouch, GET_TEXT_F(MSG_STOPPING), GET_TEXT_F(MSG_PLEASE_WAIT)); - } - else - Goto_PrintProcess(); // cancel stop - } - } - DWIN_UpdateLCD(); -} - #include "../../../libs/buzzer.h" void HMI_AudioFeedback(const bool success/*=true*/) { @@ -1452,24 +1303,11 @@ void Draw_Main_Area() { case SelectFile: Draw_Print_File_Menu(); break; case PrintProcess: Draw_PrintProcess(); break; case PrintDone: Draw_PrintDone(); break; - case Info: Draw_Info_Menu(); break; #if HAS_ESDIAG case ESDiagProcess: Draw_EndStopDiag(); break; #endif - #if ENABLED(PRINTCOUNTER) - case PrintStatsProcess: Draw_PrintStats(); break; - #endif - case PauseOrStop: Popup_window_PauseOrStop(); break; - #if ENABLED(POWER_LOSS_RECOVERY) - case PwrlossRec: Popup_PowerLossRecovery(); break; - #endif - #if ENABLED(ADVANCED_PAUSE_FEATURE) - case FilamentPurge: Draw_Popup_FilamentPurge(); break; - #endif + case Popup: popupDraw(); break; case Locked: lockScreen.draw(); break; - #if HAS_GCODE_PREVIEW - case ConfirmToPrint: Draw_PreviewFromSD(); break; - #endif case Menu: case SetInt: case SetPInt: @@ -1484,19 +1322,32 @@ void HMI_ReturnScreen() { checkkey = last_checkkey; wait_for_user = false; Draw_Main_Area(); - return; } -void HMI_Popup() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - if (encoder_diffState == ENCODER_DIFF_ENTER) { - HMI_ReturnScreen(); +void HMI_WaitForUser() { + get_encoder_state(); + if (!wait_for_user) { + switch (checkkey) { + case PrintDone: + select_page.reset(); + Goto_Main_Menu(); + break; + #if HAS_ONESTEP_LEVELING + case Leveling: + //TERN_(ProUI, ProEx.StopLeveling()); + HMI_ReturnScreen(); + break; + #endif + default: + HMI_ReturnScreen(); + break; + } } } void HMI_Init() { - HMI_SDCardInit(); + DWINUI::Draw_Box(1, Color_Black, {5, 220, DWIN_WIDTH-5, DWINUI::fontHeight()}); + DWINUI::Draw_CenteredString(Color_White, 220, F("Professional Firmware ")); for (uint16_t t = 0; t <= 100; t += 2) { DWINUI::Draw_Icon(ICON_Bar, 15, 260); DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 15 + t * 242 / 100, 260, 257, 280); @@ -1506,12 +1357,6 @@ void HMI_Init() { HMI_SetLanguage(); } -void DWIN_Update() { - EachMomentUpdate(); // Status update - HMI_SDCardUpdate(); // SD card update - DWIN_HandleScreen(); // Rotary encoder update -} - void EachMomentUpdate() { static millis_t next_var_update_ms = 0, next_rts_update_ms = 0, next_status_update_ms = 0; @@ -1538,52 +1383,45 @@ void EachMomentUpdate() { if (PENDING(ms, next_rts_update_ms)) return; next_rts_update_ms = ms + DWIN_SCROLL_UPDATE_INTERVAL; - if (checkkey == PrintProcess) { - // if print done - if (HMI_flag.print_finish) { - HMI_flag.print_finish = false; - TERN_(POWER_LOSS_RECOVERY, recovery.cancel()); - planner.finish_and_disable(); - checkkey = PrintDone; - Draw_PrintDone(); - } - else if (HMI_flag.pause_flag != printingIsPaused()) { - // print status update - HMI_flag.pause_flag = printingIsPaused(); - ICON_ResumeOrPause(); - } - } - - // pause after homing - if (HMI_flag.pause_action && printingIsPaused() && !planner.has_blocks_queued()) { - HMI_flag.pause_action = false; - #if ENABLED(PAUSE_HEAT) - TERN_(HAS_HOTEND, resume_hotend_temp = sdprint ? thermalManager.degTargetHotend(0) : thermalManager.wholeDegHotend(0)); - TERN_(HAS_HEATED_BED, resume_bed_temp = sdprint ? thermalManager.degTargetBed() : thermalManager.wholeDegBed()); - TERN_(HAS_FAN, resume_fan = thermalManager.fan_speed[0]); - #endif - IF_DISABLED(ADVANCED_PAUSE_FEATURE, thermalManager.disable_all_heaters()); - IF_DISABLED(PARK_HEAD_ON_PAUSE, queue.inject(F("G1 F1200 X0 Y0"))); - } - if (checkkey == PrintProcess) { // print process + // Print pause + if (HMI_flag.pause_flag && !HMI_flag.home_flag) { + HMI_flag.pause_flag = false; + if (!HMI_flag.pause_action) { + HMI_flag.pause_action = true; + return ui.pause_print(); + } + } + + // if print done + if (HMI_flag.print_finish && !HMI_flag.home_flag) { + HMI_flag.print_finish = false; + return DWIN_Print_Finished(); + } + + // if print was aborted + if (HMI_flag.abort_flag && !HMI_flag.home_flag) { // Print Stop + HMI_flag.abort_flag = false; + if (!HMI_flag.abort_action) { + HMI_flag.abort_action = true; + ui.abort_print(); + return Goto_PrintDone(); + } + } + duration_t elapsed = print_job_timer.duration(); // print timer if (sdprint && card.isPrinting()) { uint8_t percentDone = card.percentDone(); - static uint8_t last_percentValue = 101; - if (last_percentValue != percentDone) { // print percent - last_percentValue = percentDone; - if (percentDone) { + if (_percent_done != percentDone) { // print percent _percent_done = percentDone; Draw_Print_ProgressBar(); } - } // Estimate remaining time every 20 seconds static millis_t next_remain_time_update = 0; - if (_percent_done > 1 && ELAPSED(ms, next_remain_time_update) && !HMI_flag.heat_flag) { + if (_percent_done > 1 && ELAPSED(ms, next_remain_time_update) && !HMI_flag.heat_flag && !HMI_flag.remain_flag) { _remain_time = (elapsed.value - dwin_heat_time) / (_percent_done * 0.01f) - (elapsed.value - dwin_heat_time); next_remain_time_update += DWIN_REMAIN_TIME_UPDATE_INTERVAL; Draw_Print_ProgressRemain(); @@ -1599,12 +1437,6 @@ void EachMomentUpdate() { } } - else if (dwin_abort_flag && !HMI_flag.home_flag) { // Print Stop - dwin_abort_flag = false; - dwin_zoffset = BABY_Z_VAR; - select_page.set(PAGE_PRINT); - Goto_Main_Menu(); - } #if ENABLED(POWER_LOSS_RECOVERY) else if (DWIN_lcd_sd_status && recovery.dwin_flag) { // resume print before power off @@ -1629,8 +1461,8 @@ void EachMomentUpdate() { DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 70, GET_TEXT_F(MSG_OUTAGE_RECOVERY)); DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 147, F("It looks like the last")); DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 167, F("file was interrupted.")); - DWINUI::Draw_IconWB(ICON_Cancel_E, 26, 280); - DWINUI::Draw_IconWB(ICON_Continue_E, 146, 280); + DWINUI::Draw_Button(BTN_Cancel, 26, 280); + DWINUI::Draw_Button(BTN_Continue, 146, 280); } SdFile *dir = nullptr; const char * const filename = card.diveToFile(true, dir, recovery.info.sd_filename); @@ -1640,35 +1472,26 @@ void EachMomentUpdate() { DWIN_UpdateLCD(); } + void onClick_PowerLossRecovery() { + if (HMI_flag.select_flag) { + queue.inject(F("M1000C")); + select_page.reset(); + return Goto_Main_Menu(); + } + else { + select_print.set(PRINT_SETUP); + queue.inject(F("M1000")); + sdprint = true; + return Goto_PrintProcess(); + } + } + void Goto_PowerLossRecovery() { recovery.dwin_flag = false; LCD_MESSAGE_F(GET_TEXT_F(MSG_CONTINUE_PRINT_JOB)); - HMI_flag.select_flag = false; - Popup_PowerLossRecovery(); - last_checkkey = MainMenu; - checkkey = PwrlossRec; + Goto_Popup(Popup_PowerLossRecovery, onClick_PowerLossRecovery); } - void HMI_PowerlossRecovery() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - if (encoder_diffState == ENCODER_DIFF_ENTER) { - if (HMI_flag.select_flag) { - queue.inject(F("M1000C")); - select_page.reset(); - Goto_Main_Menu(); - } - else { - select_print.set(PRINT_SETUP); - queue.inject(F("M1000")); - sdprint = true; - Goto_PrintProcess(); - } - } - else - Draw_Select_Highlight(encoder_diffState != ENCODER_DIFF_CW); - DWIN_UpdateLCD(); - } #endif // POWER_LOSS_RECOVERY @@ -1682,49 +1505,39 @@ void DWIN_HandleScreen() { case SetFloat: HMI_SetFloat(); break; case SetPFloat: HMI_SetPFloat(); break; case SelectFile: HMI_SelectFile(); break; - case Homing: break; - case Leveling: break; case PrintProcess: HMI_Printing(); break; - case PrintDone: HMI_PrintDone(); break; - case PauseOrStop: HMI_PauseOrStop(); break; - case Info: HMI_Popup(); break; - case WaitResponse: HMI_Popup(); break; - #if ENABLED(ADVANCED_PAUSE_FEATURE) - case FilamentPurge: HMI_FilamentPurge(); break; - #endif - case NothingToDo: break; + case Popup: HMI_Popup(); break; + case Leveling: //TERN_(ProUI, HMI_WaitForUser()); + break; case Locked: HMI_LockScreen(); break; - #if ENABLED(POWER_LOSS_RECOVERY) - case PwrlossRec: HMI_PowerlossRecovery(); break; - #endif - #if HAS_GCODE_PREVIEW - case ConfirmToPrint: HMI_ConfirmToPrint(); break; - #endif - #if HAS_ESDIAG - case ESDiagProcess: HMI_Popup(); break; - #endif - #if ENABLED(PRINTCOUNTER) - case PrintStatsProcess: HMI_Popup(); break; - #endif + case PrintDone: + TERN_(HAS_ESDIAG, case ESDiagProcess:) + case WaitResponse: HMI_WaitForUser(); break; + case Homing: + case PidProcess: + case NothingToDo: break; default: break; } } bool IDisPopUp() { // If ID is popup... - return (checkkey == NothingToDo) || - (checkkey == WaitResponse) || - (checkkey == Info) || - (checkkey == Homing) || - (checkkey == Leveling) || - TERN_(HAS_ESDIAG, (checkkey == ESDiagProcess) ||) - TERN_(PRINTCOUNTER, (checkkey == PrintStatsProcess) ||) - (checkkey == PauseOrStop) || - (checkkey == FilamentPurge); + return (checkkey == NothingToDo) + || (checkkey == WaitResponse) + || (checkkey == Homing) + || (checkkey == Leveling) + || (checkkey == PidProcess) + || TERN0(HAS_ESDIAG, (checkkey == ESDiagProcess)) + || (checkkey == Popup); } void HMI_SaveProcessID(const uint8_t id) { if (checkkey != id) { if (!IDisPopUp()) last_checkkey = checkkey; // if previous is not a popup + if ((id == Popup) + || TERN0(HAS_ESDIAG, (id == ESDiagProcess)) + || (id == PrintDone) + || (id == Leveling) + || (id == WaitResponse)) wait_for_user = true; checkkey = id; } } @@ -1732,37 +1545,35 @@ void HMI_SaveProcessID(const uint8_t id) { void DWIN_StartHoming() { HMI_flag.home_flag = true; HMI_SaveProcessID(Homing); - Title.ShowCaption(GET_TEXT_F(MSG_LEVEL_BED_HOMING)); - DWIN_Draw_Popup(ICON_BLTouch, GET_TEXT_F(MSG_LEVEL_BED_HOMING), GET_TEXT_F(MSG_PLEASE_WAIT)); + Title.ShowCaption(GET_TEXT_F(MSG_HOMING)); + DWIN_Show_Popup(ICON_BLTouch, GET_TEXT_F(MSG_HOMING), GET_TEXT_F(MSG_PLEASE_WAIT)); } void DWIN_CompletedHoming() { HMI_flag.home_flag = false; dwin_zoffset = TERN0(HAS_BED_PROBE, probe.offset.z); - if (dwin_abort_flag) { - planner.finish_and_disable(); - } - HMI_ReturnScreen(); + if (HMI_flag.abort_action) DWIN_Print_Aborted(); else HMI_ReturnScreen(); } void DWIN_MeshLevelingStart() { #if HAS_ONESTEP_LEVELING HMI_SaveProcessID(Leveling); Title.ShowCaption(GET_TEXT_F(MSG_BED_LEVELING)); - DWIN_Show_Popup(ICON_AutoLeveling, GET_TEXT_F(MSG_BED_LEVELING), GET_TEXT_F(MSG_PLEASE_WAIT), ICON_Cancel_E); + DWIN_Show_Popup(ICON_AutoLeveling, GET_TEXT_F(MSG_BED_LEVELING), GET_TEXT_F(MSG_PLEASE_WAIT)); #elif ENABLED(MESH_BED_LEVELING) Draw_ManualMesh_Menu(); #endif } -void DWIN_CompletedLeveling() { TERN_(HAS_MESH, DWIN_MeshViewer()); } +void DWIN_CompletedLeveling() { + TERN_(HAS_ONESTEP_LEVELING, if (planner.leveling_active) Goto_MeshViewer()); +} #if HAS_MESH - void DWIN_MeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + void DWIN_MeshUpdate(const int8_t xpos, const int8_t ypos, const_float_t zval) { char msg[33] = ""; char str_1[6] = ""; - sprintf_P(msg, PSTR(S_FMT " %i/%i Z=%s"), GET_TEXT(MSG_PROBING_POINT), xpos, ypos, - dtostrf(zval, 1, 2, str_1)); + sprintf_P(msg, PSTR(S_FMT " %i/%i Z=%s"), GET_TEXT(MSG_PROBING_POINT), xpos, ypos, dtostrf(zval, 1, 2, str_1)); ui.set_status(msg); } #endif @@ -1800,67 +1611,63 @@ void DWIN_PidTuning(pidresult_t result) { } } -// Update filename on print -void DWIN_Print_Header(const char *text = nullptr) { - static char headertxt[31] = ""; // Print header text - - if (text) { - const int8_t size = _MIN((unsigned) 30, strlen_P(text)); - LOOP_L_N(i, size) headertxt[i] = text[i]; - headertxt[size] = '\0'; - } - if (checkkey == PrintProcess || checkkey == PrintDone) { - DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, 60, DWIN_WIDTH, 60+16); - DWINUI::Draw_CenteredString(60, headertxt); - } -} - -void Draw_Title(TitleClass* title) { - DWIN_Draw_Rectangle(1, HMI_data.TitleBg_color, 0, 0, DWIN_WIDTH - 1, TITLE_HEIGHT - 1); - if (title->frameid) - DWIN_Frame_AreaCopy(title->frameid, title->frame.left, title->frame.top, title->frame.right, title->frame.bottom, 14, (TITLE_HEIGHT - (title->frame.bottom - title->frame.top)) / 2 - 1); - else - DWIN_Draw_String(false, DWIN_FONT_HEAD, HMI_data.TitleTxt_color, HMI_data.TitleBg_color, 14, (TITLE_HEIGHT - DWINUI::fontHeight(DWIN_FONT_HEAD)) / 2 - 1, title->caption); -} - -void Draw_Menu(MenuClass* menu) { - DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color); - DWIN_Draw_Rectangle(1, DWINUI::backcolor, 0, TITLE_HEIGHT, DWIN_WIDTH - 1, STATUS_Y - 1); - DWIN_ResetStatusLine(); -} - -// Startup routines -void DWIN_Startup() { - DWINUI::init(); - DWINUI::onCursorDraw = Draw_Menu_Cursor; - DWINUI::onCursorErase = Erase_Menu_Cursor; - DWINUI::onTitleDraw = Draw_Title; - DWINUI::onMenuDraw = Draw_Menu; - DWIN_JPG_ShowAndCache(3); - HMI_SetLanguage(); -} - // Started a Print Job void DWIN_Print_Started(const bool sd) { - sdprint = card.isPrinting() || sd; + sdprint = IS_SD_PRINTING() || sd; _percent_done = 0; _remain_time = 0; + HMI_flag.remain_flag = false; + HMI_flag.pause_flag = false; + HMI_flag.pause_action = false; + HMI_flag.abort_flag = false; + HMI_flag.abort_action = false; HMI_flag.print_finish = false; Goto_PrintProcess(); } +// Pause a print job +void DWIN_Print_Pause() { + ICON_ResumeOrPause(); +} + +// Resume print job +void DWIN_Print_Resume() { + HMI_flag.pause_action = false; + ICON_ResumeOrPause(); + if (printJobOngoing()) { + LCD_MESSAGE(MSG_RESUME_PRINT); + Goto_PrintProcess(); + } +} + // Ended print job void DWIN_Print_Finished() { - if (checkkey == PrintProcess || printingIsActive()) { + if (HMI_flag.abort_flag || checkkey == PrintDone) return; + TERN_(POWER_LOSS_RECOVERY, if (card.isPrinting()) recovery.cancel()); + HMI_flag.pause_flag = false; + wait_for_heatup = false; + planner.finish_and_disable(); thermalManager.cooldown(); - HMI_flag.print_finish = true; - } + Goto_PrintDone(); +} + +// Print was aborted +void DWIN_Print_Aborted() { + TERN_(DEBUG_DWIN, SERIAL_ECHOLNPGM("DWIN_Print_Aborted")); + HMI_flag.abort_action = false; + wait_for_heatup = false; + planner.finish_and_disable(); + thermalManager.cooldown(); + Goto_PrintDone(); } // Progress Bar update void DWIN_Progress_Update() { if (parser.seenval('P')) _percent_done = parser.byteval('P'); - if (parser.seenval('R')) _remain_time = parser.ulongval('R') * 60; + if (parser.seenval('R')) { + _remain_time = parser.ulongval('R') * 60; + HMI_flag.remain_flag = true; + } if (checkkey == PrintProcess) { Draw_Print_ProgressBar(); Draw_Print_ProgressRemain(); @@ -1896,11 +1703,18 @@ void DWIN_SetColorDefaults() { void DWIN_SetDataDefaults() { DWIN_SetColorDefaults(); - DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color); - TERN_(HAS_HOTEND, HMI_data.HotendPidT = PREHEAT_1_TEMP_HOTEND); - TERN_(HAS_HEATED_BED, HMI_data.BedPidT = PREHEAT_1_TEMP_BED); - TERN_(HAS_HOTEND, HMI_data.PidCycles = 5); - TERN_(PREVENT_COLD_EXTRUSION, HMI_data.ExtMinT = EXTRUDE_MINTEMP); + DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color); + TERN_(HAS_HOTEND, HMI_data.HotendPidT = PREHEAT_1_TEMP_HOTEND); + TERN_(HAS_HEATED_BED, HMI_data.BedPidT = PREHEAT_1_TEMP_BED); + TERN_(HAS_HOTEND, HMI_data.PidCycles = 5); + #if ENABLED(PREVENT_COLD_EXTRUSION) + HMI_data.ExtMinT = EXTRUDE_MINTEMP; + ApplyExtMinT(); + #endif + #if BOTH(HAS_HEATED_BED, PREHEAT_BEFORE_LEVELING) + HMI_data.BedLevT = PREHEAT_1_TEMP_BED; + #endif + TERN_(BAUD_RATE_GCODE, SetBaud250K()); } void DWIN_StoreSettings(char *buff) { @@ -1912,9 +1726,10 @@ void DWIN_LoadSettings(const char *buff) { memcpy((void *)&HMI_data, buff, _MIN(sizeof(HMI_data), eeprom_data_size)); dwin_zoffset = TERN0(HAS_BED_PROBE, probe.offset.z); if (HMI_data.Text_Color == HMI_data.Background_Color) DWIN_SetColorDefaults(); - DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color); + DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color); TERN_(PREVENT_COLD_EXTRUSION, ApplyExtMinT()); feedrate_percentage = 100; + TERN_(BAUD_RATE_GCODE, HMI_SetBaudRate()); #if BOTH(CASE_LIGHT_MENU, CASELIGHT_USES_BRIGHTNESS) // Apply Case light brightness caselight.brightness = HMI_data.CaseLight_Brightness; @@ -1926,6 +1741,37 @@ void DWIN_LoadSettings(const char *buff) { #endif } +// Initialize or re-initialize the LCD +void MarlinUI::init_lcd() { + TERN_(DEBUG_DWIN, SERIAL_ECHOLNPGM("DWIN_Startup")); + DWINUI::init(); + DWIN_JPG_CacheTo1(Language_English); + Encoder_Configuration(); +} + +void DWIN_InitScreen() { + HMI_Init(); // draws boot screen + DWINUI::onCursorDraw = Draw_Menu_Cursor; + DWINUI::onCursorErase = Erase_Menu_Cursor; + DWINUI::onTitleDraw = Draw_Title; + DWINUI::onMenuDraw = Draw_Menu; + DWIN_DrawStatusLine(nullptr); + DWIN_Draw_Dashboard(); + Goto_Main_Menu(); +} + +void MarlinUI::update() { + EachMomentUpdate(); // Status update + HMI_SDCardUpdate(); // SD card update + DWIN_HandleScreen(); // Rotary encoder update +} + +void MarlinUI::refresh() { /* Nothing to see here */ } + +#if HAS_LCD_BRIGHTNESS + void MarlinUI::_set_brightness() { DWIN_LCD_Brightness(backlight ? brightness : 0); } +#endif + void MarlinUI::kill_screen(FSTR_P const lcd_error, FSTR_P const lcd_component) { DWIN_Draw_Popup(ICON_BLTouch, F("Printer killed:"), lcd_error); DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 270, F("Turn off the printer")); @@ -1938,65 +1784,55 @@ void DWIN_RebootScreen() { DWINUI::Draw_CenteredString(Color_White, 220, GET_TEXT_F(MSG_PLEASE_WAIT_REBOOT)); DWIN_UpdateLCD(); delay(500); - DWIN_JPG_ShowAndCache(3); } void DWIN_Redraw_screen() { Draw_Main_Area(); - Draw_Status_Area(false); + hash_changed = true; + DWIN_DrawStatusMessage(); + DWIN_Draw_Dashboard(); } #if ENABLED(ADVANCED_PAUSE_FEATURE) - - void DWIN_Popup_Pause(FSTR_P const fmsg, uint8_t button = 0) { + void DWIN_Popup_Pause(FSTR_P const fmsg, uint8_t button /*= 0*/) { HMI_SaveProcessID(button ? WaitResponse : NothingToDo); - DWIN_Draw_Popup(ICON_BLTouch, GET_TEXT_F(MSG_ADVANCED_PAUSE), fmsg, button); - ui.reset_status(true); + DWIN_Show_Popup(ICON_BLTouch, GET_TEXT_F(MSG_ADVANCED_PAUSE), fmsg, button); } void MarlinUI::pause_show_message(const PauseMessage message, const PauseMode mode/*=PAUSE_MODE_SAME*/, const uint8_t extruder/*=active_extruder*/) { + //if (mode == PAUSE_MODE_SAME) return; + pause_mode = mode; switch (message) { - case PAUSE_MESSAGE_PARKING: DWIN_Popup_Pause(GET_TEXT_F(MSG_PAUSE_PRINT_PARKING)); break; - case PAUSE_MESSAGE_CHANGING: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_INIT)); break; - case PAUSE_MESSAGE_UNLOAD: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_UNLOAD)); break; - case PAUSE_MESSAGE_WAITING: DWIN_Popup_Pause(GET_TEXT_F(MSG_ADVANCED_PAUSE_WAITING), ICON_Continue_E); break; + case PAUSE_MESSAGE_PARKING: DWIN_Popup_Pause(GET_TEXT_F(MSG_PAUSE_PRINT_PARKING)); break; // M125 + case PAUSE_MESSAGE_CHANGING: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_INIT)); break; // pause_print (M125, M600) + case PAUSE_MESSAGE_WAITING: DWIN_Popup_Pause(GET_TEXT_F(MSG_ADVANCED_PAUSE_WAITING), BTN_Continue); break; case PAUSE_MESSAGE_INSERT: DWIN_Popup_Continue(ICON_BLTouch, GET_TEXT_F(MSG_ADVANCED_PAUSE), GET_TEXT_F(MSG_FILAMENT_CHANGE_INSERT)); break; case PAUSE_MESSAGE_LOAD: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_LOAD)); break; - case PAUSE_MESSAGE_PURGE: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE)); break; - case PAUSE_MESSAGE_OPTION: DWIN_Popup_FilamentPurge(); break; + case PAUSE_MESSAGE_UNLOAD: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_UNLOAD)); break; // Unload of pause and Unload of M702 + case PAUSE_MESSAGE_PURGE: + #if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE) + DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_CONT_PURGE)); + #else + DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE)); + #endif + break; + case PAUSE_MESSAGE_OPTION: Goto_FilamentPurge(); break; case PAUSE_MESSAGE_RESUME: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_RESUME)); break; - case PAUSE_MESSAGE_HEAT: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_HEAT), ICON_Continue_E); break; + case PAUSE_MESSAGE_HEAT: DWIN_Popup_Pause(GET_TEXT_F(MSG_FILAMENT_CHANGE_HEAT), BTN_Continue); break; case PAUSE_MESSAGE_HEATING: LCD_MESSAGE(MSG_FILAMENT_CHANGE_HEATING); break; - case PAUSE_MESSAGE_STATUS: HMI_ReturnScreen(); break; + case PAUSE_MESSAGE_STATUS: HMI_ReturnScreen(); break; // Exit from Pause, Load and Unload default: break; } } void Draw_Popup_FilamentPurge() { DWIN_Draw_Popup(ICON_BLTouch, GET_TEXT_F(MSG_ADVANCED_PAUSE), F("Purge or Continue?")); - DWINUI::Draw_IconWB(ICON_Confirm_E, 26, 280); - DWINUI::Draw_IconWB(ICON_Continue_E, 146, 280); + DWINUI::Draw_Button(BTN_Confirm, 26, 280); + DWINUI::Draw_Button(BTN_Continue, 146, 280); Draw_Select_Highlight(true); - DWIN_UpdateLCD(); } - // Handle responses such as: - // - Purge More, Continue - // - General "Continue" response - void DWIN_Popup_FilamentPurge() { - HMI_SaveProcessID(FilamentPurge); - pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; - Draw_Popup_FilamentPurge(); - } - - void HMI_FilamentPurge() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - if (encoder_diffState == ENCODER_DIFF_CW) - Draw_Select_Highlight(false); - else if (encoder_diffState == ENCODER_DIFF_CCW) - Draw_Select_Highlight(true); - else if (encoder_diffState == ENCODER_DIFF_ENTER) { + void onClick_FilamentPurge() { if (HMI_flag.select_flag) pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // "Purge More" button else { @@ -2004,7 +1840,10 @@ void DWIN_Redraw_screen() { pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // "Continue" button } } - DWIN_UpdateLCD(); + + void Goto_FilamentPurge() { + pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; + Goto_Popup(Draw_Popup_FilamentPurge, onClick_FilamentPurge); } #endif // ADVANCED_PAUSE_FEATURE @@ -2042,39 +1881,10 @@ void HMI_LockScreen() { if (lockScreen.isUnlocked()) DWIN_UnLockScreen(); } -#if HAS_GCODE_PREVIEW - - void HMI_ConfirmToPrint() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - if (encoder_diffState == ENCODER_DIFF_CW) - Draw_Select_Highlight(false); - else if (encoder_diffState == ENCODER_DIFF_CCW) - Draw_Select_Highlight(true); - else if (encoder_diffState == ENCODER_DIFF_ENTER) { - if (HMI_flag.select_flag) { // Confirm - card.openAndPrintFile(card.filename); - DWIN_Print_Started(true); - } - else { // Cancel - DWIN_ResetStatusLine(); - checkkey = SelectFile; - Draw_Print_File_Menu(); - } - } - DWIN_UpdateLCD(); - } - -#endif void Goto_ConfirmToPrint() { - #if HAS_GCODE_PREVIEW - HMI_SaveProcessID(ConfirmToPrint); - Draw_PreviewFromSD(); - #else - card.openAndPrintFile(card.filename); - DWIN_Print_Started(true); - #endif + card.openAndPrintFile(card.filename); + DWIN_Print_Started(true); } #if HAS_ESDIAG @@ -2084,103 +1894,11 @@ void Goto_ConfirmToPrint() { } #endif -#if ENABLED(PRINTCOUNTER) - void Draw_PrintStats() { - HMI_SaveProcessID(PrintStatsProcess); - PrintStats.Draw(); - } -#endif - //============================================================================= // NEW MENU SUBSYSTEM //============================================================================= -// On click functions - -// Generic onclick event without draw anything -// process: process id HMI destiny -// lo: low limit -// hi: high limit -// dp: decimal places, 0 for integers -// val: value / scaled value -// LiveUpdate: live update function when the encoder changes -// Apply: update function when the encoder is pressed -void SetOnClick(uint8_t process, const int32_t lo, const int32_t hi, uint8_t dp, const int32_t val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - checkkey = process; - HMI_value.MinValue = lo; - HMI_value.MaxValue = hi; - HMI_value.dp = dp; - HMI_value.Apply = Apply; - HMI_value.LiveUpdate = LiveUpdate; - HMI_value.Value = val; - EncoderRate.enabled = true; -} - -// Generic onclick event for integer values -// process: process id HMI destiny -// lo: scaled low limit -// hi: scaled high limit -// val: value -// LiveUpdate: live update function when the encoder changes -// Apply: update function when the encoder is pressed -void SetValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - SetOnClick(process, lo, hi, 0, val, Apply, LiveUpdate); - Draw_Menu_IntValue(HMI_data.Selected_Color, CurrentMenu->line(), 4, HMI_value.Value); -} - -// Generic onclick event for float values -// process: process id HMI destiny -// lo: scaled low limit -// hi: scaled high limit -// val: value -// LiveUpdate: live update function when the encoder changes -// Apply: update function when the encoder is pressed -void SetValueOnClick(uint8_t process, const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - const int32_t value = round(val * POW(10, dp)); - SetOnClick(process, lo * POW(10, dp), hi * POW(10, dp), dp, value, Apply, LiveUpdate); - DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Selected_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), val); -} - -// Generic onclick event for integer values -// lo: scaled low limit -// hi: scaled high limit -// val: value -// LiveUpdate: live update function when the encoder changes -// Apply: update function when the encoder is pressed -inline void SetIntOnClick(const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - SetValueOnClick(SetInt, lo, hi, val, Apply, LiveUpdate); -} - -// Generic onclick event for set pointer to 16 bit uinteger values -// lo: low limit -// hi: high limit -// LiveUpdate: live update function when the encoder changes -// Apply: update function when the encoder is pressed -void SetPIntOnClick(const int32_t lo, const int32_t hi, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - HMI_value.P_Int = (int16_t*)static_cast(CurrentMenu->SelectedItem())->value; - const int32_t value = *HMI_value.P_Int; - SetValueOnClick(SetPInt, lo, hi, value, Apply, LiveUpdate); -} - -// Generic onclick event for float values -// process: process id HMI destiny -// lo: low limit -// hi: high limit -// dp: decimal places -// val: value -inline void SetFloatOnClick(const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - SetValueOnClick(SetFloat, lo, hi, dp, val, Apply, LiveUpdate); -} - -// Generic onclick event for set pointer to float values -// lo: low limit -// hi: high limit -// LiveUpdate: live update function when the encoder changes -// Apply: update function when the encoder is pressed -void SetPFloatOnClick(const float lo, const float hi, uint8_t dp, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr) { - HMI_value.P_Float = (float*)static_cast(CurrentMenu->SelectedItem())->value; - SetValueOnClick(SetPFloat, lo, hi, dp, *HMI_value.P_Float, Apply, LiveUpdate); -} +// Tool functions #if ENABLED(EEPROM_SETTINGS) void WriteEeprom() { @@ -2203,7 +1921,6 @@ void SetPFloatOnClick(const float lo, const float hi, uint8_t dp, void (*Apply)( // Reset Printer void RebootPrinter() { - dwin_abort_flag = true; wait_for_heatup = wait_for_user = false; // Stop waiting for heating/user thermalManager.disable_all_heaters(); planner.finish_and_disable(); @@ -2212,8 +1929,8 @@ void RebootPrinter() { } void Goto_Info_Menu(){ - HMI_SaveProcessID(Info); Draw_Info_Menu(); + HMI_SaveProcessID(WaitResponse); } void Goto_Move_Menu() { @@ -2226,14 +1943,11 @@ void Goto_Move_Menu() { void DisableMotors() { queue.inject(F("M84")); } -void AutoLev() { queue.inject(F("G28Z\nG29")); } // Force to get the current Z home position +void AutoLev() { queue.inject(F("G28XYO\nG28Z\nG29")); } // Force to get the current Z home position void AutoHome() { queue.inject_P(G28_STR); } - void HomeX() { queue.inject(F("G28X")); } - void HomeY() { queue.inject(F("G28Y")); } - void HomeZ() { queue.inject(F("G28Z")); } void SetHome() { @@ -2247,7 +1961,7 @@ void SetHome() { void ApplyZOffset() { TERN_(EEPROM_SETTINGS, settings.save()); } void LiveZOffset() { last_zoffset = dwin_zoffset; - dwin_zoffset = HMI_value.Value / 100.0f; + dwin_zoffset = MenuData.Value / 100.0f; #if EITHER(BABYSTEP_ZPROBE_OFFSET, JUST_BABYSTEP) if (BABYSTEP_ALLOWED()) babystep.add_mm(Z_AXIS, dwin_zoffset - last_zoffset); #endif @@ -2257,6 +1971,24 @@ void SetHome() { SetPFloatOnClick(Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, 2, ApplyZOffset, LiveZOffset); } #endif + + void SetMoveZto0() { + char cmd[48] = ""; + char str_1[5] = "", str_2[5] = ""; + sprintf_P(cmd, PSTR("G28XYO\nG28Z\nG0X%sY%sF5000\nM420S0\nG0Z0F300"), + #if ENABLED(MESH_BED_LEVELING) + dtostrf(0, 1, 1, str_1), + dtostrf(0, 1, 1, str_2) + #else + dtostrf(X_CENTER, 1, 1, str_1), + dtostrf(Y_CENTER, 1, 1, str_2) + #endif + ); + gcode.process_subcommands_now(cmd); + planner.synchronize(); + LCD_MESSAGE_F("Now adjust Z Offset"); + HMI_AudioFeedback(true); + } #endif #if HAS_PREHEAT @@ -2274,14 +2006,14 @@ void SetLanguage() { } void LiveMove() { - *HMI_value.P_Float = HMI_value.Value / MINUNITMULT; + *MenuData.P_Float = MenuData.Value / MINUNITMULT; if (!planner.is_full()) { planner.synchronize(); planner.buffer_line(current_position, homing_feedrate(HMI_value.axis)); } } void ApplyMoveE() { - last_E = HMI_value.Value / MINUNITMULT; + last_E = MenuData.Value / MINUNITMULT; if (!planner.is_full()) { planner.synchronize(); planner.buffer_line(current_position, MMM_TO_MMS(FEEDRATE_E)); @@ -2294,33 +2026,13 @@ void SetMoveZ() { HMI_value.axis = Z_AXIS; SetPFloatOnClick(Z_MIN_POS, Z_MAX_POS #if HAS_HOTEND void SetMoveE() { #if ENABLED(PREVENT_COLD_EXTRUSION) - if (thermalManager.tooColdToExtrude(0)) { - Popup_Window_ETempTooLow(); - return; - } + if (thermalManager.tooColdToExtrude(0)) + return DWIN_Popup_Confirm(ICON_TempTooLow, GET_TEXT_F(MSG_HOTEND_TOO_COLD), GET_TEXT_F(MSG_PLEASE_PREHEAT)); #endif SetPFloatOnClick(last_E - (EXTRUDE_MAXLENGTH), last_E + (EXTRUDE_MAXLENGTH), UNITFDIGITS, ApplyMoveE); } #endif -void SetMoveZto0() { - char cmd[48] = ""; - char str_1[5] = "", str_2[5] = ""; - sprintf_P(cmd, PSTR("G28Z\nG0X%sY%sF5000\nM420S0\nG0Z0F300"), - #if ENABLED(MESH_BED_LEVELING) - dtostrf(0, 1, 1, str_1), - dtostrf(0, 1, 1, str_2) - #else - dtostrf(X_CENTER, 1, 1, str_1), - dtostrf(Y_CENTER, 1, 1, str_2) - #endif - ); - gcode.process_subcommands_now(cmd); - planner.synchronize(); - LCD_MESSAGE_F("Now adjust Z Offset"); - HMI_AudioFeedback(true); -} - void SetPID(celsius_t t, heater_id_t h) { char cmd[48] = ""; char str_1[5] = "", str_2[5] = ""; @@ -2347,10 +2059,24 @@ void SetPID(celsius_t t, heater_id_t h) { } #endif +#if ENABLED(BAUD_RATE_GCODE) + void HMI_SetBaudRate() { + if (HMI_data.Baud115K) SetBaud115K(); else SetBaud250K(); + } + void SetBaudRate() { + HMI_SetBaudRate(); + Draw_Chkb_Line(CurrentMenu->line(), HMI_data.Baud115K); + DWIN_UpdateLCD(); + } + void SetBaud115K() { queue.inject(F("M575 P0 B115200")); HMI_data.Baud115K = true; } + void SetBaud250K() { queue.inject(F("M575 P0 B250000")); HMI_data.Baud115K = false; } +#endif + #if HAS_LCD_BRIGHTNESS - void ApplyBrightness() { ui.set_brightness(HMI_value.Value); } - void LiveBrightness() { DWIN_LCD_Brightness(HMI_value.Value); } + void ApplyBrightness() { ui.set_brightness(MenuData.Value); } + void LiveBrightness() { DWIN_LCD_Brightness(MenuData.Value); } void SetBrightness() { SetIntOnClick(LCD_BRIGHTNESS_MIN, LCD_BRIGHTNESS_MAX, ui.brightness, ApplyBrightness, LiveBrightness); } + void TurnOffBacklight() { HMI_SaveProcessID(WaitResponse); ui.set_brightness(0); DWIN_Redraw_screen(); } #endif #if ENABLED(CASE_LIGHT_MENU) @@ -2361,7 +2087,7 @@ void SetPID(celsius_t t, heater_id_t h) { DWIN_UpdateLCD(); } #if ENABLED(CASELIGHT_USES_BRIGHTNESS) - void LiveCaseLightBrightness() { HMI_data.CaseLight_Brightness = caselight.brightness = HMI_value.Value; caselight.update_brightness(); } + void LiveCaseLightBrightness() { HMI_data.CaseLight_Brightness = caselight.brightness = MenuData.Value; caselight.update_brightness(); } void SetCaseLightBrightness() { SetIntOnClick(0, 255, caselight.brightness, nullptr, LiveCaseLightBrightness); } #endif #endif @@ -2375,14 +2101,14 @@ void SetPID(celsius_t t, heater_id_t h) { } #endif #if ENABLED(HAS_COLOR_LEDS) - void LiveLedColorR() { leds.color.r = HMI_value.Value; HMI_data.Led_Color = leds.color; leds.update(); } + void LiveLedColorR() { leds.color.r = MenuData.Value; HMI_data.Led_Color = leds.color; leds.update(); } void SetLedColorR() { SetIntOnClick(0, 255, leds.color.r, nullptr, LiveLedColorR); } - void LiveLedColorG() { leds.color.g = HMI_value.Value; HMI_data.Led_Color = leds.color; leds.update(); } + void LiveLedColorG() { leds.color.g = MenuData.Value; HMI_data.Led_Color = leds.color; leds.update(); } void SetLedColorG() { SetIntOnClick(0, 255, leds.color.g, nullptr, LiveLedColorG); } - void LiveLedColorB() { leds.color.b = HMI_value.Value; HMI_data.Led_Color = leds.color; leds.update(); } + void LiveLedColorB() { leds.color.b = MenuData.Value; HMI_data.Led_Color = leds.color; leds.update(); } void SetLedColorB() { SetIntOnClick(0, 255, leds.color.b, nullptr, LiveLedColorB); } #if HAS_WHITE_LED - void LiveLedColorW() { leds.color.w = HMI_value.Value; HMI_data.Led_Color = leds.color; leds.update(); } + void LiveLedColorW() { leds.color.w = MenuData.Value; HMI_data.Led_Color = leds.color; leds.update(); } void SetLedColorW() { SetIntOnClick(0, 255, leds.color.w, nullptr, LiveLedColorW); } #endif #endif @@ -2397,7 +2123,7 @@ void SetPID(celsius_t t, heater_id_t h) { #endif #if HAS_HOME_OFFSET - void ApplyHomeOffset() { set_home_offset(HMI_value.axis, HMI_value.Value / MINUNITMULT); } + void ApplyHomeOffset() { set_home_offset(HMI_value.axis, MenuData.Value / MINUNITMULT); } void SetHomeOffsetX() { HMI_value.axis = X_AXIS; SetPFloatOnClick(-50, 50, UNITFDIGITS, ApplyHomeOffset); } void SetHomeOffsetY() { HMI_value.axis = Y_AXIS; SetPFloatOnClick(-50, 50, UNITFDIGITS, ApplyHomeOffset); } void SetHomeOffsetZ() { HMI_value.axis = Z_AXIS; SetPFloatOnClick( -2, 2, UNITFDIGITS, ApplyHomeOffset); } @@ -2421,12 +2147,11 @@ void SetPID(celsius_t t, heater_id_t h) { DWIN_UpdateLCD(); } #endif -#endif -#if ENABLED(NOZZLE_PARK_FEATURE) - void SetParkPosX() { SetPIntOnClick(0, X_MAX_POS); } - void SetParkPosY() { SetPIntOnClick(0, Y_MAX_POS); } - void SetParkZRaise() { SetPIntOnClick(0, 50); } + #if BOTH(HAS_HEATED_BED, PREHEAT_BEFORE_LEVELING) + void SetBedLevT() { SetPIntOnClick(BED_MINTEMP, BED_MAX_TARGET); } + #endif + #endif #if HAS_FILAMENT_SENSOR @@ -2437,7 +2162,7 @@ void SetPID(celsius_t t, heater_id_t h) { DWIN_UpdateLCD(); } #if HAS_FILAMENT_RUNOUT_DISTANCE - void ApplyRunoutDistance() { runout.set_runout_distance(HMI_value.Value / MINUNITMULT); } + void ApplyRunoutDistance() { runout.set_runout_distance(MenuData.Value / MINUNITMULT); } void SetRunoutDistance() { SetFloatOnClick(0, 999, UNITFDIGITS, runout.runout_distance(), ApplyRunoutDistance); } #endif #endif @@ -2454,20 +2179,20 @@ void SetPID(celsius_t t, heater_id_t h) { void RestoreDefaultsColors() { DWIN_SetColorDefaults(); - DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color); + DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color); DWIN_Redraw_screen(); } void SelColor() { - HMI_value.P_Int = (int16_t*)static_cast(CurrentMenu->SelectedItem())->value; - HMI_value.Color[0] = GetRColor(*HMI_value.P_Int); // Red - HMI_value.Color[1] = GetGColor(*HMI_value.P_Int); // Green - HMI_value.Color[2] = GetBColor(*HMI_value.P_Int); // Blue + MenuData.P_Int = (int16_t*)static_cast(CurrentMenu->SelectedItem())->value; + HMI_value.Color[0] = GetRColor(*MenuData.P_Int); // Red + HMI_value.Color[1] = GetGColor(*MenuData.P_Int); // Green + HMI_value.Color[2] = GetBColor(*MenuData.P_Int); // Blue Draw_GetColor_Menu(); } void LiveRGBColor() { - HMI_value.Color[CurrentMenu->line() - 2] = HMI_value.Value; + HMI_value.Color[CurrentMenu->line() - 2] = MenuData.Value; uint16_t color = RGB(HMI_value.Color[0], HMI_value.Color[1], HMI_value.Color[2]); DWIN_Draw_Rectangle(1, color, 20, 315, DWIN_WIDTH - 20, 335); } @@ -2477,27 +2202,28 @@ void SetRGBColor() { } void DWIN_ApplyColor() { - *HMI_value.P_Int = RGB(HMI_value.Color[0], HMI_value.Color[1], HMI_value.Color[2]); - DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color); - Draw_Status_Area(false); + *MenuData.P_Int = RGB(HMI_value.Color[0], HMI_value.Color[1], HMI_value.Color[2]); + DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color); Draw_SelectColors_Menu(); + hash_changed = true; LCD_MESSAGE_F(GET_TEXT_F(MSG_COLORS_APPLIED)); + DWIN_Draw_Dashboard(); } void SetSpeed() { SetPIntOnClick(MIN_PRINT_SPEED, MAX_PRINT_SPEED); } #if HAS_HOTEND - void ApplyHotendTemp() { thermalManager.setTargetHotend(HMI_value.Value, 0); } + void ApplyHotendTemp() { thermalManager.setTargetHotend(MenuData.Value, 0); } void SetHotendTemp() { SetIntOnClick(MIN_ETEMP, MAX_ETEMP, thermalManager.degTargetHotend(0), ApplyHotendTemp); } #endif #if HAS_HEATED_BED - void ApplyBedTemp() { thermalManager.setTargetBed(HMI_value.Value); } + void ApplyBedTemp() { thermalManager.setTargetBed(MenuData.Value); } void SetBedTemp() { SetIntOnClick(BED_MINTEMP, BED_MAX_TARGET, thermalManager.degTargetBed(), ApplyBedTemp); } #endif #if HAS_FAN - void ApplyFanSpeed() { thermalManager.set_fan_speed(0, HMI_value.Value); } + void ApplyFanSpeed() { thermalManager.set_fan_speed(0, MenuData.Value); } void SetFanSpeed() { SetIntOnClick(0, 255, thermalManager.fan_speed[0], ApplyFanSpeed); } #endif @@ -2531,17 +2257,15 @@ void ApplyFlow() { planner.refresh_e_factor(0); } void SetFlow() { SetPIntOnClick(MIN_PRINT_FLOW, MAX_PRINT_FLOW, ApplyFlow); } // Bed Tramming -void Tram(uint8_t point) { +TERN(HAS_ONESTEP_LEVELING, float, void) Tram(uint8_t point) { char cmd[100] = ""; #if HAS_ONESTEP_LEVELING static bool inLev = false; - if (inLev) return; + float xpos = 0, ypos = 0, zval = 0, margin = 0; char str_1[6] = "", str_2[6] = "", str_3[6] = ""; - #define fmt "X:%s, Y:%s, Z:%s" - float xpos = 0, ypos = 0, zval = 0; - float margin = PROBING_MARGIN; + if (inLev) return NAN; + margin = HMI_data.FullManualTramming ? 30 : PROBING_MARGIN; #else - #define fmt "M420S0\nG28O\nG90\nG0Z5F300\nG0X%iY%iF5000\nG0Z0F300" int16_t xpos = 0, ypos = 0; int16_t margin = 30; #endif @@ -2569,24 +2293,45 @@ void Tram(uint8_t point) { break; } + planner.synchronize(); + #if HAS_ONESTEP_LEVELING - planner.synchronize(); - probe.stow(); - gcode.process_subcommands_now(F("M420S0\nG28O")); - planner.synchronize(); - inLev = true; - zval = probe.probe_at_point(xpos, ypos, PROBE_PT_STOW); - sprintf_P(cmd, PSTR(fmt), - dtostrf(xpos, 1, 1, str_1), - dtostrf(ypos, 1, 1, str_2), - dtostrf(zval, 1, 2, str_3) - ); - ui.set_status(cmd); - inLev = false; + + if (HMI_data.FullManualTramming) { + planner.synchronize(); + sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%sY%sF5000\nG0Z0F300"), + dtostrf(xpos, 1, 1, str_1), + dtostrf(ypos, 1, 1, str_2) + ); + queue.inject(cmd); + } + else { + LIMIT(xpos, X_MIN_POS, (X_MAX_POS + probe.offset.x)); + LIMIT(ypos, Y_MIN_POS, (Y_MAX_POS + probe.offset.y)); + probe.stow(); + gcode.process_subcommands_now(F("M420S0\nG28O")); + planner.synchronize(); + inLev = true; + zval = probe.probe_at_point(xpos, ypos, PROBE_PT_STOW); + if (isnan(zval)) + ui.set_status(F("Position Not Reachable, check offsets")); + else { + sprintf_P(cmd, PSTR("X:%s, Y:%s, Z:%s"), + dtostrf(xpos, 1, 1, str_1), + dtostrf(ypos, 1, 1, str_2), + dtostrf(zval, 1, 2, str_3) + ); + ui.set_status(cmd); + } + inLev = false; + } + return zval; + #else - planner.synchronize(); - sprintf_P(cmd, PSTR(fmt), xpos, ypos); + + sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%iY%iF5000\nG0Z0F300"), xpos, ypos); queue.inject(cmd); + #endif } @@ -2596,11 +2341,72 @@ void TramBR() { Tram(2); } void TramBL() { Tram(3); } void TramC () { Tram(4); } +#if HAS_ONESTEP_LEVELING + + void Trammingwizard() { + bed_mesh_t zval = {0}; + if (HMI_data.FullManualTramming) { + ui.set_status(F("Disable manual tramming")); + return; + } + zval[0][0] = Tram(0); + checkkey = NothingToDo; + MeshViewer.DrawMesh(zval, 2, 2); + zval[1][0] = Tram(1); + MeshViewer.DrawMesh(zval, 2, 2); + zval[1][1] = Tram(2); + MeshViewer.DrawMesh(zval, 2, 2); + zval[0][1] = Tram(3); + MeshViewer.DrawMesh(zval, 2, 2); + char str_1[6] = "", str_2[6] = ""; + ui.status_printf(0, F("Limits minZ: %s, maxZ: %s"), + dtostrf(MeshViewer.min, 1, 2, str_1), + dtostrf(MeshViewer.max, 1, 2, str_2) + ); + if (ABS(MeshViewer.max - MeshViewer.min) < 0.05) { + DWINUI::Draw_CenteredString(140,F("Corners leveled")); + DWINUI::Draw_CenteredString(160,F("Tolerance achieved!")); + } + else { + uint8_t p = 0; + float d, max = 0; + FSTR_P plabel; + LOOP_L_N(x,2) LOOP_L_N(y,2) { + d = ABS(zval[x][y] - MeshViewer.avg); + if (max < d) { + max = d; + p = x + 2 * y; + } + } + switch (p) { + case 0b00 : plabel = GET_TEXT_F(MSG_LEVBED_FL); break; + case 0b01 : plabel = GET_TEXT_F(MSG_LEVBED_FR); break; + case 0b10 : plabel = GET_TEXT_F(MSG_LEVBED_BL); break; + case 0b11 : plabel = GET_TEXT_F(MSG_LEVBED_BR); break; + default : plabel = F(""); break; + } + DWINUI::Draw_CenteredString(130, F("Corners not leveled")); + DWINUI::Draw_CenteredString(150, F("Knob adjustment required")); + DWINUI::Draw_CenteredString(Color_Green, 170, plabel); + } + DWINUI::Draw_Button(BTN_Continue, 86, 305); + checkkey = Menu; + HMI_SaveProcessID(WaitResponse); + } + + void SetManualTramming() { + HMI_data.FullManualTramming = !HMI_data.FullManualTramming; + Draw_Chkb_Line(CurrentMenu->line(), HMI_data.FullManualTramming); + DWIN_UpdateLCD(); + } + +#endif // HAS_ONESTEP_LEVELING + #if ENABLED(MESH_BED_LEVELING) void ManualMeshStart(){ LCD_MESSAGE(MSG_UBL_BUILD_MESH_MENU); - gcode.process_subcommands_now(F("G28Z\nM211S0\nG29S1")); + gcode.process_subcommands_now(F("G28XYO\nG28Z\nM211S0\nG29S1")); planner.synchronize(); #ifdef MANUAL_PROBE_START_Z const uint8_t line = CurrentMenu->line(MMeshMoveZItem->pos); @@ -2609,7 +2415,7 @@ void TramC () { Tram(4); } } void LiveMeshMoveZ() { - *HMI_value.P_Float = HMI_value.Value / POW(10, 2); + *MenuData.P_Float = MenuData.Value / POW(10, 2); if (!planner.is_full()) { planner.synchronize(); planner.buffer_line(current_position, homing_feedrate(Z_AXIS)); @@ -2642,29 +2448,29 @@ void TramC () { Tram(4); } #endif #endif -void ApplyMaxSpeed() { planner.set_max_feedrate(HMI_value.axis, HMI_value.Value / MINUNITMULT); } -void SetMaxSpeedX() { HMI_value.axis = X_AXIS, SetFloatOnClick(MIN_MAXFEEDSPEED, default_max_feedrate[X_AXIS] * 2, UNITFDIGITS, planner.settings.max_feedrate_mm_s[X_AXIS], ApplyMaxSpeed); } -void SetMaxSpeedY() { HMI_value.axis = Y_AXIS, SetFloatOnClick(MIN_MAXFEEDSPEED, default_max_feedrate[Y_AXIS] * 2, UNITFDIGITS, planner.settings.max_feedrate_mm_s[Y_AXIS], ApplyMaxSpeed); } -void SetMaxSpeedZ() { HMI_value.axis = Z_AXIS, SetFloatOnClick(MIN_MAXFEEDSPEED, default_max_feedrate[Z_AXIS] * 2, UNITFDIGITS, planner.settings.max_feedrate_mm_s[Z_AXIS], ApplyMaxSpeed); } +void ApplyMaxSpeed() { planner.set_max_feedrate(HMI_value.axis, MenuData.Value / MINUNITMULT); } +void SetMaxSpeedX() { HMI_value.axis = X_AXIS, SetFloatOnClick(MIN_MAXFEEDSPEED, max_feedrate_edit_values[X_AXIS], UNITFDIGITS, planner.settings.max_feedrate_mm_s[X_AXIS], ApplyMaxSpeed); } +void SetMaxSpeedY() { HMI_value.axis = Y_AXIS, SetFloatOnClick(MIN_MAXFEEDSPEED, max_feedrate_edit_values[Y_AXIS], UNITFDIGITS, planner.settings.max_feedrate_mm_s[Y_AXIS], ApplyMaxSpeed); } +void SetMaxSpeedZ() { HMI_value.axis = Z_AXIS, SetFloatOnClick(MIN_MAXFEEDSPEED, max_feedrate_edit_values[Z_AXIS], UNITFDIGITS, planner.settings.max_feedrate_mm_s[Z_AXIS], ApplyMaxSpeed); } #if HAS_HOTEND - void SetMaxSpeedE() { HMI_value.axis = E_AXIS; SetFloatOnClick(MIN_MAXFEEDSPEED, default_max_feedrate[E_AXIS] * 2, UNITFDIGITS, planner.settings.max_feedrate_mm_s[E_AXIS], ApplyMaxSpeed); } + void SetMaxSpeedE() { HMI_value.axis = E_AXIS; SetFloatOnClick(MIN_MAXFEEDSPEED, max_feedrate_edit_values[E_AXIS], UNITFDIGITS, planner.settings.max_feedrate_mm_s[E_AXIS], ApplyMaxSpeed); } #endif -void ApplyMaxAccel() { planner.set_max_acceleration(HMI_value.axis, HMI_value.Value); } -void SetMaxAccelX() { HMI_value.axis = X_AXIS, SetIntOnClick(MIN_MAXACCELERATION, default_max_acceleration[X_AXIS] * 2, planner.settings.max_acceleration_mm_per_s2[X_AXIS], ApplyMaxAccel); } -void SetMaxAccelY() { HMI_value.axis = Y_AXIS, SetIntOnClick(MIN_MAXACCELERATION, default_max_acceleration[Y_AXIS] * 2, planner.settings.max_acceleration_mm_per_s2[Y_AXIS], ApplyMaxAccel); } -void SetMaxAccelZ() { HMI_value.axis = Z_AXIS, SetIntOnClick(MIN_MAXACCELERATION, default_max_acceleration[Z_AXIS] * 2, planner.settings.max_acceleration_mm_per_s2[Z_AXIS], ApplyMaxAccel); } +void ApplyMaxAccel() { planner.set_max_acceleration(HMI_value.axis, MenuData.Value); } +void SetMaxAccelX() { HMI_value.axis = X_AXIS, SetIntOnClick(MIN_MAXACCELERATION, max_acceleration_edit_values[X_AXIS], planner.settings.max_acceleration_mm_per_s2[X_AXIS], ApplyMaxAccel); } +void SetMaxAccelY() { HMI_value.axis = Y_AXIS, SetIntOnClick(MIN_MAXACCELERATION, max_acceleration_edit_values[Y_AXIS], planner.settings.max_acceleration_mm_per_s2[Y_AXIS], ApplyMaxAccel); } +void SetMaxAccelZ() { HMI_value.axis = Z_AXIS, SetIntOnClick(MIN_MAXACCELERATION, max_acceleration_edit_values[Z_AXIS], planner.settings.max_acceleration_mm_per_s2[Z_AXIS], ApplyMaxAccel); } #if HAS_HOTEND - void SetMaxAccelE() { HMI_value.axis = E_AXIS; SetIntOnClick(MIN_MAXACCELERATION, default_max_acceleration[E_AXIS] * 2, planner.settings.max_acceleration_mm_per_s2[E_AXIS], ApplyMaxAccel); } + void SetMaxAccelE() { HMI_value.axis = E_AXIS; SetIntOnClick(MIN_MAXACCELERATION, max_acceleration_edit_values[E_AXIS], planner.settings.max_acceleration_mm_per_s2[E_AXIS], ApplyMaxAccel); } #endif #if HAS_CLASSIC_JERK - void ApplyMaxJerk() { planner.set_max_jerk(HMI_value.axis, HMI_value.Value / MINUNITMULT); } - void SetMaxJerkX() { HMI_value.axis = X_AXIS, SetFloatOnClick(MIN_MAXJERK, default_max_jerk[X_AXIS] * 2, UNITFDIGITS, planner.max_jerk[X_AXIS], ApplyMaxJerk); } - void SetMaxJerkY() { HMI_value.axis = Y_AXIS, SetFloatOnClick(MIN_MAXJERK, default_max_jerk[Y_AXIS] * 2, UNITFDIGITS, planner.max_jerk[Y_AXIS], ApplyMaxJerk); } - void SetMaxJerkZ() { HMI_value.axis = Z_AXIS, SetFloatOnClick(MIN_MAXJERK, default_max_jerk[Z_AXIS] * 2, UNITFDIGITS, planner.max_jerk[Z_AXIS], ApplyMaxJerk); } + void ApplyMaxJerk() { planner.set_max_jerk(HMI_value.axis, MenuData.Value / MINUNITMULT); } + void SetMaxJerkX() { HMI_value.axis = X_AXIS, SetFloatOnClick(MIN_MAXJERK, max_jerk_edit_values[X_AXIS], UNITFDIGITS, planner.max_jerk[X_AXIS], ApplyMaxJerk); } + void SetMaxJerkY() { HMI_value.axis = Y_AXIS, SetFloatOnClick(MIN_MAXJERK, max_jerk_edit_values[Y_AXIS], UNITFDIGITS, planner.max_jerk[Y_AXIS], ApplyMaxJerk); } + void SetMaxJerkZ() { HMI_value.axis = Z_AXIS, SetFloatOnClick(MIN_MAXJERK, max_jerk_edit_values[Z_AXIS], UNITFDIGITS, planner.max_jerk[Z_AXIS], ApplyMaxJerk); } #if HAS_HOTEND - void SetMaxJerkE() { HMI_value.axis = E_AXIS; SetFloatOnClick(MIN_MAXJERK, default_max_jerk[E_AXIS] * 2, UNITFDIGITS, planner.max_jerk[E_AXIS], ApplyMaxJerk); } + void SetMaxJerkE() { HMI_value.axis = E_AXIS; SetFloatOnClick(MIN_MAXJERK, max_jerk_edit_values[E_AXIS], UNITFDIGITS, planner.max_jerk[E_AXIS], ApplyMaxJerk); } #endif #endif @@ -2683,21 +2489,21 @@ void SetStepsZ() { HMI_value.axis = Z_AXIS, SetPFloatOnClick( MIN_STEP, MAX_STEP void SetPidCycles() { SetPIntOnClick(3, 50); } void SetKp() { SetPFloatOnClick(0, 1000, 2); } void ApplyPIDi() { - *HMI_value.P_Float = scalePID_i(HMI_value.Value / POW(10, 2)); + *MenuData.P_Float = scalePID_i(MenuData.Value / POW(10, 2)); thermalManager.updatePID(); } void ApplyPIDd() { - *HMI_value.P_Float = scalePID_d(HMI_value.Value / POW(10, 2)); + *MenuData.P_Float = scalePID_d(MenuData.Value / POW(10, 2)); thermalManager.updatePID(); } void SetKi() { - HMI_value.P_Float = (float*)static_cast(CurrentMenu->SelectedItem())->value; - const float value = unscalePID_i(*HMI_value.P_Float); + MenuData.P_Float = (float*)static_cast(CurrentMenu->SelectedItem())->value; + const float value = unscalePID_i(*MenuData.P_Float); SetFloatOnClick(0, 1000, 2, value, ApplyPIDi); } void SetKd() { - HMI_value.P_Float = (float*)static_cast(CurrentMenu->SelectedItem())->value; - const float value = unscalePID_d(*HMI_value.P_Float); + MenuData.P_Float = (float*)static_cast(CurrentMenu->SelectedItem())->value; + const float value = unscalePID_d(*MenuData.P_Float); SetFloatOnClick(0, 1000, 2, value, ApplyPIDd); } #endif @@ -2709,62 +2515,7 @@ void SetStepsZ() { HMI_value.axis = Z_AXIS, SetPFloatOnClick( MIN_STEP, MAX_STEP void SetRecoverSpeed() { SetPFloatOnClick( 1, 90, UNITFDIGITS); }; #endif -// Menuitem Drawing functions ================================================= - -void onDrawMenuItem(MenuItemClass* menuitem, int8_t line) { - if (menuitem->icon) DWINUI::Draw_Icon(menuitem->icon, ICOX, MBASE(line) - 3); - if (menuitem->frameid) - DWIN_Frame_AreaCopy(menuitem->frameid, menuitem->frame.left, menuitem->frame.top, menuitem->frame.right, menuitem->frame.bottom, LBLX, MBASE(line)); - else if (menuitem->caption) - DWINUI::Draw_String(LBLX, MBASE(line) - 1, menuitem->caption); - DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240); -} - -void onDrawSubMenu(MenuItemClass* menuitem, int8_t line) { - onDrawMenuItem(menuitem, line); - DWINUI::Draw_Icon(ICON_More, VALX + 16, MBASE(line) - 3); -} - -void onDrawIntMenu(MenuItemClass* menuitem, int8_t line, uint16_t value) { - onDrawMenuItem(menuitem, line); - Draw_Menu_IntValue(HMI_data.Background_Color, line, 4, value); -} - -void onDrawPIntMenu(MenuItemClass* menuitem, int8_t line) { - const uint16_t value = *(uint16_t*)static_cast(menuitem)->value; - onDrawIntMenu(menuitem, line, value); -} - -void onDrawPInt8Menu(MenuItemClass* menuitem, int8_t line) { - const uint8_t value = *(uint8_t*)static_cast(menuitem)->value; - onDrawIntMenu(menuitem, line, value); -} - -void onDrawPInt32Menu(MenuItemClass* menuitem, int8_t line) { - const uint32_t value = *(uint32_t*)static_cast(menuitem)->value; - onDrawIntMenu(menuitem, line, value); -} - -void onDrawFloatMenu(MenuItemClass* menuitem, int8_t line, uint8_t dp, const float value) { - onDrawMenuItem(menuitem, line); - DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Background_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(line), value); -} - -void onDrawPFloatMenu(MenuItemClass* menuitem, int8_t line) { - const float value = *(float*)static_cast(menuitem)->value; - const int8_t dp = UNITFDIGITS; - onDrawFloatMenu(menuitem, line, dp, value); -} - -void onDrawPFloat2Menu(MenuItemClass* menuitem, int8_t line) { - const float value = *(float*)static_cast(menuitem)->value; - onDrawFloatMenu(menuitem, line, 2, value); -} - -void onDrawChkbMenu(MenuItemClass* menuitem, int8_t line, bool checked) { - onDrawMenuItem(menuitem, line); - Draw_Chkb_Line(line, checked); -} +// Special Menuitem Drawing functions ================================================= void onDrawBack(MenuItemClass* menuitem, int8_t line) { if (HMI_IsChinese()) menuitem->SetFrame(1, 129, 72, 156, 84); @@ -2882,6 +2633,10 @@ void onDrawLanguage(MenuItemClass* menuitem, int8_t line) { void onDrawPwrLossR(MenuItemClass* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, recovery.enabled); } #endif +#if ENABLED(BAUD_RATE_GCODE) + void onDrawBaudrate(MenuItemClass* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, HMI_data.Baud115K); } +#endif + #if ENABLED(CASE_LIGHT_MENU) void onDrawCaseLight(MenuItemClass* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, caselight.on); } #endif @@ -3172,137 +2927,9 @@ void onDrawStepsZ(MenuItemClass* menuitem, int8_t line) { } #endif -// HMI Control functions ====================================================== - -// Generic menu control using the encoder -void HMI_Menu() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - if (CurrentMenu) { - if (encoder_diffState == ENCODER_DIFF_ENTER) - CurrentMenu->onClick(); - else - CurrentMenu->onScroll(encoder_diffState == ENCODER_DIFF_CW); - } -} - -// Get an integer value using the encoder without draw anything -// lo: low limit -// hi: high limit -// Return value: -// 0 : no change -// 1 : live change -// 2 : apply change -int8_t HMI_GetIntNoDraw(const int32_t lo, const int32_t hi) { - EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); - if (encoder_diffState != ENCODER_DIFF_NO) { - if (Apply_Encoder(encoder_diffState, HMI_value.Value)) { - EncoderRate.enabled = false; - checkkey = Menu; - return 2; - } - LIMIT(HMI_value.Value, lo, hi); - return 1; - } - return 0; -} - -// Get an integer value using the encoder -// lo: low limit -// hi: high limit -// Return value: -// 0 : no change -// 1 : live change -// 2 : apply change -int8_t HMI_GetInt(const int32_t lo, const int32_t hi) { - EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); - if (encoder_diffState != ENCODER_DIFF_NO) { - if (Apply_Encoder(encoder_diffState, HMI_value.Value)) { - EncoderRate.enabled = false; - DWINUI::Draw_Int(HMI_data.Text_Color, HMI_data.Background_Color, 4 , VALX, MBASE(CurrentMenu->line()) - 1, HMI_value.Value); - checkkey = Menu; - return 2; - } - LIMIT(HMI_value.Value, lo, hi); - DWINUI::Draw_Int(HMI_data.Text_Color, HMI_data.Selected_Color, 4 , VALX, MBASE(CurrentMenu->line()) - 1, HMI_value.Value); - return 1; - } - return 0; -} - -// Set an integer using the encoder -void HMI_SetInt() { - int8_t val = HMI_GetInt(HMI_value.MinValue, HMI_value.MaxValue); - switch (val) { - case 0: return; break; - case 1: if (HMI_value.LiveUpdate) HMI_value.LiveUpdate(); break; - case 2: if (HMI_value.Apply) HMI_value.Apply(); break; - } -} - -// Set an integer without drawing -void HMI_SetIntNoDraw() { - int8_t val = HMI_GetIntNoDraw(HMI_value.MinValue, HMI_value.MaxValue); - switch (val) { - case 0: return; break; - case 1: if (HMI_value.LiveUpdate) HMI_value.LiveUpdate(); break; - case 2: if (HMI_value.Apply) HMI_value.Apply(); break; - } -} - -// Set an integer pointer variable using the encoder -void HMI_SetPInt() { - int8_t val = HMI_GetInt(HMI_value.MinValue, HMI_value.MaxValue); - switch (val) { - case 0: return; - case 1: if (HMI_value.LiveUpdate) HMI_value.LiveUpdate(); break; - case 2: *HMI_value.P_Int = HMI_value.Value; if (HMI_value.Apply) HMI_value.Apply(); break; - } -} - -// Get a scaled float value using the encoder -// dp: decimal places -// lo: scaled low limit -// hi: scaled high limit -// Return value: -// 0 : no change -// 1 : live change -// 2 : apply change -int8_t HMI_GetFloat(uint8_t dp, int32_t lo, int32_t hi) { - EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); - if (encoder_diffState != ENCODER_DIFF_NO) { - if (Apply_Encoder(encoder_diffState, HMI_value.Value)) { - EncoderRate.enabled = false; - DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Background_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), HMI_value.Value / POW(10, dp)); - checkkey = Menu; - return 2; - } - LIMIT(HMI_value.Value, lo, hi); - DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Selected_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), HMI_value.Value / POW(10, dp)); - return 1; - } - return 0; -} - -// Set a scaled float using the encoder -void HMI_SetFloat() { - const int8_t val = HMI_GetFloat(HMI_value.dp, HMI_value.MinValue, HMI_value.MaxValue); - switch (val) { - case 0: return; - case 1: if (HMI_value.LiveUpdate) HMI_value.LiveUpdate(); break; - case 2: if (HMI_value.Apply) HMI_value.Apply(); break; - } -} - -// Set a scaled float pointer variable using the encoder -void HMI_SetPFloat() { - const int8_t val = HMI_GetFloat(HMI_value.dp, HMI_value.MinValue, HMI_value.MaxValue); - switch (val) { - case 0: return; - case 1: if (HMI_value.LiveUpdate) HMI_value.LiveUpdate(); break; - case 2: *HMI_value.P_Float = HMI_value.Value / POW(10, HMI_value.dp); if (HMI_value.Apply) HMI_value.Apply(); break; - } -} +#if HAS_ONESTEP_LEVELING + void onDrawManualTramming(MenuItemClass* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, HMI_data.FullManualTramming); } +#endif // Menu Creation and Drawing functions ====================================================== @@ -3359,6 +2986,7 @@ void Draw_Prepare_Menu() { MENU_ITEM(ICON_Cool, GET_TEXT_F(MSG_COOLDOWN), onDrawCooldown, DoCoolDown); MENU_ITEM(ICON_Language, PSTR(GET_TEXT_F(MSG_UI_LANGUAGE)), onDrawLanguage, SetLanguage); } + ui.reset_status(true); CurrentMenu->draw(); } @@ -3369,13 +2997,17 @@ void Draw_Tramming_Menu() { if (CurrentMenu != TrammingMenu) { CurrentMenu = TrammingMenu; SetMenuTitle({0}, GET_TEXT_F(MSG_BED_TRAMMING)); // TODO: Chinese, English "Bed Tramming" JPG - DWINUI::MenuItemsPrepare(6); + DWINUI::MenuItemsPrepare(8); MENU_ITEM(ICON_Back, GET_TEXT_F(MSG_BUTTON_BACK), onDrawBack, Draw_Prepare_Menu); MENU_ITEM(ICON_Axis, GET_TEXT_F(MSG_LEVBED_FL), onDrawMenuItem, TramFL); MENU_ITEM(ICON_Axis, GET_TEXT_F(MSG_LEVBED_FR), onDrawMenuItem, TramFR); MENU_ITEM(ICON_Axis, GET_TEXT_F(MSG_LEVBED_BR), onDrawMenuItem, TramBR); MENU_ITEM(ICON_Axis, GET_TEXT_F(MSG_LEVBED_BL), onDrawMenuItem, TramBL); MENU_ITEM(ICON_Axis, GET_TEXT_F(MSG_LEVBED_C ), onDrawMenuItem, TramC ); + #if HAS_ONESTEP_LEVELING + MENU_ITEM(ICON_ProbeSet, F("Bed tramming wizard"), onDrawMenuItem, Trammingwizard); + MENU_ITEM(ICON_ProbeSet, GET_TEXT_F(MSG_BED_TRAMMING_MANUAL), onDrawManualTramming, SetManualTramming); + #endif } CurrentMenu->draw(); } @@ -3386,7 +3018,7 @@ void Draw_Control_Menu() { if (CurrentMenu != ControlMenu) { CurrentMenu = ControlMenu; SetMenuTitle({103, 1, 28, 14}, GET_TEXT_F(MSG_CONTROL)); - DWINUI::MenuItemsPrepare(8); + DWINUI::MenuItemsPrepare(10); MENU_ITEM(ICON_Back, GET_TEXT_F(MSG_BUTTON_BACK), onDrawBack, Goto_Main_Menu); #if ENABLED(CASE_LIGHT_MENU) #if ENABLED(CASELIGHT_USES_BRIGHTNESS) @@ -3408,6 +3040,7 @@ void Draw_Control_Menu() { MENU_ITEM(ICON_Reboot, GET_TEXT_F(MSG_RESET_PRINTER), onDrawMenuItem, RebootPrinter); MENU_ITEM(ICON_Info, GET_TEXT_F(MSG_INFO_SCREEN), onDrawInfoSubMenu, Goto_Info_Menu); } + ui.reset_status(true); CurrentMenu->draw(); } @@ -3417,8 +3050,11 @@ void Draw_AdvancedSettings_Menu() { if (CurrentMenu != AdvancedSettings) { CurrentMenu = AdvancedSettings; SetMenuTitle({0}, GET_TEXT_F(MSG_ADVANCED_SETTINGS)); // TODO: Chinese, English "Advanced Settings" JPG - DWINUI::MenuItemsPrepare(15); + DWINUI::MenuItemsPrepare(17); MENU_ITEM(ICON_Back, GET_TEXT_F(MSG_BUTTON_BACK), onDrawBack, Goto_Main_Menu); + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(ICON_WriteEEPROM, GET_TEXT_F(MSG_STORE_EEPROM), onDrawMenuItem, WriteEeprom); + #endif #if HAS_HOME_OFFSET MENU_ITEM(ICON_HomeOffset, GET_TEXT_F(MSG_SET_HOME_OFFSETS), onDrawSubMenu, Draw_HomeOffset_Menu); #endif @@ -3437,6 +3073,9 @@ void Draw_AdvancedSettings_Menu() { #if ENABLED(POWER_LOSS_RECOVERY) MENU_ITEM(ICON_Pwrlossr, GET_TEXT_F(MSG_OUTAGE_RECOVERY), onDrawPwrLossR, SetPwrLossr); #endif + #if ENABLED(BAUD_RATE_GCODE) + MENU_ITEM(ICON_SetBaudRate, F("115K baud"), onDrawBaudrate, SetBaudRate); + #endif #if HAS_LCD_BRIGHTNESS EDIT_ITEM(ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS), onDrawPInt8Menu, SetBrightness, &ui.brightness); #endif @@ -3451,11 +3090,12 @@ void Draw_AdvancedSettings_Menu() { MENU_ITEM(ICON_ESDiag, F("End-stops diag."), onDrawSubMenu, Draw_EndStopDiag); #endif #if ENABLED(PRINTCOUNTER) - MENU_ITEM(ICON_PrintStats, GET_TEXT_F(MSG_INFO_STATS_MENU), onDrawSubMenu, Draw_PrintStats); + MENU_ITEM(ICON_PrintStats, GET_TEXT_F(MSG_INFO_STATS_MENU), onDrawSubMenu, Goto_PrintStats); MENU_ITEM(ICON_PrintStatsReset, GET_TEXT_F(MSG_INFO_PRINT_COUNT_RESET), onDrawSubMenu, PrintStats.Reset); #endif MENU_ITEM(ICON_Lock, GET_TEXT_F(MSG_LOCKSCREEN), onDrawMenuItem, DWIN_LockScreen); } + ui.reset_status(true); CurrentMenu->draw(); } @@ -3502,11 +3142,14 @@ void Draw_Move_Menu() { if (CurrentMenu != ProbeSetMenu) { CurrentMenu = ProbeSetMenu; SetMenuTitle({0}, GET_TEXT_F(MSG_ZPROBE_SETTINGS)); // TODO: Chinese, English "Probe Settings" JPG - DWINUI::MenuItemsPrepare(8); + DWINUI::MenuItemsPrepare(9); MENU_ITEM(ICON_Back, GET_TEXT_F(MSG_BUTTON_BACK), onDrawBack, Draw_AdvancedSettings_Menu); EDIT_ITEM(ICON_ProbeOffsetX, GET_TEXT_F(MSG_ZPROBE_XOFFSET), onDrawPFloatMenu, SetProbeOffsetX, &probe.offset.x); EDIT_ITEM(ICON_ProbeOffsetY, GET_TEXT_F(MSG_ZPROBE_YOFFSET), onDrawPFloatMenu, SetProbeOffsetY, &probe.offset.y); EDIT_ITEM(ICON_ProbeOffsetZ, GET_TEXT_F(MSG_ZPROBE_ZOFFSET), onDrawPFloat2Menu, SetProbeOffsetZ, &probe.offset.z); + #if BOTH(HAS_HEATED_BED, PREHEAT_BEFORE_LEVELING) + EDIT_ITEM(ICON_Temperature, GET_TEXT_F(MSG_UBL_SET_TEMP_BED), onDrawPIntMenu, SetBedLevT, &HMI_data.BedLevT); + #endif #ifdef BLTOUCH_HS_MODE MENU_ITEM(ICON_HSMode, F("Enable HS mode"), onDrawHSMode, SetHSMode); #endif @@ -3596,7 +3239,7 @@ void Draw_GetColor_Menu() { MENU_ITEM(2, GET_TEXT_F(MSG_COLORS_BLUE), onDrawGetColorItem, SetRGBColor); } CurrentMenu->draw(); - DWIN_Draw_Rectangle(1, *HMI_value.P_Int, 20, 315, DWIN_WIDTH - 20, 335); + DWIN_Draw_Rectangle(1, *MenuData.P_Int, 20, 315, DWIN_WIDTH - 20, 335); } #if BOTH(CASE_LIGHT_MENU, CASELIGHT_USES_BRIGHTNESS) @@ -3646,7 +3289,7 @@ void Draw_Tune_Menu() { if (CurrentMenu != TuneMenu) { CurrentMenu = TuneMenu; SetMenuTitle({73, 2, 28, 12}, GET_TEXT_F(MSG_TUNE)); // TODO: Chinese, English "Tune" JPG - DWINUI::MenuItemsPrepare(14); + DWINUI::MenuItemsPrepare(16); MENU_ITEM(ICON_Back, GET_TEXT_F(MSG_BUTTON_BACK), onDrawBack, Goto_PrintProcess); #if ENABLED(CASE_LIGHT_MENU) MENU_ITEM(ICON_CaseLight, GET_TEXT_F(MSG_CASE_LIGHT), onDrawCaseLight, SetCaseLight); @@ -3679,6 +3322,7 @@ void Draw_Tune_Menu() { MENU_ITEM(ICON_Lock, GET_TEXT_F(MSG_LOCKSCREEN), onDrawMenuItem, DWIN_LockScreen); #if HAS_LCD_BRIGHTNESS EDIT_ITEM(ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS), onDrawPInt8Menu, SetBrightness, &ui.brightness); + MENU_ITEM(ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS_OFF), onDrawMenuItem, TurnOffBacklight); #endif } CurrentMenu->draw(); diff --git a/Marlin/src/lcd/e3v2/proui/dwin.h b/Marlin/src/lcd/e3v2/proui/dwin.h index 04ac1590eb..9f49fa1825 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.h +++ b/Marlin/src/lcd/e3v2/proui/dwin.h @@ -22,32 +22,18 @@ #pragma once /** - * Enhanced DWIN implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.9.2 - * date: 2021/11/21 - * - * Based on the original code provided by Creality under GPL + * Version: 3.15.2 + * Date: 2022/03/01 */ -#include "../../../inc/MarlinConfigPre.h" +#include "dwin_defines.h" #include "dwinui.h" #include "../common/encoder.h" #include "../../../libs/BL24CXX.h" -#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) && DISABLED(PROBE_MANUALLY) - #define HAS_ONESTEP_LEVELING 1 -#endif - -#if !HAS_BED_PROBE && ENABLED(BABYSTEPPING) - #define JUST_BABYSTEP 1 -#endif - -#if ANY(BABYSTEPPING, HAS_BED_PROBE, HAS_WORKSPACE_OFFSET) - #define HAS_ZOFFSET_ITEM 1 -#endif - -#include "dwin_defines.h" +#include "../../../inc/MarlinConfig.h" enum processID : uint8_t { // Process ID @@ -60,23 +46,16 @@ enum processID : uint8_t { SetPFloat, SelectFile, PrintProcess, - PrintDone, - PwrlossRec, - Reboot, - Info, - ConfirmToPrint, - - // Popup Windows - Homing, + Popup, Leveling, - PidProcess, - ESDiagProcess, - PrintStatsProcess, - PauseOrStop, - FilamentPurge, - WaitResponse, Locked, - NothingToDo, + Reboot, + PrintDone, + ESDiagProcess, + WaitResponse, + Homing, + PidProcess, + NothingToDo }; enum pidresult_t : uint8_t { @@ -93,24 +72,18 @@ enum pidresult_t : uint8_t { typedef struct { int8_t Color[3]; // Color components - uint16_t pidgrphpoints = 0; pidresult_t pidresult = PID_DONE; int8_t Preheat = 0; // Material Select 0: PLA, 1: ABS, 2: Custom AxisEnum axis = X_AXIS; // Axis Select - int32_t MaxValue = 0; // Auxiliar max integer/scaled float value - int32_t MinValue = 0; // Auxiliar min integer/scaled float value - int8_t dp = 0; // Auxiliar decimal places - int32_t Value = 0; // Auxiliar integer / scaled float value - int16_t *P_Int = nullptr; // Auxiliar pointer to 16 bit integer variable - float *P_Float = nullptr; // Auxiliar pointer to float variable - void (*Apply)() = nullptr; // Auxiliar apply function - void (*LiveUpdate)() = nullptr; // Auxiliar live update function } HMI_value_t; typedef struct { uint8_t language; + bool remain_flag:1; // remain was override by M73 bool pause_flag:1; // printing is paused bool pause_action:1; // flag a pause action + bool abort_flag:1; // printing is aborting + bool abort_action:1; // flag a aborting action bool print_finish:1; // print was finished bool select_flag:1; // Popup button selected bool home_flag:1; // homing in course @@ -126,9 +99,6 @@ extern millis_t dwin_heat_time; #if HAS_HOTEND || HAS_HEATED_BED void DWIN_Popup_Temperature(const bool toohigh); #endif -#if HAS_HOTEND - void Popup_Window_ETempTooLow(); -#endif #if ENABLED(POWER_LOSS_RECOVERY) void Popup_PowerLossRecovery(); #endif @@ -143,50 +113,64 @@ void Goto_Main_Menu(); void Goto_Info_Menu(); void Goto_PowerLossRecovery(); void Goto_ConfirmToPrint(); -void Draw_Status_Area(const bool with_update); // Status Area +void DWIN_Draw_Dashboard(const bool with_update); // Status Area void Draw_Main_Area(); // Redraw main area; void DWIN_Redraw_screen(); // Redraw all screen elements -void HMI_StartFrame(const bool with_update); // Prepare the menu view void HMI_MainMenu(); // Main process screen void HMI_SelectFile(); // File page void HMI_Printing(); // Print page void HMI_ReturnScreen(); // Return to previous screen before popups void ApplyExtMinT(); void HMI_SetLanguageCache(); // Set the languaje image cache +void RebootPrinter(); +#if ENABLED(BAUD_RATE_GCODE) + void HMI_SetBaudRate(); + void SetBaud115K(); + void SetBaud250K(); +#endif +#if ENABLED(EEPROM_SETTINGS) + void WriteEeprom(); + void ReadEeprom(); + void ResetEeprom(); +#endif -void HMI_Init(); -void HMI_Popup(); +void HMI_WaitForUser(); void HMI_SaveProcessID(const uint8_t id); void HMI_AudioFeedback(const bool success=true); void EachMomentUpdate(); void update_variable(); +void DWIN_InitScreen(); void DWIN_HandleScreen(); -void DWIN_Update(); void DWIN_CheckStatusMessage(); void DWIN_StartHoming(); void DWIN_CompletedHoming(); #if HAS_MESH - void DWIN_MeshUpdate(const int8_t xpos, const int8_t ypos, const float zval); + void DWIN_MeshUpdate(const int8_t xpos, const int8_t ypos, const_float_t zval); #endif void DWIN_MeshLevelingStart(); void DWIN_CompletedLeveling(); void DWIN_PidTuning(pidresult_t result); -void DWIN_Print_Started(const bool sd = false); +void DWIN_Print_Started(const bool sd=false); +void DWIN_Print_Pause(); +void DWIN_Print_Resume(); void DWIN_Print_Finished(); +void DWIN_Print_Aborted(); #if HAS_FILAMENT_SENSOR void DWIN_FilamentRunout(const uint8_t extruder); #endif void DWIN_Progress_Update(); void DWIN_Print_Header(const char *text); void DWIN_SetColorDefaults(); +void DWIN_ApplyColor(); void DWIN_StoreSettings(char *buff); void DWIN_LoadSettings(const char *buff); void DWIN_SetDataDefaults(); void DWIN_RebootScreen(); #if ENABLED(ADVANCED_PAUSE_FEATURE) + void DWIN_Popup_Pause(FSTR_P const fmsg, uint8_t button=0); void Draw_Popup_FilamentPurge(); - void DWIN_Popup_FilamentPurge(); + void Goto_FilamentPurge(); void HMI_FilamentPurge(); #endif @@ -207,14 +191,6 @@ void HMI_LockScreen(); void Draw_PrintStats(); #endif -// HMI user control functions -void HMI_Menu(); -void HMI_SetInt(); -void HMI_SetPInt(); -void HMI_SetIntNoDraw(); -void HMI_SetFloat(); -void HMI_SetPFloat(); - // Menu drawing functions void Draw_Control_Menu(); void Draw_AdvancedSettings_Menu(); diff --git a/Marlin/src/lcd/e3v2/proui/dwin_defines.h b/Marlin/src/lcd/e3v2/proui/dwin_defines.h index 3dc2408f4a..5065bb94d7 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_defines.h +++ b/Marlin/src/lcd/e3v2/proui/dwin_defines.h @@ -22,18 +22,37 @@ #pragma once /** - * DWIN general defines and data structs + * DWIN general defines and data structs for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.9.2 - * Date: 2021/11/21 - * - * Based on the original code provided by Creality under GPL + * Version: 3.11.2 + * Date: 2022/02/28 */ -//#define NEED_HEX_PRINT 1 //#define DEBUG_DWIN 1 +//#define NEED_HEX_PRINT 1 + +#include "../../../inc/MarlinConfigPre.h" +#include + +#if DISABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU) + #error "INDIVIDUAL_AXIS_HOMING_SUBMENU is required with ProUI." +#endif +#if DISABLED(LCD_SET_PROGRESS_MANUALLY) + #error "LCD_SET_PROGRESS_MANUALLY is required with ProUI." +#endif +#if DISABLED(STATUS_MESSAGE_SCROLLING) + #error "STATUS_MESSAGE_SCROLLING is required with ProUI." +#endif +#if DISABLED(BAUD_RATE_GCODE) + #error "BAUD_RATE_GCODE is required with ProUI." +#endif +#if DISABLED(SOUND_MENU_ITEM) + #error "SOUND_MENU_ITEM is required with ProUI." +#endif +#if DISABLED(PRINTCOUNTER) + #error "PRINTCOUNTER is required with ProUI." +#endif -#include "../../../core/types.h" #include "../common/dwin_color.h" #if ENABLED(LED_CONTROL_MENU) #include "../../../feature/leds/leds.h" @@ -57,8 +76,8 @@ #define Def_Barfill_Color BarFill_Color #define Def_Indicator_Color Color_White #define Def_Coordinate_Color Color_White +#define Def_Button_Color RGB( 0, 23, 16) -//#define HAS_GCODE_PREVIEW 1 #define HAS_ESDIAG 1 #if ENABLED(LED_CONTROL_MENU, HAS_COLOR_LEDS) @@ -101,6 +120,9 @@ typedef struct { #if ENABLED(PREVENT_COLD_EXTRUSION) int16_t ExtMinT = EXTRUDE_MINTEMP; #endif + int16_t BedLevT = PREHEAT_1_TEMP_BED; + TERN_(BAUD_RATE_GCODE, bool Baud115K = false); + bool FullManualTramming = false; // Led #if BOTH(LED_CONTROL_MENU, HAS_COLOR_LEDS) LEDColor Led_Color = Def_Leds_Color; @@ -113,3 +135,8 @@ typedef struct { static constexpr size_t eeprom_data_size = 64; extern HMI_data_t HMI_data; + +#if PREHEAT_1_TEMP_BED + #undef LEVELING_BED_TEMP + #define LEVELING_BED_TEMP HMI_data.BedLevT +#endif diff --git a/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp b/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp index b8bff35159..3da3fc8086 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp @@ -21,12 +21,10 @@ */ /** - * DWIN UI Enhanced implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.8.1 - * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL + * Version: 3.9.1 + * Date: 2022/02/08 */ #include "../../../inc/MarlinConfigPre.h" @@ -37,6 +35,54 @@ #include "dwin_lcd.h" +/*---------------------------------------- Numeric related functions ----------------------------------------*/ + +// Draw a numeric value +// bShow: true=display background color; false=don't display background color +// zeroFill: true=zero fill; false=no zero fill +// signedMode: 1=signed; 0=unsigned +// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space +// size: Font size +// color: Character color +// bColor: Background color +// iNum: Number of digits +// fNum: Number of decimal digits +// x/y: Upper-left coordinate +// value: Integer value +void DWIN_Draw_Value(uint8_t bShow, bool signedMode, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, int32_t value) { + size_t i = 0; + DWIN_Byte(i, 0x14); + // Bit 7: bshow + // Bit 6: 1 = signed; 0 = unsigned number; + // Bit 5: zeroFill + // Bit 4: zeroMode + // Bit 3-0: size + DWIN_Byte(i, (bShow * 0x80) | (signedMode * 0x40) | (zeroFill * 0x20) | (zeroMode * 0x10) | size); + DWIN_Word(i, color); + DWIN_Word(i, bColor); + DWIN_Byte(i, signedMode && (value >= 0) ? iNum + 1 : iNum); + DWIN_Byte(i, fNum); + DWIN_Word(i, x); + DWIN_Word(i, y); + // Write a big-endian 64 bit integer + const size_t p = i + 1; + for (size_t count = 8; count--;) { // 7..0 + ++i; + DWIN_SendBuf[p + count] = value; + value >>= 8; + } + DWIN_Send(i); +} + +// Draw a numeric value +// value: positive unscaled float value +void DWIN_Draw_Value(uint8_t bShow, bool signedMode, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { + const int32_t val = round(value * POW(10, fNum)); + DWIN_Draw_Value(bShow, signedMode, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, val); +} + /*---------------------------------------- Picture related functions ----------------------------------------*/ // Display QR code diff --git a/Marlin/src/lcd/e3v2/proui/dwin_lcd.h b/Marlin/src/lcd/e3v2/proui/dwin_lcd.h index 623a94f09e..cdffb96f2f 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_lcd.h +++ b/Marlin/src/lcd/e3v2/proui/dwin_lcd.h @@ -22,16 +22,32 @@ #pragma once /** - * DWIN UI Enhanced implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.8.1 - * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL + * Version: 3.9.1 + * Date: 2022/02/08 */ #include "../common/dwin_api.h" +// Draw a numeric value +// bShow: true=display background color; false=don't display background color +// zeroFill: true=zero fill; false=no zero fill +// signedMode: 1=signed; 0=unsigned +// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space +// size: Font size +// color: Character color +// bColor: Background color +// iNum: Number of digits +// fNum: Number of decimal digits +// x/y: Upper-left coordinate +// value: Integer value +void DWIN_Draw_Value(uint8_t bShow, bool signedMode, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, int32_t value); +// value: positive unscaled float value +void DWIN_Draw_Value(uint8_t bShow, bool signedMode, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, + uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value); + // Display QR code // The size of the QR code is (46*QR_Pixel)*(46*QR_Pixel) dot matrix // QR_Pixel: The pixel size occupied by each point of the QR code: 0x01-0x0F (1-16) diff --git a/Marlin/src/lcd/e3v2/proui/dwin_popup.cpp b/Marlin/src/lcd/e3v2/proui/dwin_popup.cpp index 33f216fde6..59b6c0d328 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_popup.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin_popup.cpp @@ -21,12 +21,10 @@ */ /** - * DWIN UI Enhanced implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.10.1 - * Date: 2022/01/21 - * - * Based on the original code provided by Creality under GPL + * Version: 3.11.1 + * Date: 2022/02/28 */ #include "../../../inc/MarlinConfigPre.h" @@ -34,30 +32,64 @@ #if ENABLED(DWIN_LCD_PROUI) #include "dwin.h" +#include "dwinui.h" #include "dwin_popup.h" -void Draw_Select_Highlight(const bool sel) { +#include "../../../MarlinCore.h" // for wait_for_user + +popupDrawFunc_t popupDraw = nullptr; +popupClickFunc_t popupClick = nullptr; +popupChangeFunc_t popupChange = nullptr; + +uint16_t HighlightYPos = 280; + +void Draw_Select_Highlight(const bool sel, const uint16_t ypos) { + HighlightYPos = ypos; HMI_flag.select_flag = sel; const uint16_t c1 = sel ? HMI_data.Highlight_Color : HMI_data.PopupBg_color, c2 = sel ? HMI_data.PopupBg_color : HMI_data.Highlight_Color; - DWIN_Draw_Rectangle(0, c1, 25, 279, 126, 318); - DWIN_Draw_Rectangle(0, c1, 24, 278, 127, 319); - DWIN_Draw_Rectangle(0, c2, 145, 279, 246, 318); - DWIN_Draw_Rectangle(0, c2, 144, 278, 247, 319); + DWIN_Draw_Rectangle(0, c1, 25, ypos - 1, 126, ypos + 38); + DWIN_Draw_Rectangle(0, c1, 24, ypos - 2, 127, ypos + 39); + DWIN_Draw_Rectangle(0, c2, 145, ypos - 1, 246, ypos + 38); + DWIN_Draw_Rectangle(0, c2, 144, ypos - 2, 247, ypos + 39); } void DWIN_Popup_Continue(const uint8_t icon, FSTR_P const fmsg1, FSTR_P const fmsg2) { HMI_SaveProcessID(WaitResponse); - DWIN_Draw_Popup(icon, fmsg1, fmsg2, ICON_Continue_E); // Button Continue + DWIN_Draw_Popup(icon, fmsg1, fmsg2, BTN_Continue); // Button Continue DWIN_UpdateLCD(); } void DWIN_Popup_ConfirmCancel(const uint8_t icon, FSTR_P const fmsg2) { DWIN_Draw_Popup(ICON_BLTouch, F("Please confirm"), fmsg2); - DWINUI::Draw_IconWB(ICON_Confirm_E, 26, 280); - DWINUI::Draw_IconWB(ICON_Cancel_E, 146, 280); - Draw_Select_Highlight(true); + DWINUI::Draw_Button(BTN_Confirm, 26, 280); + DWINUI::Draw_Button(BTN_Cancel, 146, 280); + Draw_Select_Highlight(HMI_flag.select_flag); DWIN_UpdateLCD(); } +void Goto_Popup(const popupDrawFunc_t fnDraw, const popupClickFunc_t fnClick/*=nullptr*/, const popupChangeFunc_t fnChange/*=nullptr*/) { + popupDraw = fnDraw; + popupClick = fnClick; + popupChange = fnChange; + HMI_SaveProcessID(Popup); + HMI_flag.select_flag = false; + popupDraw(); +} + +void HMI_Popup() { + if (!wait_for_user) { + if (popupClick) popupClick(); + return; + } + else { + EncoderState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_CW || encoder_diffState == ENCODER_DIFF_CCW) { + const bool change = encoder_diffState != ENCODER_DIFF_CW; + if (popupChange) popupChange(change); else Draw_Select_Highlight(change, HighlightYPos); + DWIN_UpdateLCD(); + } + } +} + #endif // DWIN_LCD_PROUI diff --git a/Marlin/src/lcd/e3v2/proui/dwin_popup.h b/Marlin/src/lcd/e3v2/proui/dwin_popup.h index 2e952cc1b9..0d86499475 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_popup.h +++ b/Marlin/src/lcd/e3v2/proui/dwin_popup.h @@ -22,20 +22,26 @@ #pragma once /** - * DWIN UI Enhanced implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.10.1 - * Date: 2022/01/21 - * - * Based on the original code provided by Creality under GPL + * Version: 3.11.1 + * Date: 2022/02/28 */ #include "dwinui.h" #include "dwin.h" -// Popup windows +typedef void (*popupDrawFunc_t)(); +typedef void (*popupClickFunc_t)(); +typedef void (*popupChangeFunc_t)(const bool state); +extern popupDrawFunc_t popupDraw; -void Draw_Select_Highlight(const bool sel); +void Draw_Select_Highlight(const bool sel, const uint16_t ypos); +inline void Draw_Select_Highlight(const bool sel) { Draw_Select_Highlight(sel, 280); }; +void DWIN_Popup_Continue(const uint8_t icon, FSTR_P const fmsg1, FSTR_P const fmsg2); +void DWIN_Popup_ConfirmCancel(const uint8_t icon, FSTR_P const fmsg2); +void Goto_Popup(const popupDrawFunc_t fnDraw, const popupClickFunc_t fnClick=nullptr, const popupChangeFunc_t fnChange=nullptr); +void HMI_Popup(); inline void Draw_Popup_Bkgd() { DWIN_Draw_Rectangle(1, HMI_data.PopupBg_color, 14, 60, 258, 330); @@ -49,7 +55,7 @@ void DWIN_Draw_Popup(const uint8_t icon, T amsg1=nullptr, U amsg2=nullptr, uint8 if (icon) DWINUI::Draw_Icon(icon, 101, 105); if (amsg1) DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 210, amsg1); if (amsg2) DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 240, amsg2); - if (button) DWINUI::Draw_IconWB(button, 86, 280); + if (button) DWINUI::Draw_Button(button, 86, 280); } template @@ -61,10 +67,7 @@ void DWIN_Show_Popup(const uint8_t icon, T amsg1=nullptr, U amsg2=nullptr, uint8 template void DWIN_Popup_Confirm(const uint8_t icon, T amsg1, U amsg2) { HMI_SaveProcessID(WaitResponse); - DWIN_Draw_Popup(icon, amsg1, amsg2, ICON_Confirm_E); // Button Confirm + DWIN_Draw_Popup(icon, amsg1, amsg2, BTN_Confirm); // Button Confirm DWIN_UpdateLCD(); } -void DWIN_Popup_Continue(const uint8_t icon, FSTR_P const fmsg1, FSTR_P const fmsg2); - -void DWIN_Popup_ConfirmCancel(const uint8_t icon, FSTR_P const fmsg2); diff --git a/Marlin/src/lcd/e3v2/proui/dwinui.cpp b/Marlin/src/lcd/e3v2/proui/dwinui.cpp index 1dbd531390..ddc494fc84 100644 --- a/Marlin/src/lcd/e3v2/proui/dwinui.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwinui.cpp @@ -21,12 +21,10 @@ */ /** - * DWIN UI Enhanced implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.8.2 - * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL + * Version: 3.15.1 + * Date: 2022/02/25 */ #include "../../../inc/MarlinConfigPre.h" @@ -51,7 +49,9 @@ xy_int_t DWINUI::cursor = { 0 }; uint16_t DWINUI::pencolor = Color_White; uint16_t DWINUI::textcolor = Def_Text_Color; uint16_t DWINUI::backcolor = Def_Background_Color; +uint16_t DWINUI::buttoncolor = Def_Button_Color; uint8_t DWINUI::font = font8x16; +FSTR_P const DWINUI::Author = F(STRING_CONFIG_H_AUTHOR); void (*DWINUI::onCursorErase)(const int8_t line)=nullptr; void (*DWINUI::onCursorDraw)(const int8_t line)=nullptr; @@ -59,18 +59,16 @@ void (*DWINUI::onTitleDraw)(TitleClass* title)=nullptr; void (*DWINUI::onMenuDraw)(MenuClass* menu)=nullptr; void DWINUI::init() { - DEBUG_ECHOPGM("\r\nDWIN handshake "); - delay(750); // Delay here or init later in the boot process - const bool success = DWIN_Handshake(); - if (success) DEBUG_ECHOLNPGM("ok."); else DEBUG_ECHOLNPGM("error."); + TERN_(DEBUG_DWIN, SERIAL_ECHOPGM("\r\nDWIN handshake ")); + delay(750); // Delay for wait to wakeup screen + const bool hs = DWIN_Handshake(); + TERN(DEBUG_DWIN, SERIAL_ECHOLNF(hs ? F("ok.") : F("error.")), UNUSED(hs)); DWIN_Frame_SetDir(1); - TERN(SHOW_BOOTSCREEN,,DWIN_Frame_Clear(Color_Bg_Black)); - DWIN_UpdateLCD(); - cursor.x = 0; - cursor.y = 0; + cursor.reset(); pencolor = Color_White; textcolor = Def_Text_Color; backcolor = Def_Background_Color; + buttoncolor = Def_Button_Color; font = font8x16; } @@ -124,9 +122,10 @@ uint16_t DWINUI::RowToY(uint8_t row) { } // Set text/number color -void DWINUI::SetColors(uint16_t fgcolor, uint16_t bgcolor) { +void DWINUI::SetColors(uint16_t fgcolor, uint16_t bgcolor, uint16_t alcolor) { textcolor = fgcolor; backcolor = bgcolor; + buttoncolor = alcolor; } void DWINUI::SetTextColor(uint16_t fgcolor) { textcolor = fgcolor; @@ -159,16 +158,22 @@ void DWINUI::MoveBy(xy_int_t point) { cursor += point; } -// Draw a Centered string using DWIN_WIDTH -void DWINUI::Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string) { - const int8_t x = _MAX(0U, DWIN_WIDTH - strlen_P(string) * fontWidth(size)) / 2 - 1; +// Draw a Centered string using arbitrary x1 and x2 margins +void DWINUI::Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x1, uint16_t x2, uint16_t y, const char * const string) { + const uint16_t x = _MAX(0U, x2 + x1 - strlen_P(string) * fontWidth(size)) / 2 - 1; DWIN_Draw_String(bShow, size, color, bColor, x, y, string); } +// // Draw a Centered string using DWIN_WIDTH +// void DWINUI::Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string) { +// const int8_t x = _MAX(0U, DWIN_WIDTH - strlen_P(string) * fontWidth(size)) / 2 - 1; +// DWIN_Draw_String(bShow, size, color, bColor, x, y, string); +// } + // Draw a char at cursor position -void DWINUI::Draw_Char(const char c) { +void DWINUI::Draw_Char(uint16_t color, const char c) { const char string[2] = { c, 0}; - DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, 1); + DWIN_Draw_String(false, font, color, backcolor, cursor.x, cursor.y, string, 1); MoveBy(fontWidth(font), 0); } @@ -185,21 +190,26 @@ void DWINUI::Draw_String(uint16_t color, const char * const string, uint16_t rli MoveBy(strlen(string) * fontWidth(font), 0); } -// Draw a signed floating point number -// bShow: true=display background color; false=don't display background color -// zeroFill: true=zero fill; false=no zero fill -// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space -// size: Font size -// bColor: Background color -// iNum: Number of whole digits -// fNum: Number of decimal digits -// x/y: Upper-left point -// value: Float value -void DWINUI::Draw_Signed_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value < 0 ? -value : value); - DWIN_Draw_String(bShow, size, color, bColor, x - 6, y, value < 0 ? F("-") : F(" ")); +// ------------------------- Buttons ------------------------------// + +void DWINUI::Draw_Button(uint16_t color, uint16_t bcolor, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, const char * const caption) { + DWIN_Draw_Rectangle(1, bcolor, x1, y1, x2, y2); + Draw_CenteredString(0, font, color, bcolor, x1, x2, (y2 + y1 - fontHeight())/2, caption); } +void DWINUI::Draw_Button(uint8_t id, uint16_t x, uint16_t y) { + switch (id) { + case BTN_Cancel : Draw_Button(GET_TEXT_F(MSG_BUTTON_CANCEL), x, y); break; + case BTN_Confirm : Draw_Button(GET_TEXT_F(MSG_BUTTON_CONFIRM), x, y); break; + case BTN_Continue: Draw_Button(GET_TEXT_F(MSG_BUTTON_CONTINUE), x, y); break; + case BTN_Print : Draw_Button(GET_TEXT_F(MSG_BUTTON_PRINT), x, y); break; + case BTN_Save : Draw_Button(GET_TEXT_F(MSG_BUTTON_SAVE), x, y); break; + default: break; + } +} + +// -------------------------- Extra -------------------------------// + // Draw a circle // color: circle color // x: the abscissa of the center of the circle @@ -247,13 +257,12 @@ void DWINUI::Draw_FillCircle(uint16_t bcolor, uint16_t x,uint16_t y,uint8_t r) { // color1 : Start color // color2 : End color uint16_t DWINUI::ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t color1, uint16_t color2) { - uint8_t B,G,R; - float n; - n = (float)(val-minv)/(maxv-minv); - R = (1-n)*GetRColor(color1) + n*GetRColor(color2); - G = (1-n)*GetGColor(color1) + n*GetGColor(color2); - B = (1-n)*GetBColor(color1) + n*GetBColor(color2); - return RGB(R,G,B); + uint8_t B, G, R; + const float n = (float)(val - minv) / (maxv - minv); + R = (1 - n) * GetRColor(color1) + n * GetRColor(color2); + G = (1 - n) * GetGColor(color1) + n * GetGColor(color2); + B = (1 - n) * GetBColor(color1) + n * GetBColor(color2); + return RGB(R, G, B); } // Color Interpolator through Red->Yellow->Green->Blue @@ -261,33 +270,27 @@ uint16_t DWINUI::ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t colo // minv : Minimum value // maxv : Maximum value uint16_t DWINUI::RainbowInt(int16_t val, int16_t minv, int16_t maxv) { - uint8_t B,G,R; - const uint8_t maxB = 28; - const uint8_t maxR = 28; - const uint8_t maxG = 38; + uint8_t B, G, R; + const uint8_t maxB = 28, maxR = 28, maxG = 38; const int16_t limv = _MAX(abs(minv), abs(maxv)); - float n; - if (minv>=0) { - n = (float)(val-minv)/(maxv-minv); - } else { - n = (float)val/limv; - } - n = _MIN(1, n); - n = _MAX(-1, n); + float n = minv >= 0 ? (float)(val - minv) / (maxv - minv) : (float)val / limv; + LIMIT(n, -1, 1); if (n < 0) { R = 0; - G = (1+n)*maxG; - B = (-n)*maxB; - } else if (n < 0.5) { - R = maxR*n*2; + G = (1 + n) * maxG; + B = (-n) * maxB; + } + else if (n < 0.5) { + R = maxR * n * 2; G = maxG; B = 0; - } else { + } + else { R = maxR; - G = maxG*(1-n); + G = maxG * (1 - n); B = 0; } - return RGB(R,G,B); + return RGB(R, G, B); } // Draw a checkbox diff --git a/Marlin/src/lcd/e3v2/proui/dwinui.h b/Marlin/src/lcd/e3v2/proui/dwinui.h index 595c534356..1504dcd305 100644 --- a/Marlin/src/lcd/e3v2/proui/dwinui.h +++ b/Marlin/src/lcd/e3v2/proui/dwinui.h @@ -22,12 +22,10 @@ #pragma once /** - * DWIN UI Enhanced implementation + * DWIN Enhanced implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.11.1 - * Date: 2022/01/19 - * - * Based on the original code provided by Creality under GPL + * Version: 3.15.1 + * Date: 2022/02/25 */ #include "dwin_lcd.h" @@ -107,6 +105,13 @@ #define ICON_CaseLight ICON_Motion #define ICON_LedControl ICON_Motion +// Buttons +#define BTN_Continue 85 +#define BTN_Cancel 87 +#define BTN_Confirm 89 +#define BTN_Print 90 +#define BTN_Save 91 + // Extended and default UI Colors #define Color_Black 0 #define Color_Green RGB(0,63,0) @@ -119,7 +124,11 @@ #define DWIN_FONT_HEAD font10x20 #define DWIN_FONT_ALERT font10x20 #define STATUS_Y 354 -#define LCD_WIDTH (DWIN_WIDTH / 8) +#define LCD_WIDTH (DWIN_WIDTH / 8) // only if the default font is font8x16 + +// Minimum unit (0.1) : multiple (10) +#define UNITFDIGITS 1 +#define MINUNITMULT POW(10, UNITFDIGITS) constexpr uint16_t TITLE_HEIGHT = 30, // Title bar height MLINE = 53, // Menu line height @@ -212,7 +221,9 @@ namespace DWINUI { extern uint16_t pencolor; extern uint16_t textcolor; extern uint16_t backcolor; + extern uint16_t buttoncolor; extern uint8_t font; + extern FSTR_P const Author; extern void (*onCursorErase)(const int8_t line); extern void (*onCursorDraw)(const int8_t line); @@ -240,7 +251,7 @@ namespace DWINUI { uint16_t RowToY(uint8_t row); // Set text/number color - void SetColors(uint16_t fgcolor, uint16_t bgcolor); + void SetColors(uint16_t fgcolor, uint16_t bgcolor, uint16_t alcolor); void SetTextColor(uint16_t fgcolor); void SetBackgroundColor(uint16_t bgcolor); @@ -268,6 +279,17 @@ namespace DWINUI { DWIN_Draw_Line(pencolor, cursor.x, cursor.y, x, y); } + // Extend a frame box + // v: value to extend + inline frame_rect_t ExtendFrame(frame_rect_t frame, uint8_t v) { + frame_rect_t t; + t.x = frame.x - v; + t.y = frame.y - v; + t.w = frame.w + 2 * v; + t.h = frame.h + 2 * v; + return t; + } + // Draw an Icon with transparent background from the library ICON // icon: Icon ID // x/y: Upper-left point @@ -293,26 +315,56 @@ namespace DWINUI { // x/y: Upper-left coordinate // value: Integer value inline void Draw_Int(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { - DWIN_Draw_IntValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, x, y, value); + DWIN_Draw_Value(bShow, 0, zeroFill, zeroMode, size, color, bColor, iNum, 0, x, y, value); } inline void Draw_Int(uint8_t iNum, long value) { - DWIN_Draw_IntValue(false, true, 0, font, textcolor, backcolor, iNum, cursor.x, cursor.y, value); + DWIN_Draw_Value(false, 0, true, 0, font, textcolor, backcolor, iNum, 0, cursor.x, cursor.y, value); MoveBy(iNum * fontWidth(font), 0); } inline void Draw_Int(uint8_t iNum, uint16_t x, uint16_t y, long value) { - DWIN_Draw_IntValue(false, true, 0, font, textcolor, backcolor, iNum, x, y, value); + DWIN_Draw_Value(false, 0, true, 0, font, textcolor, backcolor, iNum, 0, x, y, value); } inline void Draw_Int(uint16_t color, uint8_t iNum, uint16_t x, uint16_t y, long value) { - DWIN_Draw_IntValue(false, true, 0, font, color, backcolor, iNum, x, y, value); + DWIN_Draw_Value(false, 0, true, 0, font, color, backcolor, iNum, 0, x, y, value); } inline void Draw_Int(uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { - DWIN_Draw_IntValue(true, true, 0, font, color, bColor, iNum, x, y, value); + DWIN_Draw_Value(true, 0, true, 0, font, color, bColor, iNum, 0, x, y, value); } inline void Draw_Int(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { - DWIN_Draw_IntValue(true, true, 0, size, color, bColor, iNum, x, y, value); + DWIN_Draw_Value(true, 0, true, 0, size, color, bColor, iNum, 0, x, y, value); } - // Draw a floating point number + // Draw a signed integer + // bShow: true=display background color; false=don't display background color + // zeroFill: true=zero fill; false=no zero fill + // zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space + // size: Font size + // color: Character color + // bColor: Background color + // iNum: Number of digits + // x/y: Upper-left coordinate + // value: Integer value + inline void Draw_Signed_Int(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { + DWIN_Draw_Value(bShow, 1, zeroFill, zeroMode, size, color, bColor, iNum, 0, x, y, value); + } + inline void Draw_Signed_Int(uint8_t iNum, long value) { + DWIN_Draw_Value(false, 1, true, 0, font, textcolor, backcolor, iNum, 0, cursor.x, cursor.y, value); + MoveBy(iNum * fontWidth(font), 0); + } + inline void Draw_Signed_Int(uint8_t iNum, uint16_t x, uint16_t y, long value) { + DWIN_Draw_Value(false, 1, true, 0, font, textcolor, backcolor, iNum, 0, x, y, value); + } + inline void Draw_Signed_Int(uint16_t color, uint8_t iNum, uint16_t x, uint16_t y, long value) { + DWIN_Draw_Value(false, 1, true, 0, font, color, backcolor, iNum, 0, x, y, value); + } + inline void Draw_Signed_Int(uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { + DWIN_Draw_Value(true, 1, true, 0, font, color, bColor, iNum, 0, x, y, value); + } + inline void Draw_Signed_Int(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { + DWIN_Draw_Value(true, 1, true, 0, size, color, bColor, iNum, 0, x, y, value); + } + + // Draw a positive floating point number // bShow: true=display background color; false=don't display background color // zeroFill: true=zero fill; false=no zero fill // zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space @@ -324,23 +376,23 @@ namespace DWINUI { // x/y: Upper-left point // value: Float value inline void Draw_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value); + DWIN_Draw_Value(bShow, 0, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value); } inline void Draw_Float(uint8_t iNum, uint8_t fNum, float value) { - DWIN_Draw_FloatValue(false, true, 0, font, textcolor, backcolor, iNum, fNum, cursor.x, cursor.y, value); + DWIN_Draw_Value(false, 0, true, 0, font, textcolor, backcolor, iNum, fNum, cursor.x, cursor.y, value); MoveBy((iNum + fNum + 1) * fontWidth(font), 0); } inline void Draw_Float(uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - DWIN_Draw_FloatValue(false, true, 0, font, textcolor, backcolor, iNum, fNum, x, y, value); + DWIN_Draw_Value(false, 0, true, 0, font, textcolor, backcolor, iNum, fNum, x, y, value); } inline void Draw_Float(uint16_t color, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - DWIN_Draw_FloatValue(false, true, 0, font, color, backcolor, iNum, fNum, x, y, value); + DWIN_Draw_Value(false, 0, true, 0, font, color, backcolor, iNum, fNum, x, y, value); } inline void Draw_Float(uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - DWIN_Draw_FloatValue(true, true, 0, font, color, bColor, iNum, fNum, x, y, value); + DWIN_Draw_Value(true, 0, true, 0, font, color, bColor, iNum, fNum, x, y, value); } inline void Draw_Float(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - DWIN_Draw_FloatValue(true, true, 0, size, color, bColor, iNum, fNum, x, y, value); + DWIN_Draw_Value(true, 0, true, 0, size, color, bColor, iNum, fNum, x, y, value); } // Draw a signed floating point number @@ -348,31 +400,35 @@ namespace DWINUI { // zeroFill: true=zero fill; false=no zero fill // zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space // size: Font size + // color: Character color // bColor: Background color // iNum: Number of whole digits // fNum: Number of decimal digits // x/y: Upper-left point // value: Float value - void Draw_Signed_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value); + inline void Draw_Signed_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { + DWIN_Draw_Value(bShow, 1, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value); + } inline void Draw_Signed_Float(uint8_t iNum, uint8_t fNum, float value) { - Draw_Signed_Float(false, true, 0, font, textcolor, backcolor, iNum, fNum, cursor.x, cursor.y, value); + DWIN_Draw_Value(false, 1, true, 0, font, textcolor, backcolor, iNum, fNum, cursor.x, cursor.y, value); MoveBy((iNum + fNum + 1) * fontWidth(font), 0); } inline void Draw_Signed_Float(uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - Draw_Signed_Float(false, true, 0, font, textcolor, backcolor, iNum, fNum, x, y, value); + DWIN_Draw_Value(false, 1, true, 0, font, textcolor, backcolor, iNum, fNum, x, y, value); } inline void Draw_Signed_Float(uint8_t size, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - Draw_Signed_Float(false, true, 0, size, textcolor, backcolor, iNum, fNum, x, y, value); + DWIN_Draw_Value(false, 1, true, 0, size, textcolor, backcolor, iNum, fNum, x, y, value); } inline void Draw_Signed_Float(uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - Draw_Signed_Float(true, true, 0, font, color, bColor, iNum, fNum, x, y, value); + DWIN_Draw_Value(true, 1, true, 0, font, color, bColor, iNum, fNum, x, y, value); } inline void Draw_Signed_Float(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) { - Draw_Signed_Float(true, true, 0, size, color, bColor, iNum, fNum, x, y, value); + DWIN_Draw_Value(true, 1, true, 0, size, color, bColor, iNum, fNum, x, y, value); } // Draw a char at cursor position - void Draw_Char(const char c); + void Draw_Char(uint16_t color, const char c); + inline void Draw_Char(const char c) { Draw_Char(textcolor, c); } // Draw a string at cursor position // color: Character color @@ -425,7 +481,10 @@ namespace DWINUI { // bColor: Background color // y: Upper coordinate of the string // *string: The string - void Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string); + void Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x1, uint16_t x2, uint16_t y, const char * const string); + inline void Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string) { + Draw_CenteredString(bShow, size, color, bColor, 0, DWIN_WIDTH, y, string); + } inline void Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, FSTR_P string) { Draw_CenteredString(bShow, size, color, bColor, y, FTOP(string)); } @@ -487,6 +546,17 @@ namespace DWINUI { // color2 : End color uint16_t ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t color1, uint16_t color2); + // ------------------------- Buttons ------------------------------// + + void Draw_Button(uint16_t color, uint16_t bcolor, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, const char * const caption); + inline void Draw_Button(uint16_t color, uint16_t bcolor, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, FSTR_P caption) { + Draw_Button(color, bcolor, x1, y1, x2, y2, FTOP(caption)); + } + inline void Draw_Button(FSTR_P caption, uint16_t x, uint16_t y) { + Draw_Button(textcolor, buttoncolor, x, y, x + 99, y + 37, caption); + } + void Draw_Button(uint8_t id, uint16_t x, uint16_t y); + // -------------------------- Extra -------------------------------// // Draw a circle filled with color diff --git a/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp b/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp index f04c079017..74eb94e751 100644 --- a/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp +++ b/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp @@ -21,15 +21,12 @@ */ /** - * DWIN End Stops diagnostic page + * DWIN End Stops diagnostic page for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 1.0.2 - * Date: 2021/11/06 - * - * Based on the original code provided by Creality under GPL + * Version: 1.2.2 + * Date: 2022/02/24 */ -#include "../../../inc/MarlinConfigPre.h" #include "dwin_defines.h" #if BOTH(DWIN_LCD_PROUI, HAS_ESDIAG) @@ -72,7 +69,7 @@ void ESDiagClass::Draw() { Title.ShowCaption(F("End-stops Diagnostic")); DWINUI::ClearMenuArea(); Draw_Popup_Bkgd(); - DWINUI::Draw_Icon(ICON_Continue_E, 86, 250); + DWINUI::Draw_Button(BTN_Continue, 86, 250); DWINUI::cursor.y = 80; #define ES_LABEL(S) draw_es_label(F(STR_##S)) #if HAS_X_MIN diff --git a/Marlin/src/lcd/e3v2/proui/endstop_diag.h b/Marlin/src/lcd/e3v2/proui/endstop_diag.h index 4694ddb141..316a1e1ed3 100644 --- a/Marlin/src/lcd/e3v2/proui/endstop_diag.h +++ b/Marlin/src/lcd/e3v2/proui/endstop_diag.h @@ -22,12 +22,10 @@ #pragma once /** - * DWIN End Stops diagnostic page + * DWIN End Stops diagnostic page for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 1.0 - * Date: 2021/11/06 - * - * Based on the original code provided by Creality under GPL + * Version: 1.2.3 + * Date: 2022/02/24 */ class ESDiagClass { diff --git a/Marlin/src/lcd/e3v2/proui/lockscreen.cpp b/Marlin/src/lcd/e3v2/proui/lockscreen.cpp index 2ccdcc1207..2895c01544 100644 --- a/Marlin/src/lcd/e3v2/proui/lockscreen.cpp +++ b/Marlin/src/lcd/e3v2/proui/lockscreen.cpp @@ -21,12 +21,10 @@ */ /** - * Lock screen implementation for DWIN UI Enhanced implementation + * Lock screen implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) * Version: 2.1 * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL */ #include "../../../inc/MarlinConfigPre.h" diff --git a/Marlin/src/lcd/e3v2/proui/lockscreen.h b/Marlin/src/lcd/e3v2/proui/lockscreen.h index bf2fdb3f4b..ec967fe2db 100644 --- a/Marlin/src/lcd/e3v2/proui/lockscreen.h +++ b/Marlin/src/lcd/e3v2/proui/lockscreen.h @@ -22,12 +22,10 @@ #pragma once /** - * Lock screen implementation for DWIN UI Enhanced implementation + * Lock screen implementation for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) * Version: 2.1 * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL */ #include "../common/encoder.h" diff --git a/Marlin/src/lcd/e3v2/proui/menus.cpp b/Marlin/src/lcd/e3v2/proui/menus.cpp new file mode 100644 index 0000000000..6dfcb8595c --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/menus.cpp @@ -0,0 +1,370 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Menu functions for ProUI + * Author: Miguel A. Risco-Castillo + * Version: 1.2.1 + * Date: 2022/02/25 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(DWIN_LCD_PROUI) + +#include "../common/encoder.h" +#include "dwin_lcd.h" +#include "dwinui.h" +#include "dwin.h" +#include "menus.h" + +MenuData_t MenuData; + +// Menuitem Drawing functions ================================================= + +void Draw_Title(TitleClass* title) { + DWIN_Draw_Rectangle(1, HMI_data.TitleBg_color, 0, 0, DWIN_WIDTH - 1, TITLE_HEIGHT - 1); + if (title->frameid) + DWIN_Frame_AreaCopy(title->frameid, title->frame.left, title->frame.top, title->frame.right, title->frame.bottom, 14, (TITLE_HEIGHT - (title->frame.bottom - title->frame.top)) / 2 - 1); + else + DWIN_Draw_String(false, DWIN_FONT_HEAD, HMI_data.TitleTxt_color, HMI_data.TitleBg_color, 14, (TITLE_HEIGHT - DWINUI::fontHeight(DWIN_FONT_HEAD)) / 2 - 1, title->caption); +} + +void Draw_Menu(MenuClass* menu) { + DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color); + DWIN_Draw_Rectangle(1, DWINUI::backcolor, 0, TITLE_HEIGHT, DWIN_WIDTH - 1, STATUS_Y - 1); +} + +void Draw_Menu_Cursor(const int8_t line) { + DWIN_Draw_Rectangle(1, HMI_data.Cursor_color, 0, MBASE(line) - 18, 14, MBASE(line + 1) - 20); +} + +void Erase_Menu_Cursor(const int8_t line) { + DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, MBASE(line) - 18, 14, MBASE(line + 1) - 20); +} + +void Draw_Menu_Line(const uint8_t line, const uint8_t icon /*=0*/, const char * const label /*=nullptr*/, bool more /*=false*/) { + if (icon) DWINUI::Draw_Icon(icon, ICOX, MBASE(line) - 3); + if (label) DWINUI::Draw_String(LBLX, MBASE(line) - 1, (char*)label); + if (more) DWINUI::Draw_Icon(ICON_More, VALX + 16, MBASE(line) - 3); + DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240); +} + +void Draw_Chkb_Line(const uint8_t line, const bool checked) { + DWINUI::Draw_Checkbox(HMI_data.Text_Color, HMI_data.Background_Color, VALX + 16, MBASE(line) - 1, checked); +} + +void Draw_Menu_IntValue(uint16_t bcolor, const uint8_t line, uint8_t iNum, const int32_t value /*=0*/) { + DWINUI::Draw_Signed_Int(HMI_data.Text_Color, bcolor, iNum , VALX, MBASE(line) - 1, value); +} + +void onDrawMenuItem(MenuItemClass* menuitem, int8_t line) { + if (menuitem->icon) DWINUI::Draw_Icon(menuitem->icon, ICOX, MBASE(line) - 3); + if (menuitem->frameid) + DWIN_Frame_AreaCopy(menuitem->frameid, menuitem->frame.left, menuitem->frame.top, menuitem->frame.right, menuitem->frame.bottom, LBLX, MBASE(line)); + else if (menuitem->caption) + DWINUI::Draw_String(LBLX, MBASE(line) - 1, menuitem->caption); + DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240); +} + +void onDrawSubMenu(MenuItemClass* menuitem, int8_t line) { + onDrawMenuItem(menuitem, line); + DWINUI::Draw_Icon(ICON_More, VALX + 16, MBASE(line) - 3); +} + +void onDrawIntMenu(MenuItemClass* menuitem, int8_t line, int32_t value) { + onDrawMenuItem(menuitem, line); + Draw_Menu_IntValue(HMI_data.Background_Color, line, 4, value); +} + +void onDrawPIntMenu(MenuItemClass* menuitem, int8_t line) { + const int16_t value = *(int16_t*)static_cast(menuitem)->value; + onDrawIntMenu(menuitem, line, value); +} + +void onDrawPInt8Menu(MenuItemClass* menuitem, int8_t line) { + const uint8_t value = *(uint8_t*)static_cast(menuitem)->value; + onDrawIntMenu(menuitem, line, value); +} + +void onDrawPInt32Menu(MenuItemClass* menuitem, int8_t line) { + const uint32_t value = *(uint32_t*)static_cast(menuitem)->value; + onDrawIntMenu(menuitem, line, value); +} + +void onDrawFloatMenu(MenuItemClass* menuitem, int8_t line, uint8_t dp, const float value) { + onDrawMenuItem(menuitem, line); + DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Background_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(line), value); +} + +void onDrawPFloatMenu(MenuItemClass* menuitem, int8_t line) { + const float value = *(float*)static_cast(menuitem)->value; + const int8_t dp = UNITFDIGITS; + onDrawFloatMenu(menuitem, line, dp, value); +} + +void onDrawPFloat2Menu(MenuItemClass* menuitem, int8_t line) { + const float value = *(float*)static_cast(menuitem)->value; + onDrawFloatMenu(menuitem, line, 2, value); +} + +void onDrawChkbMenu(MenuItemClass* menuitem, int8_t line, bool checked) { + onDrawMenuItem(menuitem, line); + Draw_Chkb_Line(line, checked); +} + +//----------------------------------------------------------------------------- +// On click functions +//----------------------------------------------------------------------------- + +// Generic onclick event without draw +// process: process id HMI destiny +// lo: low limit +// hi: high limit +// dp: decimal places, 0 for integers +// val: value / scaled value +// LiveUpdate: live update function when the encoder changes +// Apply: update function when the encoder is pressed +void SetOnClick(uint8_t process, const int32_t lo, const int32_t hi, uint8_t dp, const int32_t val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + checkkey = process; + MenuData.MinValue = lo; + MenuData.MaxValue = hi; + MenuData.dp = dp; + MenuData.Apply = Apply; + MenuData.LiveUpdate = LiveUpdate; + MenuData.Value = val; + EncoderRate.enabled = true; +} + +// Generic onclick event for integer values +// process: process id HMI destiny +// lo: scaled low limit +// hi: scaled high limit +// val: value +// LiveUpdate: live update function when the encoder changes +// Apply: update function when the encoder is pressed +void SetValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + SetOnClick(process, lo, hi, 0, val, Apply, LiveUpdate); + Draw_Menu_IntValue(HMI_data.Selected_Color, CurrentMenu->line(), 4, MenuData.Value); +} + +// Generic onclick event for float values +// process: process id HMI destiny +// lo: scaled low limit +// hi: scaled high limit +// val: value +// LiveUpdate: live update function when the encoder changes +// Apply: update function when the encoder is pressed +void SetValueOnClick(uint8_t process, const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + const int32_t value = round(val * POW(10, dp)); + SetOnClick(process, lo * POW(10, dp), hi * POW(10, dp), dp, value, Apply, LiveUpdate); + DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Selected_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), val); +} + +// Generic onclick event for integer values +// lo: scaled low limit +// hi: scaled high limit +// val: value +// LiveUpdate: live update function when the encoder changes +// Apply: update function when the encoder is pressed +void SetIntOnClick(const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + SetValueOnClick(SetInt, lo, hi, val, Apply, LiveUpdate); +} + +// Generic onclick event for set pointer to 16 bit uinteger values +// lo: low limit +// hi: high limit +// LiveUpdate: live update function when the encoder changes +// Apply: update function when the encoder is pressed +void SetPIntOnClick(const int32_t lo, const int32_t hi, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + MenuData.P_Int = (int16_t*)static_cast(CurrentMenu->SelectedItem())->value; + const int32_t value = *MenuData.P_Int; + SetValueOnClick(SetPInt, lo, hi, value, Apply, LiveUpdate); +} + +// Generic onclick event for float values +// process: process id HMI destiny +// lo: low limit +// hi: high limit +// dp: decimal places +// val: value +void SetFloatOnClick(const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + SetValueOnClick(SetFloat, lo, hi, dp, val, Apply, LiveUpdate); +} + +// Generic onclick event for set pointer to float values +// lo: low limit +// hi: high limit +// LiveUpdate: live update function when the encoder changes +// Apply: update function when the encoder is pressed +void SetPFloatOnClick(const float lo, const float hi, uint8_t dp, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) { + MenuData.P_Float = (float*)static_cast(CurrentMenu->SelectedItem())->value; + SetValueOnClick(SetPFloat, lo, hi, dp, *MenuData.P_Float, Apply, LiveUpdate); +} + +// HMI Control functions ====================================================== + +// Generic menu control using the encoder +void HMI_Menu() { + EncoderState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + if (CurrentMenu) { + if (encoder_diffState == ENCODER_DIFF_ENTER) + CurrentMenu->onClick(); + else + CurrentMenu->onScroll(encoder_diffState == ENCODER_DIFF_CW); + } +} + +// Get an integer value using the encoder without draw anything +// lo: low limit +// hi: high limit +// Return value: +// 0 : no change +// 1 : live change +// 2 : apply change +int8_t HMI_GetIntNoDraw(const int32_t lo, const int32_t hi) { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, MenuData.Value)) { + EncoderRate.enabled = false; + checkkey = Menu; + return 2; + } + LIMIT(MenuData.Value, lo, hi); + return 1; + } + return 0; +} + +// Get an integer value using the encoder +// lo: low limit +// hi: high limit +// Return value: +// 0 : no change +// 1 : live change +// 2 : apply change +int8_t HMI_GetInt(const int32_t lo, const int32_t hi) { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, MenuData.Value)) { + EncoderRate.enabled = false; + DWINUI::Draw_Signed_Int(HMI_data.Text_Color, HMI_data.Background_Color, 4 , VALX, MBASE(CurrentMenu->line()) - 1, MenuData.Value); + checkkey = Menu; + return 2; + } + LIMIT(MenuData.Value, lo, hi); + DWINUI::Draw_Signed_Int(HMI_data.Text_Color, HMI_data.Selected_Color, 4 , VALX, MBASE(CurrentMenu->line()) - 1, MenuData.Value); + return 1; + } + return 0; +} + +// Set an integer using the encoder +void HMI_SetInt() { + int8_t val = HMI_GetInt(MenuData.MinValue, MenuData.MaxValue); + switch (val) { + case 0: return; break; + case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break; + case 2: if (MenuData.Apply) MenuData.Apply(); break; + } +} + +// Set an integer without drawing +void HMI_SetIntNoDraw() { + int8_t val = HMI_GetIntNoDraw(MenuData.MinValue, MenuData.MaxValue); + switch (val) { + case 0: return; break; + case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break; + case 2: if (MenuData.Apply) MenuData.Apply(); break; + } +} + +// Set an integer pointer variable using the encoder +void HMI_SetPInt() { + int8_t val = HMI_GetInt(MenuData.MinValue, MenuData.MaxValue); + switch (val) { + case 0: return; + case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break; + case 2: *MenuData.P_Int = MenuData.Value; if (MenuData.Apply) MenuData.Apply(); break; + } +} + +// Get a scaled float value using the encoder +// dp: decimal places +// lo: scaled low limit +// hi: scaled high limit +// Return value: +// 0 : no change +// 1 : live change +// 2 : apply change +int8_t HMI_GetFloat(uint8_t dp, int32_t lo, int32_t hi) { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); + if (encoder_diffState != ENCODER_DIFF_NO) { + if (Apply_Encoder(encoder_diffState, MenuData.Value)) { + EncoderRate.enabled = false; + DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Background_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), MenuData.Value / POW(10, dp)); + checkkey = Menu; + return 2; + } + LIMIT(MenuData.Value, lo, hi); + DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Selected_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), MenuData.Value / POW(10, dp)); + return 1; + } + return 0; +} + +// Set a scaled float using the encoder +void HMI_SetFloat() { + const int8_t val = HMI_GetFloat(MenuData.dp, MenuData.MinValue, MenuData.MaxValue); + switch (val) { + case 0: return; + case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break; + case 2: if (MenuData.Apply) MenuData.Apply(); break; + } +} + +// Set a scaled float pointer variable using the encoder +void HMI_SetPFloat() { + const int8_t val = HMI_GetFloat(MenuData.dp, MenuData.MinValue, MenuData.MaxValue); + switch (val) { + case 0: return; + case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break; + case 2: *MenuData.P_Float = MenuData.Value / POW(10, MenuData.dp); if (MenuData.Apply) MenuData.Apply(); break; + } +} + +#endif // DWIN_LCD_PROUI diff --git a/Marlin/src/lcd/e3v2/proui/menus.h b/Marlin/src/lcd/e3v2/proui/menus.h new file mode 100644 index 0000000000..0147c1616b --- /dev/null +++ b/Marlin/src/lcd/e3v2/proui/menus.h @@ -0,0 +1,94 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Menu functions for ProUI + * Author: Miguel A. Risco-Castillo + * Version: 1.2.1 + * Date: 2022/02/25 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "dwinui.h" + +typedef struct { + int32_t MaxValue = 0; // Auxiliar max integer/scaled float value + int32_t MinValue = 0; // Auxiliar min integer/scaled float value + int8_t dp = 0; // Auxiliar decimal places + int32_t Value = 0; // Auxiliar integer / scaled float value + int16_t *P_Int = nullptr; // Auxiliar pointer to 16 bit integer variable + float *P_Float = nullptr; // Auxiliar pointer to float variable + void (*Apply)() = nullptr; // Auxiliar apply function + void (*LiveUpdate)() = nullptr; // Auxiliar live update function +} MenuData_t; + +extern MenuData_t MenuData; + +// Menuitem Drawing functions ================================================= +void Draw_Title(TitleClass* title); +void Draw_Menu(MenuClass* menu); +void Draw_Menu_Cursor(const int8_t line); +void Erase_Menu_Cursor(const int8_t line); +void Draw_Menu_Line(const uint8_t line, const uint8_t icon=0, const char * const label=nullptr, bool more=false); +void Draw_Chkb_Line(const uint8_t line, const bool checked); +void Draw_Menu_IntValue(uint16_t bcolor, const uint8_t line, uint8_t iNum, const int32_t value=0); +void onDrawMenuItem(MenuItemClass* menuitem, int8_t line); +void onDrawSubMenu(MenuItemClass* menuitem, int8_t line); +void onDrawIntMenu(MenuItemClass* menuitem, int8_t line, int32_t value); +void onDrawPIntMenu(MenuItemClass* menuitem, int8_t line); +void onDrawPInt8Menu(MenuItemClass* menuitem, int8_t line); +void onDrawPInt32Menu(MenuItemClass* menuitem, int8_t line); +void onDrawFloatMenu(MenuItemClass* menuitem, int8_t line, uint8_t dp, const float value); +void onDrawPFloatMenu(MenuItemClass* menuitem, int8_t line); +void onDrawPFloat2Menu(MenuItemClass* menuitem, int8_t line); +void onDrawChkbMenu(MenuItemClass* menuitem, int8_t line, bool checked); + +// On click functions ========================================================= +void SetOnClick(uint8_t process, const int32_t lo, const int32_t hi, uint8_t dp, const int32_t val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); +void SetValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); +void SetValueOnClick(uint8_t process, const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); +void SetIntOnClick(const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); +void SetPIntOnClick(const int32_t lo, const int32_t hi, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); +void SetFloatOnClick(const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); +void SetPFloatOnClick(const float lo, const float hi, uint8_t dp, void (*Apply)() = nullptr, void (*LiveUpdate)() = nullptr); + +// HMI user control functions ================================================= +void HMI_Menu(); +void HMI_SetInt(); +void HMI_SetPInt(); +void HMI_SetIntNoDraw(); +void HMI_SetFloat(); +void HMI_SetPFloat(); diff --git a/Marlin/src/lcd/e3v2/proui/meshviewer.cpp b/Marlin/src/lcd/e3v2/proui/meshviewer.cpp index 275a29cd38..0b22ae98d5 100644 --- a/Marlin/src/lcd/e3v2/proui/meshviewer.cpp +++ b/Marlin/src/lcd/e3v2/proui/meshviewer.cpp @@ -21,12 +21,10 @@ */ /** - * DWIN Mesh Viewer + * Mesh Viewer for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.9.1 - * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL + * version: 3.12.1 + * Date: 2022/02/24 */ #include "../../../inc/MarlinConfigPre.h" @@ -40,49 +38,53 @@ #include "dwin_lcd.h" #include "dwinui.h" #include "dwin.h" +#include "dwin_popup.h" #include "../../../feature/bedlevel/bedlevel.h" MeshViewerClass MeshViewer; -void MeshViewerClass::Draw() { +void MeshViewerClass::DrawMesh(bed_mesh_t zval, const uint8_t sizex, const uint8_t sizey) { const int8_t mx = 25, my = 25; // Margins - const int16_t stx = (DWIN_WIDTH - 2 * mx) / (GRID_MAX_POINTS_X - 1), // Steps - sty = (DWIN_WIDTH - 2 * my) / (GRID_MAX_POINTS_Y - 1); + const int16_t stx = (DWIN_WIDTH - 2 * mx) / (sizex - 1), // Steps + sty = (DWIN_WIDTH - 2 * my) / (sizey - 1); const int8_t rmax = _MIN(mx - 2, stx / 2); const int8_t rmin = 7; - int16_t zmesh[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], maxz =-32000, minz = 32000; + int16_t zmesh[sizex][sizey]; #define px(xp) (mx + (xp) * stx) #define py(yp) (30 + DWIN_WIDTH - my - (yp) * sty) #define rm(z) ((z - minz) * (rmax - rmin) / _MAX(1, (maxz - minz)) + rmin) - #define DrawMeshValue(xp, yp, zv) DWINUI::Draw_Signed_Float(font6x12, 1, 2, px(xp) - 12, py(yp) - 6, zv) + #define DrawMeshValue(xp, yp, zv) DWINUI::Draw_Signed_Float(font6x12, 1, 2, px(xp) - 18, py(yp) - 6, zv) #define DrawMeshHLine(yp) DWIN_Draw_HLine(HMI_data.SplitLine_Color, px(0), py(yp), DWIN_WIDTH - 2 * mx) - #define DrawMeshVLine(xp) DWIN_Draw_VLine(HMI_data.SplitLine_Color, px(xp), py(GRID_MAX_POINTS_Y - 1), DWIN_WIDTH - 2 * my) - GRID_LOOP(x, y) { - const float v = isnan(Z_VALUES(x,y)) ? 0 : round(Z_VALUES(x,y) * 100); + #define DrawMeshVLine(xp) DWIN_Draw_VLine(HMI_data.SplitLine_Color, px(xp), py(sizey - 1), DWIN_WIDTH - 2 * my) + int16_t maxz =-32000; int16_t minz = 32000; avg = 0; + LOOP_L_N(y, sizey) LOOP_L_N(x, sizex) { + const float v = isnan(zval[x][y]) ? 0 : round(zval[x][y] * 100); zmesh[x][y] = v; + avg += v; NOLESS(maxz, v); NOMORE(minz, v); } - Title.ShowCaption(F("Mesh Viewer")); + max = (float)maxz / 100; + min = (float)minz / 100; + avg = avg / (100 * sizex * sizey); DWINUI::ClearMenuArea(); - DWINUI::Draw_Icon(ICON_Continue_E, 86, 305); - DWIN_Draw_Rectangle(0, HMI_data.SplitLine_Color, px(0), py(0), px(GRID_MAX_POINTS_X - 1), py(GRID_MAX_POINTS_Y - 1)); - LOOP_S_L_N(x, 1, GRID_MAX_POINTS_X - 1) DrawMeshVLine(x); - LOOP_S_L_N(y, 1, GRID_MAX_POINTS_Y - 1) DrawMeshHLine(y); - LOOP_L_N(y, GRID_MAX_POINTS_Y) { + DWIN_Draw_Rectangle(0, HMI_data.SplitLine_Color, px(0), py(0), px(sizex - 1), py(sizey - 1)); + LOOP_S_L_N(x, 1, sizex - 1) DrawMeshVLine(x); + LOOP_S_L_N(y, 1, sizey - 1) DrawMeshHLine(y); + LOOP_L_N(y, sizey) { watchdog_refresh(); - LOOP_L_N(x, GRID_MAX_POINTS_X) { + LOOP_L_N(x, sizex) { uint16_t color = DWINUI::RainbowInt(zmesh[x][y], _MIN(-5, minz), _MAX(5, maxz)); uint8_t radius = rm(zmesh[x][y]); DWINUI::Draw_FillCircle(color, px(x), py(y), radius); - if (GRID_MAX_POINTS_X < 9) - DWINUI::Draw_Signed_Float(font6x12, 1, 2, px(x) - 12, py(y) - 6, Z_VALUES(x,y)); + if (sizex < 9) + DWINUI::Draw_Signed_Float(font6x12, 1, 2, px(x) - 18, py(y) - 6, zval[x][y]); else { char str_1[9]; str_1[0] = 0; switch (zmesh[x][y]) { case -999 ... -100: - DWINUI::Draw_Signed_Float(font6x12, 1, 1, px(x) - 12, py(y) - 6, Z_VALUES(x,y)); + DWINUI::Draw_Signed_Float(font6x12, 1, 1, px(x) - 18, py(y) - 6, zval[x][y]); break; case -99 ... -1: sprintf_P(str_1, PSTR("-.%02i"), -zmesh[x][y]); @@ -94,7 +96,7 @@ void MeshViewerClass::Draw() { sprintf_P(str_1, PSTR(".%02i"), zmesh[x][y]); break; case 100 ... 999: - DWINUI::Draw_Signed_Float(font6x12, 1, 1, px(x) - 12, py(y) - 6, Z_VALUES(x,y)); + DWINUI::Draw_Signed_Float(font6x12, 1, 1, px(x) - 18, py(y) - 6, zval[x][y]); break; } if (str_1[0]) @@ -102,11 +104,25 @@ void MeshViewerClass::Draw() { } } } +} + +void MeshViewerClass::Draw(bool withsave /*= false*/) { + Title.ShowCaption(F("Mesh Viewer")); + DrawMesh(Z_VALUES_ARR, GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y); + if (withsave) { + DWINUI::Draw_Button(BTN_Save, 26, 305); + DWINUI::Draw_Button(BTN_Continue, 146, 305); + Draw_Select_Highlight(HMI_flag.select_flag, 305); + } else DWINUI::Draw_Button(BTN_Continue, 86, 305); char str_1[6], str_2[6] = ""; ui.status_printf(0, F("Mesh minZ: %s, maxZ: %s"), - dtostrf((float)minz / 100, 1, 2, str_1), - dtostrf((float)maxz / 100, 1, 2, str_2) + dtostrf(min, 1, 2, str_1), + dtostrf(max, 1, 2, str_2) ); } +void Draw_MeshViewer() { MeshViewer.Draw(true); } +void onClick_MeshViewer() { if (HMI_flag.select_flag) WriteEeprom(); HMI_ReturnScreen(); } +void Goto_MeshViewer() { if (leveling_is_valid()) Goto_Popup(Draw_MeshViewer, onClick_MeshViewer); else HMI_ReturnScreen(); } + #endif // DWIN_LCD_PROUI && HAS_MESH diff --git a/Marlin/src/lcd/e3v2/proui/meshviewer.h b/Marlin/src/lcd/e3v2/proui/meshviewer.h index acd5f0d5c4..f914bab4ae 100644 --- a/Marlin/src/lcd/e3v2/proui/meshviewer.h +++ b/Marlin/src/lcd/e3v2/proui/meshviewer.h @@ -21,18 +21,23 @@ */ #pragma once +#include "../../../core/types.h" +#include "../../../feature/bedlevel/bedlevel.h" + /** - * DWIN Mesh Viewer + * Mesh Viewer for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 3.9.1 - * Date: 2021/11/09 - * - * Based on the original code provided by Creality under GPL + * version: 3.12.1 + * Date: 2022/02/24 */ class MeshViewerClass { public: - void Draw(); + float avg, max, min; + void Draw(bool withsave = false); + void DrawMesh(bed_mesh_t zval, const uint8_t sizex, const uint8_t sizey); }; extern MeshViewerClass MeshViewer; + +void Goto_MeshViewer(); diff --git a/Marlin/src/lcd/e3v2/proui/printstats.cpp b/Marlin/src/lcd/e3v2/proui/printstats.cpp index 54c87f4be1..d4ca4ca225 100644 --- a/Marlin/src/lcd/e3v2/proui/printstats.cpp +++ b/Marlin/src/lcd/e3v2/proui/printstats.cpp @@ -21,12 +21,10 @@ */ /** - * DWIN Print Stats page + * Print Stats page for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 1.1 - * Date: 2022/01/09 - * - * Based on the original code provided by Creality under GPL + * Version: 1.3.0 + * Date: 2022/02/24 */ #include "../../../inc/MarlinConfigPre.h" @@ -36,6 +34,7 @@ #include "printstats.h" #include "../../../core/types.h" +#include "../../../MarlinCore.h" #include "../../marlinui.h" #include "../../../module/printcounter.h" #include "dwin_lcd.h" @@ -53,7 +52,7 @@ void PrintStatsClass::Draw() { Title.ShowCaption(GET_TEXT_F(MSG_INFO_STATS_MENU)); DWINUI::ClearMenuArea(); Draw_Popup_Bkgd(); - DWINUI::Draw_Icon(ICON_Continue_E, 86, 250); + DWINUI::Draw_Button(BTN_Continue, 86, 250); printStatistics ps = print_job_timer.getStats(); sprintf_P(buf, PSTR(S_FMT ": %i"), GET_TEXT(MSG_INFO_PRINT_COUNT), ps.totalPrints); @@ -75,4 +74,9 @@ void PrintStatsClass::Reset() { HMI_AudioFeedback(); } +void Goto_PrintStats() { + PrintStats.Draw(); + HMI_SaveProcessID(WaitResponse); +} + #endif // DWIN_LCD_PROUI && PRINTCOUNTER diff --git a/Marlin/src/lcd/e3v2/proui/printstats.h b/Marlin/src/lcd/e3v2/proui/printstats.h index f17e4dc9dd..705c923da4 100644 --- a/Marlin/src/lcd/e3v2/proui/printstats.h +++ b/Marlin/src/lcd/e3v2/proui/printstats.h @@ -22,18 +22,18 @@ #pragma once /** - * DWIN Print Stats page + * Print Stats page for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 1.1 - * Date: 2022/01/09 - * - * Based on the original code provided by Creality under GPL + * Version: 1.3.0 + * Date: 2022/02/24 */ class PrintStatsClass { public: - void Draw(); + static void Draw(); static void Reset(); }; extern PrintStatsClass PrintStats; + +void Goto_PrintStats(); diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 9925f225e3..7fe5c22271 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -151,6 +151,7 @@ namespace Language_en { LSTR MSG_BED_LEVELING = _UxGT("Bed Leveling"); LSTR MSG_LEVEL_BED = _UxGT("Level Bed"); LSTR MSG_BED_TRAMMING = _UxGT("Bed Tramming"); + LSTR MSG_BED_TRAMMING_MANUAL = _UxGT("Manual Tramming"); LSTR MSG_BED_TRAMMING_RAISE = _UxGT("Adjust bed until the probe triggers."); LSTR MSG_BED_TRAMMING_IN_RANGE = _UxGT("Corners within tolerance. Bed trammed."); LSTR MSG_BED_TRAMMING_GOOD_POINTS = _UxGT("Good Points: "); @@ -402,7 +403,7 @@ namespace Language_en { LSTR MSG_ADVANCE_K_E = _UxGT("Advance K *"); LSTR MSG_CONTRAST = _UxGT("LCD Contrast"); LSTR MSG_BRIGHTNESS = _UxGT("LCD Brightness"); - LSTR MSG_LCD_BKL_TIMEOUT = _UxGT("LCD Sleep (s)"); + LSTR MSG_BRIGHTNESS_OFF = _UxGT("Turn Off LCD"); LSTR MSG_STORE_EEPROM = _UxGT("Store Settings"); LSTR MSG_LOAD_EEPROM = _UxGT("Load Settings"); LSTR MSG_RESTORE_DEFAULTS = _UxGT("Restore Defaults"); @@ -429,6 +430,8 @@ namespace Language_en { LSTR MSG_BUTTON_RESET = _UxGT("Reset"); LSTR MSG_BUTTON_IGNORE = _UxGT("Ignore"); LSTR MSG_BUTTON_CANCEL = _UxGT("Cancel"); + LSTR MSG_BUTTON_CONFIRM = _UxGT("Confirm"); + LSTR MSG_BUTTON_CONTINUE = _UxGT("Continue"); LSTR MSG_BUTTON_DONE = _UxGT("Done"); LSTR MSG_BUTTON_BACK = _UxGT("Back"); LSTR MSG_BUTTON_PROCEED = _UxGT("Proceed"); @@ -438,6 +441,7 @@ namespace Language_en { LSTR MSG_BUTTON_PAUSE = _UxGT("Pause"); LSTR MSG_BUTTON_RESUME = _UxGT("Resume"); LSTR MSG_BUTTON_ADVANCED = _UxGT("Advanced"); + LSTR MSG_BUTTON_SAVE = _UxGT("Save"); LSTR MSG_PAUSING = _UxGT("Pausing..."); LSTR MSG_PAUSE_PRINT = _UxGT("Pause Print"); LSTR MSG_ADVANCED_PAUSE = _UxGT("Advanced Pause"); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 810d0db527..f0677afd2d 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -48,7 +48,6 @@ MarlinUI ui; #if ENABLED(DWIN_CREALITY_LCD) #include "e3v2/creality/dwin.h" #elif ENABLED(DWIN_LCD_PROUI) - #include "fontutils.h" #include "e3v2/proui/dwin.h" #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) #include "e3v2/jyersui/dwin.h" @@ -1441,8 +1440,10 @@ void MarlinUI::init() { else if (print_job_timer.needsService(3)) msg = FPSTR(service3); #endif - else if (!no_welcome) - msg = GET_TEXT_F(WELCOME_MSG); + else if (!no_welcome) msg = GET_TEXT_F(WELCOME_MSG); + + else if (ENABLED(DWIN_LCD_PROUI)) + msg = F(""); else return; diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 36cbb14c5c..83eb332105 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -367,15 +367,6 @@ public: static void set_status(FSTR_P const fstr, const int8_t level=0); static void status_printf(const uint8_t level, FSTR_P const fmt, ...); - #if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI) - static void kill_screen(FSTR_P const lcd_error, FSTR_P const lcd_component); - #if DISABLED(LIGHTWEIGHT_UI) - static void draw_status_message(const bool blink); - #endif - #else - static void kill_screen(FSTR_P const, FSTR_P const) {} - #endif - #if HAS_DISPLAY static void update(); @@ -489,11 +480,16 @@ public: #endif static void draw_kill_screen(); + static void kill_screen(FSTR_P const lcd_error, FSTR_P const lcd_component); + #if DISABLED(LIGHTWEIGHT_UI) + static void draw_status_message(const bool blink); + #endif #else // No LCD static void update() {} static void return_to_status() {} + static void kill_screen(FSTR_P const, FSTR_P const) {} #endif diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index e0b2eccbbd..2b2e335565 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -1467,16 +1467,18 @@ void MarlinSettings::postprocess() { // #if ENABLED(DWIN_LCD_PROUI) { + _FIELD_TEST(dwin_data); char dwin_data[eeprom_data_size] = { 0 }; DWIN_StoreSettings(dwin_data); - _FIELD_TEST(dwin_data); EEPROM_WRITE(dwin_data); } - #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) + #endif + + #if ENABLED(DWIN_CREALITY_LCD_JYERSUI) { + _FIELD_TEST(dwin_settings); char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 }; CrealityDWIN.Save_Settings(dwin_settings); - _FIELD_TEST(dwin_settings); EEPROM_WRITE(dwin_settings); } #endif diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index a96ed3a651..f83104fe9c 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -497,6 +497,9 @@ void Stepper::enable_axis(const AxisEnum axis) { bool Stepper::disable_axis(const AxisEnum axis) { mark_axis_disabled(axis); + + TERN_(DWIN_LCD_PROUI, set_axis_untrusted(axis)); // MRISCOC workaround: https://github.com/MarlinFirmware/Marlin/issues/23095 + // If all the axes that share the enabled bit are disabled const bool can_disable = can_axis_disable(axis); if (can_disable) { diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 4adf968919..653b3179b0 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -821,7 +821,7 @@ volatile bool Temperature::raw_temps_ready = false; hal.idletask(); // Run UI update - TERN(HAS_DWIN_E3V2_BASIC, DWIN_Update(), ui.update()); + TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update()); } wait_for_heatup = false; diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h index 92d65babfa..5b48d7cadb 100644 --- a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h @@ -235,7 +235,7 @@ #define TFTGLCD_CS PA9 #endif - + #elif ENABLED(FYSETC_MINI_12864_2_1) #error "CAUTION! FYSETC_MINI_12864_2_1 / MKS_MINI_12864_V3 / BTT_MINI_12864_V1 requires wiring modifications. See 'pins_BTT_SKR_MINI_E3_common.h' for details. Comment out this line to continue." diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V24S1_301.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V24S1_301.h index 8616a8fb34..fb7198e57c 100644 --- a/Marlin/src/pins/stm32f1/pins_CREALITY_V24S1_301.h +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V24S1_301.h @@ -28,7 +28,11 @@ #include "env_validate.h" #if HAS_MULTI_HOTEND || E_STEPPERS > 1 - #error "Creality V4 only supports one hotend / E-stepper. Comment out this line to continue." + #error "Creality V24S1 only supports one hotend / E-stepper. Comment out this line to continue." +#endif + +#if BOTH(BLTOUCH, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #error "Disable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN when using BLTOUCH with Creality V24S1-301." #endif #define BOARD_INFO_NAME "Creality V24S1-301" @@ -44,7 +48,7 @@ // // Limit Switches // -#define Z_STOP_PIN PC14 +#define Z_STOP_PIN PA15 #ifndef Z_MIN_PROBE_PIN #define Z_MIN_PROBE_PIN PC14 // BLTouch IN @@ -63,4 +67,22 @@ #define HEATER_BED_PIN PA7 // HOT BED #define FAN1_PIN PC0 // extruder fan +// +// SD Card +// +#define ONBOARD_SPI_DEVICE 1 +#define ONBOARD_SD_CS_PIN PA4 // SDSS + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if HAS_CUTTER + //#define HEATER_0_PIN -1 + //#define HEATER_BED_PIN -1 + #define FAN_PIN -1 + #define SPINDLE_LASER_ENA_PIN PA0 // FET 1 + #define SPINDLE_LASER_PWM_PIN PA0 // Bed FET + #define SPINDLE_DIR_PIN PA0 // FET 4 +#endif + #include "pins_CREALITY_V4.h" diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 41ec44d4b7..724de8f82a 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -195,7 +195,7 @@ char *createFilename(char * const buffer, const dir_t &p) { } // -// Return 'true' if the item is something Marlin can read +// Return 'true' if the item is a folder, G-code file or Binary file // bool CardReader::is_visible_entity(const dir_t &p OPTARG(CUSTOM_FIRMWARE_UPLOAD, bool onlyBin/*=false*/)) { //uint8_t pn0 = p.name[0]; @@ -212,14 +212,15 @@ bool CardReader::is_visible_entity(const dir_t &p OPTARG(CUSTOM_FIRMWARE_UPLOAD, ) return false; flag.filenameIsDir = DIR_IS_SUBDIR(&p); // We know it's a File or Folder + setBinFlag(p.name[8] == 'B' && // List .bin files (a firmware file for flashing) + p.name[9] == 'I' && + p.name[10]== 'N'); return ( flag.filenameIsDir // All Directories are ok + || fileIsBinary() // BIN files are accepted || (!onlyBin && p.name[8] == 'G' && p.name[9] != '~') // Non-backup *.G* files are accepted - || ( onlyBin && p.name[8] == 'B' - && p.name[9] == 'I' - && p.name[10] == 'N') // BIN files are accepted ); } @@ -867,6 +868,7 @@ void CardReader::selectFileByIndex(const uint16_t nr) { strcpy(filename, sortshort[nr]); strcpy(longFilename, sortnames[nr]); flag.filenameIsDir = IS_DIR(nr); + setBinFlag(strcmp_P(strrchr(filename, '.'), PSTR(".BIN")) == 0); return; } #endif @@ -884,6 +886,7 @@ void CardReader::selectFileByName(const char * const match) { strcpy(filename, sortshort[nr]); strcpy(longFilename, sortnames[nr]); flag.filenameIsDir = IS_DIR(nr); + setBinFlag(strcmp_P(strrchr(filename, '.'), PSTR(".BIN")) == 0); return; } #endif diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 2b3dcd00fb..483ab81395 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -80,6 +80,9 @@ typedef struct { filenameIsDir:1, workDirIsRoot:1, abort_sd_printing:1 + #if DO_LIST_BIN_FILES + , filenameIsBin:1 + #endif #if ENABLED(BINARY_FILE_TRANSFER) , binary_mode:1 #endif @@ -218,6 +221,10 @@ public: static void removeJobRecoveryFile(); #endif + // Binary flag for the current file + static bool fileIsBinary() { return TERN0(DO_LIST_BIN_FILES, flag.filenameIsBin); } + static void setBinFlag(const bool bin) { TERN(DO_LIST_BIN_FILES, flag.filenameIsBin = bin, UNUSED(bin)); } + // Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...) static char* getWorkDirName() { workDir.getDosName(filename); return filename; } static SdFile& getWorkDir() { return workDir.isOpen() ? workDir : root; } diff --git a/buildroot/tests/STM32F103RE_creality b/buildroot/tests/STM32F103RE_creality index 6a15ec1221..6440c56792 100755 --- a/buildroot/tests/STM32F103RE_creality +++ b/buildroot/tests/STM32F103RE_creality @@ -15,8 +15,9 @@ exec_test $1 $2 "Ender 3 v2 with CrealityUI" "$3" use_example_configs "Creality/Ender-3 V2/CrealityV422/CrealityUI" opt_disable DWIN_CREALITY_LCD -opt_enable DWIN_LCD_PROUI BLTOUCH AUTO_BED_LEVELING_UBL Z_SAFE_HOMING INDIVIDUAL_AXIS_HOMING_SUBMENU LCD_SET_PROGRESS_MANUALLY STATUS_MESSAGE_SCROLLING BAUD_RATE_GCODE -exec_test $1 $2 "Ender 3 v2 with Pro UI" "$3" +opt_enable BLTOUCH AUTO_BED_LEVELING_UBL Z_SAFE_HOMING INDIVIDUAL_AXIS_HOMING_SUBMENU LCD_SET_PROGRESS_MANUALLY STATUS_MESSAGE_SCROLLING BAUD_RATE_GCODE \ + DWIN_LCD_PROUI SOUND_MENU_ITEM PRINTCOUNTER +exec_test $1 $2 "Ender 3 v2 with ProUI" "$3" use_example_configs "Creality/Ender-3 V2/CrealityV422/CrealityUI" opt_disable DWIN_CREALITY_LCD