🎨 Axis name string interpolation, with examples (#22879)
This commit is contained in:
@@ -103,42 +103,28 @@ void MarlinUI::_goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_b
|
||||
/////////// Menu Editing Actions ///////////
|
||||
////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Functions for editing single values
|
||||
*
|
||||
* The "DEFINE_MENU_EDIT_ITEM" macro generates the classes needed to edit a numerical value.
|
||||
*
|
||||
* The prerequisite is that in the header the type was already declared:
|
||||
*
|
||||
* DEFINE_MENU_EDIT_ITEM_TYPE(int3, int16_t, i16tostr3rj, 1)
|
||||
*
|
||||
* For example, DEFINE_MENU_EDIT_ITEM(int3) expands into:
|
||||
*
|
||||
* template class TMenuEditItem<MenuEditItemInfo_int3>
|
||||
*
|
||||
* You can then use one of the menu macros to present the edit interface:
|
||||
* EDIT_ITEM(int3, MSG_SPEED, &feedrate_percentage, 10, 999)
|
||||
*
|
||||
* This expands into a more primitive menu item:
|
||||
* _MENU_ITEM_P(int3, false, GET_TEXT(MSG_SPEED), &feedrate_percentage, 10, 999)
|
||||
*
|
||||
* ...which calls:
|
||||
* MenuItem_int3::action(plabel, &feedrate_percentage, 10, 999)
|
||||
* MenuItem_int3::draw(encoderLine == _thisItemNr, _lcdLineNr, plabel, &feedrate_percentage, 10, 999)
|
||||
*/
|
||||
// All Edit Screens run the same way, but `draw_edit_screen` is implementation-specific
|
||||
void MenuEditItemBase::edit_screen(strfunc_t strfunc, loadfunc_t loadfunc) {
|
||||
// Reset repeat_delay for Touch Buttons
|
||||
TERN_(HAS_TOUCH_BUTTONS, ui.repeat_delay = BUTTON_DELAY_EDIT);
|
||||
// Constrain ui.encoderPosition to 0 ... maxEditValue (calculated in encoder steps)
|
||||
if (int32_t(ui.encoderPosition) < 0) ui.encoderPosition = 0;
|
||||
if (int32_t(ui.encoderPosition) > maxEditValue) ui.encoderPosition = maxEditValue;
|
||||
// If drawing is flagged then redraw the (whole) edit screen
|
||||
if (ui.should_draw())
|
||||
draw_edit_screen(strfunc(ui.encoderPosition + minEditValue));
|
||||
// If there was a click or "live editing" and encoder moved...
|
||||
if (ui.lcd_clicked || (liveEdit && ui.should_draw())) {
|
||||
// Pass the editValue pointer to the loadfunc along with the encoder plus min
|
||||
if (editValue) loadfunc(editValue, ui.encoderPosition + minEditValue);
|
||||
// If a callbackFunc was set, call it for click or always for "live editing"
|
||||
if (callbackFunc && (liveEdit || ui.lcd_clicked)) (*callbackFunc)();
|
||||
// Use up the click to finish editing and go to the previous screen
|
||||
if (ui.use_click()) ui.goto_previous_screen();
|
||||
}
|
||||
}
|
||||
|
||||
// Going to an edit screen sets up some persistent values first
|
||||
void MenuEditItemBase::goto_edit_screen(
|
||||
PGM_P const el, // Edit label
|
||||
void * const ev, // Edit value pointer
|
||||
|
@@ -60,7 +60,9 @@ class MenuItemBase {
|
||||
// Store the index of the item ahead of use by indexed items
|
||||
FORCE_INLINE static void init(const int8_t ind=0, PGM_P const pstr=nullptr) { itemIndex = ind; itemString = pstr; }
|
||||
|
||||
// Implementation-specific:
|
||||
// Draw an item either selected (pre_char) or not (space) with post_char
|
||||
// Menus may set up itemIndex, itemString and pass them to string-building or string-emitting functions
|
||||
static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char);
|
||||
|
||||
// Draw an item either selected ('>') or not (space) with post_char
|
||||
@@ -167,11 +169,11 @@ class MenuEditItemBase : public MenuItemBase {
|
||||
);
|
||||
static void edit_screen(strfunc_t, loadfunc_t); // Edit value handler
|
||||
public:
|
||||
// Implemented for HD44780 and DOGM
|
||||
// Implementation-specific:
|
||||
// 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 inStr, const bool pgm=false);
|
||||
|
||||
// Implemented for HD44780 and DOGM
|
||||
// Implementation-specific:
|
||||
// This low-level method is good to draw from anywhere
|
||||
static void draw_edit_screen(PGM_P const pstr, const char * const value);
|
||||
|
||||
|
@@ -174,12 +174,12 @@ void menu_advanced_settings();
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_CONFIGURATION);
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets);
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_HOTEND_OFFSET_A, &hotend_offset[1].x, float(X2_HOME_POS - 25), float(X2_HOME_POS + 25), _recalc_offsets);
|
||||
#else
|
||||
EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_X, &hotend_offset[1].x, -99.0, 99.0, _recalc_offsets);
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_HOTEND_OFFSET_A, &hotend_offset[1].x, -99.0, 99.0, _recalc_offsets);
|
||||
#endif
|
||||
EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_Y, &hotend_offset[1].y, -99.0, 99.0, _recalc_offsets);
|
||||
EDIT_ITEM_FAST(float42_52, MSG_HOTEND_OFFSET_Z, &hotend_offset[1].z, Z_PROBE_LOW_POINT, 10.0, _recalc_offsets);
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_HOTEND_OFFSET_A, &hotend_offset[1].y, -99.0, 99.0, _recalc_offsets);
|
||||
EDIT_ITEM_FAST_N(float42_52, Z_AXIS, MSG_HOTEND_OFFSET_A, &hotend_offset[1].z, Z_PROBE_LOW_POINT, 10.0, _recalc_offsets);
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings);
|
||||
#endif
|
||||
|
@@ -106,9 +106,23 @@ class TMenuEditItem : MenuEditItemBase {
|
||||
}
|
||||
};
|
||||
|
||||
// Provide a set of Edit Item Types which encompass a primitive
|
||||
// type, a string function, and a scale factor for edit and display.
|
||||
// These items call the Edit Item draw method passing the prepared string.
|
||||
/**
|
||||
* DEFINE_MENU_EDIT_ITEM_TYPE(int3, int16_t, i16tostr3rj, 1)
|
||||
*
|
||||
* Define struct types for use by EDIT_ITEM(...) macros, which encompass
|
||||
* a primitive storage type, a string function, and a scale factor for edit / display.
|
||||
* The EDIT_ITEM macros take care of calling action and draw methods as needed.
|
||||
*
|
||||
* For example, DEFINE_MENU_EDIT_ITEM_TYPE(percent, uint8_t, ui8tostr4pctrj, 100.f/255.f, +0.5f) expands into:
|
||||
*
|
||||
* struct MenuEditItemInfo_percent {
|
||||
* typedef uint8_t type_t;
|
||||
* static inline float scale(const_float_t value) { return value * (100.f/255.f) +0.5f; }
|
||||
* static inline float unscale(const_float_t value) { return value / (100.f/255.f) +0.5f; }
|
||||
* static inline const char* strfunc(const_float_t value) { return ui8tostr4pctrj(_DOFIX(uint8_t,value)); }
|
||||
* };
|
||||
* typedef TMenuEditItem<MenuEditItemInfo_percent> MenuItem_percent
|
||||
*/
|
||||
#define __DOFIXfloat PROBE()
|
||||
#define _DOFIX(TYPE,V) TYPE(TERN(IS_PROBE(__DOFIX##TYPE),FIXFLOAT(V),(V)))
|
||||
#define DEFINE_MENU_EDIT_ITEM_TYPE(NAME, TYPE, STRFUNC, SCALE, ETC...) \
|
||||
|
@@ -329,21 +329,21 @@ void menu_move() {
|
||||
BACK_ITEM(MSG_MOTION);
|
||||
|
||||
GCODES_ITEM(MSG_AUTO_HOME, G28_STR);
|
||||
GCODES_ITEM(MSG_AUTO_HOME_X, PSTR("G28X"));
|
||||
GCODES_ITEM_N(X_AXIS, MSG_AUTO_HOME_A, PSTR("G28X"));
|
||||
#if HAS_Y_AXIS
|
||||
GCODES_ITEM(MSG_AUTO_HOME_Y, PSTR("G28Y"));
|
||||
GCODES_ITEM_N(Y_AXIS, MSG_AUTO_HOME_A, PSTR("G28Y"));
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
GCODES_ITEM(MSG_AUTO_HOME_Z, PSTR("G28Z"));
|
||||
GCODES_ITEM_N(Z_AXIS, MSG_AUTO_HOME_A, PSTR("G28Z"));
|
||||
#endif
|
||||
#if LINEAR_AXES >= 4
|
||||
GCODES_ITEM(MSG_AUTO_HOME_I, PSTR("G28" AXIS4_STR));
|
||||
GCODES_ITEM_N(I_AXIS, MSG_AUTO_HOME_A, PSTR("G28" AXIS4_STR));
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
GCODES_ITEM(MSG_AUTO_HOME_J, PSTR("G28" AXIS5_STR));
|
||||
GCODES_ITEM_N(J_AXIS, MSG_AUTO_HOME_A, PSTR("G28" AXIS5_STR));
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
GCODES_ITEM(MSG_AUTO_HOME_K, PSTR("G28" AXIS6_STR));
|
||||
GCODES_ITEM_N(K_AXIS, MSG_AUTO_HOME_A, PSTR("G28" AXIS6_STR));
|
||||
#endif
|
||||
|
||||
END_MENU();
|
||||
@@ -382,21 +382,21 @@ void menu_motion() {
|
||||
#else
|
||||
GCODES_ITEM(MSG_AUTO_HOME, G28_STR);
|
||||
#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU)
|
||||
GCODES_ITEM(MSG_AUTO_HOME_X, PSTR("G28X"));
|
||||
GCODES_ITEM_N(X_AXIS, MSG_AUTO_HOME_A, PSTR("G28X"));
|
||||
#if HAS_Y_AXIS
|
||||
GCODES_ITEM(MSG_AUTO_HOME_Y, PSTR("G28Y"));
|
||||
GCODES_ITEM_N(Y_AXIS, MSG_AUTO_HOME_A, PSTR("G28Y"));
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
GCODES_ITEM(MSG_AUTO_HOME_Z, PSTR("G28Z"));
|
||||
GCODES_ITEM_N(Z_AXIS, MSG_AUTO_HOME_A, PSTR("G28Z"));
|
||||
#endif
|
||||
#if LINEAR_AXES >= 4
|
||||
GCODES_ITEM(MSG_AUTO_HOME_I, PSTR("G28" AXIS4_STR));
|
||||
GCODES_ITEM_N(I_AXIS, MSG_AUTO_HOME_A, PSTR("G28" AXIS4_STR));
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
GCODES_ITEM(MSG_AUTO_HOME_J, PSTR("G28" AXIS5_STR));
|
||||
GCODES_ITEM_N(J_AXIS, MSG_AUTO_HOME_A, PSTR("G28" AXIS5_STR));
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
GCODES_ITEM(MSG_AUTO_HOME_K, PSTR("G28" AXIS6_STR));
|
||||
GCODES_ITEM_N(K_AXIS, MSG_AUTO_HOME_A, PSTR("G28" AXIS6_STR));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user