🎨 Axis name string interpolation, with examples (#22879)

This commit is contained in:
Scott Lahteine
2021-10-04 00:24:41 -05:00
parent 854ce63358
commit 1de265ea5d
26 changed files with 100 additions and 106 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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...) \

View File

@@ -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