MarlinUI support for up to 5 Material Presets (#18488)

- Add `I` preset parameter to `G26`, `M106`, `M140`, and `M190`.
- Extend menu items to permit a string interpolation.
- Keep material names in a list and interpolate in menu items.
- Extend material presets to support up to 5 predefined materials.

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Giuliano Zaro
2020-07-09 10:11:57 +02:00
committed by GitHub
parent abc5c93986
commit b0c6cfb051
51 changed files with 1179 additions and 870 deletions

View File

@ -62,6 +62,7 @@ menuPosition screen_history[6];
uint8_t screen_history_depth = 0;
int8_t MenuItemBase::itemIndex; // Index number for draw and action
PGM_P MenuItemBase::itemString; // A PSTR for substitution
chimera_t editable; // Value Editing
// Menu Edit Items

View File

@ -63,12 +63,14 @@ typedef void (*selectFunc_t)();
class MenuItemBase {
public:
// An index to interject in the item label and for
// use by the action
// Index to interject in the item label and/or for use by its action.
static int8_t itemIndex;
// An optional pointer for use in display or by the action
static PGM_P itemString;
// Store the index of the item ahead of use by indexed items
FORCE_INLINE static void init(const int8_t ind) { itemIndex = ind; }
FORCE_INLINE static void init(const int8_t ind=0, PGM_P const pstr=nullptr) { itemIndex = ind; itemString = pstr; }
// Draw an item either selected (pre_char) or not (space) with post_char
static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char);
@ -221,7 +223,7 @@ class MenuEditItemBase : public MenuItemBase {
public:
// Implemented for HD44780 and DOGM
// Draw the current item at specified row with edit data
static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm=false);
static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const inStr, const bool pgm=false);
// Implemented for HD44780 and DOGM
// This low-level method is good to draw from anywhere
@ -403,15 +405,15 @@ class MenuItem_bool : public MenuEditItemBase {
*/
#define _MENU_INNER_P(TYPE, USE_MULTIPLIER, PLABEL, V...) do { \
PGM_P const plabel = PLABEL; \
if (encoderLine == _thisItemNr && ui.use_click()) { \
_MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER); \
MenuItem_##TYPE::action(plabel, ##V); \
if (ui.screen_changed) return; \
} \
if (ui.should_draw()) \
MenuItem_##TYPE::draw \
(encoderLine == _thisItemNr, _lcdLineNr, plabel, ##V); \
PGM_P const plabel = PLABEL; \
if (encoderLine == _thisItemNr && ui.use_click()) { \
_MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER); \
MenuItem_##TYPE::action(plabel, ##V); \
if (ui.screen_changed) return; \
} \
if (ui.should_draw()) \
MenuItem_##TYPE::draw \
(encoderLine == _thisItemNr, _lcdLineNr, plabel, ##V); \
}while(0)
#define _MENU_ITEM_P(TYPE, V...) do { \
@ -421,11 +423,31 @@ class MenuItem_bool : public MenuEditItemBase {
NEXT_ITEM(); \
}while(0)
// Indexed items set a global index value and optional data
#define _MENU_ITEM_N_S_P(TYPE, N, S, V...) do{ \
_skipStatic = false; \
if (_menuLineNr == _thisItemNr) { \
MenuItemBase::init(N, S); \
_MENU_INNER_P(TYPE, ##V); \
} \
NEXT_ITEM(); \
}while(0)
// Indexed items set a global index value
#define _MENU_ITEM_N_P(TYPE, N, V...) do{ \
_skipStatic = false; \
if (_menuLineNr == _thisItemNr) { \
MenuItemBase::init(N); \
MenuItemBase::itemIndex = N; \
_MENU_INNER_P(TYPE, ##V); \
} \
NEXT_ITEM(); \
}while(0)
// Items with a unique string
#define _MENU_ITEM_S_P(TYPE, S, V...) do{ \
_skipStatic = false; \
if (_menuLineNr == _thisItemNr) { \
MenuItemBase::itemString = S; \
_MENU_INNER_P(TYPE, ##V); \
} \
NEXT_ITEM(); \
@ -457,72 +479,94 @@ class MenuItem_bool : public MenuEditItemBase {
NEXT_ITEM(); \
}while(0)
#define STATIC_ITEM(LABEL, V...) STATIC_ITEM_P( GET_TEXT(LABEL), ##V)
#define STATIC_ITEM_N(LABEL, N, V...) STATIC_ITEM_N_P(GET_TEXT(LABEL), ##V)
#define STATIC_ITEM(LABEL, V...) STATIC_ITEM_P(GET_TEXT(LABEL), ##V)
#define STATIC_ITEM_N(LABEL, N, V...) STATIC_ITEM_N_P(GET_TEXT(LABEL), ##V)
#define MENU_ITEM_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, false, PLABEL, ##V)
#define MENU_ITEM(TYPE, LABEL, V...) MENU_ITEM_P(TYPE, GET_TEXT(LABEL), ##V)
#define MENU_ITEM_N_S_P(TYPE, N, S, PLABEL, V...) _MENU_ITEM_N_S_P(TYPE, N, S, false, PLABEL, ##V)
#define MENU_ITEM_N_S(TYPE, N, S, LABEL, V...) MENU_ITEM_N_S_P(TYPE, N, S, GET_TEXT(LABEL), ##V)
#define MENU_ITEM_S_P(TYPE, S, PLABEL, V...) _MENU_ITEM_S_P(TYPE, S, false, PLABEL, ##V)
#define MENU_ITEM_S(TYPE, S, LABEL, V...) MENU_ITEM_S_P(TYPE, S, GET_TEXT(LABEL), ##V)
#define MENU_ITEM_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, false, PLABEL, ##V)
#define MENU_ITEM_N(TYPE, N, LABEL, V...) MENU_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V)
#define MENU_ITEM_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, false, PLABEL, ##V)
#define MENU_ITEM(TYPE, LABEL, V...) MENU_ITEM_P(TYPE, GET_TEXT(LABEL), ##V)
#define MENU_ITEM_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, false, PLABEL, ##V)
#define MENU_ITEM_N(TYPE, N, LABEL, V...) MENU_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V)
#define BACK_ITEM(LABEL) MENU_ITEM(back, LABEL)
#define BACK_ITEM(LABEL) MENU_ITEM(back, LABEL)
#define ACTION_ITEM_N_S_P(N, S, PLABEL, ACTION) MENU_ITEM_N_S_P(function, N, S, PLABEL, ACTION)
#define ACTION_ITEM_N_S(N, S, LABEL, ACTION) ACTION_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ACTION)
#define ACTION_ITEM_S_P(S, PLABEL, ACTION) MENU_ITEM_S_P(function, S, PLABEL, ACTION)
#define ACTION_ITEM_S(S, LABEL, ACTION) ACTION_ITEM_S_P(S, GET_TEXT(LABEL), ACTION)
#define ACTION_ITEM_N_P(N, PLABEL, ACTION) MENU_ITEM_N_P(function, N, PLABEL, ACTION)
#define ACTION_ITEM_N(N, LABEL, ACTION) ACTION_ITEM_N_P(N, GET_TEXT(LABEL), ACTION)
#define ACTION_ITEM_P(PLABEL, ACTION) MENU_ITEM_P(function, PLABEL, ACTION)
#define ACTION_ITEM(LABEL, ACTION) ACTION_ITEM_P(GET_TEXT(LABEL), ACTION)
#define ACTION_ITEM_P(PLABEL, ACTION) MENU_ITEM_P(function, PLABEL, ACTION)
#define ACTION_ITEM(LABEL, ACTION) ACTION_ITEM_P(GET_TEXT(LABEL), ACTION)
#define GCODES_ITEM_N_S_P(N, S, PLABEL, GCODES) MENU_ITEM_N_S_P(gcode, N, S, PLABEL, GCODES)
#define GCODES_ITEM_N_S(N, S, LABEL, GCODES) GCODES_ITEM_N_S_P(N, S, GET_TEXT(LABEL), GCODES)
#define GCODES_ITEM_S_P(S, PLABEL, GCODES) MENU_ITEM_S_P(gcode, S, PLABEL, GCODES)
#define GCODES_ITEM_S(S, LABEL, GCODES) GCODES_ITEM_S_P(S, GET_TEXT(LABEL), GCODES)
#define GCODES_ITEM_N_P(N, PLABEL, GCODES) MENU_ITEM_N_P(gcode, N, PLABEL, GCODES)
#define GCODES_ITEM_N(N, LABEL, GCODES) GCODES_ITEM_N_P(N, GET_TEXT(LABEL), GCODES)
#define GCODES_ITEM_P(PLABEL, GCODES) MENU_ITEM_P(gcode, PLABEL, GCODES)
#define GCODES_ITEM(LABEL, GCODES) GCODES_ITEM_P(GET_TEXT(LABEL), GCODES)
#define ACTION_ITEM_N_P(N, PLABEL, ACTION) MENU_ITEM_N_P(function, N, PLABEL, ACTION)
#define ACTION_ITEM_N(N, LABEL, ACTION) ACTION_ITEM_N_P(N, GET_TEXT(LABEL), ACTION)
#define SUBMENU_N_S_P(N, S, PLABEL, DEST) MENU_ITEM_N_S_P(submenu, N, S, PLABEL, DEST)
#define SUBMENU_N_S(N, S, LABEL, DEST) SUBMENU_N_S_P(N, S, GET_TEXT(LABEL), DEST)
#define SUBMENU_S_P(S, PLABEL, DEST) MENU_ITEM_S_P(submenu, S, PLABEL, DEST)
#define SUBMENU_S(S, LABEL, DEST) SUBMENU_S_P(S, GET_TEXT(LABEL), DEST)
#define SUBMENU_N_P(N, PLABEL, DEST) MENU_ITEM_N_P(submenu, N, PLABEL, DEST)
#define SUBMENU_N(N, LABEL, DEST) SUBMENU_N_P(N, GET_TEXT(LABEL), DEST)
#define SUBMENU_P(PLABEL, DEST) MENU_ITEM_P(submenu, PLABEL, DEST)
#define SUBMENU(LABEL, DEST) SUBMENU_P(GET_TEXT(LABEL), DEST)
#define GCODES_ITEM_P(PLABEL, GCODES) MENU_ITEM_P(gcode, PLABEL, GCODES)
#define GCODES_ITEM(LABEL, GCODES) GCODES_ITEM_P(GET_TEXT(LABEL), GCODES)
#define EDIT_ITEM_N_S_P(TYPE, N, S, PLABEL, V...) MENU_ITEM_N_S_P(TYPE, N, S, PLABEL, ##V)
#define EDIT_ITEM_N_S(TYPE, N, S, LABEL, V...) EDIT_ITEM_N_S_P(TYPE, N, S, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_S_P(TYPE, S, PLABEL, V...) MENU_ITEM_S_P(TYPE, S, PLABEL, ##V)
#define EDIT_ITEM_S(TYPE, S, LABEL, V...) EDIT_ITEM_S_P(TYPE, S, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_N_P(TYPE, N, PLABEL, V...) MENU_ITEM_N_P(TYPE, N, PLABEL, ##V)
#define EDIT_ITEM_N(TYPE, N, LABEL, V...) EDIT_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_P(TYPE, PLABEL, V...) MENU_ITEM_P(TYPE, PLABEL, ##V)
#define EDIT_ITEM(TYPE, LABEL, V...) EDIT_ITEM_P(TYPE, GET_TEXT(LABEL), ##V)
#define GCODES_ITEM_N_P(N, PLABEL, GCODES) MENU_ITEM_N_P(gcode, N, PLABEL, GCODES)
#define GCODES_ITEM_N(N, LABEL, GCODES) GCODES_ITEM_N_P(N, GET_TEXT(LABEL), GCODES)
#define EDIT_ITEM_FAST_N_S_P(TYPE, N, S, PLABEL, V...) _MENU_ITEM_N_S_P(TYPE, N, S, true, PLABEL, ##V)
#define EDIT_ITEM_FAST_N_S(TYPE, N, S, LABEL, V...) EDIT_ITEM_FAST_N_S_P(TYPE, N, S, true, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_FAST_S_P(TYPE, S, PLABEL, V...) _MENU_ITEM_S_P(TYPE, S, true, PLABEL, ##V)
#define EDIT_ITEM_FAST_S(TYPE, S, LABEL, V...) EDIT_ITEM_FAST_S_P(TYPE, S, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_FAST_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, true, PLABEL, ##V)
#define EDIT_ITEM_FAST_N(TYPE, N, LABEL, V...) EDIT_ITEM_FAST_N_P(TYPE, N, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_FAST_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, true, PLABEL, ##V)
#define EDIT_ITEM_FAST(TYPE, LABEL, V...) EDIT_ITEM_FAST_P(TYPE, GET_TEXT(LABEL), ##V)
#define SUBMENU_P(PLABEL, DEST) MENU_ITEM_P(submenu, PLABEL, DEST)
#define SUBMENU(LABEL, DEST) SUBMENU_P(GET_TEXT(LABEL), DEST)
#define SUBMENU_N_P(N, PLABEL, DEST) MENU_ITEM_N_P(submenu, N, PLABEL, DEST)
#define SUBMENU_N(N, LABEL, DEST) SUBMENU_N_P(N, GET_TEXT(LABEL), DEST)
#define EDIT_ITEM_P(TYPE, PLABEL, V...) MENU_ITEM_P(TYPE, PLABEL, ##V)
#define EDIT_ITEM(TYPE, LABEL, V...) EDIT_ITEM_P(TYPE, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_N_P(TYPE, N, PLABEL, V...) MENU_ITEM_N_P(TYPE, N, PLABEL, ##V)
#define EDIT_ITEM_N(TYPE, N, LABEL, V...) EDIT_ITEM_N_P(TYPE, N, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_FAST_P(TYPE, PLABEL, V...) _MENU_ITEM_P(TYPE, true, PLABEL, ##V)
#define EDIT_ITEM_FAST(TYPE, LABEL, V...) EDIT_ITEM_FAST_P(TYPE, GET_TEXT(LABEL), ##V)
#define EDIT_ITEM_FAST_N_P(TYPE, N, PLABEL, V...) _MENU_ITEM_N_P(TYPE, N, true, PLABEL, ##V)
#define EDIT_ITEM_FAST_N(TYPE, N, LABEL, V...) EDIT_ITEM_FAST_N_P(TYPE, N, GET_TEXT(LABEL), ##V)
#define _CONFIRM_ITEM_INNER_P(PLABEL, V...) do { \
if (encoderLine == _thisItemNr && ui.use_click()) { \
ui.goto_screen([]{MenuItem_confirm::select_screen(V);}); \
return; \
} \
if (ui.should_draw()) MenuItem_confirm::draw \
(encoderLine == _thisItemNr, _lcdLineNr, PLABEL, ##V); \
#define _CONFIRM_ITEM_INNER_P(PLABEL, V...) do { \
if (encoderLine == _thisItemNr && ui.use_click()) { \
ui.goto_screen([]{MenuItem_confirm::select_screen(V);}); \
return; \
} \
if (ui.should_draw()) MenuItem_confirm::draw \
(encoderLine == _thisItemNr, _lcdLineNr, PLABEL, ##V); \
}while(0)
#define _CONFIRM_ITEM_P(PLABEL, V...) do { \
// Indexed items set a global index value and optional data
#define _CONFIRM_ITEM_P(PLABEL, V...) do { \
_skipStatic = false; \
if (_menuLineNr == _thisItemNr) \
_CONFIRM_ITEM_INNER_P(PLABEL, ##V); \
NEXT_ITEM(); \
}while(0)
// Indexed items set a global index value
#define _CONFIRM_ITEM_N_S_P(N, S, V...) do{ \
_skipStatic = false; \
if (_menuLineNr == _thisItemNr) \
_CONFIRM_ITEM_INNER_P(PLABEL, ##V); \
if (_menuLineNr == _thisItemNr) { \
MenuItemBase::init(N, S); \
_CONFIRM_ITEM_INNER_P(TYPE, ##V); \
} \
NEXT_ITEM(); \
}while(0)
// Indexed items set a global index value
#define _CONFIRM_ITEM_N_P(N, V...) do{ \
_skipStatic = false; \
if (_menuLineNr == _thisItemNr) { \
MenuItemBase::init(N); \
_CONFIRM_ITEM_INNER_P(TYPE, ##V); \
} \
NEXT_ITEM(); \
}while(0)
#define _CONFIRM_ITEM_N_P(N, V...) _CONFIRM_ITEM_N_S_P(N, nullptr, V)
#define CONFIRM_ITEM_P(PLABEL,A,B,V...) _CONFIRM_ITEM_P(PLABEL, GET_TEXT(A), GET_TEXT(B), ##V)
#define CONFIRM_ITEM(LABEL, V...) CONFIRM_ITEM_P(GET_TEXT(LABEL), ##V)
@ -530,11 +574,15 @@ class MenuItem_bool : public MenuEditItemBase {
#define YESNO_ITEM_P(PLABEL, V...) _CONFIRM_ITEM_P(PLABEL, ##V)
#define YESNO_ITEM(LABEL, V...) YESNO_ITEM_P(GET_TEXT(LABEL), ##V)
#define CONFIRM_ITEM_N_P(N,PLABEL,A,B,V...) _CONFIRM_ITEM_N_P(N, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V)
#define CONFIRM_ITEM_N(N,LABEL, V...) CONFIRM_ITEM_N_P(N, GET_TEXT(LABEL), ##V)
#define CONFIRM_ITEM_N_S_P(N,S,PLABEL,A,B,V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V)
#define CONFIRM_ITEM_N_S(N,S,LABEL,V...) CONFIRM_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V)
#define CONFIRM_ITEM_N_P(N,PLABEL,A,B,V...) _CONFIRM_ITEM_N_P(N, PLABEL, GET_TEXT(A), GET_TEXT(B), ##V)
#define CONFIRM_ITEM_N(N,LABEL, V...) CONFIRM_ITEM_N_P(N, GET_TEXT(LABEL), ##V)
#define YESNO_ITEM_N_P(N,PLABEL, V...) _CONFIRM_ITEM_N_P(N, PLABEL, ##V)
#define YESNO_ITEM_N(N,LABEL, V...) YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V)
#define YESNO_ITEM_N_S_P(N,S,PLABEL, V...) _CONFIRM_ITEM_N_S_P(N, S, PLABEL, ##V)
#define YESNO_ITEM_N_S(N,S,LABEL, V...) YESNO_ITEM_N_S_P(N, S, GET_TEXT(LABEL), ##V)
#define YESNO_ITEM_N_P(N,PLABEL, V...) _CONFIRM_ITEM_N_P(N, PLABEL, ##V)
#define YESNO_ITEM_N(N,LABEL, V...) YESNO_ITEM_N_P(N, GET_TEXT(LABEL), ##V)
////////////////////////////////////////////
/////////////// Menu Screens ///////////////

View File

@ -22,9 +22,6 @@
#pragma once
#include "../lcdprint.h"
#if HAS_GRAPHICAL_LCD
#include "../dogm/ultralcd_DOGM.h"
#endif
#define MENU_ITEM_ADDON_START(X) do{ \
if (ui.should_draw() && _menuLineNr == _thisItemNr - 1) { \

View File

@ -300,11 +300,12 @@ void menu_advanced_settings();
#if PREHEAT_COUNT && DISABLED(SLIM_LCD_MENUS)
void _menu_configuration_preheat_settings(const uint8_t m) {
void _menu_configuration_preheat_settings() {
#define _MINTEMP_ITEM(N) HEATER_##N##_MINTEMP,
#define _MAXTEMP_ITEM(N) HEATER_##N##_MAXTEMP,
#define MINTEMP_ALL _MIN(REPEAT(HOTENDS, _MINTEMP_ITEM) 999)
#define MAXTEMP_ALL _MAX(REPEAT(HOTENDS, _MAXTEMP_ITEM) 0)
const uint8_t m = MenuItemBase::itemIndex;
START_MENU();
BACK_ITEM(MSG_CONFIGURATION);
#if HAS_FAN
@ -323,18 +324,6 @@ void menu_advanced_settings();
END_MENU();
}
void menu_preheat_material1_settings() { _menu_configuration_preheat_settings(0); }
void menu_preheat_material2_settings() { _menu_configuration_preheat_settings(1); }
#if PREHEAT_COUNT >= 3
void menu_preheat_material3_settings() { _menu_configuration_preheat_settings(3); }
#if PREHEAT_COUNT >= 4
void menu_preheat_material4_settings() { _menu_configuration_preheat_settings(4); }
#if PREHEAT_COUNT >= 5
void menu_preheat_material5_settings() { _menu_configuration_preheat_settings(5); }
#endif
#endif
#endif
#endif
void menu_configuration() {
@ -414,17 +403,8 @@ void menu_configuration() {
// Preheat configurations
#if PREHEAT_COUNT && DISABLED(SLIM_LCD_MENUS)
SUBMENU(MSG_PREHEAT_1_SETTINGS, menu_preheat_material1_settings);
SUBMENU(MSG_PREHEAT_2_SETTINGS, menu_preheat_material2_settings);
#if PREHEAT_COUNT >= 3
SUBMENU(MSG_PREHEAT_3_SETTINGS, menu_preheat_material3_settings);
#if PREHEAT_COUNT >= 4
SUBMENU(MSG_PREHEAT_4_SETTINGS, menu_preheat_material4_settings);
#if PREHEAT_COUNT >= 5
SUBMENU(MSG_PREHEAT_5_SETTINGS, menu_preheat_material5_settings);
#endif
#endif
#endif
LOOP_L_N(m, PREHEAT_COUNT)
SUBMENU_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings);
#endif
#if ENABLED(EEPROM_SETTINGS)

View File

@ -55,13 +55,21 @@ inline PGM_P _change_filament_command() {
}
// Initiate Filament Load/Unload/Change at the specified temperature
static void _change_filament(const uint16_t celsius) {
static void _change_filament_with_temp(const uint16_t celsius) {
char cmd[11];
sprintf_P(cmd, _change_filament_command(), _change_filament_extruder);
thermalManager.setTargetHotend(celsius, _change_filament_extruder);
queue.inject(cmd);
}
static void _change_filament_with_preset() {
_change_filament_with_temp(ui.material_preset[MenuItemBase::itemIndex].hotend_temp);
}
static void _change_filament_with_custom() {
_change_filament_with_temp(thermalManager.temp_hotend[MenuItemBase::itemIndex].target);
}
//
// Menu to choose the temperature and start Filament Change
//
@ -81,11 +89,14 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) {
START_MENU();
if (LCD_HEIGHT >= 4) STATIC_ITEM_P(change_filament_header(mode), SS_CENTER|SS_INVERT);
BACK_ITEM(MSG_BACK);
ACTION_ITEM(MSG_PREHEAT_1, []{ _change_filament(ui.material_preset[0].hotend_temp); });
ACTION_ITEM(MSG_PREHEAT_2, []{ _change_filament(ui.material_preset[1].hotend_temp); });
EDIT_ITEM_FAST(int3, MSG_PREHEAT_CUSTOM, &thermalManager.temp_hotend[_change_filament_extruder].target, EXTRUDE_MINTEMP, thermalManager.heater_maxtemp[extruder] - HOTEND_OVERSHOOT, []{
_change_filament(thermalManager.temp_hotend[_change_filament_extruder].target);
});
#if PREHEAT_COUNT
LOOP_L_N(m, PREHEAT_COUNT)
ACTION_ITEM_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M, _change_filament_with_preset);
#endif
EDIT_ITEM_FAST_N(int3, extruder, MSG_PREHEAT_CUSTOM, &thermalManager.temp_hotend[extruder].target,
EXTRUDE_MINTEMP, thermalManager.heater_maxtemp[extruder] - HOTEND_OVERSHOOT,
_change_filament_with_custom
);
END_MENU();
}

View File

@ -66,95 +66,76 @@ void Temperature::lcd_preheat(const int16_t e, const int8_t indh, const int8_t i
ui.return_to_status();
}
#if HAS_TEMP_HOTEND
inline void _preheat_end(const uint8_t m, const uint8_t e) { thermalManager.lcd_preheat(e, m, -1); }
#if HAS_HEATED_BED
inline void _preheat_both(const uint8_t m, const uint8_t e) { thermalManager.lcd_preheat(e, m, m); }
#endif
#endif
#if HAS_HEATED_BED
inline void _preheat_bed(const uint8_t m) { thermalManager.lcd_preheat(-1, -1, m); }
#endif
#if PREHEAT_COUNT
#if HAS_TEMP_HOTEND || HAS_HEATED_BED
#if HAS_TEMP_HOTEND
inline void _preheat_end(const uint8_t m, const uint8_t e) { thermalManager.lcd_preheat(e, m, -1); }
#if HAS_HEATED_BED
inline void _preheat_both(const uint8_t m, const uint8_t e) { thermalManager.lcd_preheat(e, m, m); }
#endif
#endif
#if HAS_HEATED_BED
inline void _preheat_bed(const uint8_t m) { thermalManager.lcd_preheat(-1, -1, m); }
#endif
#if HAS_TEMP_HOTEND && HAS_HEATED_BED
// Indexed "Preheat ABC" and "Heat Bed" items
#define PREHEAT_ITEMS(M,E) do{ \
ACTION_ITEM_N_P(E, msg_preheat_h[M], []{ _preheat_both(M, MenuItemBase::itemIndex); }); \
ACTION_ITEM_N_P(E, msg_preheat_end_e[M], []{ _preheat_end(M, MenuItemBase::itemIndex); }); \
ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_both(M, MenuItemBase::itemIndex); }); \
ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_END_E, []{ _preheat_end(M, MenuItemBase::itemIndex); }); \
}while(0)
#elif HAS_MULTI_HOTEND
// No heated bed, so just indexed "Preheat ABC" items
#define PREHEAT_ITEMS(M,E) ACTION_ITEM_N_P(E, msg_preheat_h[M], []{ _preheat_end(M, MenuItemBase::itemIndex); })
#define PREHEAT_ITEMS(M,E) ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_end(M, MenuItemBase::itemIndex); })
#endif
void menu_preheat_m(const uint8_t m) {
void do_preheat_end_m() { _preheat_end(editable.int8, 0); }
#if HAS_MULTI_HOTEND || HAS_HEATED_BED
// Set editable.int8 to the Material index before entering this menu
// because MenuItemBase::itemIndex will be re-used by PREHEAT_ITEMS
void menu_preheat_m() {
const uint8_t m = editable.int8; // Don't re-use 'editable' in this menu
START_MENU();
BACK_ITEM(MSG_TEMPERATURE);
#if HOTENDS == 1
#if HAS_HEATED_BED
ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, []{ _preheat_both(editable.int8, 0); });
ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_END, do_preheat_end_m);
#else
ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
#endif
#elif HAS_MULTI_HOTEND
HOTEND_LOOP() PREHEAT_ITEMS(editable.int8, e);
ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_ALL, []() {
TERN_(HAS_HEATED_BED, []{ _preheat_bed(editable.int8); });
HOTEND_LOOP() thermalManager.setTargetHotend(ui.material_preset[editable.int8].hotend_temp, e);
});
#if HOTENDS == 1
PGM_P msg_preheat[] = ARRAY_N(PREHEAT_COUNT, GET_TEXT(MSG_PREHEAT_1), GET_TEXT(MSG_PREHEAT_2), GET_TEXT(MSG_PREHEAT_3), GET_TEXT(MSG_PREHEAT_4), GET_TEXT(MSG_PREHEAT_5));
#if HAS_HEATED_BED
PGM_P msg_preheat_end[] = ARRAY_N(PREHEAT_COUNT, GET_TEXT(MSG_PREHEAT_1_END), GET_TEXT(MSG_PREHEAT_2_END), GET_TEXT(MSG_PREHEAT_3_END), GET_TEXT(MSG_PREHEAT_4_END), GET_TEXT(MSG_PREHEAT_5_END));
#endif
#elif HAS_MULTI_HOTEND
PGM_P msg_preheat_all[] = ARRAY_N(PREHEAT_COUNT, GET_TEXT(MSG_PREHEAT_1_ALL), GET_TEXT(MSG_PREHEAT_2_ALL), GET_TEXT(MSG_PREHEAT_3_ALL), GET_TEXT(MSG_PREHEAT_4_ALL), GET_TEXT(MSG_PREHEAT_5_ALL));
#endif
#if HAS_TEMP_HOTEND && HAS_HEATED_BED && HAS_MULTI_HOTEND
PGM_P msg_preheat_end_e[] = ARRAY_N(PREHEAT_COUNT, GET_TEXT(MSG_PREHEAT_1_END_E), GET_TEXT(MSG_PREHEAT_2_END_E), GET_TEXT(MSG_PREHEAT_3_END_E), GET_TEXT(MSG_PREHEAT_4_END_E), GET_TEXT(MSG_PREHEAT_5_END_E));
#endif
#if HAS_MULTI_HOTEND
PGM_P msg_preheat_h[] = ARRAY_N(PREHEAT_COUNT, GET_TEXT(MSG_PREHEAT_1_H), GET_TEXT(MSG_PREHEAT_2_H), GET_TEXT(MSG_PREHEAT_3_H), GET_TEXT(MSG_PREHEAT_4_H), GET_TEXT(MSG_PREHEAT_5_H));
#endif
MenuItemBase::itemIndex = m;
START_MENU();
BACK_ITEM(MSG_TEMPERATURE);
#if HOTENDS == 1
#if HAS_HEATED_BED
ACTION_ITEM_P(msg_preheat[m], []{ _preheat_both(MenuItemBase::itemIndex, 0); });
ACTION_ITEM_P(msg_preheat_end[m], []{ _preheat_end(MenuItemBase::itemIndex, 0); });
#else
ACTION_ITEM_P(msg_preheat[m], []{ _preheat_end(MenuItemBase::itemIndex, 0); });
ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_BEDONLY, []{ _preheat_bed(editable.int8); });
#endif
#elif HAS_MULTI_HOTEND
END_MENU();
}
LOOP_S_L_N(n, 0, HOTENDS) PREHEAT_ITEMS(MenuItemBase::itemIndex, n);
ACTION_ITEM_P(msg_preheat_all[m], []() {
TERN_(HAS_HEATED_BED, _preheat_bed(MenuItemBase::itemIndex));
HOTEND_LOOP() thermalManager.setTargetHotend(ui.material_preset[MenuItemBase::itemIndex].hotend_temp, e);
});
#endif // HAS_MULTI_HOTEND || HAS_HEATED_BED
#endif
#endif // PREHEAT_COUNT
#if HAS_HEATED_BED
PGM_P msg_preheat_bed[] = ARRAY_N(PREHEAT_COUNT, GET_TEXT(MSG_PREHEAT_1_BEDONLY), GET_TEXT(MSG_PREHEAT_2_BEDONLY), GET_TEXT(MSG_PREHEAT_3_BEDONLY), GET_TEXT(MSG_PREHEAT_4_BEDONLY), GET_TEXT(MSG_PREHEAT_5_BEDONLY));
ACTION_ITEM_P(msg_preheat_bed[m], []{ _preheat_bed(MenuItemBase::itemIndex); });
#endif
END_MENU();
}
void menu_preheat_m1() { menu_preheat_m(0); }
void menu_preheat_m2() { menu_preheat_m(1); }
#if PREHEAT_COUNT >= 3
void menu_preheat_m3() { menu_preheat_m(2); }
#if PREHEAT_COUNT >= 4
void menu_preheat_m4() { menu_preheat_m(3); }
#if PREHEAT_COUNT >= 5
void menu_preheat_m5() { menu_preheat_m(4); }
#endif
#endif
#endif
#if HAS_TEMP_HOTEND || HAS_HEATED_BED
void lcd_cooldown() {
thermalManager.zero_fan_speeds();
@ -165,9 +146,11 @@ void Temperature::lcd_preheat(const int16_t e, const int8_t indh, const int8_t i
#endif // HAS_TEMP_HOTEND || HAS_HEATED_BED
void menu_temperature() {
#if HAS_TEMP_HOTEND
#if HAS_TEMP_HOTEND || HAS_HEATED_BED
bool has_heat = false;
HOTEND_LOOP() if (thermalManager.temp_hotend[HOTEND_INDEX].target) { has_heat = true; break; }
#if HAS_TEMP_HOTEND
HOTEND_LOOP() if (thermalManager.temp_hotend[HOTEND_INDEX].target) { has_heat = true; break; }
#endif
#endif
START_MENU();
@ -279,44 +262,27 @@ void menu_temperature() {
#endif // HAS_FAN
#if HAS_TEMP_HOTEND
#if PREHEAT_COUNT
//
// Preheat for Material 1 and 2
// Preheat for Materials 1 to 5
//
#if HOTENDS > 1 || HAS_HEATED_BED
SUBMENU(MSG_PREHEAT_1, menu_preheat_m1);
SUBMENU(MSG_PREHEAT_2, menu_preheat_m2);
#if PREHEAT_COUNT >= 3
SUBMENU(MSG_PREHEAT_3, menu_preheat_m3);
#if PREHEAT_COUNT >= 4
SUBMENU(MSG_PREHEAT_4, menu_preheat_m4);
#if PREHEAT_COUNT >= 5
SUBMENU(MSG_PREHEAT_5, menu_preheat_m5);
#endif
#endif
LOOP_L_N(m, PREHEAT_COUNT) {
editable.int8 = m;
#if HOTENDS > 1 || HAS_HEATED_BED
SUBMENU_S(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m);
#else
ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
#endif
#else
ACTION_ITEM(MSG_PREHEAT_1, []{ _preheat_end(0, 0); });
ACTION_ITEM(MSG_PREHEAT_2, []{ _preheat_end(1, 0); });
#if PREHEAT_COUNT >= 3
ACTION_ITEM(MSG_PREHEAT_3, []{ _preheat_end(2, 0); });
#if PREHEAT_COUNT >= 3
ACTION_ITEM(MSG_PREHEAT_4, []{ _preheat_end(3, 0); });
#if PREHEAT_COUNT >= 3
ACTION_ITEM(MSG_PREHEAT_5, []{ _preheat_end(4, 0); });
#endif
#endif
#endif
#endif
}
#endif
#if HAS_TEMP_HOTEND || HAS_HEATED_BED
//
// Cooldown
//
if (TERN0(HAS_HEATED_BED, thermalManager.temp_bed.target)) has_heat = true;
if (has_heat) ACTION_ITEM(MSG_COOLDOWN, lcd_cooldown);
#endif // HAS_TEMP_HOTEND
#endif
END_MENU();
}

View File

@ -196,21 +196,36 @@ void _lcd_ubl_edit_mesh() {
* UBL Validate Mesh submenu
*
* << UBL Tools
* Mesh Validation with Material 1
* Mesh Validation with Material 2
* Mesh Validation with Material 1 up to 5
* Validate Custom Mesh
* << Info Screen
*/
void _lcd_ubl_validate_mesh() {
START_MENU();
BACK_ITEM(MSG_UBL_TOOLS);
#if HAS_HEATED_BED
GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M1, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_1_TEMP_BED) " H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P"));
GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M2, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_2_TEMP_BED) " H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P"));
#else
GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M1, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P"));
GCODES_ITEM(MSG_UBL_VALIDATE_MESH_M2, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P"));
#endif
#if PREHEAT_COUNT
#if HAS_HEATED_BED
#define VALIDATE_MESH_GCODE_ITEM(M) \
GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, PSTR("G28\nG26 C P I" STRINGIFY(M)))
#else
#define VALIDATE_MESH_GCODE_ITEM(M) \
GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, PSTR("G28\nG26 C P B0 I" STRINGIFY(M)))
#endif
VALIDATE_MESH_GCODE_ITEM(0);
#if PREHEAT_COUNT > 1
VALIDATE_MESH_GCODE_ITEM(1);
#if PREHEAT_COUNT > 2
VALIDATE_MESH_GCODE_ITEM(2);
#if PREHEAT_COUNT > 3
VALIDATE_MESH_GCODE_ITEM(3);
#if PREHEAT_COUNT > 4
VALIDATE_MESH_GCODE_ITEM(4);
#endif
#endif
#endif
#endif
#endif // PREHEAT_COUNT
ACTION_ITEM(MSG_UBL_VALIDATE_CUSTOM_MESH, _lcd_ubl_validate_custom_mesh);
ACTION_ITEM(MSG_INFO_SCREEN, ui.return_to_status);
END_MENU();
@ -292,8 +307,7 @@ void _lcd_ubl_invalidate() {
* UBL Build Mesh submenu
*
* << UBL Tools
* Build Mesh with Material 1
* Build Mesh with Material 2
* Build Mesh with Material 1 up to 5
* - Build Custom Mesh >>
* Build Cold Mesh
* - Fill-in Mesh >>
@ -305,37 +319,36 @@ void _lcd_ubl_invalidate() {
void _lcd_ubl_build_mesh() {
START_MENU();
BACK_ITEM(MSG_UBL_TOOLS);
#if HAS_HEATED_BED
GCODES_ITEM(MSG_UBL_BUILD_MESH_M1, PSTR(
"G28\n"
"M190 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\n"
"M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n"
"G29 P1\n"
"M104 S0\n"
"M140 S0"
));
GCODES_ITEM(MSG_UBL_BUILD_MESH_M2, PSTR(
"G28\n"
"M190 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\n"
"M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n"
"G29 P1\n"
"M104 S0\n"
"M140 S0"
));
#else
GCODES_ITEM(MSG_UBL_BUILD_MESH_M1, PSTR(
"G28\n"
"M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n"
"G29 P1\n"
"M104 S0"
));
GCODES_ITEM(MSG_UBL_BUILD_MESH_M2, PSTR(
"G28\n"
"M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n"
"G29 P1\n"
"M104 S0"
));
#endif
#if PREHEAT_COUNT
#if HAS_HEATED_BED
#define PREHEAT_BED_GCODE(M) "M190 I" STRINGIFY(M) "\n"
#else
#define PREHEAT_BED_GCODE(M) ""
#endif
#define BUILD_MESH_GCODE_ITEM(M) GCODES_ITEM_S(ui.get_preheat_label(M), MSG_UBL_BUILD_MESH_M, \
PSTR( \
"G28\n" \
PREHEAT_BED_GCODE(M) \
"M109 I" STRINGIFY(M) "\n" \
"G29 P1\n" \
"M104 S0\n" \
"M140 S0" \
) )
BUILD_MESH_GCODE_ITEM(0);
#if PREHEAT_COUNT > 1
BUILD_MESH_GCODE_ITEM(1);
#if PREHEAT_COUNT > 2
BUILD_MESH_GCODE_ITEM(2);
#if PREHEAT_COUNT > 3
BUILD_MESH_GCODE_ITEM(3);
#if PREHEAT_COUNT > 4
BUILD_MESH_GCODE_ITEM(4);
#endif
#endif
#endif
#endif
#endif // PREHEAT_COUNT
SUBMENU(MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_custom_mesh);
GCODES_ITEM(MSG_UBL_BUILD_COLD_MESH, PSTR("G28\nG29 P1"));
SUBMENU(MSG_UBL_FILLIN_MESH, _menu_ubl_fillin);