diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index cb36f4bc98a2..8b6af33fd11e 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -572,7 +572,7 @@ void menu_configuration() { // Preheat configurations #if HAS_PREHEAT && DISABLED(SLIM_LCD_MENUS) LOOP_L_N(m, PREHEAT_COUNT) - SUBMENU_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings); + SUBMENU_N_f(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings); #endif #if ENABLED(SOUND_MENU_ITEM) diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp index 2598278be5c5..5902a2f63f35 100644 --- a/Marlin/src/lcd/menu/menu_filament.cpp +++ b/Marlin/src/lcd/menu/menu_filament.cpp @@ -95,7 +95,7 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { BACK_ITEM(MSG_BACK); #if HAS_PREHEAT LOOP_L_N(m, PREHEAT_COUNT) - ACTION_ITEM_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M, _change_filament_with_preset); + ACTION_ITEM_N_f(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.hotend_max_target(extruder), diff --git a/Marlin/src/lcd/menu/menu_item.h b/Marlin/src/lcd/menu/menu_item.h index 3ffe96f627be..b48eaf9bae06 100644 --- a/Marlin/src/lcd/menu/menu_item.h +++ b/Marlin/src/lcd/menu/menu_item.h @@ -280,6 +280,7 @@ class MenuItem_bool : public MenuEditItemBase { (encoderLine == _thisItemNr, _lcdLineNr, flabel, ##V); \ }while(0) +// Item with optional data #define _MENU_ITEM_F(TYPE, V...) do { \ if (_menuLineNr == _thisItemNr) { \ _skipStatic = false; \ @@ -288,7 +289,7 @@ class MenuItem_bool : public MenuEditItemBase { NEXT_ITEM(); \ }while(0) -// Indexed items set a global index value and optional data +// Item with index value, C-string, and optional data #define _MENU_ITEM_N_S_F(TYPE, N, S, V...) do{ \ if (_menuLineNr == _thisItemNr) { \ _skipStatic = false; \ @@ -298,11 +299,21 @@ class MenuItem_bool : public MenuEditItemBase { NEXT_ITEM(); \ }while(0) -// Indexed items set a global index value +// Item with index value and F-string +#define _MENU_ITEM_N_f_F(TYPE, N, f, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + MenuItemBase::init(N, f); \ + _MENU_INNER_F(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + +// Item with index value #define _MENU_ITEM_N_F(TYPE, N, V...) do{ \ if (_menuLineNr == _thisItemNr) { \ _skipStatic = false; \ - MenuItemBase::itemIndex = N; \ + MenuItemBase::init(N); \ _MENU_INNER_F(TYPE, ##V); \ } \ NEXT_ITEM(); \ @@ -318,6 +329,16 @@ class MenuItem_bool : public MenuEditItemBase { NEXT_ITEM(); \ }while(0) +// Items with a unique F-string +#define _MENU_ITEM_f_F(TYPE, f, V...) do{ \ + if (_menuLineNr == _thisItemNr) { \ + _skipStatic = false; \ + MenuItemBase::init(0, f); \ + _MENU_INNER_F(TYPE, ##V); \ + } \ + NEXT_ITEM(); \ +}while(0) + // STATIC_ITEM draws a styled string with no highlight. // Parameters: label [, style [, char *value] ] @@ -361,15 +382,24 @@ class MenuItem_bool : public MenuEditItemBase { #define STATIC_ITEM(LABEL, V...) STATIC_ITEM_F(GET_TEXT_F(LABEL), ##V) #define STATIC_ITEM_N(LABEL, N, V...) STATIC_ITEM_N_F(GET_TEXT_F(LABEL), N, ##V) +// Menu item with index and composed C-string substitution #define MENU_ITEM_N_S_F(TYPE, N, S, FLABEL, V...) _MENU_ITEM_N_S_F(TYPE, N, S, false, FLABEL, ##V) #define MENU_ITEM_N_S(TYPE, N, S, LABEL, V...) MENU_ITEM_N_S_F(TYPE, N, S, GET_TEXT_F(LABEL), ##V) + +// Menu item with composed C-string substitution #define MENU_ITEM_S_F(TYPE, S, FLABEL, V...) _MENU_ITEM_S_F(TYPE, S, false, FLABEL, ##V) #define MENU_ITEM_S(TYPE, S, LABEL, V...) MENU_ITEM_S_F(TYPE, S, GET_TEXT_F(LABEL), ##V) + +// Menu item substitution, indexed #define MENU_ITEM_N_F(TYPE, N, FLABEL, V...) _MENU_ITEM_N_F(TYPE, N, false, FLABEL, ##V) #define MENU_ITEM_N(TYPE, N, LABEL, V...) MENU_ITEM_N_F(TYPE, N, GET_TEXT_F(LABEL), ##V) + +// Basic menu items, no substitution #define MENU_ITEM_F(TYPE, FLABEL, V...) _MENU_ITEM_F(TYPE, false, FLABEL, ##V) #define MENU_ITEM(TYPE, LABEL, V...) MENU_ITEM_F(TYPE, GET_TEXT_F(LABEL), ##V) +// Predefined menu item types // + #define BACK_ITEM_F(FLABEL) MENU_ITEM_F(back, FLABEL) #define BACK_ITEM(LABEL) MENU_ITEM(back, LABEL) @@ -418,6 +448,38 @@ class MenuItem_bool : public MenuEditItemBase { #define EDIT_ITEM_FAST_F(TYPE, FLABEL, V...) _MENU_ITEM_F(TYPE, true, FLABEL, ##V) #define EDIT_ITEM_FAST(TYPE, LABEL, V...) EDIT_ITEM_FAST_F(TYPE, GET_TEXT_F(LABEL), ##V) +// F-string substitution instead of C-string // + +#define MENU_ITEM_N_f_F(TYPE, N, f, FLABEL, V...) _MENU_ITEM_N_f_F(TYPE, N, f, false, FLABEL, ##V) +#define MENU_ITEM_N_f(TYPE, N, f, LABEL, V...) MENU_ITEM_N_f_F(TYPE, N, f, GET_TEXT_F(LABEL), ##V) +#define MENU_ITEM_f_F(TYPE, f, FLABEL, V...) _MENU_ITEM_f_F(TYPE, f, false, FLABEL, ##V) +#define MENU_ITEM_f(TYPE, f, LABEL, V...) MENU_ITEM_f_F(TYPE, f, GET_TEXT_F(LABEL), ##V) + +#define ACTION_ITEM_N_f_F(N, f, FLABEL, ACTION) MENU_ITEM_N_f_F(function, N, f, FLABEL, ACTION) +#define ACTION_ITEM_N_f(N, f, LABEL, ACTION) ACTION_ITEM_N_f_F(N, f, GET_TEXT_F(LABEL), ACTION) +#define ACTION_ITEM_f_F(f, FLABEL, ACTION) MENU_ITEM_f_F(function, f, FLABEL, ACTION) +#define ACTION_ITEM_f(f, LABEL, ACTION) ACTION_ITEM_f_F(f, GET_TEXT_F(LABEL), ACTION) + +#define GCODES_ITEM_N_f_F(N, f, FLABEL, GCODES) MENU_ITEM_N_f_F(gcode, N, f, FLABEL, GCODES) +#define GCODES_ITEM_N_f(N, f, LABEL, GCODES) GCODES_ITEM_N_f_F(N, f, GET_TEXT_F(LABEL), GCODES) +#define GCODES_ITEM_f_F(f, FLABEL, GCODES) MENU_ITEM_f_F(gcode, f, FLABEL, GCODES) +#define GCODES_ITEM_f(f, LABEL, GCODES) GCODES_ITEM_f_F(f, GET_TEXT_F(LABEL), GCODES) + +#define SUBMENU_N_f_F(N, f, FLABEL, DEST) MENU_ITEM_N_f_F(submenu, N, f, FLABEL, DEST) +#define SUBMENU_N_f(N, f, LABEL, DEST) SUBMENU_N_f_F(N, f, GET_TEXT_F(LABEL), DEST) +#define SUBMENU_f_F(f, FLABEL, DEST) MENU_ITEM_f_F(submenu, f, FLABEL, DEST) +#define SUBMENU_f(f, LABEL, DEST) SUBMENU_f_F(f, GET_TEXT_F(LABEL), DEST) + +#define EDIT_ITEM_N_f_F(TYPE, N, f, FLABEL, V...) MENU_ITEM_N_f_F(TYPE, N, f, FLABEL, ##V) +#define EDIT_ITEM_N_f(TYPE, N, f, LABEL, V...) EDIT_ITEM_N_f_F(TYPE, N, f, GET_TEXT_F(LABEL), ##V) +#define EDIT_ITEM_f_F(TYPE, f, FLABEL, V...) MENU_ITEM_f_F(TYPE, f, FLABEL, ##V) +#define EDIT_ITEM_f(TYPE, f, LABEL, V...) EDIT_ITEM_f_F(TYPE, f, GET_TEXT_F(LABEL), ##V) + +#define EDIT_ITEM_FAST_N_f_F(TYPE, N, f, FLABEL, V...) _MENU_ITEM_N_f_F(TYPE, N, f, true, FLABEL, ##V) +#define EDIT_ITEM_FAST_N_f(TYPE, N, f, LABEL, V...) EDIT_ITEM_FAST_N_f_F(TYPE, N, f, true, GET_TEXT_F(LABEL), ##V) +#define EDIT_ITEM_FAST_f_F(TYPE, f, FLABEL, V...) _MENU_ITEM_f_F(TYPE, f, true, FLABEL, ##V) +#define EDIT_ITEM_FAST_f(TYPE, f, LABEL, V...) EDIT_ITEM_FAST_f_F(TYPE, f, GET_TEXT_F(LABEL), ##V) + #define _CONFIRM_ITEM_INNER_F(FLABEL, V...) do { \ if (encoderLine == _thisItemNr && ui.use_click()) { \ ui.push_current_screen(); \ diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp index 43594ec5a628..90bd015efff4 100644 --- a/Marlin/src/lcd/menu/menu_motion.cpp +++ b/Marlin/src/lcd/menu/menu_motion.cpp @@ -195,7 +195,7 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int SUBMENU(MSG_MOVE_1MM, []{ _goto_manual_move( 1); }); SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move( 0.1f); }); if (axis == Z_AXIS && (FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f) - SUBMENU_S(STRINGIFY(FINE_MANUAL_MOVE), MSG_MOVE_N_MM, []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); + SUBMENU_f(F(STRINGIFY(FINE_MANUAL_MOVE)), MSG_MOVE_N_MM, []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); }); } END_MENU(); } diff --git a/Marlin/src/lcd/menu/menu_probe_offset.cpp b/Marlin/src/lcd/menu/menu_probe_offset.cpp index 0d9448b1385b..c7cbebaade82 100644 --- a/Marlin/src/lcd/menu/menu_probe_offset.cpp +++ b/Marlin/src/lcd/menu/menu_probe_offset.cpp @@ -69,7 +69,7 @@ void probe_offset_wizard_menu() { SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move_z( 0.1f); }); if ((FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f) - SUBMENU_S(STRINGIFY(FINE_MANUAL_MOVE), MSG_MOVE_N_MM, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); + SUBMENU_f(F(STRINGIFY(FINE_MANUAL_MOVE)), MSG_MOVE_N_MM, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); ACTION_ITEM(MSG_BUTTON_DONE, []{ set_offset_and_go_back(calculated_z_offset); diff --git a/Marlin/src/lcd/menu/menu_temperature.cpp b/Marlin/src/lcd/menu/menu_temperature.cpp index fb539f006c14..e493972a9712 100644 --- a/Marlin/src/lcd/menu/menu_temperature.cpp +++ b/Marlin/src/lcd/menu/menu_temperature.cpp @@ -88,14 +88,14 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i // Indexed "Preheat ABC" and "Heat Bed" items #define PREHEAT_ITEMS(M,E) do{ \ - 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); }); \ + ACTION_ITEM_N_f(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_both(M, MenuItemBase::itemIndex); }); \ + ACTION_ITEM_N_f(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_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_end(M, MenuItemBase::itemIndex); }) + #define PREHEAT_ITEMS(M,E) ACTION_ITEM_N_f(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_end(M, MenuItemBase::itemIndex); }) #endif @@ -112,16 +112,16 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i #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); + ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, []{ _preheat_both(editable.int8, 0); }); + ACTION_ITEM_f(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); + ACTION_ITEM_f(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, []() { + ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M_ALL, []() { const celsius_t t = ui.material_preset[editable.int8].hotend_temp; HOTEND_LOOP() thermalManager.setTargetHotend(t, e); TERN(HAS_HEATED_BED, _preheat_bed(editable.int8), ui.return_to_status()); @@ -130,7 +130,7 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i #endif #if HAS_HEATED_BED - ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_BEDONLY, []{ _preheat_bed(editable.int8); }); + ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M_BEDONLY, []{ _preheat_bed(editable.int8); }); #endif END_MENU(); @@ -269,9 +269,9 @@ void menu_temperature() { LOOP_L_N(m, PREHEAT_COUNT) { editable.int8 = m; #if HAS_MULTI_HOTEND || HAS_HEATED_BED - SUBMENU_S(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m); + SUBMENU_f(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m); #elif HAS_HOTEND - ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m); + ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m); #endif } #endif @@ -296,9 +296,9 @@ void menu_temperature() { LOOP_L_N(m, PREHEAT_COUNT) { editable.int8 = m; #if HAS_MULTI_HOTEND || HAS_HEATED_BED - SUBMENU_S(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m); + SUBMENU_f(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); + ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m); #endif } diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp index 297325348d23..62c1770bd4c3 100644 --- a/Marlin/src/lcd/menu/menu_ubl.cpp +++ b/Marlin/src/lcd/menu/menu_ubl.cpp @@ -211,10 +211,10 @@ void _lcd_ubl_edit_mesh() { #if HAS_PREHEAT #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, F("G28\nG26CPI" STRINGIFY(M))); + GCODES_ITEM_N_f(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPI" STRINGIFY(M))); #else #define VALIDATE_MESH_GCODE_ITEM(M) \ - GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPB0I" STRINGIFY(M))); + GCODES_ITEM_N_f(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPB0I" STRINGIFY(M))); #endif REPEAT(PREHEAT_COUNT, VALIDATE_MESH_GCODE_ITEM) #endif @@ -317,7 +317,7 @@ void _lcd_ubl_build_mesh() { #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, \ + #define BUILD_MESH_GCODE_ITEM(M) GCODES_ITEM_f(ui.get_preheat_label(M), MSG_UBL_BUILD_MESH_M, \ F( \ "G28\n" \ PREHEAT_BED_GCODE(M) \ diff --git a/Marlin/src/lcd/menu/menu_x_twist.cpp b/Marlin/src/lcd/menu/menu_x_twist.cpp index caeb7ee6db8d..e46745e8b761 100644 --- a/Marlin/src/lcd/menu/menu_x_twist.cpp +++ b/Marlin/src/lcd/menu/menu_x_twist.cpp @@ -103,7 +103,7 @@ void xatc_wizard_menu() { // Determine digits needed right of decimal const uint8_t digs = !UNEAR_ZERO((FINE_MANUAL_MOVE) * 1000 - int((FINE_MANUAL_MOVE) * 1000)) ? 4 : !UNEAR_ZERO((FINE_MANUAL_MOVE) * 100 - int((FINE_MANUAL_MOVE) * 100)) ? 3 : 2; - SUBMENU_S(STRINGIFY(FINE_MANUAL_MOVE), MSG_MOVE_N_MM, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); + SUBMENU_f(F(STRINGIFY(FINE_MANUAL_MOVE)), MSG_MOVE_N_MM, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); }); } ACTION_ITEM(MSG_BUTTON_DONE, xatc_wizard_set_offset_and_go_to_next_point);