diff --git a/Marlin/src/feature/bedlevel/abl/bbl.cpp b/Marlin/src/feature/bedlevel/abl/bbl.cpp index 14c4bd24bcf0..fec0add59db3 100644 --- a/Marlin/src/feature/bedlevel/abl/bbl.cpp +++ b/Marlin/src/feature/bedlevel/abl/bbl.cpp @@ -37,12 +37,12 @@ LevelingBilinear bedlevel; -xy_pos_t LevelingBilinear::grid_spacing, - LevelingBilinear::grid_start; xy_float_t LevelingBilinear::grid_factor; +xy_pos_t LevelingBilinear::grid_spacing, + LevelingBilinear::grid_start, + LevelingBilinear::cached_rel; +xy_int8_t LevelingBilinear::cached_g; bed_mesh_t LevelingBilinear::z_values; -xy_pos_t LevelingBilinear::cached_rel; -xy_int8_t LevelingBilinear::cached_g; /** * Extrapolate a single point from its neighbors @@ -106,9 +106,22 @@ void LevelingBilinear::reset() { } } +/** + * Set grid spacing and start position + */ void LevelingBilinear::set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _grid_start) { - grid_spacing = _grid_spacing; - grid_start = _grid_start; + #if ENABLED(PROUI_MESH_EDIT) + #define MESH_X_DIST (float((MESH_MAX_X) - (MESH_MIN_X)) / (GRID_MAX_CELLS_X)) + #define MESH_Y_DIST (float((MESH_MAX_Y) - (MESH_MIN_Y)) / (GRID_MAX_CELLS_Y)) + + grid_start.x = MESH_MIN_X; + grid_start.y = MESH_MIN_Y; + grid_spacing.x = MESH_X_DIST; + grid_spacing.y = MESH_Y_DIST; + #else + grid_spacing = _grid_spacing; + grid_start = _grid_start; + #endif grid_factor = grid_spacing.reciprocal(); } @@ -120,16 +133,16 @@ void LevelingBilinear::extrapolate_unprobed_bed_level() { #ifdef HALF_IN_X constexpr uint8_t ctrx2 = 0, xend = GRID_MAX_POINTS_X - 1; #else - constexpr uint8_t ctrx1 = (GRID_MAX_CELLS_X) / 2, // left-of-center - ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center + constexpr uint8_t ctrx1 = (GRID_MAX_CELLS_X) / 2, // left-of-center + ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center xend = ctrx1; #endif #ifdef HALF_IN_Y constexpr uint8_t ctry2 = 0, yend = GRID_MAX_POINTS_Y - 1; #else - constexpr uint8_t ctry1 = (GRID_MAX_CELLS_Y) / 2, // top-of-center - ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center + constexpr uint8_t ctry1 = (GRID_MAX_CELLS_Y) / 2, // top-of-center + ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center yend = ctry1; #endif diff --git a/Marlin/src/feature/bedlevel/bedlevel.cpp b/Marlin/src/feature/bedlevel/bedlevel.cpp index a76c6cdd269e..8a6e75986204 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.cpp +++ b/Marlin/src/feature/bedlevel/bedlevel.cpp @@ -46,8 +46,16 @@ #include "../../lcd/extui/ui_api.h" #endif +#if ALL(HAS_MESH, DWIN_LCD_PROUI) + #include "../../lcd/e3v2/proui/bedlevel_tools.h" +#endif + bool leveling_is_valid() { - return TERN1(HAS_MESH, bedlevel.mesh_is_valid()); + #if ALL(HAS_MESH, DWIN_LCD_PROUI) + return bedLevelTools.meshValidate(); + #else + return TERN1(HAS_MESH, bedlevel.mesh_is_valid()); + #endif } /** diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp index 14216ac4244e..def5bf999540 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp @@ -35,9 +35,9 @@ mesh_bed_leveling bedlevel; float mesh_bed_leveling::z_offset, - mesh_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], mesh_bed_leveling::index_to_xpos[GRID_MAX_POINTS_X], mesh_bed_leveling::index_to_ypos[GRID_MAX_POINTS_Y]; + bed_mesh_t mesh_bed_leveling::z_values; mesh_bed_leveling::mesh_bed_leveling() { for (uint8_t i = 0; i < GRID_MAX_POINTS_X; ++i) diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h index cb4f36cd59f2..226e680ccd92 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h @@ -70,7 +70,7 @@ class mesh_bed_leveling { } static float get_mesh_x(const uint8_t i) { return index_to_xpos[i]; } - static float get_mesh_y(const uint8_t i) { return index_to_ypos[i]; } + static float get_mesh_y(const uint8_t j) { return index_to_ypos[j]; } static uint8_t cell_index_x(const_float_t x) { int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST); diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp index 0228bd247ebd..24343a74bf89 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -64,23 +64,25 @@ void unified_bed_leveling::report_state() { int8_t unified_bed_leveling::storage_slot; -float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; - -#define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST)) - -const float -unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X, - _GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3), - _GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7), - _GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11), - _GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15) -), -unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y, - _GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3), - _GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7), - _GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11), - _GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15) -); +bed_mesh_t unified_bed_leveling::z_values; + +#if DISABLED(PROUI_MESH_EDIT) + #define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST)) + + const float + unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X, + _GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3), + _GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7), + _GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11), + _GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15) + ), + unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y, + _GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3), + _GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7), + _GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11), + _GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15) + ); +#endif volatile int16_t unified_bed_leveling::encoder_diff; @@ -166,7 +168,7 @@ static void serial_echo_column_labels(const uint8_t sp) { void unified_bed_leveling::display_map(const uint8_t map_type) { const bool was = gcode.set_autoreport_paused(true); - constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567] + constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567] twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4; @@ -208,6 +210,7 @@ void unified_bed_leveling::display_map(const uint8_t map_type) { const float f = z_values[i][j]; if (lcd) { // TODO: Display on Graphical LCD + TERN_(DWIN_LCD_PROUI, dwinMeshViewer()); } else if (isnan(f)) SERIAL_ECHO(human ? F(" . ") : F("NAN")); diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index b08cb812f83c..e212afcb1313 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -116,8 +116,11 @@ class unified_bed_leveling { static void set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values); static void set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values); #endif - static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X], - _mesh_index_to_ypos[GRID_MAX_POINTS_Y]; + + #if DISABLED(PROUI_MESH_EDIT) + static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X], + _mesh_index_to_ypos[GRID_MAX_POINTS_Y]; + #endif #if HAS_MARLINUI_MENU static bool lcd_map_control; @@ -287,12 +290,21 @@ class unified_bed_leveling { static constexpr float get_z_offset() { return 0.0f; } - static float get_mesh_x(const uint8_t i) { - return i < (GRID_MAX_POINTS_X) ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST); - } - static float get_mesh_y(const uint8_t i) { - return i < (GRID_MAX_POINTS_Y) ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST); - } + #if ENABLED(PROUI_MESH_EDIT) + static float get_mesh_x(const uint8_t i) { + return MESH_MIN_X + i * (MESH_X_DIST); + } + static float get_mesh_y(const uint8_t j) { + return MESH_MIN_Y + j * (MESH_Y_DIST); + } + #else + static float get_mesh_x(const uint8_t i) { + return i < (GRID_MAX_POINTS_X) ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST); + } + static float get_mesh_y(const uint8_t j) { + return j < (GRID_MAX_POINTS_Y) ? pgm_read_float(&_mesh_index_to_ypos[j]) : MESH_MIN_Y + j * (MESH_Y_DIST); + } + #endif #if UBL_SEGMENTED static bool line_to_destination_segmented(const_feedRate_t scaled_fr_mm_s); diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 4637bf87e828..48711df4a2db 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -44,6 +44,10 @@ #include "../../../lcd/extui/ui_api.h" #endif +#if ENABLED(DWIN_LCD_PROUI) + #include "../../../lcd/e3v2/proui/meshviewer.h" +#endif + #if ENABLED(UBL_HILBERT_CURVE) #include "../hilbert_curve.h" #endif @@ -306,7 +310,7 @@ void unified_bed_leveling::G29() { // Check for commands that require the printer to be homed if (may_move) { planner.synchronize(); - #if ALL(DWIN_LCD_PROUI, ZHOME_BEFORE_LEVELING) + #if ENABLED(DWIN_LCD_PROUI) save_ubl_active_state_and_disable(); gcode.process_subcommands_now(F("G28Z")); restore_ubl_active_state(false); // ...without telling ExtUI "done" @@ -767,6 +771,7 @@ void unified_bed_leveling::shift_mesh_height() { SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, "."); TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS))); TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout()); + TERN_(DWIN_LCD_PROUI, if (!hmiFlag.cancel_lev) { dwinRedrawScreen(); } else { break; }) #if HAS_MARLINUI_MENU if (ui.button_pressed()) { @@ -796,11 +801,14 @@ void unified_bed_leveling::shift_mesh_height() { ExtUI::onMeshUpdate(best.pos, ExtUI::G29_POINT_FINISH); ExtUI::onMeshUpdate(best.pos, measured_z); #endif + TERN_(DWIN_LCD_PROUI, meshViewer.drawMeshPoint(best.pos.x, best.pos.y, measured_z)); } SERIAL_FLUSH(); // Prevent host M105 buffer overrun. } while (best.pos.x >= 0 && --count); + TERN_(DWIN_LCD_PROUI, if (hmiFlag.cancel_lev) { goto EXIT_PROBE_MESH; }) + GRID_LOOP(x, y) if (z_values[x][y] == HUGE_VALF) z_values[x][y] = NAN; // Restore NAN for HUGE_VALF marks TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_FINISH)); @@ -810,13 +818,18 @@ void unified_bed_leveling::shift_mesh_height() { probe.stow(); TERN_(HAS_MARLINUI_MENU, ui.capture()); - probe.move_z_after_probing(); + TERN_(Z_AFTER_PROBING, probe.move_z_after_probing()); - do_blocking_move_to_xy( - constrain(nearby.x - probe.offset_xy.x, MESH_MIN_X, MESH_MAX_X), - constrain(nearby.y - probe.offset_xy.y, MESH_MIN_Y, MESH_MAX_Y) - ); + #if ENABLED(DWIN_LCD_PROUI) + bedlevel.smart_fill_mesh(); + #else + do_blocking_move_to_xy( + constrain(nearby.x - probe.offset_xy.x, MESH_MIN_X, MESH_MAX_X), + constrain(nearby.y - probe.offset_xy.y, MESH_MIN_Y, MESH_MAX_Y) + ); + #endif + TERN_(DWIN_LCD_PROUI, EXIT_PROBE_MESH:); restore_ubl_active_state(); } @@ -1176,9 +1189,9 @@ bool unified_bed_leveling::G29_parse_parameters() { } param.XY_seen.x = parser.seenval('X'); - float sx = param.XY_seen.x ? parser.value_float() : current_position.x; + float sx = param.XY_seen.x ? parser.value_float() : current_position.x - TERN0(HAS_BED_PROBE, probe.offset.x); param.XY_seen.y = parser.seenval('Y'); - float sy = param.XY_seen.y ? parser.value_float() : current_position.y; + float sy = param.XY_seen.y ? parser.value_float() : current_position.y - TERN0(HAS_BED_PROBE, probe.offset.y); if (param.XY_seen.x != param.XY_seen.y) { SERIAL_ECHOLNPGM("Both X & Y locations must be specified.\n"); @@ -1187,8 +1200,8 @@ bool unified_bed_leveling::G29_parse_parameters() { // If X or Y are not valid, use center of the bed values // (for UBL_HILBERT_CURVE default to lower-left corner instead) - if (!COORDINATE_OKAY(sx, X_MIN_BED, X_MAX_BED)) sx = TERN(UBL_HILBERT_CURVE, 0, X_CENTER); - if (!COORDINATE_OKAY(sy, Y_MIN_BED, Y_MAX_BED)) sy = TERN(UBL_HILBERT_CURVE, 0, Y_CENTER); + if (!COORDINATE_OKAY(sx, X_MIN_BED, X_MAX_BED)) sx = TERN(UBL_HILBERT_CURVE, 0, X_CENTER - TERN0(HAS_BED_PROBE, probe.offset.x)); + if (!COORDINATE_OKAY(sy, Y_MIN_BED, Y_MAX_BED)) sy = TERN(UBL_HILBERT_CURVE, 0, Y_CENTER - TERN0(HAS_BED_PROBE, probe.offset.y)); if (err_flag) return UBL_ERR; @@ -1508,7 +1521,7 @@ void unified_bed_leveling::smart_fill_mesh() { } probe.stow(); - probe.move_z_after_probing(); + TERN_(Z_AFTER_PROBING, probe.move_z_after_probing()); if (abort_flag) { SERIAL_ECHOLNPGM("?Error probing point. Aborting operation."); @@ -1594,7 +1607,7 @@ void unified_bed_leveling::smart_fill_mesh() { } } probe.stow(); - probe.move_z_after_probing(); + TERN_(Z_AFTER_PROBING, probe.move_z_after_probing()); if (abort_flag || finish_incremental_LSF(&lsf_results)) { SERIAL_ECHOLNPGM("Could not complete LSF!"); @@ -1762,8 +1775,8 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_EOL(); SERIAL_ECHOPGM("Y-Axis Mesh Points at: "); - for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; ++i) { - SERIAL_ECHO(p_float_t(LOGICAL_Y_POSITION(get_mesh_y(i)), 3), F(" ")); + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; ++j) { + SERIAL_ECHO(p_float_t(LOGICAL_Y_POSITION(get_mesh_y(j)), 3), F(" ")); serial_delay(25); } SERIAL_EOL(); diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 7c8289b7de80..ce38c82f205a 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -56,6 +56,10 @@ #include "../../../lcd/sovol_rts/sovol_rts.h" #endif +#if ENABLED(DWIN_LCD_PROUI) + #include "../../../lcd/e3v2/proui/meshviewer.h" +#endif + #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../../../core/debug_out.h" @@ -262,6 +266,11 @@ G29_TYPE GcodeSuite::G29() { // Send 'N' to force homing before G29 (internal only) if (parser.seen_test('N')) process_subcommands_now(TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR))); + #if ENABLED(DWIN_LCD_PROUI) + else { + process_subcommands_now(F("G28Z")); + } + #endif // Don't allow auto-leveling without homing first if (homing_needed_error()) G29_RETURN(false, false); @@ -671,6 +680,8 @@ G29_TYPE GcodeSuite::G29() { int8_t inStart, inStop, inInc; + TERN_(DWIN_LCD_PROUI, if (hmiFlag.cancel_lev) break); + if (zig) { // Zig away from origin inStart = 0; // Left or front inStop = PR_INNER_SIZE; // Right or back @@ -783,6 +794,7 @@ G29_TYPE GcodeSuite::G29() { const float z = abl.measured_z + abl.Z_offset; abl.z_values[abl.meshCount.x][abl.meshCount.y] = z; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z)); + TERN_(DWIN_LCD_PROUI, meshViewer.drawMeshPoint(abl.meshCount.x, abl.meshCount.y, z)); #if ENABLED(SOVOL_SV06_RTS) if (pt_index <= GRID_MAX_POINTS) rts.sendData(pt_index, AUTO_BED_LEVEL_ICON_VP); @@ -794,6 +806,7 @@ G29_TYPE GcodeSuite::G29() { abl.reenable = false; // Don't re-enable after modifying the mesh idle_no_sleep(); + TERN_(DWIN_LCD_PROUI, if (hmiFlag.cancel_lev) break); } // inner } // outer @@ -999,7 +1012,7 @@ G29_TYPE GcodeSuite::G29() { // Restore state after probing if (!faux) restore_feedrate_and_scaling(); - TERN_(HAS_BED_PROBE, probe.move_z_after_probing()); + TERN_(Z_AFTER_PROBING, probe.move_z_after_probing()); #ifdef EVENT_GCODE_AFTER_G29 if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Probe End Script: ", EVENT_GCODE_AFTER_G29); diff --git a/Marlin/src/inc/Conditionals-5-post.h b/Marlin/src/inc/Conditionals-5-post.h index 55d91c4b81dc..a1e8cd6f9970 100644 --- a/Marlin/src/inc/Conditionals-5-post.h +++ b/Marlin/src/inc/Conditionals-5-post.h @@ -529,7 +529,7 @@ #endif // Extender cable doesn't support SD_DETECT_PIN - #if ENABLED(NO_SD_DETECT) + #if ENABLED(NO_SD_DETECT) && DISABLED(DWIN_LCD_PROUI) #undef SD_DETECT_PIN #endif @@ -3349,7 +3349,7 @@ #ifndef MESH_MAX_Y #define MESH_MAX_Y _MESH_MAX_Y #endif -#else +#elif DISABLED(DWIN_LCD_PROUI) #undef MESH_MIN_X #undef MESH_MIN_Y #undef MESH_MAX_X diff --git a/Marlin/src/inc/MarlinConfigPre.h b/Marlin/src/inc/MarlinConfigPre.h index 6abd9e1ea690..bd737cd657fb 100644 --- a/Marlin/src/inc/MarlinConfigPre.h +++ b/Marlin/src/inc/MarlinConfigPre.h @@ -32,3 +32,8 @@ #ifndef __MARLIN_DEPS__ #include HAL_PATH(.., inc/Conditionals_adv.h) #endif + +// ProUI extra features +#if ENABLED(DWIN_LCD_PROUI) + #include "../lcd/e3v2/proui/dwin_defines.h" +#endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 9ec17b28089e..4ad8fe8d583a 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1524,13 +1524,15 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i static_assert(Z_AFTER_PROBING >= 0, "Probes require Z_AFTER_PROBING >= 0."); #endif - #if MULTIPLE_PROBING > 0 || EXTRA_PROBING > 0 - #if MULTIPLE_PROBING == 0 - #error "EXTRA_PROBING requires MULTIPLE_PROBING." - #elif MULTIPLE_PROBING < 2 - #error "MULTIPLE_PROBING must be 2 or more." - #elif MULTIPLE_PROBING <= EXTRA_PROBING - #error "EXTRA_PROBING must be less than MULTIPLE_PROBING." + #if DISABLED(DWIN_LCD_PROUI) + #if MULTIPLE_PROBING > 0 || EXTRA_PROBING > 0 + #if MULTIPLE_PROBING == 0 + #error "EXTRA_PROBING requires MULTIPLE_PROBING." + #elif MULTIPLE_PROBING < 2 + #error "MULTIPLE_PROBING must be 2 or more." + #elif MULTIPLE_PROBING <= EXTRA_PROBING + #error "EXTRA_PROBING must be less than MULTIPLE_PROBING." + #endif #endif #endif @@ -1584,7 +1586,6 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Bed Leveling Requirements */ - #if IS_SCARA && ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_UBL) #error "SCARA machines can only use AUTO_BED_LEVELING_BILINEAR or MESH_BED_LEVELING." #elif ENABLED(AUTO_BED_LEVELING_LINEAR) && !(WITHIN(GRID_MAX_POINTS_X, 2, 255) && WITHIN(GRID_MAX_POINTS_Y, 2, 255)) diff --git a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp index e4b6fb72a03d..1a6edb656531 100644 --- a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp +++ b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp @@ -190,6 +190,7 @@ float BedLevelTools::getMinValue() { // Return 'true' if mesh is good and within LCD limits bool BedLevelTools::meshValidate() { + TERN_(PROUI_MESH_EDIT, if ((MESH_MAX_X <= MESH_MIN_X) || (MESH_MAX_Y <= MESH_MIN_Y)) return false); GRID_LOOP(x, y) { const float z = bedlevel.z_values[x][y]; if (isnan(z) || !WITHIN(z, Z_OFFSET_MIN, Z_OFFSET_MAX)) return false; @@ -246,7 +247,7 @@ bool BedLevelTools::meshValidate() { } else { // has value MString<12> msg; - constexpr bool is_wide = (GRID_MAX_POINTS_X) >= TERN(TJC_DISPLAY, 8, 10); + const bool is_wide = (GRID_MAX_POINTS_X) >= TERN(TJC_DISPLAY, 8, 10); if (is_wide) msg.setf(F("%02i"), uint16_t(z * 100) % 100); else diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp index f4b5ba5339ac..3a100eeeee66 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp @@ -182,7 +182,7 @@ enum SelectItem : uint8_t { PAGE_PRINT = 0, PAGE_PREPARE, PAGE_CONTROL, - PAGE_ADVANCE, + PAGE_LEVEL, PAGE_COUNT, PRINT_SETUP = 0, @@ -218,6 +218,7 @@ Menu *prepareMenu = nullptr; Menu *moveMenu = nullptr; Menu *controlMenu = nullptr; Menu *advancedSettingsMenu = nullptr; +Menu *levelMenu = nullptr; #if HAS_HOME_OFFSET Menu *homeOffsetMenu = nullptr; #endif @@ -371,12 +372,12 @@ void ICON_Control() { } // -// Main Menu: "Advanced Settings" +// Main Menu: "Level" // -void ICON_AdvSettings() { +void ICON_Level() { constexpr frame_rect_t ico = { 145, 226, 110, 100 }; constexpr text_info_t txt = { 91, { 405, 447 }, 27, 15 }; - ICON_Button(select_page.now == PAGE_ADVANCE, ICON_Info_0, ico, txt, GET_TEXT_F(MSG_BUTTON_ADVANCED)); + ICON_Button(select_page.now == PAGE_LEVEL, ICON_Leveling_0, ico, txt, GET_TEXT_F(MSG_BUTTON_LEVEL)); } // @@ -477,9 +478,7 @@ void popupPauseOrStop() { } #endif -// // Draw status line -// void dwinDrawStatusLine(const char *text) { dwinDrawRectangle(1, hmiData.colorStatusBg, 0, STATUS_Y, DWIN_WIDTH, STATUS_Y + 20); if (text) DWINUI::drawCenteredString(hmiData.colorStatusTxt, STATUS_Y + 2, text); @@ -684,7 +683,7 @@ void drawMainMenu() { ICON_Print(); ICON_Prepare(); ICON_Control(); - ICON_AdvSettings(); + ICON_Level(); } void gotoMainMenu() { @@ -1135,7 +1134,7 @@ void hmiMainMenu() { case PAGE_PRINT: ICON_Print(); break; case PAGE_PREPARE: ICON_Print(); ICON_Prepare(); break; case PAGE_CONTROL: ICON_Prepare(); ICON_Control(); break; - case PAGE_ADVANCE: ICON_Control(); ICON_AdvSettings(); break; + case PAGE_LEVEL: ICON_Control(); ICON_Level(); break; } } } @@ -1144,8 +1143,8 @@ void hmiMainMenu() { switch (select_page.now) { 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_ADVANCE: ICON_AdvSettings(); break; + case PAGE_CONTROL: ICON_Control(); ICON_Level(); break; + case PAGE_LEVEL: ICON_Level(); break; } } } @@ -1160,7 +1159,7 @@ void hmiMainMenu() { break; case PAGE_PREPARE: drawPrepareMenu(); break; case PAGE_CONTROL: drawControlMenu(); break; - case PAGE_ADVANCE: drawAdvancedSettingsMenu(); break; + case PAGE_LEVEL: drawLevelMenu(); break; } } dwinUpdateLCD(); @@ -1250,7 +1249,7 @@ void drawMainArea() { case ID_SetPInt: case ID_SetIntNoDraw: case ID_SetFloat: - case ID_SetPFloat: ReDrawMenu(true); break; + case ID_SetPFloat: redrawMenu(true); break; default: break; } } @@ -1264,6 +1263,12 @@ void hmiWaitForUser() { if (!wait_for_user) { switch (checkkey) { case ID_PrintDone: select_page.reset(); gotoMainMenu(); break; + case ID_Leveling: + hmiFlag.cancel_lev = 1; + dwinDrawStatusLine("Canceling auto leveling..."); + dwinUpdateLCD(); + case ID_NothingToDo: + break; default: hmiReturnScreen(); break; } } @@ -1514,7 +1519,7 @@ void hmiReturnScreen() { void dwinHomingStart() { hmiFlag.home_flag = true; - hmiSaveProcessID(ID_Homing); + if (checkkey != ID_NothingToDo) { hmiSaveProcessID(ID_Homing); } title.showCaption(GET_TEXT_F(MSG_HOMING)); #if ANY(TJC_DISPLAY, DACAI_DISPLAY) dwinShowPopup(ICON_BLTouch, GET_TEXT_F(MSG_HOMING), GET_TEXT_F(MSG_PLEASE_WAIT)); @@ -1527,26 +1532,44 @@ void dwinHomingDone() { hmiFlag.home_flag = false; if (last_checkkey == ID_PrintDone) gotoPrintDone(); - else - hmiReturnScreen(); + else if (checkkey != ID_NothingToDo) { hmiReturnScreen(); } } -void dwinLevelingStart() { - #if HAS_BED_PROBE - hmiSaveProcessID(ID_Leveling); - title.showCaption(GET_TEXT_F(MSG_BED_LEVELING)); - dwinShowPopup(ICON_AutoLeveling, GET_TEXT_F(MSG_BED_LEVELING), GET_TEXT_F(MSG_PLEASE_WAIT)); +#if HAS_LEVELING + void dwinLevelingStart() { + #if HAS_BED_PROBE + hmiFlag.cancel_lev = 0; + hmiSaveProcessID(ID_Leveling); + title.showCaption(GET_TEXT_F(MSG_BED_LEVELING)); + #if ENABLED(AUTO_BED_LEVELING_UBL) + meshViewer.drawMeshGrid(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y); + DWINUI::drawButton(BTN_Cancel, 86, 305); + #else + dwinShowPopup(ICON_AutoLeveling, GET_TEXT_F(MSG_BED_LEVELING), GET_TEXT_F(MSG_PLEASE_WAIT)); + #endif + #elif ENABLED(MESH_BED_LEVELING) + drawManualMeshMenu(); + #endif #if ALL(AUTO_BED_LEVELING_UBL, PREHEAT_BEFORE_LEVELING) if (!DEBUGGING(DRYRUN)) probe.preheat_for_probing(LEVELING_NOZZLE_TEMP, hmiData.bedLevT); #endif - #elif ENABLED(MESH_BED_LEVELING) - drawManualMeshMenu(); - #endif -} + } -void dwinLevelingDone() { - TERN_(HAS_MESH, gotoMeshViewer(true)); -} + #if ALL(HAS_MESH, HAS_BED_PROBE) + void dwinLevelingDone() { + if (hmiFlag.cancel_lev) { + probe.stow(); + reset_bed_level(); + hmiReturnScreen(); + dwinUpdateLCD(); + ui.set_status(F("Mesh was cancelled")); + } + else { + gotoMeshViewer(true); + } + } + #endif +#endif // HAS_LEVELING #if HAS_MESH void dwinMeshUpdate(const int8_t cpos, const int8_t tpos, const_float_t zval) { @@ -1560,8 +1583,6 @@ void dwinLevelingDone() { #if PROUI_TUNING_GRAPH - #include "plot.h" - celsius_t _maxtemp, _target; void dwinDrawPIDMPCPopup() { constexpr frame_rect_t gfrm = { 30, 150, DWIN_WIDTH - 60, 160 }; @@ -1854,7 +1875,7 @@ void dwinSetColorDefaults() { hmiData.colorCoordinate = defColorCoordinate; } -static_assert(ExtUI::eeprom_data_size >= sizeof(hmi_data_t), "Insufficient space in EEPROM for UI parameters"); +static_assert(ExtUI::eeprom_data_size >= EXTUI_EEPROM_DATA_SIZE, "Insufficient space in EEPROM for UI parameters"); void dwinSetDataDefaults() { dwinSetColorDefaults(); @@ -1884,6 +1905,10 @@ void dwinSetDataDefaults() { applyLEDColor(); #endif TERN_(HAS_GCODE_PREVIEW, hmiData.enablePreview = true); + #if HAS_BED_PROBE + IF_DISABLED(BD_SENSOR, hmiData.multiple_probing = MULTIPLE_PROBING); + hmiData.zprobeFeed = DEF_Z_PROBE_FEEDRATE_SLOW; + #endif } void dwinCopySettingsTo(char * const buff) { @@ -1909,15 +1934,6 @@ void dwinCopySettingsFrom(const char * const buff) { } // Initialize or re-initialize the LCD -void MarlinUI::init_lcd() { - delay(750); // Wait to wakeup screen - const bool hs = dwinHandshake(); UNUSED(hs); - dwinFrameSetDir(1); - dwinJPGCacheTo1(Language_English); -} - -void MarlinUI::clear_lcd() {} - void dwinInitScreen() { dwinSetColorDefaults(); hmiInit(); // Draws boot screen @@ -1932,26 +1948,6 @@ void dwinInitScreen() { gotoMainMenu(); } -void MarlinUI::update() { - hmiSDCardUpdate(); // SD card update - eachMomentUpdate(); // Status update - dwinHandleScreen(); // Rotary encoder update -} - -#if HAS_LCD_BRIGHTNESS - void MarlinUI::_set_brightness() { dwinLCDBrightness(backlight ? brightness : 0); } -#endif - -void MarlinUI::kill_screen(FSTR_P const lcd_error, FSTR_P const) { - #if ANY(TJC_DISPLAY, DACAI_DISPLAY) - dwinDrawPopup(ICON_BLTouch, GET_TEXT_F(MSG_PRINTER_KILLED), lcd_error); - #else - dwinDrawPopup(ICON_Printer_0, GET_TEXT_F(MSG_PRINTER_KILLED), lcd_error); - #endif - DWINUI::drawCenteredString(hmiData.colorPopupTxt, 270, GET_TEXT_F(MSG_TURN_OFF)); - dwinUpdateLCD(); -} - void dwinRebootScreen() { dwinFrameClear(COLOR_BG_BLACK); dwinJPGShowAndCache(0); @@ -1971,103 +1967,38 @@ void dwinRedrawScreen() { dwinRedrawDash(); } -#if ENABLED(ADVANCED_PAUSE_FEATURE) - - void dwinPopupPause(FSTR_P const fmsg, uint8_t button/*=0*/) { - hmiSaveProcessID(button ? ID_WaitResponse : ID_NothingToDo); - dwinShowPopup(ICON_Pause_1, GET_TEXT_F(MSG_ADVANCED_PAUSE), fmsg, button); - } - - void drawPopupFilamentPurge() { - dwinDrawPopup(ICON_AutoLeveling, GET_TEXT_F(MSG_ADVANCED_PAUSE), GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE)); - DWINUI::drawButton(BTN_Purge, 26, 280); - DWINUI::drawButton(BTN_Continue, 146, 280); - drawSelectHighlight(true); - } - - void onClickFilamentPurge() { - if (hmiFlag.select_flag) - pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // "Purge More" button - else { - hmiSaveProcessID(ID_NothingToDo); - pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // "Continue" button - } - } +// +// MarlinUI functions +// +void MarlinUI::init_lcd() { + delay(750); // Wait to wakeup screen + const bool hs = dwinHandshake(); UNUSED(hs); + dwinFrameSetDir(1); + dwinJPGCacheTo1(Language_English); +} - void gotoFilamentPurge() { - pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; - gotoPopup(drawPopupFilamentPurge, onClickFilamentPurge); - } +void MarlinUI::clear_lcd() {} -#endif // ADVANCED_PAUSE_FEATURE +void MarlinUI::update() { + hmiSDCardUpdate(); // SD card update + eachMomentUpdate(); // Status update + dwinHandleScreen(); // Rotary encoder update +} -#if HAS_MESH - void dwinMeshViewer() { - if (!leveling_is_valid()) - dwinPopupContinue(ICON_Leveling_1, GET_TEXT_F(MSG_MESH_VIEWER), GET_TEXT_F(MSG_NO_VALID_MESH)); - else { - hmiSaveProcessID(ID_WaitResponse); - meshViewer.draw(); - } - } +#if HAS_LCD_BRIGHTNESS + void MarlinUI::_set_brightness() { dwinLCDBrightness(backlight ? brightness : 0); } #endif -#if HAS_LOCKSCREEN - - void dwinLockScreen() { - if (checkkey != ID_Locked) { - lockScreen.rprocess = checkkey; - checkkey = ID_Locked; - lockScreen.init(); - } - } - - void dwinUnLockScreen() { - if (checkkey == ID_Locked) { - checkkey = lockScreen.rprocess; - drawMainArea(); - } - } - - void hmiLockScreen() { - EncoderState encoder_diffState = get_encoder_state(); - if (encoder_diffState == ENCODER_DIFF_NO) return; - lockScreen.onEncoder(encoder_diffState); - if (lockScreen.isUnlocked()) dwinUnLockScreen(); - } - -#endif // HAS_LOCKSCREEN - -#if HAS_GCODE_PREVIEW - - void setPreview() { toggleCheckboxLine(hmiData.enablePreview); } - - void onClickConfirmToPrint() { - dwinResetStatusLine(); - if (hmiFlag.select_flag) { // Confirm - gotoMainMenu(); - return card.openAndPrintFile(card.filename); - } - else - hmiReturnScreen(); - } - -#endif // HAS_GCODE_PREVIEW - -void gotoConfirmToPrint() { - #if HAS_GCODE_PREVIEW - if (hmiData.enablePreview) return gotoPopup(preview.drawFromSD, onClickConfirmToPrint); +void MarlinUI::kill_screen(FSTR_P const lcd_error, FSTR_P const) { + #if ANY(TJC_DISPLAY, DACAI_DISPLAY) + dwinDrawPopup(ICON_BLTouch, GET_TEXT_F(MSG_PRINTER_KILLED), lcd_error); + #else + dwinDrawPopup(ICON_Printer_0, GET_TEXT_F(MSG_PRINTER_KILLED), lcd_error); #endif - card.openAndPrintFile(card.filename); // Direct print SD file + DWINUI::drawCenteredString(hmiData.colorPopupTxt, 270, GET_TEXT_F(MSG_TURN_OFF)); + dwinUpdateLCD(); } -#if HAS_ESDIAG - void drawEndStopDiag() { - hmiSaveProcessID(ID_ESDiagProcess); - esDiag.draw(); - } -#endif - //============================================================================= // MENU SUBSYSTEM //============================================================================= @@ -2117,10 +2048,6 @@ void gotoInfoMenu() { void disableMotors() { queue.inject(F("M84")); } -void autoLevel() { // Always reacquire the Z "home" position - queue.inject(F(TERN(AUTO_BED_LEVELING_UBL, "G29P1", "G29"))); -} - void autoHome() { queue.inject_P(G28_STR); } #if ENABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU) @@ -2170,9 +2097,20 @@ void autoHome() { queue.inject_P(G28_STR); } #endif // HAS_ZOFFSET_ITEM #if HAS_PREHEAT - #define _doPreheat(N) void DoPreheat##N() { ui.preheat_all(N-1); }\ - void DoPreheatHotend##N() { ui.preheat_hotend(N-1); } + + #if HAS_HOTEND + #define _DRAW_PREHEAT(N) void onDrawPreheat##N(MenuItem* menuitem, int8_t line) \ + { if (N == 1) { \ + if (hmiIsChinese()) menuitem->setFrame(1, 100, 89, 151, 101); } \ + else if (N == 2) { \ + if (hmiIsChinese()) menuitem->setFrame(1, 180, 89, 233, 100); } \ + onDrawMenuItem(menuitem, line); } + REPEAT_1(PREHEAT_COUNT, _DRAW_PREHEAT) + #endif + + #define _doPreheat(N) void DoPreheat##N() { ui.preheat_all(N-1); } REPEAT_1(PREHEAT_COUNT, _doPreheat) + #endif void doCoolDown() { thermalManager.cooldown(); } @@ -2180,7 +2118,7 @@ void doCoolDown() { thermalManager.cooldown(); } void setLanguage() { hmiToggleLanguage(); currentMenu = nullptr; // Invalidate menu to full redraw - drawPrepareMenu(); + drawControlMenu(); } bool enableLiveMove = false; @@ -2314,6 +2252,17 @@ void setMoveZ() { hmiValue.axis = Z_AXIS; setPFloatOnClick(Z_MIN_POS, Z_MAX_POS, void setHSMode() { toggleCheckboxLine(bltouch.high_speed_mode); } #endif + #if DISABLED(BD_SENSOR) + void applyProbeMultiple() { hmiData.multiple_probing = menuData.value; } + void setProbeMultiple() { setIntOnClick(0, 4, hmiData.multiple_probing, applyProbeMultiple); } + #endif + + void setProbeZSpeed() { setPIntOnClick(60, 1000); } + + void autoLevel() { + queue.inject(F(TERN(AUTO_BED_LEVELING_UBL, "G29P1", "G29"))); + } + #endif #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) @@ -2342,7 +2291,13 @@ void setMoveZ() { hmiValue.axis = Z_AXIS; setPFloatOnClick(Z_MIN_POS, Z_MAX_POS, void setExtMinT() { setPIntOnClick(MIN_ETEMP, MAX_ETEMP, applyExtMinT); } #endif -void setSpeed() { setPIntOnClick(SPEED_EDIT_MIN, SPEED_EDIT_MAX); } +#if HAS_FEEDRATE_EDIT + void setSpeed() { setPIntOnClick(SPEED_EDIT_MIN, SPEED_EDIT_MAX); } +#endif + +#if HAS_FLOW_EDIT + void setFlow() { setPIntOnClick(FLOW_EDIT_MIN, FLOW_EDIT_MAX, []{ planner.refresh_e_factor(0); }); } +#endif #if HAS_HOTEND void applyHotendTemp() { thermalManager.setTargetHotend(menuData.value, 0); } @@ -2368,6 +2323,32 @@ void setSpeed() { setPIntOnClick(SPEED_EDIT_MIN, SPEED_EDIT_MAX); } #if ENABLED(ADVANCED_PAUSE_FEATURE) + void dwinPopupPause(FSTR_P const fmsg, uint8_t button/*=0*/) { + hmiSaveProcessID(button ? ID_WaitResponse : ID_NothingToDo); + dwinShowPopup(ICON_Pause_1, GET_TEXT_F(MSG_ADVANCED_PAUSE), fmsg, button); + } + + void drawPopupFilamentPurge() { + dwinDrawPopup(ICON_AutoLeveling, GET_TEXT_F(MSG_ADVANCED_PAUSE), GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE)); + DWINUI::drawButton(BTN_Purge, 26, 280); + DWINUI::drawButton(BTN_Continue, 146, 280); + drawSelectHighlight(true); + } + + void onClickFilamentPurge() { + if (hmiFlag.select_flag) + pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // "Purge More" button + else { + hmiSaveProcessID(ID_NothingToDo); + pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // "Continue" button + } + } + + void gotoFilamentPurge() { + pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; + gotoPopup(drawPopupFilamentPurge, onClickFilamentPurge); + } + void changeFilament() { hmiSaveProcessID(ID_NothingToDo); queue.inject(F("M600 B2")); @@ -2387,52 +2368,184 @@ void setSpeed() { setPIntOnClick(SPEED_EDIT_MIN, SPEED_EDIT_MAX); } #endif // ADVANCED_PAUSE_FEATURE -void setFlow() { setPIntOnClick(FLOW_EDIT_MIN, FLOW_EDIT_MAX, []{ planner.refresh_e_factor(0); }); } - -// Bed Tramming - -#if ENABLED(LCD_BED_TRAMMING) +#if HAS_MESH - void tramXY(const uint8_t point, float &x, float &y) { - switch (point) { - case 0: - LCD_MESSAGE(MSG_TRAM_FL); - x = bed_tramming_inset_lfbr[0]; - y = bed_tramming_inset_lfbr[1]; - break; - case 1: - LCD_MESSAGE(MSG_TRAM_FR); - x = X_BED_SIZE - bed_tramming_inset_lfbr[2]; - y = bed_tramming_inset_lfbr[1]; - break; - case 2: - LCD_MESSAGE(MSG_TRAM_BR); - x = X_BED_SIZE - bed_tramming_inset_lfbr[2]; - y = Y_BED_SIZE - bed_tramming_inset_lfbr[3]; - break; - case 3: - LCD_MESSAGE(MSG_TRAM_BL); - x = bed_tramming_inset_lfbr[0]; - y = Y_BED_SIZE - bed_tramming_inset_lfbr[3]; - break; - #if ENABLED(BED_TRAMMING_INCLUDE_CENTER) - case 4: - LCD_MESSAGE(MSG_TRAM_C); - x = X_CENTER; - y = Y_CENTER; - break; - #endif + void dwinMeshViewer() { + if (!leveling_is_valid()) + dwinPopupContinue(ICON_Leveling_1, GET_TEXT_F(MSG_MESH_VIEWER), GET_TEXT_F(MSG_NO_VALID_MESH)); + else { + hmiSaveProcessID(ID_WaitResponse); + meshViewer.draw(); } } - #if HAS_BED_PROBE - - float tram(const uint8_t point) { - static bool inLev = false; - if (inLev) return NAN; + void applyMeshFadeHeight() { set_z_fade_height(planner.z_fade_height); } + void setMeshFadeHeight() { setPFloatOnClick(0, 100, 1, applyMeshFadeHeight); } - float xpos = 0, ypos = 0, zval = 0; - tramXY(point, xpos, ypos); + void setMeshActive() { + set_bed_leveling_enabled(!planner.leveling_active); + drawCheckboxLine(currentMenu->line(), planner.leveling_active); + dwinUpdateLCD(); + } + + #if ENABLED(PREHEAT_BEFORE_LEVELING) + void setBedLevT() { setPIntOnClick(MIN_BEDTEMP, MAX_BEDTEMP); } + #endif + + #if ENABLED(PROUI_MESH_EDIT) + void liveEditMesh() { ((MenuItemPtr*)editZValueItem)->value = &bedlevel.z_values[hmiValue.select ? bedLevelTools.mesh_x : menuData.value][hmiValue.select ? menuData.value : bedLevelTools.mesh_y]; editZValueItem->redraw(); } + void applyEditMeshX() { bedLevelTools.mesh_x = menuData.value; } + void applyEditMeshY() { bedLevelTools.mesh_y = menuData.value; } + void resetMesh() { bedLevelTools.meshReset(); LCD_MESSAGE(MSG_MESH_RESET); } + void setEditMeshX() { hmiValue.select = 0; setIntOnClick(0, GRID_MAX_POINTS_X - 1, bedLevelTools.mesh_x, applyEditMeshX, liveEditMesh); } + void setEditMeshY() { hmiValue.select = 1; setIntOnClick(0, GRID_MAX_POINTS_Y - 1, bedLevelTools.mesh_y, applyEditMeshY, liveEditMesh); } + void setEditZValue() { setPFloatOnClick(Z_OFFSET_MIN, Z_OFFSET_MAX, 3); } + void applyMeshInset() { TERN_(AUTO_BED_LEVELING_UBL, set_bed_leveling_enabled(false)); reset_bed_level(); redrawItem(); } + void setMeshInset() { setPFloatOnClick(X_MIN_POS, X_MAX_POS, UNITFDIGITS, applyMeshInset); } + #endif + +#endif // HAS_MESH + +#if HAS_LOCKSCREEN + + void dwinLockScreen() { + if (checkkey != ID_Locked) { + lockScreen.rprocess = checkkey; + checkkey = ID_Locked; + lockScreen.init(); + } + } + + void dwinUnLockScreen() { + if (checkkey == ID_Locked) { + checkkey = lockScreen.rprocess; + drawMainArea(); + } + } + + void hmiLockScreen() { + EncoderState encoder_diffState = get_encoder_state(); + if (encoder_diffState == ENCODER_DIFF_NO) return; + lockScreen.onEncoder(encoder_diffState); + if (lockScreen.isUnlocked()) dwinUnLockScreen(); + } + +#endif // HAS_LOCKSCREEN + +#if HAS_GCODE_PREVIEW + + void setPreview() { toggleCheckboxLine(hmiData.enablePreview); } + + void onClickConfirmToPrint() { + dwinResetStatusLine(); + if (hmiFlag.select_flag) { // Confirm + gotoMainMenu(); + return card.openAndPrintFile(card.filename); + } + else + hmiReturnScreen(); + } + +#endif // HAS_GCODE_PREVIEW + +void gotoConfirmToPrint() { + #if HAS_GCODE_PREVIEW + if (hmiData.enablePreview) return gotoPopup(preview.drawFromSD, onClickConfirmToPrint); + #endif + card.openAndPrintFile(card.filename); // Direct print SD file +} + +#if HAS_ESDIAG + void drawEndStopDiag() { + hmiSaveProcessID(ID_ESDiagProcess); + esDiag.draw(); + } +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + + void applyUBLSlot() { bedlevel.storage_slot = menuData.value; } + void setUBLSlot() { setIntOnClick(0, settings.calc_num_meshes() - 1, bedlevel.storage_slot, applyUBLSlot); } + void onDrawUBLSlot(MenuItem* menuitem, int8_t line) { + NOLESS(bedlevel.storage_slot, 0); + onDrawIntMenu(menuitem, line, bedlevel.storage_slot); + } + + void applyUBLTiltGrid() { bedLevelTools.tilt_grid = menuData.value; } + void setUBLTiltGrid() { setIntOnClick(1, 3, bedLevelTools.tilt_grid, applyUBLTiltGrid); } + + void ublMeshTilt() { + NOLESS(bedlevel.storage_slot, 0); + if (bedLevelTools.tilt_grid > 1) + gcode.process_subcommands_now(TS(F("G29J"), bedLevelTools.tilt_grid)); + else + gcode.process_subcommands_now(F("G29J")); + LCD_MESSAGE(MSG_UBL_MESH_TILTED); + } + + void ublSmartFillMesh() { + for (uint8_t x = 0; x < GRID_MAX_POINTS_Y; ++x) bedlevel.smart_fill_mesh(); + LCD_MESSAGE(MSG_UBL_MESH_FILLED); + } + + void ublMeshSave() { + NOLESS(bedlevel.storage_slot, 0); + settings.store_mesh(bedlevel.storage_slot); + ui.status_printf(0, GET_TEXT_F(MSG_MESH_SAVED), bedlevel.storage_slot); + DONE_BUZZ(true); + } + + void ublMeshLoad() { + NOLESS(bedlevel.storage_slot, 0); + settings.load_mesh(bedlevel.storage_slot); + } + +#endif // AUTO_BED_LEVELING_UBL + +// Bed Tramming + +#if ENABLED(LCD_BED_TRAMMING) + + void tramXY(const uint8_t point, float &x, float &y) { + switch (point) { + case 0: + LCD_MESSAGE(MSG_TRAM_FL); + x = bed_tramming_inset_lfbr[0]; + y = bed_tramming_inset_lfbr[1]; + break; + case 1: + LCD_MESSAGE(MSG_TRAM_FR); + x = X_BED_SIZE - bed_tramming_inset_lfbr[2]; + y = bed_tramming_inset_lfbr[1]; + break; + case 2: + LCD_MESSAGE(MSG_TRAM_BR); + x = X_BED_SIZE - bed_tramming_inset_lfbr[2]; + y = Y_BED_SIZE - bed_tramming_inset_lfbr[3]; + break; + case 3: + LCD_MESSAGE(MSG_TRAM_BL); + x = bed_tramming_inset_lfbr[0]; + y = Y_BED_SIZE - bed_tramming_inset_lfbr[3]; + break; + #if ENABLED(BED_TRAMMING_INCLUDE_CENTER) + case 4: + LCD_MESSAGE(MSG_TRAM_C); + x = X_CENTER; + y = Y_CENTER; + break; + #endif + } + } + + #if HAS_BED_PROBE + + float tram(const uint8_t point) { + static bool inLev = false; + if (inLev) return NAN; + + float xpos = 0, ypos = 0, zval = 0; + tramXY(point, xpos, ypos); if (hmiData.fullManualTramming) { queue.inject(MString<100>( @@ -2440,18 +2553,20 @@ void setFlow() { setPIntOnClick(FLOW_EDIT_MIN, FLOW_EDIT_MAX, []{ planner.refres )); } else { - // AUTO_BED_LEVELING_BILINEAR does not define MESH_INSET - #ifndef MESH_MIN_X - #define MESH_MIN_X (_MAX(X_MIN_BED + (PROBING_MARGIN_LEFT), X_MIN_POS)) - #endif - #ifndef MESH_MIN_Y - #define MESH_MIN_Y (_MAX(Y_MIN_BED + (PROBING_MARGIN_FRONT), Y_MIN_POS)) - #endif - #ifndef MESH_MAX_X - #define MESH_MAX_X (_MIN(X_MAX_BED - (PROBING_MARGIN_RIGHT), X_MAX_POS)) - #endif - #ifndef MESH_MAX_Y - #define MESH_MAX_Y (_MIN(Y_MAX_BED - (PROBING_MARGIN_BACK), Y_MAX_POS)) + #if DISABLED(PROUI_MESH_EDIT) + // AUTO_BED_LEVELING_BILINEAR does not define MESH_INSET + #ifndef MESH_MIN_X + #define MESH_MIN_X (_MAX(X_MIN_BED + (PROBING_MARGIN_LEFT), X_MIN_POS)) + #endif + #ifndef MESH_MIN_Y + #define MESH_MIN_Y (_MAX(Y_MIN_BED + (PROBING_MARGIN_FRONT), Y_MIN_POS)) + #endif + #ifndef MESH_MAX_X + #define MESH_MAX_X (_MIN(X_MAX_BED - (PROBING_MARGIN_RIGHT), X_MAX_POS)) + #endif + #ifndef MESH_MAX_Y + #define MESH_MAX_Y (_MIN(Y_MAX_BED - (PROBING_MARGIN_BACK), Y_MAX_POS)) + #endif #endif LIMIT(xpos, MESH_MIN_X, MESH_MAX_X); @@ -2685,7 +2800,7 @@ void applyMaxAccel() { planner.set_max_acceleration(hmiValue.axis, menuData.valu #endif #if ENABLED(FWRETRACT) - void returnFWRetractMenu() { (previousMenu == filSetMenu) ? drawFilSetMenu() : drawTuneMenu(); } + void returnFWRetractMenu() { (previousMenu == filamentMenu) ? drawFilamentManMenu() : drawTuneMenu(); } void setRetractLength() { setPFloatOnClick( 0, 10, UNITFDIGITS); } void setRetractSpeed() { setPFloatOnClick( 1, 90, UNITFDIGITS); } void setZRaise() { setPFloatOnClick( 0, 2, 2); } @@ -2778,19 +2893,6 @@ void onDrawAutoHome(MenuItem* menuitem, int8_t line) { #endif #endif -#if HAS_HOTEND - void onDrawPreheat1(MenuItem* menuitem, int8_t line) { - if (hmiIsChinese()) menuitem->setFrame(1, 100, 89, 151, 101); - onDrawMenuItem(menuitem, line); - } - #if PREHEAT_COUNT > 1 - void onDrawPreheat2(MenuItem* menuitem, int8_t line) { - if (hmiIsChinese()) menuitem->setFrame(1, 180, 89, 233, 100); - onDrawMenuItem(menuitem, line); - } - #endif -#endif - #if HAS_PREHEAT void onDrawCooldown(MenuItem* menuitem, int8_t line) { if (hmiIsChinese()) menuitem->setFrame(1, 1, 104, 56, 117); @@ -3097,24 +3199,16 @@ frame_rect_t selrect(frame_rect_t) { void drawPrepareMenu() { checkkey = ID_Menu; - if (SET_MENU_R(prepareMenu, selrect({133, 1, 28, 13}), MSG_PREPARE, 12 + PREHEAT_COUNT)) { + if (SET_MENU_R(prepareMenu, selrect({133, 1, 28, 13}), MSG_PREPARE, 11)) { BACK_ITEM(gotoMainMenu); - MENU_ITEM(ICON_FilMan, MSG_FILAMENT_MAN, onDrawSubMenu, drawFilamentManMenu); - MENU_ITEM(ICON_Axis, MSG_MOVE_AXIS, onDrawMoveSubMenu, drawMoveMenu); - #if ENABLED(LCD_BED_TRAMMING) - MENU_ITEM(ICON_Tram, MSG_BED_TRAMMING, onDrawSubMenu, drawTrammingMenu); - #endif - MENU_ITEM(ICON_CloseMotor, MSG_DISABLE_STEPPERS, onDrawDisableMotors, disableMotors); #if ENABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU) MENU_ITEM(ICON_Homing, MSG_HOMING, onDrawSubMenu, drawHomingMenu); #else MENU_ITEM(ICON_Homing, MSG_AUTO_HOME, onDrawAutoHome, autoHome); #endif - #if ENABLED(MESH_BED_LEVELING) - MENU_ITEM(ICON_ManualMesh, MSG_MANUAL_MESH, onDrawSubMenu, drawManualMeshMenu); - #elif HAS_BED_PROBE - MENU_ITEM(ICON_Level, MSG_AUTO_MESH, onDrawMenuItem, autoLevel); - #endif + MENU_ITEM(ICON_Axis, MSG_MOVE_AXIS, onDrawMoveSubMenu, drawMoveMenu); + MENU_ITEM(ICON_CloseMotor, MSG_DISABLE_STEPPERS, onDrawDisableMotors, disableMotors); + MENU_ITEM(ICON_FilMan, MSG_FILAMENT_MAN, onDrawSubMenu, drawFilamentManMenu); #if HAS_ZOFFSET_ITEM #if HAS_BED_PROBE MENU_ITEM(ICON_SetZOffset, MSG_PROBE_WIZARD, onDrawSubMenu, drawZOffsetWizMenu); @@ -3122,16 +3216,21 @@ void drawPrepareMenu() { EDIT_ITEM(ICON_Zoffset, MSG_HOME_OFFSET_Z, onDrawPFloat2Menu, setZOffset, &BABY_Z_VAR); #endif #endif + #if ENABLED(LCD_BED_TRAMMING) + MENU_ITEM(ICON_Tram, MSG_BED_TRAMMING, onDrawSubMenu, drawTrammingMenu); + #endif #if HAS_PREHEAT - #define _ITEM_PREHEAT(N) MENU_ITEM(ICON_Preheat##N, MSG_PREHEAT_##N, onDrawMenuItem, DoPreheat##N); - REPEAT_1(PREHEAT_COUNT, _ITEM_PREHEAT) + #if PREHEAT_COUNT > 1 + MENU_ITEM(ICON_SetEndTemp, MSG_PREHEAT_HOTEND, onDrawSubMenu, drawPreheatHotendMenu); + #else + MENU_ITEM(ICON_Preheat1, MSG_PREHEAT_1, onDrawPreheat1, DoPreheat1); + #endif #endif MENU_ITEM(ICON_Cool, MSG_COOLDOWN, onDrawCooldown, doCoolDown); #if ALL(PROUI_TUNING_GRAPH, PROUI_ITEM_PLOT) MENU_ITEM(ICON_PIDNozzle, MSG_HOTEND_TEMP_GRAPH, onDrawMenuItem, drawHPlot); MENU_ITEM(ICON_PIDBed, MSG_BED_TEMP_GRAPH, onDrawMenuItem, drawBPlot); #endif - MENU_ITEM(ICON_Language, MSG_UI_LANGUAGE, onDrawLanguage, setLanguage); } ui.reset_status(true); updateMenu(prepareMenu); @@ -3164,21 +3263,18 @@ void drawPrepareMenu() { void drawControlMenu() { checkkey = ID_Menu; - if (SET_MENU_R(controlMenu, selrect({103, 1, 28, 14}), MSG_CONTROL, 11)) { + if (SET_MENU_R(controlMenu, selrect({103, 1, 28, 14}), MSG_CONTROL, 12)) { BACK_ITEM(gotoMainMenu); MENU_ITEM(ICON_Temperature, MSG_TEMPERATURE, onDrawTempSubMenu, drawTemperatureMenu); MENU_ITEM(ICON_Motion, MSG_MOTION, onDrawMotionSubMenu, drawMotionMenu); - #if ENABLED(CASE_LIGHT_MENU) - #if CASELIGHT_USES_BRIGHTNESS - enableLiveCaseLightBrightness = true; // Allow live update of brightness in control menu - MENU_ITEM(ICON_CaseLight, MSG_CASE_LIGHT, onDrawSubMenu, drawCaseLightMenu); - #else - EDIT_ITEM(ICON_CaseLight, MSG_CASE_LIGHT, onDrawChkbMenu, setCaseLight, &caselight.on); - #endif + #if HAS_CUSTOM_COLORS + MENU_ITEM(ICON_Scolor, MSG_COLORS_SELECT, onDrawSubMenu, drawSelectColorsMenu); #endif - #if ENABLED(LED_CONTROL_MENU) - enableLiveLedColor = true; // Allow live update of color in control menu - MENU_ITEM(ICON_LedControl, MSG_LED_CONTROL, onDrawSubMenu, drawLedControlMenu); + #if HAS_ESDIAG + MENU_ITEM_F(ICON_esDiag, "End-stops diag.", onDrawSubMenu, drawEndStopDiag); + #endif + #if HAS_LOCKSCREEN + MENU_ITEM(ICON_Lock, MSG_LOCKSCREEN, onDrawMenuItem, dwinLockScreen); #endif #if ENABLED(EEPROM_SETTINGS) MENU_ITEM(ICON_WriteEEPROM, MSG_STORE_EEPROM, onDrawWriteEeprom, writeEEPROM); @@ -3186,7 +3282,9 @@ void drawControlMenu() { MENU_ITEM(ICON_ResetEEPROM, MSG_RESTORE_DEFAULTS, onDrawResetEeprom, resetEEPROM); #endif MENU_ITEM(ICON_Reboot, MSG_RESET_PRINTER, onDrawMenuItem, rebootPrinter); + MENU_ITEM(ICON_AdvSet, MSG_ADVANCED_SETTINGS, onDrawSubMenu, drawAdvancedSettingsMenu); MENU_ITEM(ICON_Info, MSG_INFO_SCREEN, onDrawInfoSubMenu, gotoInfoMenu); + MENU_ITEM(ICON_Language, MSG_UI_LANGUAGE, onDrawLanguage, setLanguage); } ui.reset_status(true); updateMenu(controlMenu); @@ -3194,8 +3292,8 @@ void drawControlMenu() { void drawAdvancedSettingsMenu() { checkkey = ID_Menu; - if (SET_MENU(advancedSettingsMenu, MSG_ADVANCED_SETTINGS, 24)) { - BACK_ITEM(gotoMainMenu); + if (SET_MENU(advancedSettingsMenu, MSG_ADVANCED_SETTINGS, 21)) { + BACK_ITEM(drawControlMenu); #if ENABLED(EEPROM_SETTINGS) MENU_ITEM(ICON_WriteEEPROM, MSG_STORE_EEPROM, onDrawMenuItem, writeEEPROM); #endif @@ -3208,7 +3306,6 @@ void drawAdvancedSettingsMenu() { #if HAS_HOME_OFFSET MENU_ITEM(ICON_HomeOffset, MSG_SET_HOME_OFFSETS, onDrawSubMenu, drawHomeOffsetMenu); #endif - MENU_ITEM(ICON_FilSet, MSG_FILAMENT_SET, onDrawSubMenu, drawFilSetMenu); #if ENABLED(PIDTEMP) && ANY(PID_AUTOTUNE_MENU, PID_EDIT_MENU) MENU_ITEM_F(ICON_PIDNozzle, STR_HOTEND_PID " Settings", onDrawSubMenu, drawHotendPIDMenu); #endif @@ -3218,19 +3315,10 @@ void drawAdvancedSettingsMenu() { #if ENABLED(PIDTEMPBED) && ANY(PID_AUTOTUNE_MENU, PID_EDIT_MENU) MENU_ITEM_F(ICON_PIDBed, STR_BED_PID " Settings", onDrawSubMenu, drawBedPIDMenu); #endif - #if HAS_TRINAMIC_CONFIG - MENU_ITEM(ICON_TMCSet, MSG_TMC_DRIVERS, onDrawSubMenu, drawTrinamicConfigMenu); - #endif - #if HAS_ESDIAG - MENU_ITEM_F(ICON_esDiag, "End-stops diag.", onDrawSubMenu, drawEndStopDiag); - #endif #if ENABLED(PRINTCOUNTER) MENU_ITEM(ICON_PrintStats, MSG_INFO_STATS_MENU, onDrawSubMenu, gotoPrintStats); MENU_ITEM(ICON_PrintStatsReset, MSG_INFO_PRINT_COUNT_RESET, onDrawSubMenu, printStatsReset); #endif - #if HAS_LOCKSCREEN - MENU_ITEM(ICON_Lock, MSG_LOCKSCREEN, onDrawMenuItem, dwinLockScreen); - #endif #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) EDIT_ITEM(ICON_RemainTime, MSG_SCREEN_TIMEOUT, onDrawPIntMenu, setTimer, &ui.backlight_timeout_minutes); #endif @@ -3254,8 +3342,17 @@ void drawAdvancedSettingsMenu() { EDIT_ITEM(ICON_Brightness, MSG_BRIGHTNESS, onDrawPInt8Menu, setBrightness, &ui.brightness); MENU_ITEM(ICON_Box, MSG_BRIGHTNESS_OFF, onDrawMenuItem, turnOffBacklight); #endif - #if HAS_CUSTOM_COLORS - MENU_ITEM(ICON_Scolor, MSG_COLORS_SELECT, onDrawSubMenu, drawSelectColorsMenu); + #if ENABLED(CASE_LIGHT_MENU) + #if CASELIGHT_USES_BRIGHTNESS + enableLiveCaseLightBrightness = true; // Allow live update of brightness in control menu + MENU_ITEM(ICON_CaseLight, MSG_CASE_LIGHT, onDrawSubMenu, drawCaseLightMenu); + #else + EDIT_ITEM(ICON_CaseLight, MSG_CASE_LIGHT, onDrawChkbMenu, setCaseLight, &caselight.on); + #endif + #endif + #if ENABLED(LED_CONTROL_MENU) + enableLiveLedColor = true; // Allow live update of color in control menu + MENU_ITEM(ICON_LedControl, MSG_LED_CONTROL, onDrawSubMenu, drawLedControlMenu); #endif } ui.reset_status(true); @@ -3290,7 +3387,7 @@ void drawMoveMenu() { void drawHomeOffsetMenu() { checkkey = ID_Menu; if (SET_MENU(homeOffsetMenu, MSG_SET_HOME_OFFSETS, 4)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawLevelMenu); #if HAS_X_AXIS EDIT_ITEM(ICON_HomeOffsetX, MSG_HOME_OFFSET_X, onDrawPFloatMenu, setHomeOffsetX, &home_offset.x); #endif @@ -3311,7 +3408,7 @@ void drawMoveMenu() { void drawProbeSetMenu() { checkkey = ID_Menu; if (SET_MENU(probeSettingsMenu, MSG_ZPROBE_SETTINGS, 9)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawLevelMenu); #if HAS_X_AXIS EDIT_ITEM(ICON_ProbeOffsetX, MSG_ZPROBE_XOFFSET, onDrawPFloatMenu, setProbeOffsetX, &probe.offset.x); #endif @@ -3321,6 +3418,8 @@ void drawMoveMenu() { #if HAS_Z_AXIS EDIT_ITEM(ICON_ProbeOffsetZ, MSG_ZPROBE_ZOFFSET, onDrawPFloat2Menu, setProbeOffsetZ, &probe.offset.z); #endif + IF_DISABLED(BD_SENSOR, EDIT_ITEM(ICON_Cancel, MSG_ZPROBE_MULTIPLE, onDrawPInt8Menu, setProbeMultiple, &hmiData.multiple_probing)); + EDIT_ITEM(ICON_ProbeZSpeed, MSG_Z_FEED_RATE, onDrawPIntMenu, setProbeZSpeed, &hmiData.zprobeFeed); #if ENABLED(BLTOUCH) MENU_ITEM(ICON_ProbeStow, MSG_MANUAL_STOW, onDrawMenuItem, probeStow); MENU_ITEM(ICON_ProbeDeploy, MSG_MANUAL_DEPLOY, onDrawMenuItem, probeDeploy); @@ -3338,36 +3437,12 @@ void drawMoveMenu() { #endif // HAS_BED_PROBE -void drawFilSetMenu() { - checkkey = ID_Menu; - if (SET_MENU(filSetMenu, MSG_FILAMENT_SET, 9)) { - BACK_ITEM(drawAdvancedSettingsMenu); - #if HAS_FILAMENT_SENSOR - EDIT_ITEM(ICON_Runout, MSG_RUNOUT_SENSOR, onDrawChkbMenu, setRunoutEnable, &runout.enabled); - #endif - #if HAS_FILAMENT_RUNOUT_DISTANCE - EDIT_ITEM(ICON_Runout, MSG_RUNOUT_DISTANCE_MM, onDrawPFloatMenu, setRunoutDistance, &runout.runout_distance()); - #endif - #if ENABLED(PREVENT_COLD_EXTRUSION) - EDIT_ITEM(ICON_ExtrudeMinT, MSG_EXTRUDER_MIN_TEMP, onDrawPIntMenu, setExtMinT, &hmiData.extMinT); - #endif - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) - EDIT_ITEM(ICON_FilLoad, MSG_FILAMENT_LOAD, onDrawPFloatMenu, setFilLoad, &fc_settings[0].load_length); - EDIT_ITEM(ICON_FilUnload, MSG_FILAMENT_UNLOAD, onDrawPFloatMenu, setFilUnload, &fc_settings[0].unload_length); - #endif - #if ENABLED(FWRETRACT) - MENU_ITEM(ICON_FWRetract, MSG_FWRETRACT, onDrawSubMenu, drawFWRetractMenu); - #endif - } - updateMenu(filSetMenu); -} - #if ALL(CASE_LIGHT_MENU, CASELIGHT_USES_BRIGHTNESS) void drawCaseLightMenu() { checkkey = ID_Menu; if (SET_MENU(caseLightMenu, MSG_CASE_LIGHT, 3)) { - BACK_ITEM(drawControlMenu); + BACK_ITEM(drawAdvancedSettingsMenu); EDIT_ITEM(ICON_CaseLight, MSG_CASE_LIGHT, onDrawChkbMenu, setCaseLight, &caselight.on); EDIT_ITEM(ICON_Brightness, MSG_CASE_LIGHT_BRIGHTNESS, onDrawPInt8Menu, setCaseLightBrightness, &caselight.brightness); } @@ -3381,7 +3456,7 @@ void drawFilSetMenu() { void drawLedControlMenu() { checkkey = ID_Menu; if (SET_MENU(ledControlMenu, MSG_LED_CONTROL, 10)) { - BACK_ITEM((currentMenu == tuneMenu) ? drawTuneMenu : drawControlMenu); + BACK_ITEM((currentMenu == tuneMenu) ? drawTuneMenu : drawAdvancedSettingsMenu); #if !ALL(CASE_LIGHT_MENU, CASE_LIGHT_USE_NEOPIXEL) EDIT_ITEM(ICON_LedControl, MSG_LIGHTS, onDrawChkbMenu, setLedStatus, &leds.lights_on); #endif @@ -3414,7 +3489,12 @@ void drawTuneMenu() { checkkey = ID_Menu; if (SET_MENU_R(tuneMenu, selrect({73, 2, 28, 12}), MSG_TUNE, 20)) { BACK_ITEM(gotoPrintProcess); - EDIT_ITEM(ICON_Speed, MSG_SPEED, onDrawSpeedItem, setSpeed, &feedrate_percentage); + #if HAS_FEEDRATE_EDIT + EDIT_ITEM(ICON_Speed, MSG_SPEED, onDrawSpeedItem, setSpeed, &feedrate_percentage); + #endif + #if HAS_FLOW_EDIT + EDIT_ITEM(ICON_Flow, MSG_FLOW, onDrawPIntMenu, setFlow, &planner.flow_percentage[0]); + #endif #if HAS_HOTEND hotendTargetItem = EDIT_ITEM(ICON_HotendTemp, MSG_UBL_SET_TEMP_HOTEND, onDrawHotendTemp, setHotendTemp, &thermalManager.temp_hotend[0].target); #endif @@ -3429,7 +3509,6 @@ void drawTuneMenu() { #elif ALL(HAS_ZOFFSET_ITEM, MESH_BED_LEVELING, BABYSTEPPING) EDIT_ITEM(ICON_Zoffset, MSG_HOME_OFFSET_Z, onDrawPFloat2Menu, setZOffset, &BABY_Z_VAR); #endif - EDIT_ITEM(ICON_Flow, MSG_FLOW, onDrawPIntMenu, setFlow, &planner.flow_percentage[0]); #if ENABLED(ADVANCED_PAUSE_FEATURE) MENU_ITEM(ICON_FilMan, MSG_FILAMENTCHANGE, onDrawMenuItem, changeFilament); #endif @@ -3550,7 +3629,7 @@ void drawTuneMenu() { void drawTrinamicConfigMenu() { checkkey = ID_Menu; if (SET_MENU(trinamicConfigMenu, MSG_TMC_DRIVERS, 5)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawMotionMenu); #if AXIS_IS_TMC(X) EDIT_ITEM(ICON_TMCXSet, MSG_TMC_ACURRENT, onDrawPIntMenu, setXTMCCurrent, &stepperX.val_mA); #endif @@ -3570,10 +3649,19 @@ void drawTuneMenu() { void drawMotionMenu() { checkkey = ID_Menu; - if (SET_MENU_R(motionMenu, selrect({1, 16, 28, 13}), MSG_MOTION, 11)) { + if (SET_MENU_R(motionMenu, selrect({1, 16, 28, 13}), MSG_MOTION, 13)) { BACK_ITEM(drawControlMenu); + #if HAS_FLOW_EDIT + EDIT_ITEM(ICON_Flow, MSG_FLOW, onDrawPIntMenu, setFlow, &planner.flow_percentage[0]); + #endif + #if HAS_FEEDRATE_EDIT + EDIT_ITEM(ICON_Speed, MSG_SPEED, onDrawPIntMenu, setSpeed, &feedrate_percentage); + #endif MENU_ITEM(ICON_MaxSpeed, MSG_SPEED, onDrawSpeed, drawMaxSpeedMenu); MENU_ITEM(ICON_MaxAccelerated, MSG_ACCELERATION, onDrawAcc, drawMaxAccelMenu); + #if ENABLED(EDITABLE_STEPS_PER_UNIT) + MENU_ITEM(ICON_Step, MSG_STEPS_PER_MM, onDrawSteps, drawStepsMenu); + #endif #if ENABLED(CLASSIC_JERK) MENU_ITEM(ICON_MaxJerk, MSG_JERK, onDrawJerk, drawMaxJerkMenu); #elif HAS_JUNCTION_DEVIATION @@ -3594,42 +3682,63 @@ void drawMotionMenu() { #if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE) EDIT_ITEM(ICON_UBLActive, MSG_STEP_SMOOTHING, onDrawChkbMenu, setAdaptiveStepSmoothing, &stepper.adaptive_step_smoothing_enabled); #endif - EDIT_ITEM(ICON_Flow, MSG_FLOW, onDrawPIntMenu, setFlow, &planner.flow_percentage[0]); - EDIT_ITEM(ICON_Speed, MSG_SPEED, onDrawPIntMenu, setSpeed, &feedrate_percentage); + #if HAS_TRINAMIC_CONFIG + MENU_ITEM(ICON_TMCSet, MSG_TMC_DRIVERS, onDrawSubMenu, drawTrinamicConfigMenu); + #endif } updateMenu(motionMenu); } -#if ALL(ADVANCED_PAUSE_FEATURE, HAS_PREHEAT) - +#if HAS_PREHEAT void drawPreheatHotendMenu() { checkkey = ID_Menu; if (SET_MENU(preheatHotendMenu, MSG_PREHEAT_HOTEND, 1 + PREHEAT_COUNT)) { - BACK_ITEM(drawFilamentManMenu); - #define _ITEM_PREHEAT_HE(N) MENU_ITEM(ICON_Preheat##N, MSG_PREHEAT_##N, onDrawMenuItem, DoPreheatHotend##N); - REPEAT_1(PREHEAT_COUNT, _ITEM_PREHEAT_HE) + BACK_ITEM(drawPrepareMenu); + #define _ITEM_PREHEAT(N) MENU_ITEM(ICON_Preheat##N, MSG_PREHEAT_##N, onDrawPreheat##N, DoPreheat##N); + REPEAT_1(PREHEAT_COUNT, _ITEM_PREHEAT) } updateMenu(preheatHotendMenu); } - #endif +void drawFilSetMenu() { + checkkey = ID_Menu; + if (SET_MENU(filSetMenu, MSG_FILAMENT_SET, 7)) { + BACK_ITEM(drawFilamentManMenu); + #if HAS_FILAMENT_SENSOR + EDIT_ITEM(ICON_Runout, MSG_RUNOUT_SENSOR, onDrawChkbMenu, setRunoutEnable, &runout.enabled); + #endif + #if HAS_FILAMENT_RUNOUT_DISTANCE + EDIT_ITEM(ICON_Runout, MSG_RUNOUT_DISTANCE_MM, onDrawPFloatMenu, setRunoutDistance, &runout.runout_distance()); + #endif + #if ENABLED(PREVENT_COLD_EXTRUSION) + EDIT_ITEM(ICON_ExtrudeMinT, MSG_EXTRUDER_MIN_TEMP, onDrawPIntMenu, setExtMinT, &hmiData.extMinT); + #endif + #if ENABLED(CONFIGURE_FILAMENT_CHANGE) + EDIT_ITEM(ICON_FilLoad, MSG_FILAMENT_LOAD, onDrawPFloatMenu, setFilLoad, &fc_settings[0].load_length); + EDIT_ITEM(ICON_FilUnload, MSG_FILAMENT_UNLOAD, onDrawPFloatMenu, setFilUnload, &fc_settings[0].unload_length); + #endif + } + updateMenu(filSetMenu); +} + void drawFilamentManMenu() { checkkey = ID_Menu; - if (SET_MENU(filamentMenu, MSG_FILAMENT_MAN, 6)) { + if (SET_MENU(filamentMenu, MSG_FILAMENT_MAN, 7)) { BACK_ITEM(drawPrepareMenu); #if ENABLED(NOZZLE_PARK_FEATURE) MENU_ITEM(ICON_Park, MSG_FILAMENT_PARK_ENABLED, onDrawMenuItem, parkHead); #endif + MENU_ITEM(ICON_FilSet, MSG_FILAMENT_SET, onDrawSubMenu, drawFilSetMenu); #if ENABLED(ADVANCED_PAUSE_FEATURE) - #if HAS_PREHEAT - MENU_ITEM(ICON_SetEndTemp, MSG_PREHEAT_HOTEND, onDrawSubMenu, drawPreheatHotendMenu); - #endif MENU_ITEM(ICON_FilMan, MSG_FILAMENTCHANGE, onDrawMenuItem, changeFilament); #endif #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - MENU_ITEM(ICON_FilUnload, MSG_FILAMENTUNLOAD, onDrawMenuItem, unloadFilament); MENU_ITEM(ICON_FilLoad, MSG_FILAMENTLOAD, onDrawMenuItem, loadFilament); + MENU_ITEM(ICON_FilUnload, MSG_FILAMENTUNLOAD, onDrawMenuItem, unloadFilament); + #endif + #if ENABLED(FWRETRACT) + MENU_ITEM(ICON_FWRetract, MSG_FWRETRACT, onDrawSubMenu, drawFWRetractMenu); #endif } updateMenu(filamentMenu); @@ -3639,12 +3748,11 @@ void drawFilamentManMenu() { void drawManualMeshMenu() { checkkey = ID_Menu; - if (SET_MENU(manualMeshMenu, MSG_UBL_MANUAL_MESH, 6)) { - BACK_ITEM(drawPrepareMenu); - MENU_ITEM(ICON_ManualMesh, MSG_LEVEL_BED, onDrawMenuItem, manualMeshStart); + if (SET_MENU(manualMeshMenu, MSG_MANUAL_LEVELING, 5)) { + BACK_ITEM(drawLevelMenu); + MENU_ITEM(ICON_ManualMesh, MSG_UBL_MANUAL_MESH, onDrawMenuItem, manualMeshStart); mMeshMoveZItem = EDIT_ITEM(ICON_Zoffset, MSG_MOVE_Z, onDrawMMeshMoveZ, setMMeshMoveZ, ¤t_position.z); MENU_ITEM(ICON_Axis, MSG_UBL_CONTINUE_MESH, onDrawMenuItem, manualMeshContinue); - MENU_ITEM(ICON_MeshViewer, MSG_MESH_VIEW, onDrawSubMenu, dwinMeshViewer); MENU_ITEM(ICON_MeshSave, MSG_UBL_SAVE_MESH, onDrawMenuItem, manualMeshSave); } updateMenu(manualMeshMenu); @@ -3685,7 +3793,7 @@ void drawFilamentManMenu() { void drawTemperatureMenu() { checkkey = ID_Menu; - if (SET_MENU_R(temperatureMenu, selrect({236, 2, 28, 12}), MSG_TEMPERATURE, 4 + PREHEAT_COUNT)) { + if (SET_MENU_R(temperatureMenu, selrect({236, 2, 28, 12}), MSG_TEMPERATURE, 7 + PREHEAT_COUNT)) { BACK_ITEM(drawControlMenu); #if HAS_HOTEND hotendTargetItem = EDIT_ITEM(ICON_HotendTemp, MSG_UBL_SET_TEMP_HOTEND, onDrawHotendTemp, setHotendTemp, &thermalManager.temp_hotend[0].target); @@ -3696,6 +3804,17 @@ void drawTemperatureMenu() { #if HAS_FAN fanSpeedItem = EDIT_ITEM(ICON_FanSpeed, MSG_FAN_SPEED, onDrawFanSpeed, setFanSpeed, &thermalManager.fan_speed[0]); #endif + #if ENABLED(PIDTEMP) && ANY(PID_AUTOTUNE_MENU, PID_EDIT_MENU) + MENU_ITEM_F(ICON_PIDNozzle, STR_HOTEND_PID " Settings", onDrawSubMenu, drawHotendPIDMenu); + #elif ENABLED(MPCTEMP) && ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) + MENU_ITEM_F(ICON_MPCNozzle, "MPC Settings", onDrawSubMenu, drawHotendMPCMenu); + #endif + #if ENABLED(PIDTEMPBED) && ANY(PID_AUTOTUNE_MENU, PID_EDIT_MENU) + MENU_ITEM_F(ICON_PIDBed, STR_BED_PID " Settings", onDrawSubMenu, drawBedPIDMenu); + #endif + #if ENABLED(PIDTEMPCHAMBER) && ANY(PID_AUTOTUNE_MENU, PID_EDIT_MENU) + MENU_ITEM_F(ICON_PIDBed, STR_CHAMBER_PID " Settings", onDrawSubMenu, drawChamberPIDMenu); + #endif #if HAS_PREHEAT #define _ITEM_SETPREHEAT(N) MENU_ITEM(ICON_SetPreheat##N, MSG_PREHEAT_## N ##_SETTINGS, onDrawSubMenu, drawPreheat## N ##Menu); REPEAT_1(PREHEAT_COUNT, _ITEM_SETPREHEAT) @@ -3858,7 +3977,7 @@ void drawMaxAccelMenu() { void drawSelectColorsMenu() { checkkey = ID_Menu; if (SET_MENU(selectColorMenu, MSG_COLORS_SELECT, 20)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawControlMenu); MENU_ITEM(ICON_StockConfiguration, MSG_RESTORE_DEFAULTS, onDrawMenuItem, restoreDefaultColors); EDIT_ITEM_F(0, "Screen Background", onDrawSelColorItem, selColor, &hmiData.colorBackground); EDIT_ITEM_F(0, "Cursor", onDrawSelColorItem, selColor, &hmiData.colorCursor); @@ -3901,7 +4020,7 @@ void drawMaxAccelMenu() { // Nozzle and Bed PID/MPC //============================================================================= -#if ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) +#if ENABLED(MPCTEMP) && ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) #if ENABLED(MPC_EDIT_MENU) void setHeaterPower() { setPFloatOnClick(1, 200, 1); } @@ -3919,7 +4038,7 @@ void drawMaxAccelMenu() { checkkey = ID_Menu; if (SET_MENU_F(hotendMPCMenu, "MPC Settings", 7)) { MPC_t &mpc = thermalManager.temp_hotend[0].mpc; - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawTemperatureMenu); #if ENABLED(MPC_AUTOTUNE_MENU) MENU_ITEM(ICON_MPCNozzle, MSG_MPC_AUTOTUNE, onDrawMenuItem, []{ thermalManager.MPC_autotune(active_extruder, Temperature::MPCTuningType::AUTO); }); #endif @@ -3988,7 +4107,7 @@ void drawMaxAccelMenu() { void drawHotendPIDMenu() { checkkey = ID_Menu; if (SET_MENU_F(hotendPIDMenu, STR_HOTEND_PID " Settings", 8)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawTemperatureMenu); #if ENABLED(PID_AUTOTUNE_MENU) MENU_ITEM_F(ICON_PIDNozzle, STR_HOTEND_PID, onDrawMenuItem, hotendPID); EDIT_ITEM(ICON_Temperature, MSG_TEMPERATURE, onDrawPIntMenu, setHotendPIDT, &hmiData.hotendPIDT); @@ -4018,7 +4137,7 @@ void drawMaxAccelMenu() { void drawBedPIDMenu() { checkkey = ID_Menu; if (SET_MENU_F(bedPIDMenu, STR_BED_PID " Settings", 8)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawTemperatureMenu); #if ENABLED(PID_AUTOTUNE_MENU) MENU_ITEM_F(ICON_PIDBed, STR_BED_PID, onDrawMenuItem,bedPID); EDIT_ITEM(ICON_Temperature, MSG_TEMPERATURE, onDrawPIntMenu, setBedPIDT, &hmiData.bedPIDT); @@ -4048,7 +4167,7 @@ void drawMaxAccelMenu() { void drawChamberPIDMenu() { checkkey = ID_Menu; if (SET_MENU_F(chamberPIDMenu, STR_CHAMBER_PID " Settings", 8)) { - BACK_ITEM(drawAdvancedSettingsMenu); + BACK_ITEM(drawTemperatureMenu); #if ENABLED(PID_AUTOTUNE_MENU) MENU_ITEM_F(ICON_PIDChamber, STR_CHAMBER_PID, onDrawMenuItem,chamberPID); EDIT_ITEM(ICON_Temperature, MSG_TEMPERATURE, onDrawPIntMenu, setChamberPIDT, &hmiData.chamberPIDT); @@ -4134,100 +4253,20 @@ void drawMaxAccelMenu() { // Mesh Bed Leveling //============================================================================= -#if HAS_MESH - - void applyMeshFadeHeight() { set_z_fade_height(planner.z_fade_height); } - void setMeshFadeHeight() { setPFloatOnClick(0, 100, 1, applyMeshFadeHeight); } - - void setMeshActive() { - set_bed_leveling_enabled(!planner.leveling_active); - drawCheckboxLine(currentMenu->line(), planner.leveling_active); - dwinUpdateLCD(); - } - - #if ENABLED(PREHEAT_BEFORE_LEVELING) - void setBedLevT() { setPIntOnClick(MIN_BEDTEMP, MAX_BEDTEMP); } - #endif - - #if ENABLED(PROUI_MESH_EDIT) - void liveEditMesh() { ((MenuItemPtr*)editZValueItem)->value = &bedlevel.z_values[hmiValue.select ? bedLevelTools.mesh_x : menuData.value][hmiValue.select ? menuData.value : bedLevelTools.mesh_y]; editZValueItem->redraw(); } - void applyEditMeshX() { bedLevelTools.mesh_x = menuData.value; } - void applyEditMeshY() { bedLevelTools.mesh_y = menuData.value; } - void resetMesh() { bedLevelTools.meshReset(); LCD_MESSAGE(MSG_MESH_RESET); } - void setEditMeshX() { hmiValue.select = 0; setIntOnClick(0, GRID_MAX_POINTS_X - 1, bedLevelTools.mesh_x, applyEditMeshX, liveEditMesh); } - void setEditMeshY() { hmiValue.select = 1; setIntOnClick(0, GRID_MAX_POINTS_Y - 1, bedLevelTools.mesh_y, applyEditMeshY, liveEditMesh); } - void setEditZValue() { setPFloatOnClick(Z_OFFSET_MIN, Z_OFFSET_MAX, 3); } - #endif - -#endif // HAS_MESH - -#if ENABLED(AUTO_BED_LEVELING_UBL) - - void applyUBLSlot() { bedlevel.storage_slot = menuData.value; } - void setUBLSlot() { setIntOnClick(0, settings.calc_num_meshes() - 1, bedlevel.storage_slot, applyUBLSlot); } - void onDrawUBLSlot(MenuItem* menuitem, int8_t line) { - NOLESS(bedlevel.storage_slot, 0); - onDrawIntMenu(menuitem, line, bedlevel.storage_slot); - } - - void applyUBLTiltGrid() { bedLevelTools.tilt_grid = menuData.value; } - void setUBLTiltGrid() { setIntOnClick(1, 3, bedLevelTools.tilt_grid, applyUBLTiltGrid); } - - void ublMeshTilt() { - NOLESS(bedlevel.storage_slot, 0); - if (bedLevelTools.tilt_grid > 1) - gcode.process_subcommands_now(TS(F("G29J"), bedLevelTools.tilt_grid)); - else - gcode.process_subcommands_now(F("G29J")); - LCD_MESSAGE(MSG_UBL_MESH_TILTED); - } - - void ublSmartFillMesh() { - for (uint8_t x = 0; x < GRID_MAX_POINTS_Y; ++x) bedlevel.smart_fill_mesh(); - LCD_MESSAGE(MSG_UBL_MESH_FILLED); - } - - void ublMeshSave() { - NOLESS(bedlevel.storage_slot, 0); - settings.store_mesh(bedlevel.storage_slot); - ui.status_printf(0, GET_TEXT_F(MSG_MESH_SAVED), bedlevel.storage_slot); - DONE_BUZZ(true); - } - - void ublMeshLoad() { - NOLESS(bedlevel.storage_slot, 0); - settings.load_mesh(bedlevel.storage_slot); - } - -#endif // AUTO_BED_LEVELING_UBL - #if HAS_MESH void drawMeshSetMenu() { checkkey = ID_Menu; - if (SET_MENU(meshMenu, MSG_MESH_LEVELING, 14)) { - BACK_ITEM(drawAdvancedSettingsMenu); + if (SET_MENU(meshMenu, MSG_MESH_SETTINGS, 5)) { + BACK_ITEM(drawLevelMenu); #if ENABLED(PREHEAT_BEFORE_LEVELING) EDIT_ITEM(ICON_Temperature, MSG_UBL_SET_TEMP_BED, onDrawPIntMenu, setBedLevT, &hmiData.bedLevT); #endif EDIT_ITEM(ICON_SetZOffset, MSG_Z_FADE_HEIGHT, onDrawPFloatMenu, setMeshFadeHeight, &planner.z_fade_height); EDIT_ITEM(ICON_UBLActive, MSG_ACTIVATE_MESH, onDrawChkbMenu, setMeshActive, &planner.leveling_active); - #if HAS_BED_PROBE - MENU_ITEM(ICON_Level, MSG_AUTO_MESH, onDrawMenuItem, autoLevel); - #endif #if ENABLED(AUTO_BED_LEVELING_UBL) - EDIT_ITEM(ICON_UBLSlot, MSG_UBL_STORAGE_SLOT, onDrawUBLSlot, setUBLSlot, &bedlevel.storage_slot); - MENU_ITEM(ICON_UBLMeshSave, MSG_UBL_SAVE_MESH, onDrawMenuItem, ublMeshSave); - MENU_ITEM(ICON_UBLMeshLoad, MSG_UBL_LOAD_MESH, onDrawMenuItem, ublMeshLoad); EDIT_ITEM(ICON_UBLTiltGrid, MSG_UBL_TILTING_GRID, onDrawPInt8Menu, setUBLTiltGrid, &bedLevelTools.tilt_grid); - MENU_ITEM(ICON_UBLTiltGrid, MSG_UBL_TILT_MESH, onDrawMenuItem, ublMeshTilt); - MENU_ITEM(ICON_UBLSmartFill, MSG_UBL_SMART_FILLIN, onDrawMenuItem, ublSmartFillMesh); - #endif - #if ENABLED(PROUI_MESH_EDIT) - MENU_ITEM(ICON_MeshReset, MSG_MESH_RESET, onDrawMenuItem, resetMesh); - MENU_ITEM(ICON_MeshEdit, MSG_EDIT_MESH, onDrawSubMenu, drawEditMeshMenu); #endif - MENU_ITEM(ICON_MeshViewer, MSG_MESH_VIEW, onDrawSubMenu, dwinMeshViewer); } updateMenu(meshMenu); } @@ -4237,12 +4276,18 @@ void drawMaxAccelMenu() { if (!leveling_is_valid()) { LCD_MESSAGE(MSG_UBL_MESH_INVALID); return; } set_bed_leveling_enabled(false); checkkey = ID_Menu; - if (SET_MENU(editMeshMenu, MSG_EDIT_MESH, 4)) { + if (SET_MENU(editMeshMenu, MSG_EDIT_MESH, 10)) { bedLevelTools.mesh_x = bedLevelTools.mesh_y = 0; - BACK_ITEM(drawMeshSetMenu); + BACK_ITEM(drawLevelMenu); EDIT_ITEM(ICON_MeshEditX, MSG_MESH_X, onDrawPInt8Menu, setEditMeshX, &bedLevelTools.mesh_x); EDIT_ITEM(ICON_MeshEditY, MSG_MESH_Y, onDrawPInt8Menu, setEditMeshY, &bedLevelTools.mesh_y); editZValueItem = EDIT_ITEM(ICON_MeshEditZ, MSG_MESH_EDIT_Z, onDrawPFloat2Menu, setEditZValue, &bedlevel.z_values[bedLevelTools.mesh_x][bedLevelTools.mesh_y]); + EDIT_ITEM(200 /*ICON_Box*/, MSG_MESH_MIN_X, onDrawPFloatMenu, setMeshInset, &hmiData.mesh_min_x); + EDIT_ITEM(ICON_ProbeMargin, MSG_MESH_MAX_X, onDrawPFloatMenu, setMeshInset, &hmiData.mesh_max_x); + EDIT_ITEM(200 /*ICON_Box*/, MSG_MESH_MIN_Y, onDrawPFloatMenu, setMeshInset, &hmiData.mesh_min_y); + EDIT_ITEM(ICON_ProbeMargin, MSG_MESH_MAX_Y, onDrawPFloatMenu, setMeshInset, &hmiData.mesh_max_y); + //MENU_ITEM(254 /*ICON_AxisC*/, MSG_MESH_AMAX, onDrawMenuItem, maxMeshArea); + //MENU_ITEM(ICON_SetHome, MSG_MESH_CENTER, onDrawMenuItem, centerMeshArea); } updateMenu(editMeshMenu); } @@ -4250,4 +4295,40 @@ void drawMaxAccelMenu() { #endif // HAS_MESH +void drawLevelMenu() { + checkkey = ID_Menu; + if (SET_MENU(levelMenu, MSG_BED_LEVELING, 14)) { + BACK_ITEM(gotoMainMenu); + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(ICON_WriteEEPROM, MSG_STORE_EEPROM, onDrawMenuItem, writeEEPROM); + #endif + #if ENABLED(MESH_BED_LEVELING) + MENU_ITEM(ICON_ManualMesh, MSG_MANUAL_MESH, onDrawSubMenu, drawManualMeshMenu); + #elif HAS_BED_PROBE + MENU_ITEM(ICON_Mesh, MSG_AUTO_MESH, onDrawMenuItem, autoLevel); + MENU_ITEM(ICON_Probe, MSG_ZPROBE_SETTINGS, onDrawSubMenu, drawProbeSetMenu); + #endif + #if HAS_HOME_OFFSET + MENU_ITEM(ICON_HomeOffset, MSG_SET_HOME_OFFSETS, onDrawSubMenu, drawHomeOffsetMenu); + #endif + #if HAS_MESH + MENU_ITEM(ICON_Mesh, MSG_MESH_SETTINGS, onDrawSubMenu, drawMeshSetMenu); + MENU_ITEM(ICON_MeshViewer, MSG_MESH_VIEW, onDrawSubMenu, dwinMeshViewer); + #if ENABLED(PROUI_MESH_EDIT) + MENU_ITEM(ICON_MeshEdit, MSG_EDIT_MESH, onDrawSubMenu, drawEditMeshMenu); + MENU_ITEM(ICON_MeshReset, MSG_MESH_RESET, onDrawMenuItem, resetMesh); + #endif + #endif + #if ENABLED(AUTO_BED_LEVELING_UBL) + EDIT_ITEM(ICON_UBLSlot, MSG_UBL_STORAGE_SLOT, onDrawUBLSlot, setUBLSlot, &bedlevel.storage_slot); + MENU_ITEM(ICON_UBLMeshSave, MSG_UBL_SAVE_MESH, onDrawMenuItem, ublMeshSave); + MENU_ITEM(ICON_UBLMeshLoad, MSG_UBL_LOAD_MESH, onDrawMenuItem, ublMeshLoad); + MENU_ITEM(ICON_UBLTiltGrid, MSG_UBL_TILT_MESH, onDrawMenuItem, ublMeshTilt); + MENU_ITEM(ICON_UBLSmartFill, MSG_UBL_SMART_FILLIN, onDrawMenuItem, ublSmartFillMesh); + #endif + } + ui.reset_status(true); + updateMenu(levelMenu); +} + #endif // DWIN_LCD_PROUI diff --git a/Marlin/src/lcd/e3v2/proui/dwin.h b/Marlin/src/lcd/e3v2/proui/dwin.h index b6534a617b2f..d8348022b5c0 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.h +++ b/Marlin/src/lcd/e3v2/proui/dwin.h @@ -105,72 +105,6 @@ enum processID : uint8_t { #define DWIN_CHINESE 123 #define DWIN_ENGLISH 0 -typedef struct { - // Color settings - uint16_t colorBackground; - uint16_t colorCursor; - uint16_t colorTitleBg; - uint16_t colorTitleTxt; - uint16_t colorText; - uint16_t colorSelected; - uint16_t colorSplitLine; - uint16_t colorHighlight; - uint16_t colorStatusBg; - uint16_t colorStatusTxt; - uint16_t colorPopupBg; - uint16_t colorPopupTxt; - uint16_t colorAlertBg; - uint16_t colorAlertTxt; - uint16_t colorPercentTxt; - uint16_t colorBarfill; - uint16_t colorIndicator; - uint16_t colorCoordinate; - - // Temperatures - #if HAS_PID_HEATING - int16_t pidCycles = DEF_PIDCYCLES; - #if ENABLED(PIDTEMP) - celsius_t hotendPIDT = DEF_HOTENDPIDT; - #endif - #if ENABLED(PIDTEMPBED) - celsius_t bedPIDT = DEF_BEDPIDT; - #endif - #if ENABLED(PIDTEMPCHAMBER) - celsius_t chamberPIDT = DEF_CHAMBERPIDT; - #endif - #endif - #if ENABLED(PREVENT_COLD_EXTRUSION) - celsius_t extMinT = EXTRUDE_MINTEMP; - #endif - #if ENABLED(PREHEAT_BEFORE_LEVELING) - celsius_t bedLevT = LEVELING_BED_TEMP; - #endif - #if ENABLED(BAUD_RATE_GCODE) - bool baud115K = false; - #endif - #if ALL(LCD_BED_TRAMMING, HAS_BED_PROBE) - bool fullManualTramming = false; - #endif - #if ENABLED(PROUI_MEDIASORT) - bool mediaSort = true; - #endif - bool mediaAutoMount = ENABLED(HAS_SD_EXTENDER); - #if ALL(INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING) - uint8_t zAfterHoming = DEF_Z_AFTER_HOMING; - #define Z_POST_CLEARANCE hmiData.zAfterHoming - #endif - #if ALL(LED_CONTROL_MENU, HAS_COLOR_LEDS) - LEDColor ledColor = defColorLeds; - #endif - #if HAS_GCODE_PREVIEW - bool enablePreview = true; - #endif -} hmi_data_t; - -extern hmi_data_t hmiData; - -#define EXTUI_EEPROM_DATA_SIZE sizeof(hmi_data_t) - typedef struct { int8_t r, g, b; void set(int8_t _r, int8_t _g, int8_t _b) { r = _r; g = _g; b = _b; } @@ -202,6 +136,7 @@ typedef struct { bool pause_flag:1; // printing is paused bool select_flag:1; // Popup button selected bool home_flag:1; // homing in course + bool cancel_lev:1; // cancel abl } hmi_flag_t; extern hmi_flag_t hmiFlag; @@ -225,11 +160,16 @@ uint32_t getHash(char * str); void saveMesh(); #endif #endif +#if HAS_BED_PROBE + void autoLevel(); +#else + void homeZAndDisable(); +#endif void rebootPrinter(); void disableMotors(); -void autoLevel(); void autoHome(); #if HAS_PREHEAT + void drawPreheatHotendMenu(); #define _DOPREHEAT(N) void DoPreheat##N(); REPEAT_1(PREHEAT_COUNT, _DOPREHEAT) #endif @@ -259,9 +199,6 @@ void doCoolDown(); void ublMeshSave(); void ublMeshLoad(); #endif -#if DISABLED(HAS_BED_PROBE) - void homeZAndDisable(); -#endif // Other void gotoPrintProcess(); @@ -290,8 +227,10 @@ void dwinHomingDone(); #if HAS_MESH void dwinMeshUpdate(const int8_t cpos, const int8_t tpos, const_float_t zval); #endif -void dwinLevelingStart(); -void dwinLevelingDone(); +#if HAS_LEVELING + void dwinLevelingStart(); + void dwinLevelingDone(); +#endif void dwinPrintStarted(); void dwinPrintPause(); void dwinPrintResume(); @@ -336,6 +275,7 @@ void drawPrintFileMenu(); void drawControlMenu(); void drawAdvancedSettingsMenu(); void drawPrepareMenu(); +void drawLevelMenu(); void drawMoveMenu(); void drawTrammingMenu(); #if HAS_HOME_OFFSET diff --git a/Marlin/src/lcd/e3v2/proui/dwin_defines.h b/Marlin/src/lcd/e3v2/proui/dwin_defines.h index b72bdf1d2359..f76cb1dd4256 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_defines.h +++ b/Marlin/src/lcd/e3v2/proui/dwin_defines.h @@ -30,16 +30,18 @@ */ #include "../../../inc/MarlinConfigPre.h" +#include +#include "../../../core/types.h" -//#define TJC_DISPLAY // Enable for TJC display -//#define DACAI_DISPLAY // Enable for DACAI display -//#define TITLE_CENTERED // Center Menu Title Text +//#define TJC_DISPLAY // Enable for TJC display +//#define DACAI_DISPLAY // Enable for DACAI display +//#define TITLE_CENTERED // Center Menu Title Text #if HAS_MESH - #define PROUI_MESH_EDIT // Add a menu to edit mesh points + #define PROUI_MESH_EDIT // Add a menu to edit mesh inset #if ENABLED(PROUI_MESH_EDIT) - #define Z_OFFSET_MIN -3.0 // (mm) - #define Z_OFFSET_MAX 3.0 // (mm) + #define Z_OFFSET_MIN -3.0 // (mm) + #define Z_OFFSET_MAX 3.0 // (mm) #endif #endif @@ -111,6 +113,16 @@ /** * ProUI internal feature flags */ +#if HAS_MESH + #define PROUI_MESH_EDIT // Add a menu to edit mesh inset + points + #if ENABLED(PROUI_MESH_EDIT) + #define Z_OFFSET_MIN -3.0 // (mm) + #define Z_OFFSET_MAX 3.0 // (mm) + #endif +#endif +#if HAS_BED_PROBE + #define PROUI_ITEM_ZFRS // Add a menu item to change Z_PROBE_FEEDRATE_SLOW - probe speed +#endif #if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE) #define PROUI_MEDIASORT // Enable option to sort G-code files #endif @@ -123,7 +135,7 @@ #if ENABLED(LIN_ADVANCE) #define PROUI_ITEM_ADVK // Tune > Linear Advance #endif -#if ANY(HAS_PID_HEATING, MPC_AUTOTUNE) && DISABLED(DISABLE_TUNING_GRAPH) +#if DISABLED(DISABLE_TUNING_GRAPH) #define PROUI_TUNING_GRAPH 1 #endif #if PROUI_TUNING_GRAPH @@ -134,3 +146,140 @@ #define HAS_ESDIAG 1 // View End-stop/Runout switch continuity #define HAS_LOCKSCREEN 1 // Simple lockscreen #define HAS_SD_EXTENDER 1 // Enable to support SD card extender cables + +#if ENABLED(PROUI_MESH_EDIT) + #ifndef MESH_INSET + #define MESH_INSET 10 + #endif + #ifndef MESH_MIN_X + #define MESH_MIN_X MESH_INSET + #endif + #ifndef MESH_MIN_Y + #define MESH_MIN_Y MESH_INSET + #endif + #ifndef MESH_MAX_X + #define MESH_MAX_X X_BED_SIZE - (MESH_INSET) + #endif + #ifndef MESH_MAX_Y + #define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET) + #endif + constexpr uint16_t DEF_MESH_MIN_X = MESH_MIN_X; + constexpr uint16_t DEF_MESH_MAX_X = MESH_MAX_X; + constexpr uint16_t DEF_MESH_MIN_Y = MESH_MIN_Y; + constexpr uint16_t DEF_MESH_MAX_Y = MESH_MAX_Y; + #define MIN_MESH_INSET 0 + #define MAX_MESH_INSET X_BED_SIZE +#endif + +#ifndef MULTIPLE_PROBING + #define MULTIPLE_PROBING 0 +#endif + +#if HAS_BED_PROBE + constexpr uint16_t DEF_Z_PROBE_FEEDRATE_SLOW = Z_PROBE_FEEDRATE_SLOW; +#endif + +#if HAS_EXTRUDERS + constexpr bool DEF_INVERT_E0_DIR = INVERT_E0_DIR; +#endif + +typedef struct { + // Color settings + uint16_t colorBackground; + uint16_t colorCursor; + uint16_t colorTitleBg; + uint16_t colorTitleTxt; + uint16_t colorText; + uint16_t colorSelected; + uint16_t colorSplitLine; + uint16_t colorHighlight; + uint16_t colorStatusBg; + uint16_t colorStatusTxt; + uint16_t colorPopupBg; + uint16_t colorPopupTxt; + uint16_t colorAlertBg; + uint16_t colorAlertTxt; + uint16_t colorPercentTxt; + uint16_t colorBarfill; + uint16_t colorIndicator; + uint16_t colorCoordinate; + + // Temperatures + int16_t pidCycles = DEF_PIDCYCLES; + #if ENABLED(PIDTEMP) + celsius_t hotendPIDT = DEF_HOTENDPIDT; + #endif + #if ENABLED(PIDTEMPBED) + celsius_t bedPIDT = DEF_BEDPIDT; + #endif + #if ENABLED(PIDTEMPCHAMBER) + celsius_t chamberPIDT = DEF_CHAMBERPIDT; + #endif + #if ENABLED(PREVENT_COLD_EXTRUSION) + int16_t extMinT = EXTRUDE_MINTEMP; + #endif + #if ENABLED(PREHEAT_BEFORE_LEVELING) + int16_t bedLevT = LEVELING_BED_TEMP; + #endif + + // Various Options + #if ENABLED(BAUD_RATE_GCODE) + bool baud115K = false; + #endif + #if ALL(LCD_BED_TRAMMING, HAS_BED_PROBE) + bool fullManualTramming = false; + #endif + #if ENABLED(PROUI_MEDIASORT) + bool mediaSort = true; + #endif + bool mediaAutoMount = ENABLED(HAS_SD_EXTENDER); + #if ALL(INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING) + uint8_t zAfterHoming = DEF_Z_AFTER_HOMING; + #define Z_POST_CLEARANCE hmiData.zAfterHoming + #endif + #if ALL(LED_CONTROL_MENU, HAS_COLOR_LEDS) + LEDColor ledColor = defColorLeds; + #endif + #if HAS_GCODE_PREVIEW + bool enablePreview = true; + #endif + #if ENABLED(PROUI_MESH_EDIT) + float mesh_min_x = DEF_MESH_MIN_X; + float mesh_max_x = DEF_MESH_MAX_X; + float mesh_min_y = DEF_MESH_MIN_Y; + float mesh_max_y = DEF_MESH_MAX_Y; + #endif + #if HAS_BED_PROBE + IF_DISABLED(BD_SENSOR, uint8_t multiple_probing = MULTIPLE_PROBING); + uint16_t zprobeFeed = DEF_Z_PROBE_FEEDRATE_SLOW; + #endif + #if HAS_EXTRUDERS + bool Invert_E0 = DEF_INVERT_E0_DIR; + #endif +} hmi_data_t; + +extern hmi_data_t hmiData; + +#define EXTUI_EEPROM_DATA_SIZE sizeof(hmi_data_t) + +// ProUI extra feature redefines +#if ENABLED(PROUI_MESH_EDIT) + #undef MESH_MIN_X + #undef MESH_MAX_X + #undef MESH_MIN_Y + #undef MESH_MAX_Y + #define MESH_MIN_X hmiData.mesh_min_x + #define MESH_MAX_X hmiData.mesh_max_x + #define MESH_MIN_Y hmiData.mesh_min_y + #define MESH_MAX_Y hmiData.mesh_max_y +#endif + +#if HAS_BED_PROBE + #undef Z_PROBE_FEEDRATE_SLOW + #define Z_PROBE_FEEDRATE_SLOW hmiData.zprobeFeed +#endif + +#if HAS_EXTRUDERS + #undef INVERT_E0_DIR + #define INVERT_E0_DIR hmiData.Invert_E0 +#endif diff --git a/Marlin/src/lcd/e3v2/proui/dwin_popup.h b/Marlin/src/lcd/e3v2/proui/dwin_popup.h index 9443e88a3672..fa26402f26b7 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_popup.h +++ b/Marlin/src/lcd/e3v2/proui/dwin_popup.h @@ -29,7 +29,6 @@ * Date: 2022/02/28 */ -#include "dwinui.h" #include "dwin.h" typedef void (*popupDrawFunc_t)(); diff --git a/Marlin/src/lcd/e3v2/proui/dwinui.h b/Marlin/src/lcd/e3v2/proui/dwinui.h index f606c2440010..be121b43b895 100644 --- a/Marlin/src/lcd/e3v2/proui/dwinui.h +++ b/Marlin/src/lcd/e3v2/proui/dwinui.h @@ -73,7 +73,6 @@ #define ICON_HSMode ICON_MaxAccZ #define ICON_InputShaping ICON_MaxAccelerated #define ICON_JDmm ICON_MaxJerk -#define ICON_Level ICON_Mesh #define ICON_Lock ICON_Checkbox #define ICON_ManualMesh ICON_Mesh #define ICON_MaxPosX ICON_MoveX diff --git a/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp b/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp index 045615f3c2ae..c14e35f513f4 100644 --- a/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp +++ b/Marlin/src/lcd/e3v2/proui/gcode_preview.cpp @@ -39,51 +39,41 @@ #include "../../marlinui.h" #include "../../../sd/cardreader.h" -#include "../../../MarlinCore.h" // for wait_for_user -#include "dwin.h" #include "dwin_popup.h" #include "base64.h" -#define THUMBWIDTH 230 -#define THUMBHEIGHT 180 +#if ENABLED(TJC_DISPLAY) + #define THUMBWIDTH 180 + #define THUMBHEIGHT 180 +#else + #define THUMBWIDTH 200 + #define THUMBHEIGHT 200 +#endif Preview preview; +fileprop_t fileprop; -typedef struct { - char name[13] = ""; // 8.3 + null - uint32_t thumbstart = 0; - int thumbsize = 0; - int thumbheight = 0, thumbwidth = 0; - float time = 0; - float filament = 0; - float layer = 0; - float width = 0, height = 0, length = 0; - - void setname(const char * const fn) { - const uint8_t len = _MIN(sizeof(name) - 1, strlen(fn)); - memcpy(name, fn, len); - name[len] = '\0'; - } - - void clear() { - name[0] = '\0'; - thumbstart = 0; - thumbsize = 0; - thumbheight = thumbwidth = 0; - time = 0; - filament = 0; - layer = 0; - height = width = length = 0; - } - -} fileprop_t; +void fileprop_t::setname(const char * const fn) { + const uint8_t len = _MIN(sizeof(name) - 1, strlen(fn)); + memcpy(name, fn, len); + name[len] = '\0'; +} -fileprop_t fileprop; +void fileprop_t::clear() { + name[0] = '\0'; + thumbstart = 0; + thumbsize = 0; + thumbheight = thumbwidth = 0; + time = 0; + filament = 0; + layer = 0; + height = width = length = 0; +} void getValue(const char * const buf, PGM_P const key, float &value) { if (value != 0.0f) return; - char *posptr = strstr_P(buf, key); + const char *posptr = strstr_P(buf, key); if (posptr == nullptr) return; char num[10] = ""; @@ -101,7 +91,7 @@ void getValue(const char * const buf, PGM_P const key, float &value) { bool Preview::hasPreview() { const char * const tbstart = PSTR("; thumbnail begin " STRINGIFY(THUMBWIDTH) "x" STRINGIFY(THUMBHEIGHT)); - char *posptr = nullptr; + const char *posptr = nullptr; uint32_t indx = 0; float tmp = 0; @@ -184,11 +174,7 @@ bool Preview::hasPreview() { } void Preview::drawFromSD() { - if (!hasPreview()) { - hmiFlag.select_flag = 1; - wait_for_user = false; - return; - } + hasPreview(); MString<45> buf; dwinDrawRectangle(1, hmiData.colorBackground, 0, 0, DWIN_WIDTH, STATUS_Y - 1); @@ -208,10 +194,18 @@ void Preview::drawFromSD() { buf.set(F("Volume: "), p_float_t(fileprop.width, 1), 'x', p_float_t(fileprop.length, 1), 'x', p_float_t(fileprop.height, 1), F(" mm")); DWINUI::drawString(20, 70, &buf); } + + if (!fileprop.thumbsize) { + const uint8_t xpos = ((DWIN_WIDTH) / 2) - 55, // 55 = iconW/2 + ypos = ((DWIN_HEIGHT) / 2) - 125; + DWINUI::drawIcon(ICON_Info_0, xpos, ypos); + buf.set(PSTR("No " STRINGIFY(THUMBWIDTH) "x" STRINGIFY(THUMBHEIGHT) " Thumbnail")); + DWINUI::drawCenteredString(false, (DWINUI::fontID * 3), DWINUI::textColor, DWINUI::backColor, 0, DWIN_WIDTH, (DWIN_HEIGHT / 2), &buf); + } DWINUI::drawButton(BTN_Print, 26, 290); DWINUI::drawButton(BTN_Cancel, 146, 290); - show(); - drawSelectHighlight(true, 290); + if (fileprop.thumbsize) show(); + drawSelectHighlight(false, 290); dwinUpdateLCD(); } diff --git a/Marlin/src/lcd/e3v2/proui/gcode_preview.h b/Marlin/src/lcd/e3v2/proui/gcode_preview.h index 91466424475d..4d8325678ecb 100644 --- a/Marlin/src/lcd/e3v2/proui/gcode_preview.h +++ b/Marlin/src/lcd/e3v2/proui/gcode_preview.h @@ -39,3 +39,19 @@ class Preview { }; extern Preview preview; + +typedef struct { + char name[13] = ""; // 8.3 + null + uint32_t thumbstart; + int thumbsize, thumbheight, thumbwidth; + float time, + filament, + layer, + width, height, length; + + void setname(const char * const fn); + void clear(); + +} fileprop_t; + +extern fileprop_t fileprop; diff --git a/Marlin/src/lcd/e3v2/proui/menus.cpp b/Marlin/src/lcd/e3v2/proui/menus.cpp index 0f0005e3d139..4b32443f123c 100644 --- a/Marlin/src/lcd/e3v2/proui/menus.cpp +++ b/Marlin/src/lcd/e3v2/proui/menus.cpp @@ -157,7 +157,7 @@ void onDrawChkbMenu(MenuItem* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, val); } -void DrawItemEdit(const bool selected) { +void drawItemEdit(const bool selected) { const uint16_t bcolor = selected ? hmiData.colorSelected : hmiData.colorBackground; const uint8_t iNum = 4 - ((menuData.dp > 0) ? (menuData.dp - 1) : 0); switch (checkkey) { @@ -202,7 +202,7 @@ void setOnClick(uint8_t process, const int32_t lo, const int32_t hi, uint8_t dp, // 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); - DrawItemEdit(true); + drawItemEdit(true); } // Generic onclick event for float values @@ -215,7 +215,7 @@ void setValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const 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); - DrawItemEdit(true); + drawItemEdit(true); } // Generic onclick event for integer values @@ -285,14 +285,14 @@ int8_t hmiGet(bool draw) { if (encoder_diffState != ENCODER_DIFF_NO) { if (applyEncoder(encoder_diffState, menuData.value)) { encoderRate.enabled = false; - if (draw) DrawItemEdit(false); + if (draw) drawItemEdit(false); checkkey = ID_Menu; return 2; } LIMIT(menuData.value, lo, hi); } const bool change = cval != menuData.value; - if (change) DrawItemEdit(true); + if (change) drawItemEdit(true); return int8_t(change); } @@ -547,13 +547,13 @@ void updateMenu(Menu* &menu) { menu->draw(); } -void ReDrawMenu(bool force/*=false*/) { +void redrawMenu(bool force/*=false*/) { if (currentMenu && (force || checkkey == ID_Menu)) currentMenu->draw(); - if (force) DrawItemEdit(true); + if (force) drawItemEdit(true); } -void ReDrawItem() { - static_cast(currentMenu->selectedItem())->redraw(false); +void redrawItem() { + static_cast(currentMenu->selectedItem())->value; } #endif // DWIN_LCD_PROUI diff --git a/Marlin/src/lcd/e3v2/proui/menus.h b/Marlin/src/lcd/e3v2/proui/menus.h index d1f5cdb698ba..8ce394f32e89 100644 --- a/Marlin/src/lcd/e3v2/proui/menus.h +++ b/Marlin/src/lcd/e3v2/proui/menus.h @@ -187,10 +187,10 @@ void invalidateMenu(); void updateMenu(Menu* &menu); // Redraw the current Menu if it is valid -void ReDrawMenu(bool force=false); +void redrawMenu(bool force=false); // Redraw selected menu item -void ReDrawItem(); +void redrawItem(); // Clear menuItems array and free menuItems elements void menuItemsClear(); diff --git a/Marlin/src/lcd/e3v2/proui/meshviewer.cpp b/Marlin/src/lcd/e3v2/proui/meshviewer.cpp index 38d0af4f82ef..a9b4d3942005 100644 --- a/Marlin/src/lcd/e3v2/proui/meshviewer.cpp +++ b/Marlin/src/lcd/e3v2/proui/meshviewer.cpp @@ -34,7 +34,6 @@ #include "../../../core/types.h" #include "../../marlinui.h" -#include "dwin.h" #include "dwin_popup.h" #include "../../../feature/bedlevel/bedlevel.h" #include "meshviewer.h" diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 71a7a6869d48..bec21f84ac01 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -645,6 +645,7 @@ namespace LanguageNarrow_en { LSTR MSG_ZPROBE_OFFSET_N = _UxGT("Probe @ Offset"); LSTR MSG_BABYSTEP_PROBE_Z = _UxGT("Babystep Probe Z"); LSTR MSG_ZPROBE_MARGIN = _UxGT("Probe Margin"); + LSTR MSG_ZPROBE_MULTIPLE = _UxGT("Multiple Probing"); LSTR MSG_ZOFFSET = _UxGT("Z Offset"); LSTR MSG_Z_FEED_RATE = _UxGT("Z Feedrate"); LSTR MSG_ENABLE_HS_MODE = _UxGT("Enable HS mode"); @@ -695,6 +696,7 @@ namespace LanguageNarrow_en { LSTR MSG_UBL_LEVELING = _UxGT("Unified Bed Leveling"); LSTR MSG_MESH_LEVELING = _UxGT("Mesh Leveling"); LSTR MSG_MESH_DONE = _UxGT("Mesh probing done"); + LSTR MSG_MESH_SETTINGS = _UxGT("Mesh Settings"); LSTR MSG_INFO_PRINTER_STATS_MENU = _UxGT("Printer Stats"); LSTR MSG_INFO_STATS_MENU = _UxGT("Stats"); LSTR MSG_RESET_STATS = _UxGT("Reset Print Stats?"); diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 174f16d5c570..705e0cf4130f 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -1290,7 +1290,7 @@ void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f* * - Execute the move at the probing (or homing) feedrate */ void do_z_clearance(const_float_t zclear, const bool with_probe/*=true*/, const bool lower_allowed/*=false*/) { - UNUSED(with_probe); + IF_DISABLED(HAS_BED_PROBE, UNUSED(with_probe)); float zdest = zclear; TERN_(HAS_BED_PROBE, if (with_probe && probe.offset.z < 0) zdest -= probe.offset.z); NOMORE(zdest, Z_MAX_POS); diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 6d3bfaed0dc5..2d8b69a13528 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -242,9 +242,7 @@ inline float home_bump_mm(const AxisEnum axis) { extern soft_endstops_t soft_endstop; void apply_motion_limits(xyz_pos_t &target); void update_software_endstops(const AxisEnum axis - #if HAS_HOTEND_OFFSET - , const uint8_t old_tool_index=0, const uint8_t new_tool_index=0 - #endif + OPTARG(HAS_HOTEND_OFFSET, const uint8_t old_tool_index=0, const uint8_t new_tool_index=0) ); #define SET_SOFT_ENDSTOP_LOOSE(loose) (soft_endstop._loose = loose) diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index a66c11a782e9..228d6df264b3 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -352,7 +352,7 @@ FORCE_INLINE void probe_specific_action(const bool deploy) { #if ENABLED(PAUSE_BEFORE_DEPLOY_STOW) // Start preheating before waiting for user confirmation that the probe is ready. - TERN_(PREHEAT_BEFORE_PROBING, if (deploy) probe.preheat_for_probing(0, PROBING_BED_TEMP, true)); + TERN_(PREHEAT_BEFORE_PROBING, if (deploy) probe.preheat_for_probing(PROBING_NOZZLE_TEMP, PROBING_BED_TEMP, true)); FSTR_P const ds_fstr = deploy ? GET_TEXT_F(MSG_MANUAL_DEPLOY) : GET_TEXT_F(MSG_MANUAL_STOW); ui.return_to_status(); // To display the new status message @@ -748,43 +748,200 @@ bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) { * * @return The Z position of the bed at the current XY or NAN on error. */ -float Probe::run_z_probe(const bool sanity_check/*=true*/, const_float_t z_min_point/*=Z_PROBE_LOW_POINT*/, const_float_t z_clearance/*=Z_TWEEN_SAFE_CLEARANCE*/) { - DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING)); +#if DISABLED(DWIN_LCD_PROUI) - const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z); + float Probe::run_z_probe(const bool sanity_check/*=true*/, const_float_t z_min_point/*=Z_PROBE_LOW_POINT*/, const_float_t z_clearance/*=Z_TWEEN_SAFE_CLEARANCE*/) { + DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING)); - auto try_to_probe = [&](PGM_P const plbl, const_float_t z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck) -> bool { - constexpr float error_tolerance = Z_PROBE_ERROR_TOLERANCE; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPGM_P(plbl); - DEBUG_ECHOLNPGM("> try_to_probe(..., ", z_probe_low_point, ", ", fr_mm_s, ", ...)"); - } + const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z); - // Tare the probe, if supported - if (TERN0(PROBE_TARE, tare())) return true; + auto try_to_probe = [&](PGM_P const plbl, const_float_t z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck) -> bool { + constexpr float error_tolerance = Z_PROBE_ERROR_TOLERANCE; + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOPGM_P(plbl); + DEBUG_ECHOLNPGM("> try_to_probe(..., ", z_probe_low_point, ", ", fr_mm_s, ", ...)"); + } - // Do a first probe at the fast speed - const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger? - early_fail = (scheck && current_position.z > zoffs + error_tolerance); // Probe triggered too high? - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) { - DEBUG_ECHOPGM(" Probe fail! - "); - if (probe_fail) DEBUG_ECHOLNPGM("No trigger."); - if (early_fail) DEBUG_ECHOLNPGM("Triggered early (above ", zoffs + error_tolerance, "mm)"); + // Tare the probe, if supported + if (TERN0(PROBE_TARE, tare())) return true; + + // Do a first probe at the fast speed + const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger? + early_fail = (scheck && current_position.z > zoffs + error_tolerance); // Probe triggered too high? + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) { + DEBUG_ECHOPGM(" Probe fail! - "); + if (probe_fail) DEBUG_ECHOLNPGM("No trigger."); + if (early_fail) DEBUG_ECHOLNPGM("Triggered early (above ", zoffs + error_tolerance, "mm)"); + } + #else + UNUSED(plbl); + #endif + return probe_fail || early_fail; + }; + + // Stop the probe before it goes too low to prevent damage. + // For known Z probe below the expected trigger point, otherwise -10mm lower. + const float z_probe_low_point = zoffs + z_min_point -float((!axis_is_trusted(Z_AXIS)) * 10); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe Low Point: ", z_probe_low_point); + + // Double-probing does a fast probe followed by a slow probe + #if TOTAL_PROBING == 2 + + // Attempt to tare the probe + if (TERN0(PROBE_TARE, tare())) return NAN; + + // Do a first probe at the fast speed + if (try_to_probe(PSTR("FAST"), z_probe_low_point, z_probe_fast_mm_s, sanity_check)) return NAN; + + const float z1 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("1st Probe Z:", z1); + + // Raise to give the probe clearance + do_z_clearance(z1 + (Z_CLEARANCE_MULTI_PROBE), false); + + #elif Z_PROBE_FEEDRATE_FAST != Z_PROBE_FEEDRATE_SLOW + + // If the nozzle is well over the travel height then + // move down quickly before doing the slow probe + const float z = (Z_CLEARANCE_DEPLOY_PROBE) + 5.0f + _MAX(zoffs, 0.0f); + if (current_position.z > z) { + // Probe down fast. If the probe never triggered, raise for probe clearance + if (!probe_down_to_z(z, z_probe_fast_mm_s)) + do_z_clearance(z_clearance); } + #endif + + #if EXTRA_PROBING > 0 + float probes[TOTAL_PROBING]; + #endif + + #if TOTAL_PROBING > 2 + float probes_z_sum = 0; + for ( + #if EXTRA_PROBING > 0 + uint8_t p = 0; p < TOTAL_PROBING; p++ + #else + uint8_t p = TOTAL_PROBING; p--; + #endif + ) + #endif + { + // If the probe won't tare, return + if (TERN0(PROBE_TARE, tare())) return true; + + // Probe downward slowly to find the bed + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Slow Probe:"); + if (try_to_probe(PSTR("SLOW"), z_probe_low_point, MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW), sanity_check)) return NAN; + + TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe()); + + const float z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj); + + #if EXTRA_PROBING > 0 + // Insert Z measurement into probes[]. Keep it sorted ascending. + for (uint8_t i = 0; i <= p; ++i) { // Iterate the saved Zs to insert the new Z + if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z + for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point + probes[i] = z; // Insert the new Z measurement + break; // Only one to insert. Done! + } + } + #elif TOTAL_PROBING > 2 + probes_z_sum += z; + #else + UNUSED(z); + #endif + + #if TOTAL_PROBING > 2 + // Small Z raise after all but the last probe + if (p + #if EXTRA_PROBING > 0 + < TOTAL_PROBING - 1 + #endif + ) do_z_clearance(z + (Z_CLEARANCE_MULTI_PROBE), false); + #endif + } + + #if TOTAL_PROBING > 2 + + #if EXTRA_PROBING > 0 + // Take the center value (or average the two middle values) as the median + static constexpr int PHALF = (TOTAL_PROBING - 1) / 2; + const float middle = probes[PHALF], + median = ((TOTAL_PROBING) & 1) ? middle : (middle + probes[PHALF + 1]) * 0.5f; + + // Remove values farthest from the median + uint8_t min_avg_idx = 0, max_avg_idx = TOTAL_PROBING - 1; + for (uint8_t i = EXTRA_PROBING; i--;) + if (ABS(probes[max_avg_idx] - median) > ABS(probes[min_avg_idx] - median)) + max_avg_idx--; else min_avg_idx++; + + // Return the average value of all remaining probes. + for (uint8_t i = min_avg_idx; i <= max_avg_idx; ++i) + probes_z_sum += probes[i]; + + #endif + + const float measured_z = probes_z_sum * RECIPROCAL(MULTIPLE_PROBING); + + #elif TOTAL_PROBING == 2 + + const float z2 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj); + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", z1 - z2); + + // Return a weighted average of the fast and slow probes + const float measured_z = (z2 * 3.0f + z1 * 2.0f) * 0.2f; + #else - UNUSED(plbl); + + // Return the single probe result + const float measured_z = current_position.z; + #endif - return probe_fail || early_fail; - }; - // Stop the probe before it goes too low to prevent damage. - // For known Z probe below the expected trigger point, otherwise -10mm lower. - const float z_probe_low_point = zoffs + z_min_point -float((!axis_is_trusted(Z_AXIS)) * 10); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe Low Point: ", z_probe_low_point); + return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z); + } + +#else // if DWIN_LCD_PROUI - // Double-probing does a fast probe followed by a slow probe - #if TOTAL_PROBING == 2 + float Probe::run_z_probe(const bool sanity_check/*=true*/, const_float_t z_min_point/*=Z_PROBE_LOW_POINT*/, const_float_t z_clearance/*=Z_TWEEN_SAFE_CLEARANCE*/) { + DEBUG_SECTION(log_probe, "Probe::run_z_probe", DEBUGGING(LEVELING)); + + const float zoffs = SUM_TERN(HAS_HOTEND_OFFSET, -offset.z, hotend_offset[active_extruder].z); + + auto try_to_probe = [&](PGM_P const plbl, const_float_t z_probe_low_point, const feedRate_t fr_mm_s, const bool scheck) -> bool { + constexpr float error_tolerance = Z_PROBE_ERROR_TOLERANCE; + if (DEBUGGING(LEVELING)) { + DEBUG_ECHOPGM_P(plbl); + DEBUG_ECHOLNPGM("> try_to_probe(..., ", z_probe_low_point, ", ", fr_mm_s, ", ...)"); + } + + // Tare the probe, if supported + if (TERN0(PROBE_TARE, tare())) return true; + + // Do a first probe at the fast speed + const bool probe_fail = probe_down_to_z(z_probe_low_point, fr_mm_s), // No probe trigger? + early_fail = (scheck && current_position.z > zoffs + error_tolerance); // Probe triggered too high? + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING) && (probe_fail || early_fail)) { + DEBUG_ECHOPGM(" Probe fail! - "); + if (probe_fail) DEBUG_ECHOLNPGM("No trigger."); + if (early_fail) DEBUG_ECHOLNPGM("Triggered early (above ", zoffs + error_tolerance, "mm)"); + } + #else + UNUSED(plbl); + #endif + return probe_fail || early_fail; + }; + + // Stop the probe before it goes too low to prevent damage. + // For known Z probe below the expected trigger point, otherwise -10mm lower. + const float z_probe_low_point = zoffs + z_min_point - float((!axis_is_trusted(Z_AXIS)) * 10); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probe Low Point: ", z_probe_low_point); + + // Double-probing does a fast probe followed by a slow probe // Attempt to tare the probe if (TERN0(PROBE_TARE, tare())) return NAN; @@ -798,33 +955,8 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/, const_float_t z_min_p // Raise to give the probe clearance do_z_clearance(z1 + (Z_CLEARANCE_MULTI_PROBE), false); - #elif Z_PROBE_FEEDRATE_FAST != Z_PROBE_FEEDRATE_SLOW - - // If the nozzle is well over the travel height then - // move down quickly before doing the slow probe - const float z = (Z_CLEARANCE_DEPLOY_PROBE) + 5.0f + _MAX(zoffs, 0.0f); - if (current_position.z > z) { - // Probe down fast. If the probe never triggered, raise for probe clearance - if (!probe_down_to_z(z, z_probe_fast_mm_s)) - do_z_clearance(z_clearance); - } - #endif - - #if EXTRA_PROBING > 0 - float probes[TOTAL_PROBING]; - #endif - - #if TOTAL_PROBING > 2 float probes_z_sum = 0; - for ( - #if EXTRA_PROBING > 0 - uint8_t p = 0; p < TOTAL_PROBING; p++ - #else - uint8_t p = TOTAL_PROBING; p--; - #endif - ) - #endif - { + for (uint8_t p = 0; p < hmiData.multiple_probing - 1; p++) { // If the probe won't tare, return if (TERN0(PROBE_TARE, tare())) return true; @@ -835,72 +967,19 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/, const_float_t z_min_p TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe()); const float z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj); - - #if EXTRA_PROBING > 0 - // Insert Z measurement into probes[]. Keep it sorted ascending. - for (uint8_t i = 0; i <= p; ++i) { // Iterate the saved Zs to insert the new Z - if (i == p || probes[i] > z) { // Last index or new Z is smaller than this Z - for (int8_t m = p; --m >= i;) probes[m + 1] = probes[m]; // Shift items down after the insertion point - probes[i] = z; // Insert the new Z measurement - break; // Only one to insert. Done! - } - } - #elif TOTAL_PROBING > 2 - probes_z_sum += z; - #else - UNUSED(z); - #endif - - #if TOTAL_PROBING > 2 - // Small Z raise after all but the last probe - if (p - #if EXTRA_PROBING > 0 - < TOTAL_PROBING - 1 - #endif - ) do_z_clearance(z + (Z_CLEARANCE_MULTI_PROBE), false); - #endif + probes_z_sum += z; + // Small Z raise after probe + do_z_clearance(z + (Z_CLEARANCE_MULTI_PROBE), false); } - #if TOTAL_PROBING > 2 - - #if EXTRA_PROBING > 0 - // Take the center value (or average the two middle values) as the median - static constexpr int PHALF = (TOTAL_PROBING - 1) / 2; - const float middle = probes[PHALF], - median = ((TOTAL_PROBING) & 1) ? middle : (middle + probes[PHALF + 1]) * 0.5f; - - // Remove values farthest from the median - uint8_t min_avg_idx = 0, max_avg_idx = TOTAL_PROBING - 1; - for (uint8_t i = EXTRA_PROBING; i--;) - if (ABS(probes[max_avg_idx] - median) > ABS(probes[min_avg_idx] - median)) - max_avg_idx--; else min_avg_idx++; - - // Return the average value of all remaining probes. - for (uint8_t i = min_avg_idx; i <= max_avg_idx; ++i) - probes_z_sum += probes[i]; - - #endif - - const float measured_z = probes_z_sum * RECIPROCAL(MULTIPLE_PROBING); - - #elif TOTAL_PROBING == 2 - - const float z2 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj); - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", z1 - z2); - // Return a weighted average of the fast and slow probes - const float measured_z = (z2 * 3.0f + z1 * 2.0f) * 0.2f; + const float measured_z = (hmiData.multiple_probing > 1) ? + (probes_z_sum * 3.0f + z1 * 2.0f) * 0.2f : z1; - #else - - // Return the single probe result - const float measured_z = current_position.z; - - #endif + return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z); + } - return DIFF_TERN(HAS_HOTEND_OFFSET, measured_z, hotend_offset[active_extruder].z); -} +#endif // !DWIN_LCD_PROUI #if DO_TOOLCHANGE_FOR_PROBING