From 24cdbf0269447641f80b393d3da022c18348bdce Mon Sep 17 00:00:00 2001 From: SuuperW Date: Sat, 25 Aug 2018 09:52:49 -0500 Subject: [PATCH] (Windows) Allow rearranging of cheats in the cheat list. (Requested by #178) --- desmume/src/cheatSystem.cpp | 13 ++++ desmume/src/cheatSystem.h | 1 + desmume/src/frontend/windows/cheatsWin.cpp | 89 ++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/desmume/src/cheatSystem.cpp b/desmume/src/cheatSystem.cpp index 9ba400437..cf1d8ba6e 100644 --- a/desmume/src/cheatSystem.cpp +++ b/desmume/src/cheatSystem.cpp @@ -73,6 +73,19 @@ BOOL CHEATS::update(u8 size, u32 address, u32 val, char *description, BOOL enabl return TRUE; } +BOOL CHEATS::move(u32 srcPos, u32 dstPos) +{ + if (srcPos >= list.size() || dstPos > list.size()) return false; + if (srcPos < 0 || dstPos < 0) return false; + + CHEATS_LIST srcCheat = list[srcPos]; + list.insert(list._Make_iterator_offset(dstPos), srcCheat); + if (dstPos < srcPos) srcPos++; + remove(srcPos); + + return true; +} + #define CHEATLOG(...) //#define CHEATLOG(...) printf(__VA_ARGS__) diff --git a/desmume/src/cheatSystem.h b/desmume/src/cheatSystem.h index 1cccd5410..502be154e 100644 --- a/desmume/src/cheatSystem.h +++ b/desmume/src/cheatSystem.h @@ -75,6 +75,7 @@ public: void init(char *path); BOOL add(u8 size, u32 address, u32 val, char *description, BOOL enabled); BOOL update(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos); + BOOL move(u32 srcPos, u32 dstPos); BOOL add_AR(char *code, char *description, BOOL enabled); BOOL update_AR(char *code, char *description, BOOL enabled, u32 pos); BOOL add_AR_Direct(CHEATS_LIST cheat); diff --git a/desmume/src/frontend/windows/cheatsWin.cpp b/desmume/src/frontend/windows/cheatsWin.cpp index 2b323c53f..416a4b75a 100644 --- a/desmume/src/frontend/windows/cheatsWin.cpp +++ b/desmume/src/frontend/windows/cheatsWin.cpp @@ -56,6 +56,8 @@ static u32 cheatEditPos = 0; static u8 cheatAddPasteCheck = 0; static u8 cheatXXtype = 0; static u8 cheatXXaction = 0; +static s32 draggedItem = -1; +static s32 highlightedItem = -1; static HWND searchWnd = NULL; static HWND searchListView = NULL; @@ -677,6 +679,39 @@ void AttemptSaveAndClose(HWND dialog) else MessageBox(dialog, "Can't save cheats to file.\nCheck your path (Menu->Config->Path Settings->\"Cheats\")", "Error", MB_OK); } +void MoveRow(HWND list, int src, int dst) +{ + // move the cheat + if (!cheats->move(src, dst)) + return; + + // insert new row + LVITEM item; + memset(&item, 0, sizeof(LVITEM)); + item.mask = LVIF_TEXT | LVIF_STATE; + item.iItem = dst; + ListView_InsertItem(cheatListView, &item); + if (dst < src) src++; + + // get and set each subitem + item.iItem = src; + char* buf = new char[256]; + item.pszText = buf; + item.cchTextMax = 256; + item.mask = LVIF_TEXT; + for (int i = 1; i < 4; i++) + { + item.iSubItem = i; + ListView_GetItem(cheatListView, &item); + ListView_SetItemText(cheatListView, dst, i, item.pszText); + } + + // set check state + ListView_SetCheckState(cheatListView, dst, ListView_GetCheckState(cheatListView, src)); + + // delete the original item + ListView_DeleteItem(cheatListView, src); +} INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam) { switch(msg) @@ -819,12 +854,66 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l } } break; + + case LVN_BEGINDRAG: + { + draggedItem = ListView_GetSelectionMark(cheatListView); + SetCapture(dialog); // This sends all mouse messages to the dialog. + } + break; } return TRUE; } return FALSE; + case WM_MOUSEMOVE: + { + if (draggedItem != -1) + { + // un-highlight any previously highlighted item + if (highlightedItem != -1) + ListView_SetItemState(cheatListView, highlightedItem, 0, LVIS_DROPHILITED); + + // get location of the cursor, relative to the list view + RECT r; + GetWindowRect(GetDlgItem(dialog, IDC_LIST1), &r); + POINT p = { r.left, r.top }; + ScreenToClient(dialog, &p); + + LVHITTESTINFO hitTestInfo; + hitTestInfo.pt.x = LOWORD(lparam) - p.x; + hitTestInfo.pt.y = HIWORD(lparam) - p.y; + + // find the item under the cursor and highlight it + ListView_HitTest(cheatListView, &hitTestInfo); + if (hitTestInfo.iItem != -1) + ListView_SetItemState(cheatListView, hitTestInfo.iItem, LVIS_DROPHILITED, LVIS_DROPHILITED); + highlightedItem = hitTestInfo.iItem; + } + } + break; + + case WM_LBUTTONUP: + { + if (highlightedItem != -1) + ListView_SetItemState(cheatListView, highlightedItem, 0, LVIS_DROPHILITED); + + if (draggedItem != -1) + { + if (highlightedItem != -1 && highlightedItem != draggedItem) + { + if (highlightedItem > draggedItem) + highlightedItem++; // if dragging an item down, item should be placed below highlighted item (required to move an item to the bottom) + MoveRow(cheatListView, draggedItem, highlightedItem); + EnableWindow(GetDlgItem(dialog, IDOK), TRUE); + } + } + draggedItem = -1; + ReleaseCapture(); + } + break; + case WM_COMMAND: { switch (LOWORD(wparam))