@ -37,109 +37,103 @@ bool printer_busy();
////////////////////////////////////////////
////////////////////////////////////////////
# define DECLARE_MENU_EDIT_TYPE(TYPE, NAME, STRFUNC, SCALE) \
# define DECLARE_MENU_EDIT_TYPE(TYPE, NAME, STRFUNC, SCALE) \
struct NAME # # _item_info { \
struct MenuItemInfo_ # # NAME { \
typedef TYPE type_t ; \
typedef TYPE type_t ; \
static constexpr float scale = SCALE ; \
static constexpr float scale = SCALE ; \
static inline char * strfunc ( const float value ) { return STRFUNC ( ( TYPE ) value ) ; } \
static inline char * strfunc ( const float value ) { return STRFUNC ( ( TYPE ) value ) ; } \
} ;
} ;
DECLARE_MENU_EDIT_TYPE ( int16_t , int3 , itostr3 , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( int16_t , int3 , itostr3 , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( int16_t , int4 , itostr4sign , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( int16_t , int4 , itostr4sign , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( uint8_t , int8 , i8tostr3 , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( uint8_t , int8 , i8tostr3 , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float3 , ftostr3 , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float3 , ftostr3 , 1 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float52 , ftostr52 , 100 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float52 , ftostr52 , 100 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float43 , ftostr43sign , 1000 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float43 , ftostr43sign , 1000 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float5 , ftostr5rj , 0.01f ) ;
DECLARE_MENU_EDIT_TYPE ( float , float5 , ftostr5rj , 0.01f ) ;
DECLARE_MENU_EDIT_TYPE ( float , float51 , ftostr51sign , 10 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float51 , ftostr51sign , 10 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float52sign , ftostr52sign , 100 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float52sign , ftostr52sign , 100 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float62 , ftostr62rj , 100 ) ;
DECLARE_MENU_EDIT_TYPE ( float , float62 , ftostr62rj , 100 ) ;
DECLARE_MENU_EDIT_TYPE ( uint32_t , long5 , ftostr5rj , 0.01f ) ;
DECLARE_MENU_EDIT_TYPE ( uint32_t , long5 , ftostr5rj , 0.01f ) ;
////////////////////////////////////////////
////////////////////////////////////////////
///////// Menu Item Draw Functions /////////
///////// Menu Item Draw Functions /////////
////////////////////////////////////////////
////////////////////////////////////////////
void draw_menu_item_generic ( const bool isSelected , const uint8_t row , PGM_P const pstr , const char pre_char , const char post_char ) ;
void draw_menu_item_static ( const uint8_t row , PGM_P const pstr , const bool center = true , const bool invert = false , const char * valstr = NULL ) ;
void draw_edit_screen ( PGM_P const pstr , const char * const value = NULL ) ;
void draw_edit_screen ( PGM_P const pstr , const char * const value = NULL ) ;
void draw_menu_item ( const bool sel , const uint8_t row , PGM_P const pstr , const char pre_char , const char post_char ) ;
void draw_menu_item_static ( const uint8_t row , PGM_P const pstr , const bool center = true , const bool invert = false , const char * valstr = NULL ) ;
void _draw_menu_item_edit ( const bool sel , const uint8_t row , PGM_P const pstr , const char * const data , const bool pgm ) ;
FORCE_INLINE void draw_menu_item_back ( const bool sel , const uint8_t row , PGM_P const pstr ) { draw_menu_item ( sel , row , pstr , LCD_STR_UPLEVEL [ 0 ] , LCD_STR_UPLEVEL [ 0 ] ) ; }
FORCE_INLINE void draw_menu_item_edit ( const bool sel , const uint8_t row , PGM_P const pstr , const char * const data ) { _draw_menu_item_edit ( sel , row , pstr , data , false ) ; }
FORCE_INLINE void draw_menu_item_edit_P ( const bool sel , const uint8_t row , PGM_P const pstr , const char * const data ) { _draw_menu_item_edit ( sel , row , pstr , data , true ) ; }
# define draw_menu_item_submenu(sel, row, pstr, data) draw_menu_item(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
# define draw_menu_item_gcode(sel, row, pstr, gcode) draw_menu_item(sel, row, pstr, '>', ' ')
# define draw_menu_item_function(sel, row, pstr, data) draw_menu_item(sel, row, pstr, '>', ' ')
# define DRAW_MENU_ITEM_SETTING_EDIT_GENERIC(VAL) draw_menu_item_edit(sel, row, pstr, VAL)
# define DRAW_BOOL_SETTING(sel, row, pstr, data) draw_menu_item_edit_P(sel, row, pstr, (*(data))?PSTR(MSG_LCD_ON):PSTR(MSG_LCD_OFF))
# if ENABLED(SDSUPPORT)
# if ENABLED(SDSUPPORT)
class CardReader ;
class CardReader ;
void draw_sd_menu_item ( const bool isSelected , const uint8_t row , PGM_P const pstr , CardReader & theCard , const bool isDir ) ;
void draw_sd_menu_item ( const bool sel , const uint8_t row , PGM_P const pstr , CardReader & theCard , const bool isDir ) ;
inline void draw_menu_item_sdfile ( const bool sel , const uint8_t row , PGM_P const pstr , CardReader & theCard ) { draw_sd_menu_item ( sel , row , pstr , theCard , false ) ; }
FORCE_INLINE void draw_menu_item_sdfile ( const bool sel , const uint8_t row , PGM_P const pstr , CardReader & theCard ) { draw_sd_menu_item ( sel , row , pstr , theCard , false ) ; }
inline void draw_menu_item_sdfolder ( const bool sel , const uint8_t row , PGM_P const pstr , CardReader & theCard ) { draw_sd_menu_item ( sel , row , pstr , theCard , true ) ; }
FORCE_INLINE void draw_menu_item_sdfolder ( const bool sel , const uint8_t row , PGM_P const pstr , CardReader & theCard ) { draw_sd_menu_item ( sel , row , pstr , theCard , true ) ; }
# endif
# endif
# if HAS_GRAPHICAL_LCD
void _drawmenu_setting_edit_generic ( const bool isSelected , const uint8_t row , const char * pstr , const char * const data , const bool pgm ) ;
# if HAS_GRAPHICAL_LCD && (ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) || ENABLED(MESH_EDIT_GFX_OVERLAY))
# define draw_menu_item_back(sel, row, pstr) draw_menu_item_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
# define draw_menu_item_setting_edit_generic(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, false)
# define draw_menu_item_setting_edit_generic_P(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, true)
# define DRAWMENU_SETTING_EDIT_GENERIC(SRC) draw_menu_item_setting_edit_generic(sel, row, pstr, SRC)
# define DRAW_BOOL_SETTING(sel, row, pstr, data) draw_menu_item_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_LCD_ON):PSTR(MSG_LCD_OFF))
# if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) || ENABLED(MESH_EDIT_GFX_OVERLAY)
void _lcd_zoffset_overlay_gfx ( const float zvalue ) ;
void _lcd_zoffset_overlay_gfx ( const float zvalue ) ;
# endif
# else
# define draw_menu_item_back(sel, row, pstr) draw_menu_item_generic(sel, row, pstr, LCD_UPLEVEL_CHAR, LCD_UPLEVEL_CHAR)
void draw_menu_item_setting_edit_generic ( const bool sel , const uint8_t row , const char * pstr , const char pre_char , const char * const data ) ;
void draw_menu_item_setting_edit_generic_P ( const bool sel , const uint8_t row , const char * pstr , const char pre_char , const char * const data ) ;
# define DRAWMENU_SETTING_EDIT_GENERIC(SRC) draw_menu_item_setting_edit_generic(sel, row, pstr, '>', SRC)
# define DRAW_BOOL_SETTING(sel, row, pstr, data) draw_menu_item_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_LCD_ON):PSTR(MSG_LCD_OFF))
# endif
# endif
# define draw_menu_item_submenu(sel, row, pstr, data) draw_menu_item_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
# define draw_menu_item_gcode(sel, row, pstr, gcode) draw_menu_item_generic(sel, row, pstr, '>', ' ')
# define draw_menu_item_function(sel, row, pstr, data) draw_menu_item_generic(sel, row, pstr, '>', ' ')
////////////////////////////////////////////
////////////////////////////////////////////
/////// Edit Setting Draw Functions ////////
/////// Edit Setting Draw Functions ////////
////////////////////////////////////////////
////////////////////////////////////////////
# define _DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE (TYPE, NAME, STRFUNC) \
# define _DEFINE_DRAW_MENU_ITEM_SETTING_EDIT(TYPE, NAME, STRFUNC) \
FORCE_INLINE void draw_menu_item_setting_ edit_ # # NAME ( const bool sel , const uint8_t row , PGM_P const pstr , PGM_P const pstr2 , TYPE * const data , . . . ) { \
FORCE_INLINE void draw_menu_item_edit_ # # NAME ( const bool sel , const uint8_t row , PGM_P const pstr , PGM_P const pstr2 , TYPE * const data , . . . ) { \
UNUSED ( pstr2 ) ; \
UNUSED ( pstr2 ) ; \
DRAWMENU_SETTING_EDIT_GENERIC ( STRFUNC ( * ( data ) ) ) ; \
DRAW_ MENU_ITEM _SETTING_EDIT_GENERIC ( STRFUNC ( * ( data ) ) ) ; \
} \
} \
FORCE_INLINE void draw_menu_item_setting_ edit_accessor_ # # NAME ( const bool sel , const uint8_t row , PGM_P const pstr , PGM_P const pstr2 , TYPE ( * pget ) ( ) , void ( * pset ) ( TYPE ) , . . . ) { \
FORCE_INLINE void draw_menu_item_edit_accessor_ # # NAME ( const bool sel , const uint8_t row , PGM_P const pstr , PGM_P const pstr2 , TYPE ( * pget ) ( ) , void ( * pset ) ( TYPE ) , . . . ) { \
UNUSED ( pstr2 ) ; UNUSED ( pset ) ; \
UNUSED ( pstr2 ) ; UNUSED ( pset ) ; \
DRAWMENU_SETTING_EDIT_GENERIC ( STRFUNC ( pget ( ) ) ) ; \
DRAW_ MENU_ITEM _SETTING_EDIT_GENERIC ( STRFUNC ( pget ( ) ) ) ; \
} \
} \
typedef void NAME # # _void
typedef void NAME # # _void
# define DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(NAME) _DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(NAME ## _item_info::type_t, NAME, NAME ## _item_info ::strfunc)
# define DEFINE_DRAW_MENU_ITEM_SETTING_EDIT(NAME) _DEFINE_DRAW_MENU_ITEM_SETTING_EDIT(MenuItemInfo_##NAME::type_t, NAME, MenuItemInfo_##NAME ::strfunc)
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( int3 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( int3 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( int4 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( int4 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( int8 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( int8 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float3 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float3 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float52 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float52 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float43 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float43 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float5 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float5 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float51 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float51 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float52sign ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float52sign ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( float62 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( float62 ) ;
DEFINE_LCD_IMPLEMENTATION_ DRAWMENU_SETTING_EDIT_TYPE ( long5 ) ;
DEFINE_DRAW_ MENU_ITEM_ SETTING_EDIT ( long5 ) ;
# define draw_menu_item_setting_ edit_bool(sel, row, pstr, pstr2, data, ...) DRAW_BOOL_SETTING(sel, row, pstr, data)
# define draw_menu_item_edit_bool(sel, row, pstr, pstr2, data, ...) DRAW_BOOL_SETTING(sel, row, pstr, data)
# define draw_menu_item_setting_ edit_accessor_bool(sel, row, pstr, pstr2, pget, pset) DRAW_BOOL_SETTING(sel, row, pstr, data)
# define draw_menu_item_edit_accessor_bool(sel, row, pstr, pstr2, pget, pset) DRAW_BOOL_SETTING(sel, row, pstr, data)
////////////////////////////////////////////
////////////////////////////////////////////
/////////////// Menu Actions ///////////////
/////////////// Menu Actions ///////////////
////////////////////////////////////////////
////////////////////////////////////////////
class menu_i tem_back {
class MenuI tem_back {
public :
public :
static inline void action ( ) { ui . goto_previous_screen ( ) ; }
static inline void action ( ) { ui . goto_previous_screen ( ) ; }
} ;
} ;
class menu_i tem_submenu {
class MenuI tem_submenu {
public :
public :
static inline void action ( const screenFunc_t func ) { ui . save_previous_screen ( ) ; ui . goto_screen ( func ) ; }
static inline void action ( const screenFunc_t func ) { ui . save_previous_screen ( ) ; ui . goto_screen ( func ) ; }
} ;
} ;
class menu_i tem_gcode {
class MenuI tem_gcode {
public :
public :
static void action ( const char * const pgcode ) ;
static void action ( const char * const pgcode ) ;
} ;
} ;
class menu_i tem_function {
class MenuI tem_function {
public :
public :
static inline void action ( const menuAction_t func ) { ( * func ) ( ) ; } ;
static inline void action ( const menuAction_t func ) { ( * func ) ( ) ; } ;
} ;
} ;
@ -160,19 +154,19 @@ template<typename NAME>
class TMenuItem : MenuItemBase {
class TMenuItem : MenuItemBase {
private :
private :
typedef typename NAME : : type_t type_t ;
typedef typename NAME : : type_t type_t ;
inline static float unscale ( const float value ) { return value * ( 1.0f / NAME : : scale ) ; }
inline static float unscale ( const float value ) { return value * ( 1.0f / NAME : : scale ) ; }
inline static float scale ( const float value ) { return value * NAME : : scale ; }
inline static float scale ( const float value ) { return value * NAME : : scale ; }
static void load ( void * ptr , const int32_t value ) { * ( ( type_t * ) ptr ) = unscale ( value ) ; }
static void load ( void * ptr , const int32_t value ) { * ( ( type_t * ) ptr ) = unscale ( value ) ; }
static char * to_string ( const int32_t value ) { return NAME : : strfunc ( unscale ( value ) ) ; }
static char * to_string ( const int32_t value ) { return NAME : : strfunc ( unscale ( value ) ) ; }
public :
public :
static void action_setting_ edit ( PGM_P const pstr , type_t * const ptr , const type_t minValue , const type_t maxValue , const screenFunc_t callback = NULL , const bool live = false ) {
static void action_edit ( PGM_P const pstr , type_t * const ptr , const type_t minValue , const type_t maxValue , const screenFunc_t callback = NULL , const bool live = false ) {
const int32_t minv = scale ( minValue ) ;
const int32_t minv = scale ( minValue ) ;
init ( pstr , ptr , minv , int32_t ( scale ( maxValue ) ) - minv , int32_t ( scale ( * ptr ) ) - minv , edit , callback , live ) ;
init ( pstr , ptr , minv , int32_t ( scale ( maxValue ) ) - minv , int32_t ( scale ( * ptr ) ) - minv , edit , callback , live ) ;
}
}
static void edit ( ) { MenuItemBase : : edit ( to_string , load ) ; }
static void edit ( ) { MenuItemBase : : edit ( to_string , load ) ; }
} ;
} ;
# define DECLARE_MENU_EDIT_ITEM(NAME) typedef TMenuItem<NAME ## _item_info> menu_item_ ## NAME;
# define DECLARE_MENU_EDIT_ITEM(NAME) typedef TMenuItem<MenuItemInfo_##NAME> MenuItem_## NAME;
DECLARE_MENU_EDIT_ITEM ( int3 ) ;
DECLARE_MENU_EDIT_ITEM ( int3 ) ;
DECLARE_MENU_EDIT_ITEM ( int4 ) ;
DECLARE_MENU_EDIT_ITEM ( int4 ) ;
@ -186,9 +180,9 @@ DECLARE_MENU_EDIT_ITEM(float52sign);
DECLARE_MENU_EDIT_ITEM ( float62 ) ;
DECLARE_MENU_EDIT_ITEM ( float62 ) ;
DECLARE_MENU_EDIT_ITEM ( long5 ) ;
DECLARE_MENU_EDIT_ITEM ( long5 ) ;
class menu_i tem_bool {
class MenuI tem_bool {
public :
public :
static void action_setting_ edit ( PGM_P const pstr , bool * ptr , const screenFunc_t callbackFunc = NULL ) ;
static void action_edit ( PGM_P const pstr , bool * ptr , const screenFunc_t callbackFunc = NULL ) ;
} ;
} ;
////////////////////////////////////////////
////////////////////////////////////////////
@ -247,22 +241,22 @@ class menu_item_bool {
* MENU_ITEM generates draw & handler code for a menu item , potentially calling :
* MENU_ITEM generates draw & handler code for a menu item , potentially calling :
*
*
* draw_menu_item_ < type > [ _variant ] ( sel , row , label , arg3 . . . )
* draw_menu_item_ < type > [ _variant ] ( sel , row , label , arg3 . . . )
* menu_i tem_< type > : : action [ _variant ] ( arg3 . . . )
* MenuI tem_< type > : : action [ _variant ] ( arg3 . . . )
*
*
* Examples :
* Examples :
* MENU_ITEM ( back , MSG_WATCH , 0 [ dummy parameter ] )
* MENU_ITEM ( back , MSG_WATCH , 0 [ dummy parameter ] )
* or
* or
* MENU_BACK ( MSG_WATCH )
* MENU_BACK ( MSG_WATCH )
* draw_menu_item_back ( sel , row , PSTR ( MSG_WATCH ) )
* draw_menu_item_back ( sel , row , PSTR ( MSG_WATCH ) )
* menu_i tem_back: : action ( )
* MenuI tem_back: : action ( )
*
*
* MENU_ITEM ( function , MSG_PAUSE_PRINT , lcd_sdcard_pause )
* MENU_ITEM ( function , MSG_PAUSE_PRINT , lcd_sdcard_pause )
* draw_menu_item_function ( sel , row , PSTR ( MSG_PAUSE_PRINT ) , lcd_sdcard_pause )
* draw_menu_item_function ( sel , row , PSTR ( MSG_PAUSE_PRINT ) , lcd_sdcard_pause )
* menu_i tem_function: : action ( lcd_sdcard_pause )
* MenuI tem_function: : action ( lcd_sdcard_pause )
*
*
* MENU_ITEM_EDIT ( int3 , MSG_SPEED , & feedrate_percentage , 10 , 999 )
* MENU_ITEM_EDIT ( int3 , MSG_SPEED , & feedrate_percentage , 10 , 999 )
* draw_menu_item_setting_ edit_int3 ( sel , row , PSTR ( MSG_SPEED ) , PSTR ( MSG_SPEED ) , & feedrate_percentage , 10 , 999 )
* draw_menu_item_edit_int3 ( sel , row , PSTR ( MSG_SPEED ) , PSTR ( MSG_SPEED ) , & feedrate_percentage , 10 , 999 )
* menu_i tem_int3: : action_setting _edit ( PSTR ( MSG_SPEED ) , & feedrate_percentage , 10 , 999 )
* MenuI tem_int3: : action_edit ( PSTR ( MSG_SPEED ) , & feedrate_percentage , 10 , 999 )
*
*
*/
*/
# define _MENU_ITEM_VARIANT_P(TYPE, VARIANT, USE_MULTIPLIER, PLABEL, ...) do { \
# define _MENU_ITEM_VARIANT_P(TYPE, VARIANT, USE_MULTIPLIER, PLABEL, ...) do { \
@ -270,7 +264,7 @@ class menu_item_bool {
if ( _menuLineNr = = _thisItemNr ) { \
if ( _menuLineNr = = _thisItemNr ) { \
if ( encoderLine = = _thisItemNr & & ui . use_click ( ) ) { \
if ( encoderLine = = _thisItemNr & & ui . use_click ( ) ) { \
_MENU_ITEM_MULTIPLIER_CHECK ( USE_MULTIPLIER ) ; \
_MENU_ITEM_MULTIPLIER_CHECK ( USE_MULTIPLIER ) ; \
menu_item_ # # TYPE : : action # # VARIANT ( __VA_ARGS__ ) ; \
MenuItem_ # # TYPE : : action # # VARIANT ( __VA_ARGS__ ) ; \
if ( screen_changed ) return ; \
if ( screen_changed ) return ; \
} \
} \
if ( ui . should_draw ( ) ) \
if ( ui . should_draw ( ) ) \
@ -305,10 +299,10 @@ class menu_item_bool {
# define MENU_ITEM_DUMMY() do { _thisItemNr++; }while(0)
# define MENU_ITEM_DUMMY() do { _thisItemNr++; }while(0)
# define MENU_ITEM_P(TYPE, PLABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, , false, PLABEL, ## __VA_ARGS__)
# define MENU_ITEM_P(TYPE, PLABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, , false, PLABEL, ## __VA_ARGS__)
# define MENU_ITEM(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, , false, PSTR(LABEL), ## __VA_ARGS__)
# define MENU_ITEM(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, , false, PSTR(LABEL), ## __VA_ARGS__)
# define MENU_ITEM_EDIT(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _setting_ edit, false, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_ITEM_EDIT(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _edit, false, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_ITEM_EDIT_CALLBACK(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _setting_ edit, false, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_ITEM_EDIT_CALLBACK(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _edit, false, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_MULTIPLIER_ITEM_EDIT(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _setting_ edit, true, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_MULTIPLIER_ITEM_EDIT(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _edit, true, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _setting_ edit, true, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
# define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(TYPE, LABEL, ...) _MENU_ITEM_VARIANT_P(TYPE, _edit, true, PSTR(LABEL), PSTR(LABEL), ## __VA_ARGS__)
////////////////////////////////////////////
////////////////////////////////////////////
/////////////// Menu Screens ///////////////
/////////////// Menu Screens ///////////////