From f09e060c338b87cdb39face214b835e0025b6656 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 18 Jul 2025 18:43:40 -0500 Subject: [PATCH] GUI: new pattern cursor logic, part 21 --- src/gui/editing.cpp | 58 +++++++++++++++++++++------------------------ src/gui/gui.cpp | 1 + src/gui/gui.h | 27 +++++++++++++-------- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/gui/editing.cpp b/src/gui/editing.cpp index ece8acead..96a739d07 100644 --- a/src/gui/editing.cpp +++ b/src/gui/editing.cpp @@ -53,7 +53,10 @@ const char* FurnaceGUI::noteNameNormal(short note, short octave) { } void FurnaceGUI::prepareUndo(ActionType action, UndoRegion region) { - prevCursor=cursor; + undoCursor=cursor; + undoSelStart=selStart; + undoSelEnd=selEnd; + undoOrder=curOrder; if (region.begin.ord==-1) { region.begin.ord=selStart.order; @@ -128,11 +131,16 @@ void FurnaceGUI::makeUndo(ActionType action, UndoRegion region) { bool shallWalk=false; UndoStep s; s.type=action; - s.cursor=prevCursor; - s.selStart=selStart; - s.selEnd=selEnd; - s.scroll=patScroll; - s.order=curOrder; + s.oldCursor=undoCursor; + s.oldSelStart=undoSelStart; + s.oldSelEnd=undoSelEnd; + s.oldScroll=patScroll; + s.oldOrder=undoOrder; + s.newCursor=cursor; + s.newSelStart=selStart; + s.newSelEnd=selEnd; + s.newScroll=(nextScroll>=0.0f)?nextScroll:patScroll; + s.newOrder=curOrder; s.oldOrdersLen=oldOrdersLen; s.newOrdersLen=e->curSubSong->ordersLen; s.nibble=curNibble; @@ -2134,6 +2142,7 @@ void FurnaceGUI::moveSelected(int x, int y) { void FurnaceGUI::doUndo() { if (undoHist.empty()) return; UndoStep& us=undoHist.back(); + redoHist.push_back(us); MARK_MODIFIED; switch (us.type) { @@ -2170,13 +2179,13 @@ void FurnaceGUI::doUndo() { } if (us.type!=GUI_UNDO_REPLACE) { if (!e->isPlaying() || !followPattern) { - cursor=us.cursor; - selStart=us.selStart; - selEnd=us.selEnd; + cursor=us.oldCursor; + selStart=us.oldSelStart; + selEnd=us.oldSelEnd; curNibble=us.nibble; - setOrder(us.order); - if (us.scroll>=0.0f) { - updateScrollRaw(us.scroll); + setOrder(us.oldOrder); + if (us.oldScroll>=0.0f) { + updateScrollRaw(us.oldScroll); } } } @@ -2199,21 +2208,12 @@ void FurnaceGUI::doUndo() { } } if (shallReplay && e->isPlaying()) play(); - - if (cursor.order!=curOrder) { - e->setOrder(cursor.order); - } if (curOrder>=e->curSubSong->ordersLen) { curOrder=e->curSubSong->ordersLen-1; e->setOrder(curOrder); } - // reverse state for redo - us.cursor=cursor; - us.scroll=patScroll; - redoHist.push_back(us); - undoHist.pop_back(); } @@ -2257,13 +2257,13 @@ void FurnaceGUI::doRedo() { } if (us.type!=GUI_UNDO_REPLACE) { if (!e->isPlaying() || !followPattern) { - cursor=us.cursor; - selStart=us.selStart; - selEnd=us.selEnd; + cursor=us.newCursor; + selStart=us.newSelStart; + selEnd=us.newSelEnd; curNibble=us.nibble; - setOrder(us.order); - if (us.scroll>=0.0f) { - updateScrollRaw(us.scroll); + setOrder(us.newOrder); + if (us.newScroll>=0.0f) { + updateScrollRaw(us.newScroll); } } } @@ -2287,10 +2287,6 @@ void FurnaceGUI::doRedo() { } if (shallReplay && e->isPlaying()) play(); - if (cursor.order!=curOrder) { - e->setOrder(cursor.order); - } - if (curOrder>=e->curSubSong->ordersLen) { curOrder=e->curSubSong->ordersLen-1; e->setOrder(curOrder); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index f0b76f46c..9e37ed740 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -8636,6 +8636,7 @@ FurnaceGUI::FurnaceGUI(): isClipping(0), newSongCategory(0), latchTarget(0), + undoOrder(0), wheelX(0), wheelY(0), dragSourceX(0), diff --git a/src/gui/gui.h b/src/gui/gui.h index ab5fa65b1..33f778e83 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1097,9 +1097,10 @@ struct UndoOtherData { struct UndoStep { ActionType type; - SelectionPoint cursor, selStart, selEnd; - float scroll; - int order; + SelectionPoint oldCursor, oldSelStart, oldSelEnd; + SelectionPoint newCursor, newSelStart, newSelEnd; + float oldScroll, newScroll; + int oldOrder, newOrder; bool nibble; int oldOrdersLen, newOrdersLen; int oldPatLen, newPatLen; @@ -1109,11 +1110,16 @@ struct UndoStep { UndoStep(): type(GUI_UNDO_CHANGE_ORDER), - cursor(), - selStart(), - selEnd(), - scroll(-1.0f), - order(0), + oldCursor(), + oldSelStart(), + oldSelEnd(), + newCursor(), + newSelStart(), + newSelEnd(), + oldScroll(-1.0f), + newScroll(-1.0f), + oldOrder(0), + newOrder(0), nibble(false), oldOrdersLen(0), newOrdersLen(0), @@ -2346,7 +2352,7 @@ class FurnaceGUI { FixedQueue pendingLayoutImportReopen; int curIns, curWave, curSample, curOctave, curOrder, playOrder, prevIns, oldRow, editStep, editStepCoarse, soloChan, orderEditMode, orderCursor; - int loopOrder, loopRow, loopEnd, isClipping, newSongCategory, latchTarget; + int loopOrder, loopRow, loopEnd, isClipping, newSongCategory, latchTarget, undoOrder; int wheelX, wheelY, dragSourceX, dragSourceXFine, dragSourceY, dragSourceOrder, dragDestinationX, dragDestinationXFine, dragDestinationY, dragDestinationOrder, oldBeat, oldBar; int curGroove, exitDisabledTimer; int curPaletteChoice, curPaletteType; @@ -2373,7 +2379,8 @@ class FurnaceGUI { bool clockShowReal, clockShowRow, clockShowBeat, clockShowMetro, clockShowTime; float clockMetroTick[16]; - SelectionPoint selStart, selEnd, cursor, cursorDrag, dragStart, dragEnd, prevCursor; + SelectionPoint selStart, selEnd, cursor, cursorDrag, dragStart, dragEnd; + SelectionPoint undoSelStart, undoSelEnd, undoCursor; bool selecting, selectingFull, dragging, curNibble, orderNibble, followOrders, followPattern, wasFollowing, changeAllOrders, mobileUI; bool collapseWindow, demandScrollX, fancyPattern, firstFrame, tempoView, waveHex, waveSigned, waveGenVisible, lockLayout, editOptsVisible, latchNibble, nonLatchNibble; bool keepLoopAlive, keepGrooveAlive, orderScrollLocked, orderScrollTolerance, dragMobileMenu, dragMobileEditButton, wantGrooveListFocus;