This commit is contained in:
Andrew 2026-02-26 13:45:57 -08:00 committed by GitHub
commit fbd91cf662
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 140 additions and 0 deletions

View file

@ -174,6 +174,12 @@
hmi_value_t hmiValue;
hmi_flag_t hmiFlag{0};
hmi_data_t hmiData;
#if ENABLED(GCODE_MACROS)
hmi_macro_t hmiMacro;
static const char macroChars[] PROGMEM = " GM0123456789.XYZABCDEFHIJKLNOPQRSTUVW|";
char hmi_macro_data[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1] = {};
char run_labels[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 20] = {};
#endif
enum SelectItem : uint8_t {
PAGE_PRINT = 0,
@ -285,6 +291,9 @@ Menu *stepsMenu = nullptr;
#if HAS_TRINAMIC_CONFIG
Menu *trinamicConfigMenu = nullptr;
#endif
#if ENABLED(GCODE_MACROS)
Menu *macroMenu = nullptr;
#endif
// Updatable menuitems pointers
MenuItem *hotendTargetItem = nullptr;
@ -1477,6 +1486,10 @@ void dwinHandleScreen() {
#if HAS_LOCKSCREEN
case ID_Locked: hmiLockScreen(); break;
#endif
#if ENABLED(GCODE_MACROS)
case ID_Macros: hmiMacroEditor(); break;
#endif
TERN_(HAS_ESDIAG, case ID_ESDiagProcess:)
TERN_(PROUI_ITEM_PLOT, case ID_PlotProcess:)
case ID_PrintDone:
@ -3144,6 +3157,114 @@ void onDrawAcc(MenuItem* menuitem, int8_t line) {
#endif
#if ENABLED(GCODE_MACROS)
void drawMacroEditor() {
DWINUI::drawString(10, 100, hmiMacro.edit_buffer);
// Calculate cursor position once
const uint16_t cursor_pos = 10 + hmiMacro.cursor_pos * DWINUI::fontWidth();
DWINUI::drawBox(1, hmiData.colorBackground, {10, 120, uint16_t(1 + cursor_pos), DWINUI::fontHeight()});
DWINUI::drawChar(hmiData.colorAlertTxt, cursor_pos, 120, macroChars[hmiMacro.char_index]);
DWINUI::drawBox(1, hmiData.colorCursor, {cursor_pos, uint16_t(120 + DWINUI::fontHeight()), uint16_t(1 + DWINUI::fontWidth()), DWINUI::fontHeight()});
}
void macroEncoder(EncoderState encoder_diffState) {
switch (encoder_diffState) {
case ENCODER_DIFF_CW:
hmiMacro.char_index = (hmiMacro.char_index + 1) % (sizeof(macroChars) - 1);
break;
case ENCODER_DIFF_CCW:
hmiMacro.char_index = (hmiMacro.char_index == 0 ? sizeof(macroChars) - 2 : hmiMacro.char_index - 1);
break;
case ENCODER_DIFF_ENTER: {
char selectedChar = macroChars[hmiMacro.char_index];
// Check if the selected character is the end-and-save character.
if (selectedChar == '=') {
hmiMacro.edit_buffer[hmiMacro.cursor_pos] = '\0';
// Build and process the G-code command.
char cmd[80];
sprintf(cmd, "M81%u %s", hmiMacro.slot_edit, hmiMacro.edit_buffer);
gcode.process_subcommands_now(cmd);
#if ENABLED(EEPROM_SETTINGS)
gcode.process_subcommands_now(F("M500"));
#endif
// Copy the edited buffer to the permanent storage array.
memcpy(hmi_macro_data[hmiMacro.slot_edit], hmiMacro.edit_buffer, sizeof(hmiMacro.edit_buffer));
// UI updates and return.
DWINUI::clearMainArea();
hmiReturnScreen();
ReDrawMenu();
return;
}
else {
hmiMacro.edit_buffer[hmiMacro.cursor_pos] = selectedChar;
hmiMacro.cursor_pos++;
hmiMacro.char_index = 0; // Reset character index for next selection
}
}
break;
default:
break;
}
drawMacroEditor();
}
void hmiMacroEditor() {
EncoderState encoder_diffState = get_encoder_state();
if (encoder_diffState == ENCODER_DIFF_NO) return;
macroEncoder(encoder_diffState);
dwinUpdateLCD();
TERN_(DASH_REDRAW, dwinRedrawDash();)
}
void runMacro(uint8_t slot) {
char cmd[8];
sprintf(cmd, "M81%u", slot);
gcode.process_subcommands_now(cmd);
}
void editMacro(uint8_t slot) {
hmiMacro.slot_edit = slot;
hmiMacro.cursor_pos = 0;
hmiMacro.char_index = 0;
memset(hmiMacro.edit_buffer, 0, sizeof(hmiMacro.edit_buffer));
hmiSaveProcessID(ID_Macros);
char draw_title[20];
sprintf(draw_title, "Edit M81%u", hmiMacro.slot_edit);
title.showCaption(draw_title);
DWINUI::clearMainArea();
DWINUI::drawString(10, 80, F("Macro:"));
DWINUI::drawString(10, 160, F("Select = to save and exit"));
drawMacroEditor();
}
void drawMacroMenu() {
checkkey = ID_Menu;
if (SET_MENU_F(macroMenu, "Custom Macros", (GCODE_MACROS_SLOTS * 2) + 1)) {
BACK_ITEM(drawControlMenu);
for (uint8_t i = 0; i < GCODE_MACROS_SLOTS; i++) {
const char* gcode_str = hmi_macro_data[i];
if (gcode_str[0] != '\0') {
sprintf_P(run_labels[i], PSTR("Run M81%u (%s)"), i, hmi_macro_data[i]);
} else {
sprintf_P(run_labels[i], PSTR("Run M81%u"), i);
}
}
#define _ITEM_MACRO(N) \
MENU_ITEM_F(ICON_File, "Run M81"#N, onDrawMenuItem, []{ (void)runMacro(N); }); \
MENU_ITEM_F(ICON_Info, "Edit M81"#N, onDrawMenuItem, []{ (void)editMacro(N); });
REPEAT(GCODE_MACROS_SLOTS, _ITEM_MACRO);
}
updateMenu(macroMenu);
}
#endif
// Menu Creation and Drawing functions ======================================================
frame_rect_t selrect(frame_rect_t) {
@ -3237,11 +3358,15 @@ void drawControlMenu() {
constexpr uint8_t items = (3
+ COUNT_ENABLED(CASE_LIGHT_MENU, LED_CONTROL_MENU)
+ TERN0(EEPROM_SETTINGS, 3)
+ ENABLED(GCODE_MACROS)
+ 2
);
checkkey = ID_Menu;
if (SET_MENU_R(controlMenu, selrect({103, 1, 28, 14}), MSG_CONTROL, items)) {
BACK_ITEM(gotoMainMenu);
#if ENABLED(GCODE_MACROS)
MENU_ITEM_F(ICON_WriteEEPROM, "Custom Macros", onDrawSubMenu, drawMacroMenu);
#endif
MENU_ITEM(ICON_Temperature, MSG_TEMPERATURE, onDrawTempSubMenu, drawTemperatureMenu);
MENU_ITEM(ICON_Motion, MSG_MOTION, onDrawMotionSubMenu, drawMotionMenu);
#if ENABLED(CASE_LIGHT_MENU)

View file

@ -69,6 +69,7 @@ enum processID : uint8_t {
ID_PIDProcess,
ID_PlotProcess,
ID_MPCProcess,
ID_Macros,
ID_NothingToDo
};
@ -195,6 +196,17 @@ typedef struct {
extern hmi_value_t hmiValue;
#if ENABLED(GCODE_MACROS)
typedef struct {
uint8_t slot_edit = 0;
uint8_t cursor_pos = 0;
uint8_t char_index = 0;
char edit_buffer[GCODE_MACROS_SLOT_SIZE + 1] = { 0 };
} hmi_macro_t;
extern hmi_macro_t hmiMacro;
#endif
typedef struct {
uint8_t language;
bool printing_flag:1; // sd or host printing
@ -387,6 +399,9 @@ void drawMaxAccelMenu();
#if HAS_TRINAMIC_CONFIG
void drawTrinamicConfigMenu();
#endif
#if ENABLED(GCODE_MACROS)
void hmiMacroEditor();
#endif
// Custom colors editing
#if HAS_CUSTOM_COLORS