diff --git a/src/gui/cursor.cpp b/src/gui/cursor.cpp index e47dfd62..4b75a26a 100644 --- a/src/gui/cursor.cpp +++ b/src/gui/cursor.cpp @@ -42,6 +42,22 @@ void FurnaceGUI::startSelection(int xCoarse, int xFine, int y, bool fullRow) { return; } } + + if (settings.dragMovesSelection && !fullRow) { + if (xCoarse>=selStart.xCoarse && (xFine>=selStart.xFine || xCoarse>selStart.xCoarse) && y>=selStart.y && + xCoarse<=selEnd.xCoarse && (xFine<=selEnd.xFine || xCoarsecurPat[selEnd.xCoarse].effectCols*2; - selEnd.y=y; + if (dragging) { + dragDestinationX=xCoarse; + dragDestinationY=y; + cursorDrag.xCoarse=xCoarse; + cursorDrag.xFine=xFine; + cursorDrag.y=y; + + selStart.xCoarse=dragStart.xCoarse+(dragDestinationX-dragSourceX); + selStart.xFine=dragStart.xFine; + selStart.y=dragStart.y+(dragDestinationY-dragSourceY); + selEnd.xCoarse=dragEnd.xCoarse+(dragDestinationX-dragSourceX); + selEnd.xFine=dragEnd.xFine; + selEnd.y=dragEnd.y+(dragDestinationY-dragSourceY); } else { - selEnd.xCoarse=xCoarse; - selEnd.xFine=xFine; - selEnd.y=y; + if (selectingFull) { + DETERMINE_LAST; + selEnd.xCoarse=lastChannel-1; + selEnd.xFine=2+e->curPat[selEnd.xCoarse].effectCols*2; + selEnd.y=y; + } else { + selEnd.xCoarse=xCoarse; + selEnd.xFine=xFine; + selEnd.y=y; + } } } @@ -103,6 +134,18 @@ void FurnaceGUI::finishSelection() { selecting=false; selectingFull=false; + if (dragging) { + if (dragSourceX==dragDestinationX && dragSourceY==dragDestinationY) { + cursor=cursorDrag; + selStart=cursorDrag; + selEnd=cursorDrag; + } else { // perform drag + doDrag(); + } + + dragging=false; + } + // boundary check int chanCount=e->getTotalChannelCount(); diff --git a/src/gui/editing.cpp b/src/gui/editing.cpp index ef63ab26..2f2757c2 100644 --- a/src/gui/editing.cpp +++ b/src/gui/editing.cpp @@ -918,6 +918,32 @@ void FurnaceGUI::doExpand(int multiplier) { makeUndo(GUI_UNDO_PATTERN_EXPAND); } +// 1. COPY +// 2. CLEAR +// 3. PASTE +void FurnaceGUI::doDrag() { + int iCoarse=selStart.xCoarse; + int iFine=selStart.xFine; + for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->curSubSong->chanShow[iCoarse]) continue; + DivPattern* pat=e->curPat[iCoarse].getPattern(e->curOrders->ord[iCoarse][curOrder],true); + for (; iFine<3+e->curPat[iCoarse].effectCols*2 && (iCoarsedata[j][iFine]=0; + if (selStart.y==selEnd.y) pat->data[j][2]=-1; + } + pat->data[j][iFine+1]=(iFine<1)?0:-1; + + if (selStart.y==selEnd.y && iFine>2 && iFine&1 && settings.effectDeletionAltersValue) { + pat->data[j][iFine+2]=-1; + } + } + } + iFine=0; + } +} + void FurnaceGUI::doUndo() { if (undoHist.empty()) return; UndoStep& us=undoHist.back(); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index fd904649..5717f391 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4372,6 +4372,10 @@ FurnaceGUI::FurnaceGUI(): latchTarget(0), wheelX(0), wheelY(0), + dragSourceX(0), + dragSourceY(0), + dragDestinationX(0), + dragDestinationY(0), exportFadeOut(5.0), editControlsOpen(true), ordersOpen(true), @@ -4403,6 +4407,7 @@ FurnaceGUI::FurnaceGUI(): findOpen(false), selecting(false), selectingFull(false), + dragging(false), curNibble(false), orderNibble(false), followOrders(true), diff --git a/src/gui/gui.h b/src/gui/gui.h index 9381bab0..b9a550ed 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1024,6 +1024,7 @@ class FurnaceGUI { int effectValCellSpacing; int doubleClickColumn; int blankIns; + int dragMovesSelection; unsigned int maxUndoSteps; String mainFontPath; String patFontPath; @@ -1124,6 +1125,7 @@ class FurnaceGUI { effectValCellSpacing(0), doubleClickColumn(1), blankIns(0), + dragMovesSelection(1), maxUndoSteps(100), mainFontPath(""), patFontPath(""), @@ -1138,7 +1140,7 @@ class FurnaceGUI { int curIns, curWave, curSample, curOctave, curOrder, prevIns, oldRow, oldOrder, oldOrder1, editStep, exportLoops, soloChan, soloTimeout, orderEditMode, orderCursor; int loopOrder, loopRow, loopEnd, isClipping, extraChannelButtons, patNameTarget, newSongCategory, latchTarget; - int wheelX, wheelY; + int wheelX, wheelY, dragSourceX, dragSourceY, dragDestinationX, dragDestinationY; double exportFadeOut; @@ -1148,8 +1150,8 @@ class FurnaceGUI { bool pianoOpen, notesOpen, channelsOpen, regViewOpen, logOpen, effectListOpen, chanOscOpen; bool subSongsOpen, findOpen; - SelectionPoint selStart, selEnd, cursor; - bool selecting, selectingFull, curNibble, orderNibble, followOrders, followPattern, changeAllOrders, mobileUI; + SelectionPoint selStart, selEnd, cursor, cursorDrag, dragStart, dragEnd; + bool selecting, selectingFull, dragging, curNibble, orderNibble, followOrders, followPattern, changeAllOrders, mobileUI; bool collapseWindow, demandScrollX, fancyPattern, wantPatName, firstFrame, tempoView, waveHex, lockLayout, editOptsVisible, latchNibble, nonLatchNibble; FurnaceGUIWindows curWindow, nextWindow, curWindowLast; float peak[2]; @@ -1465,6 +1467,7 @@ class FurnaceGUI { void startSelection(int xCoarse, int xFine, int y, bool fullRow=false); void updateSelection(int xCoarse, int xFine, int y, bool fullRow=false); void finishSelection(); + void finishDrag(); void moveCursor(int x, int y, bool select); void moveCursorPrevChannel(bool overflow); @@ -1494,6 +1497,7 @@ class FurnaceGUI { void doRedo(); void doFind(); void doReplace(); + void doDrag(); void editOptions(bool topMenu); void noteInput(int num, int key, int vol=-1); void valueInput(int num, bool direct=false, int target=-1); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index da3b0f27..cae24ec0 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -411,6 +411,11 @@ void FurnaceGUI::drawSettings() { if (ImGui::Checkbox("Double click selects entire column",&doubleClickColumnB)) { settings.doubleClickColumn=doubleClickColumnB; } + + bool dragMovesSelectionB=settings.dragMovesSelection; + if (ImGui::Checkbox("Allow dragging selection",&dragMovesSelectionB)) { + settings.dragMovesSelection=dragMovesSelectionB; + } bool allowEditDockingB=settings.allowEditDocking; if (ImGui::Checkbox("Allow docking editors",&allowEditDockingB)) { @@ -2037,6 +2042,8 @@ void FurnaceGUI::syncSettings() { settings.effectValCellSpacing=e->getConfInt("effectValCellSpacing",0); settings.doubleClickColumn=e->getConfInt("doubleClickColumn",1); settings.blankIns=e->getConfInt("blankIns",0); + // SET TO 1 AFTER YOU ARE DONE + settings.dragMovesSelection=e->getConfInt("dragMovesSelection",0); clampSetting(settings.mainFontSize,2,96); clampSetting(settings.patFontSize,2,96); @@ -2121,6 +2128,7 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.effectValCellSpacing,0,32); clampSetting(settings.doubleClickColumn,0,1); clampSetting(settings.blankIns,0,1); + clampSetting(settings.dragMovesSelection,0,1); settings.initialSys=e->decodeSysDesc(e->getConfString("initialSys","")); if (settings.initialSys.size()<4) { @@ -2254,6 +2262,7 @@ void FurnaceGUI::commitSettings() { e->setConf("effectValCellSpacing",settings.effectValCellSpacing); e->setConf("doubleClickColumn",settings.doubleClickColumn); e->setConf("blankIns",settings.blankIns); + e->setConf("dragMovesSelection",settings.dragMovesSelection); // colors for (int i=0; i