Skip to content
125 changes: 125 additions & 0 deletions Marlin/src/lcd/e3v2/proui/dwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,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,
Expand Down Expand Up @@ -286,6 +292,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;
Expand Down Expand Up @@ -1475,6 +1484,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:
Expand Down Expand Up @@ -3131,6 +3144,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) {
Expand Down Expand Up @@ -3224,11 +3345,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)
Expand Down
15 changes: 15 additions & 0 deletions Marlin/src/lcd/e3v2/proui/dwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum processID : uint8_t {
ID_PIDProcess,
ID_PlotProcess,
ID_MPCProcess,
ID_Macros,
ID_NothingToDo
};

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down