From 4e936f2c2d43627952518ba65a8a39894906c3d7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 10 Feb 2022 16:37:17 -0500 Subject: [PATCH] prepare for converting keybinds to actions issue #157 --- src/gui/gui.cpp | 124 ++++++++++++++++++------------------- src/gui/gui.h | 159 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 214 insertions(+), 69 deletions(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index e0a13bd36..5270a8f17 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1081,7 +1081,7 @@ void FurnaceGUI::drawOrders() { if (ImGui::Selectable(selID,(orderEditMode!=0 && curOrder==i && orderCursor==j))) { if (curOrder==i) { if (orderEditMode==0) { - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); if (changeAllOrders) { for (int k=0; kgetTotalChannelCount(); k++) { if (e->song.orders.ord[k][i]<0x7f) e->song.orders.ord[k][i]++; @@ -1090,7 +1090,7 @@ void FurnaceGUI::drawOrders() { if (e->song.orders.ord[j][i]<0x7f) e->song.orders.ord[j][i]++; } e->walkSong(loopOrder,loopRow,loopEnd); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } else { orderCursor=j; curNibble=false; @@ -1107,7 +1107,7 @@ void FurnaceGUI::drawOrders() { if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { if (curOrder==i) { if (orderEditMode==0) { - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); if (changeAllOrders) { for (int k=0; kgetTotalChannelCount(); k++) { if (e->song.orders.ord[k][i]>0) e->song.orders.ord[k][i]--; @@ -1116,7 +1116,7 @@ void FurnaceGUI::drawOrders() { if (e->song.orders.ord[j][i]>0) e->song.orders.ord[j][i]--; } e->walkSong(loopOrder,loopRow,loopEnd); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } else { orderCursor=j; curNibble=false; @@ -1139,39 +1139,39 @@ void FurnaceGUI::drawOrders() { ImGui::NextColumn(); if (ImGui::Button(ICON_FA_PLUS)) { // add order row (new) - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); e->addOrder(false,false); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } if (ImGui::Button(ICON_FA_MINUS)) { // remove this order row - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); e->deleteOrder(); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } if (ImGui::Button(ICON_FA_FILES_O)) { // duplicate order row - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); e->addOrder(true,false); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } if (ImGui::Button(ICON_FA_ANGLE_UP)) { // move order row up - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); e->moveOrderUp(); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } if (ImGui::Button(ICON_FA_ANGLE_DOWN)) { // move order row down - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); e->moveOrderDown(); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } if (ImGui::Button(ICON_FA_ANGLE_DOUBLE_DOWN)) { // duplicate order row at end - prepareUndo(GUI_ACTION_CHANGE_ORDER); + prepareUndo(GUI_UNDO_CHANGE_ORDER); e->addOrder(true,true); - makeUndo(GUI_ACTION_CHANGE_ORDER); + makeUndo(GUI_UNDO_CHANGE_ORDER); } if (ImGui::Button(changeAllOrders?ICON_FA_LINK"##ChangeAll":ICON_FA_CHAIN_BROKEN"##ChangeAll")) { // whether to change one or all orders in a row @@ -4615,16 +4615,16 @@ void FurnaceGUI::editAdvance() { void FurnaceGUI::prepareUndo(ActionType action) { int order=e->getOrder(); switch (action) { - case GUI_ACTION_CHANGE_ORDER: + case GUI_UNDO_CHANGE_ORDER: oldOrders=e->song.orders; oldOrdersLen=e->song.ordersLen; break; - case GUI_ACTION_PATTERN_EDIT: - case GUI_ACTION_PATTERN_DELETE: - case GUI_ACTION_PATTERN_PULL: - case GUI_ACTION_PATTERN_PUSH: - case GUI_ACTION_PATTERN_CUT: - case GUI_ACTION_PATTERN_PASTE: + case GUI_UNDO_PATTERN_EDIT: + case GUI_UNDO_PATTERN_DELETE: + case GUI_UNDO_PATTERN_PULL: + case GUI_UNDO_PATTERN_PUSH: + case GUI_UNDO_PATTERN_CUT: + case GUI_UNDO_PATTERN_PASTE: for (int i=0; igetTotalChannelCount(); i++) { memcpy(oldPat[i],e->song.pat[i].getPattern(e->song.orders.ord[i][order],false),sizeof(DivPattern)); } @@ -4643,7 +4643,7 @@ void FurnaceGUI::makeUndo(ActionType action) { s.order=order; s.nibble=curNibble; switch (action) { - case GUI_ACTION_CHANGE_ORDER: + case GUI_UNDO_CHANGE_ORDER: for (int i=0; isong.orders.ord[i][j]) { @@ -4660,12 +4660,12 @@ void FurnaceGUI::makeUndo(ActionType action) { doPush=true; } break; - case GUI_ACTION_PATTERN_EDIT: - case GUI_ACTION_PATTERN_DELETE: - case GUI_ACTION_PATTERN_PULL: - case GUI_ACTION_PATTERN_PUSH: - case GUI_ACTION_PATTERN_CUT: - case GUI_ACTION_PATTERN_PASTE: + case GUI_UNDO_PATTERN_EDIT: + case GUI_UNDO_PATTERN_DELETE: + case GUI_UNDO_PATTERN_PULL: + case GUI_UNDO_PATTERN_PUSH: + case GUI_UNDO_PATTERN_CUT: + case GUI_UNDO_PATTERN_PASTE: for (int i=0; igetTotalChannelCount(); i++) { DivPattern* p=e->song.pat[i].getPattern(e->song.orders.ord[i][order],false); for (int j=0; jsong.patLen; j++) { @@ -4734,7 +4734,7 @@ void FurnaceGUI::doSelectAll() { void FurnaceGUI::doDelete() { finishSelection(); - prepareUndo(GUI_ACTION_PATTERN_DELETE); + prepareUndo(GUI_UNDO_PATTERN_DELETE); curNibble=false; int iCoarse=selStart.xCoarse; @@ -4755,12 +4755,12 @@ void FurnaceGUI::doDelete() { iFine=0; } - makeUndo(GUI_ACTION_PATTERN_DELETE); + makeUndo(GUI_UNDO_PATTERN_DELETE); } void FurnaceGUI::doPullDelete() { finishSelection(); - prepareUndo(GUI_ACTION_PATTERN_PULL); + prepareUndo(GUI_UNDO_PATTERN_PULL); curNibble=false; if (settings.pullDeleteBehavior) { @@ -4794,12 +4794,12 @@ void FurnaceGUI::doPullDelete() { iFine=0; } - makeUndo(GUI_ACTION_PATTERN_PULL); + makeUndo(GUI_UNDO_PATTERN_PULL); } void FurnaceGUI::doInsert() { finishSelection(); - prepareUndo(GUI_ACTION_PATTERN_PUSH); + prepareUndo(GUI_UNDO_PATTERN_PUSH); curNibble=false; int iCoarse=selStart.xCoarse; @@ -4826,12 +4826,12 @@ void FurnaceGUI::doInsert() { iFine=0; } - makeUndo(GUI_ACTION_PATTERN_PUSH); + makeUndo(GUI_UNDO_PATTERN_PUSH); } void FurnaceGUI::doTranspose(int amount) { finishSelection(); - prepareUndo(GUI_ACTION_PATTERN_DELETE); + prepareUndo(GUI_UNDO_PATTERN_DELETE); curNibble=false; int iCoarse=selStart.xCoarse; @@ -4872,14 +4872,14 @@ void FurnaceGUI::doTranspose(int amount) { iFine=0; } - makeUndo(GUI_ACTION_PATTERN_DELETE); + makeUndo(GUI_UNDO_PATTERN_DELETE); } void FurnaceGUI::doCopy(bool cut) { finishSelection(); if (cut) { curNibble=false; - prepareUndo(GUI_ACTION_PATTERN_CUT); + prepareUndo(GUI_UNDO_PATTERN_CUT); } clipboard=fmt::sprintf("org.tildearrow.furnace - Pattern Data (%d)\n%d",DIV_ENGINE_VERSION,selStart.xFine); @@ -4919,13 +4919,13 @@ void FurnaceGUI::doCopy(bool cut) { SDL_SetClipboardText(clipboard.c_str()); if (cut) { - makeUndo(GUI_ACTION_PATTERN_CUT); + makeUndo(GUI_UNDO_PATTERN_CUT); } } void FurnaceGUI::doPaste() { finishSelection(); - prepareUndo(GUI_ACTION_PATTERN_PASTE); + prepareUndo(GUI_UNDO_PATTERN_PASTE); char* clipText=SDL_GetClipboardText(); if (clipText!=NULL) { if (clipText[0]) { @@ -5034,7 +5034,7 @@ void FurnaceGUI::doPaste() { j++; } - makeUndo(GUI_ACTION_PATTERN_PASTE); + makeUndo(GUI_UNDO_PATTERN_PASTE); } void FurnaceGUI::doUndo() { @@ -5044,18 +5044,18 @@ void FurnaceGUI::doUndo() { modified=true; switch (us.type) { - case GUI_ACTION_CHANGE_ORDER: + case GUI_UNDO_CHANGE_ORDER: e->song.ordersLen=us.oldOrdersLen; for (UndoOrderData& i: us.ord) { e->song.orders.ord[i.chan][i.ord]=i.oldVal; } break; - case GUI_ACTION_PATTERN_EDIT: - case GUI_ACTION_PATTERN_DELETE: - case GUI_ACTION_PATTERN_PULL: - case GUI_ACTION_PATTERN_PUSH: - case GUI_ACTION_PATTERN_CUT: - case GUI_ACTION_PATTERN_PASTE: + case GUI_UNDO_PATTERN_EDIT: + case GUI_UNDO_PATTERN_DELETE: + case GUI_UNDO_PATTERN_PULL: + case GUI_UNDO_PATTERN_PUSH: + case GUI_UNDO_PATTERN_CUT: + case GUI_UNDO_PATTERN_PASTE: for (UndoPatternData& i: us.pat) { DivPattern* p=e->song.pat[i.chan].getPattern(i.pat,true); p->data[i.row][i.col]=i.oldVal; @@ -5081,18 +5081,18 @@ void FurnaceGUI::doRedo() { modified=true; switch (us.type) { - case GUI_ACTION_CHANGE_ORDER: + case GUI_UNDO_CHANGE_ORDER: e->song.ordersLen=us.newOrdersLen; for (UndoOrderData& i: us.ord) { e->song.orders.ord[i.chan][i.ord]=i.newVal; } break; - case GUI_ACTION_PATTERN_EDIT: - case GUI_ACTION_PATTERN_DELETE: - case GUI_ACTION_PATTERN_PULL: - case GUI_ACTION_PATTERN_PUSH: - case GUI_ACTION_PATTERN_CUT: - case GUI_ACTION_PATTERN_PASTE: + case GUI_UNDO_PATTERN_EDIT: + case GUI_UNDO_PATTERN_DELETE: + case GUI_UNDO_PATTERN_PULL: + case GUI_UNDO_PATTERN_PUSH: + case GUI_UNDO_PATTERN_CUT: + case GUI_UNDO_PATTERN_PASTE: for (UndoPatternData& i: us.pat) { DivPattern* p=e->song.pat[i.chan].getPattern(i.pat,true); p->data[i.row][i.col]=i.newVal; @@ -5376,7 +5376,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { if (edit) { DivPattern* pat=e->song.pat[cursor.xCoarse].getPattern(e->song.orders.ord[cursor.xCoarse][e->getOrder()],true); - prepareUndo(GUI_ACTION_PATTERN_EDIT); + prepareUndo(GUI_UNDO_PATTERN_EDIT); if (key==100) { // note off pat->data[cursor.y][0]=100; @@ -5398,7 +5398,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { pat->data[cursor.y][2]=curIns; previewNote(cursor.xCoarse,num); } - makeUndo(GUI_ACTION_PATTERN_EDIT); + makeUndo(GUI_UNDO_PATTERN_EDIT); editAdvance(); curNibble=false; } else { @@ -5412,7 +5412,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { try { int num=valueKeys.at(ev.key.keysym.sym); DivPattern* pat=e->song.pat[cursor.xCoarse].getPattern(e->song.orders.ord[cursor.xCoarse][e->getOrder()],true); - prepareUndo(GUI_ACTION_PATTERN_EDIT); + prepareUndo(GUI_UNDO_PATTERN_EDIT); if (pat->data[cursor.y][cursor.xFine+1]==-1) pat->data[cursor.y][cursor.xFine+1]=0; pat->data[cursor.y][cursor.xFine+1]=((pat->data[cursor.y][cursor.xFine+1]<<4)|num)&0xff; if (cursor.xFine==1) { // instrument @@ -5422,7 +5422,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { pat->data[cursor.y][cursor.xFine+1]=(int)e->song.ins.size()-1; } } - makeUndo(GUI_ACTION_PATTERN_EDIT); + makeUndo(GUI_UNDO_PATTERN_EDIT); if (e->song.ins.size()<16) { curNibble=false; editAdvance(); @@ -5436,7 +5436,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { } else { pat->data[cursor.y][cursor.xFine+1]&=15; } - makeUndo(GUI_ACTION_PATTERN_EDIT); + makeUndo(GUI_UNDO_PATTERN_EDIT); if (e->getMaxVolumeChan(cursor.xCoarse)<16) { curNibble=false; editAdvance(); @@ -5445,7 +5445,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { if (!curNibble) editAdvance(); } } else { - makeUndo(GUI_ACTION_PATTERN_EDIT); + makeUndo(GUI_UNDO_PATTERN_EDIT); curNibble=!curNibble; if (!curNibble) editAdvance(); } diff --git a/src/gui/gui.h b/src/gui/gui.h index 1e69a5e19..2953ef097 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -117,6 +117,151 @@ enum FurnaceGUIFMAlgs { FM_ALGS_4OP_OPL }; +enum FurnaceGUIActions { + GUI_ACTION_OPEN, + GUI_ACTION_SAVE, + GUI_ACTION_UNDO, + GUI_ACTION_REDO, + GUI_ACTION_PLAY_TOGGLE, + GUI_ACTION_PLAY, + GUI_ACTION_STOP, + GUI_ACTION_PLAY_REPEAT, + GUI_ACTION_PLAY_CURSOR, + GUI_ACTION_STEP_ONE, + GUI_ACTION_OCTAVE_UP, + GUI_ACTION_OCTAVE_DOWN, + GUI_ACTION_INS_UP, + GUI_ACTION_INS_DOWN, + GUI_ACTION_STEP_UP, + GUI_ACTION_STEP_DOWN, + GUI_ACTION_TOGGLE_EDIT, + GUI_ACTION_METRONOME, + GUI_ACTION_REPEAT_PATTERN, + GUI_ACTION_FOLLOW_ORDERS, + GUI_ACTION_FOLLOW_PATTERN, + GUI_ACTION_PANIC, + + GUI_ACTION_WINDOW_EDIT_CONTROLS, + GUI_ACTION_WINDOW_ORDERS, + GUI_ACTION_WINDOW_INS_LIST, + GUI_ACTION_WINDOW_INS_EDIT, + GUI_ACTION_WINDOW_SONG_INFO, + GUI_ACTION_WINDOW_PATTERN, + GUI_ACTION_WINDOW_WAVE_LIST, + GUI_ACTION_WINDOW_WAVE_EDIT, + GUI_ACTION_WINDOW_SAMPLE_LIST, + GUI_ACTION_WINDOW_SAMPLE_EDIT, + GUI_ACTION_WINDOW_ABOUT, + GUI_ACTION_WINDOW_SETTINGS, + GUI_ACTION_WINDOW_MIXER, + GUI_ACTION_WINDOW_DEBUG, + GUI_ACTION_WINDOW_VOL_METER, + GUI_ACTION_WINDOW_STATS, + GUI_ACTION_WINDOW_COMPAT_FLAGS, + GUI_ACTION_WINDOW_PIANO, + GUI_ACTION_WINDOW_NOTES, + GUI_ACTION_WINDOW_CHANNELS, + + GUI_ACTION_COLLAPSE_WINDOW, + GUI_ACTION_CLOSE_WINDOW, + + GUI_ACTION_PAT_NOTE_UP, + GUI_ACTION_PAT_NOTE_DOWN, + GUI_ACTION_PAT_OCTAVE_UP, + GUI_ACTION_PAT_OCTAVE_DOWN, + GUI_ACTION_PAT_SELECT_ALL, + GUI_ACTION_PAT_CUT, + GUI_ACTION_PAT_COPY, + GUI_ACTION_PAT_PASTE, + GUI_ACTION_PAT_CURSOR_UP, + GUI_ACTION_PAT_CURSOR_DOWN, + GUI_ACTION_PAT_CURSOR_LEFT, + GUI_ACTION_PAT_CURSOR_RIGHT, + GUI_ACTION_PAT_CURSOR_UP_ONE, + GUI_ACTION_PAT_CURSOR_DOWN_ONE, + GUI_ACTION_PAT_CURSOR_LEFT_CHANNEL, + GUI_ACTION_PAT_CURSOR_RIGHT_CHANNEL, + GUI_ACTION_PAT_CURSOR_NEXT_CHANNEL, + GUI_ACTION_PAT_CURSOR_PREVIOUS_CHANNEL, + GUI_ACTION_PAT_CURSOR_BEGIN, + GUI_ACTION_PAT_CURSOR_END, + GUI_ACTION_PAT_CURSOR_UP_COARSE, + GUI_ACTION_PAT_CURSOR_DOWN_COARSE, + GUI_ACTION_PAT_SELECTION_UP, + GUI_ACTION_PAT_SELECTION_DOWN, + GUI_ACTION_PAT_SELECTION_LEFT, + GUI_ACTION_PAT_SELECTION_RIGHT, + GUI_ACTION_PAT_SELECTION_UP_ONE, + GUI_ACTION_PAT_SELECTION_DOWN_ONE, + GUI_ACTION_PAT_SELECTION_BEGIN, + GUI_ACTION_PAT_SELECTION_END, + GUI_ACTION_PAT_SELECTION_UP_COARSE, + GUI_ACTION_PAT_SELECTION_DOWN_COARSE, + GUI_ACTION_PAT_DELETE, + GUI_ACTION_PAT_PULL_DELETE, + GUI_ACTION_PAT_INSERT, + GUI_ACTION_PAT_MUTE_CURSOR, + GUI_ACTION_PAT_SOLO_CURSOR, + GUI_ACTION_PAT_NEXT_ORDER, + GUI_ACTION_PAT_PREV_ORDER, + GUI_ACTION_PAT_COLLAPSE, + GUI_ACTION_PAT_INCREASE_COLUMNS, + GUI_ACTION_PAT_DECREASE_COLUMNS, + + GUI_ACTION_INS_LIST_ADD, + GUI_ACTION_INS_LIST_DUPLICATE, + GUI_ACTION_INS_LIST_OPEN, + GUI_ACTION_INS_LIST_SAVE, + GUI_ACTION_INS_LIST_MOVE_UP, + GUI_ACTION_INS_LIST_MOVE_DOWN, + GUI_ACTION_INS_LIST_DELETE, + GUI_ACTION_INS_LIST_EDIT, + GUI_ACTION_INS_LIST_UP, + GUI_ACTION_INS_LIST_DOWN, + + GUI_ACTION_WAVE_LIST_ADD, + GUI_ACTION_WAVE_LIST_DUPLICATE, + GUI_ACTION_WAVE_LIST_OPEN, + GUI_ACTION_WAVE_LIST_SAVE, + GUI_ACTION_WAVE_LIST_MOVE_UP, + GUI_ACTION_WAVE_LIST_MOVE_DOWN, + GUI_ACTION_WAVE_LIST_DELETE, + GUI_ACTION_WAVE_LIST_EDIT, + GUI_ACTION_WAVE_LIST_UP, + GUI_ACTION_WAVE_LIST_DOWN, + + GUI_ACTION_SAMPLE_LIST_ADD, + GUI_ACTION_SAMPLE_LIST_DUPLICATE, + GUI_ACTION_SAMPLE_LIST_OPEN, + GUI_ACTION_SAMPLE_LIST_SAVE, + GUI_ACTION_SAMPLE_LIST_MOVE_UP, + GUI_ACTION_SAMPLE_LIST_MOVE_DOWN, + GUI_ACTION_SAMPLE_LIST_DELETE, + GUI_ACTION_SAMPLE_LIST_EDIT, + GUI_ACTION_SAMPLE_LIST_UP, + GUI_ACTION_SAMPLE_LIST_DOWN, + GUI_ACTION_SAMPLE_LIST_PREVIEW, + GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW, + + GUI_ACTION_ORDERS_UP, + GUI_ACTION_ORDERS_DOWN, + GUI_ACTION_ORDERS_LEFT, + GUI_ACTION_ORDERS_RIGHT, + GUI_ACTION_ORDERS_INCREASE, + GUI_ACTION_ORDERS_DECREASE, + GUI_ACTION_ORDERS_EDIT_MODE, + GUI_ACTION_ORDERS_LINK, + GUI_ACTION_ORDERS_ADD, + GUI_ACTION_ORDERS_DUPLICATE, + GUI_ACTION_ORDERS_DEEP_CLONE, + GUI_ACTION_ORDERS_DUPLICATE_END, + GUI_ACTION_ORDERS_DEEP_CLONE_END, + GUI_ACTION_ORDERS_REMOVE, + GUI_ACTION_ORDERS_MOVE_UP, + GUI_ACTION_ORDERS_MOVE_DOWN, + GUI_ACTION_ORDERS_REPLAY, +}; + struct SelectionPoint { int xCoarse, xFine; int y; @@ -125,13 +270,13 @@ struct SelectionPoint { }; enum ActionType { - GUI_ACTION_CHANGE_ORDER, - GUI_ACTION_PATTERN_EDIT, - GUI_ACTION_PATTERN_DELETE, - GUI_ACTION_PATTERN_PULL, - GUI_ACTION_PATTERN_PUSH, - GUI_ACTION_PATTERN_CUT, - GUI_ACTION_PATTERN_PASTE + GUI_UNDO_CHANGE_ORDER, + GUI_UNDO_PATTERN_EDIT, + GUI_UNDO_PATTERN_DELETE, + GUI_UNDO_PATTERN_PULL, + GUI_UNDO_PATTERN_PUSH, + GUI_UNDO_PATTERN_CUT, + GUI_UNDO_PATTERN_PASTE }; struct UndoPatternData {