GUI: add ability to move selection by dragging

This commit is contained in:
tildearrow 2022-06-18 23:18:34 -05:00
parent ea082b255c
commit 8a1f544eef
4 changed files with 68 additions and 21 deletions

View File

@ -1,6 +1,5 @@
# to-do for 0.6pre1
- add ability to move selection by dragging
- implement Defle slide bug when using E1xy/E2xy and repeating origin note (requires format change)
# to-do for 0.6pre2 (as this requires new data structures)

View File

@ -62,6 +62,7 @@ void FurnaceGUI::prepareUndo(ActionType action) {
case GUI_UNDO_PATTERN_FLIP:
case GUI_UNDO_PATTERN_COLLAPSE:
case GUI_UNDO_PATTERN_EXPAND:
case GUI_UNDO_PATTERN_DRAG:
for (int i=0; i<e->getTotalChannelCount(); i++) {
e->curPat[i].getPattern(e->curOrders->ord[i][curOrder],false)->copyOn(oldPat[i]);
}
@ -114,6 +115,7 @@ void FurnaceGUI::makeUndo(ActionType action) {
case GUI_UNDO_PATTERN_FLIP:
case GUI_UNDO_PATTERN_COLLAPSE:
case GUI_UNDO_PATTERN_EXPAND:
case GUI_UNDO_PATTERN_DRAG:
for (int i=0; i<e->getTotalChannelCount(); i++) {
DivPattern* p=e->curPat[i].getPattern(e->curOrders->ord[i][curOrder],false);
for (int j=0; j<e->curSubSong->patLen; j++) {
@ -918,30 +920,74 @@ 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 && (iCoarse<selEnd.xCoarse || iFine<=selEnd.xFine); iFine++) {
for (int j=selStart.y; j<=selEnd.y; j++) {
if (iFine==0) {
pat->data[j][iFine]=0;
if (selStart.y==selEnd.y) pat->data[j][2]=-1;
}
pat->data[j][iFine+1]=(iFine<1)?0:-1;
DivPattern* patBuffer=NULL;
int len=dragEnd.xCoarse-dragStart.xCoarse+1;
if (selStart.y==selEnd.y && iFine>2 && iFine&1 && settings.effectDeletionAltersValue) {
pat->data[j][iFine+2]=-1;
DETERMINE_FIRST_LAST;
if (len<1) return;
patBuffer=new DivPattern[len];
prepareUndo(GUI_UNDO_PATTERN_DRAG);
// copy and clear
{
int iCoarse=dragStart.xCoarse;
int iFine=dragStart.xFine;
int iCoarseP=0;
for (; iCoarse<=dragEnd.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 && (iCoarse<dragEnd.xCoarse || iFine<=dragEnd.xFine); iFine++) {
int row=0;
for (int j=dragStart.y; j<=dragEnd.y; j++) {
if (iFine==0) {
patBuffer[iCoarseP].data[row][iFine]=pat->data[j][iFine];
pat->data[j][iFine]=0;
if (dragStart.y==dragEnd.y) pat->data[j][2]=-1;
}
patBuffer[iCoarseP].data[row][iFine+1]=pat->data[j][iFine+1];
pat->data[j][iFine+1]=(iFine<1)?0:-1;
if (dragStart.y==dragEnd.y && iFine>2 && iFine&1 && settings.effectDeletionAltersValue) {
pat->data[j][iFine+2]=-1;
}
row++;
}
}
iFine=0;
iCoarseP++;
}
iFine=0;
}
// replace
{
int iCoarse=selStart.xCoarse;
int iFine=selStart.xFine;
int iCoarseP=0;
for (; iCoarse<=selEnd.xCoarse && iCoarseP<len; iCoarse++) {
if (iCoarse<firstChannel || iCoarse>lastChannel) continue;
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 && (iCoarse<selEnd.xCoarse || iFine<=selEnd.xFine); iFine++) {
int row=-1;
for (int j=selStart.y; j<=selEnd.y; j++) {
row++;
if (j<0 || j>=e->curSubSong->patLen) continue;
if (iFine==0) {
pat->data[j][iFine]=patBuffer[iCoarseP].data[row][iFine];
}
pat->data[j][iFine+1]=patBuffer[iCoarseP].data[row][iFine+1];
}
}
iFine=0;
iCoarseP++;
}
}
delete[] patBuffer;
makeUndo(GUI_UNDO_PATTERN_DRAG);
}
void FurnaceGUI::doUndo() {
@ -973,6 +1019,7 @@ void FurnaceGUI::doUndo() {
case GUI_UNDO_PATTERN_FLIP:
case GUI_UNDO_PATTERN_COLLAPSE:
case GUI_UNDO_PATTERN_EXPAND:
case GUI_UNDO_PATTERN_DRAG:
case GUI_UNDO_REPLACE:
for (UndoPatternData& i: us.pat) {
e->changeSongP(i.subSong);
@ -1024,6 +1071,7 @@ void FurnaceGUI::doRedo() {
case GUI_UNDO_PATTERN_FLIP:
case GUI_UNDO_PATTERN_COLLAPSE:
case GUI_UNDO_PATTERN_EXPAND:
case GUI_UNDO_PATTERN_DRAG:
case GUI_UNDO_REPLACE:
for (UndoPatternData& i: us.pat) {
e->changeSongP(i.subSong);

View File

@ -567,6 +567,7 @@ enum ActionType {
GUI_UNDO_PATTERN_FLIP,
GUI_UNDO_PATTERN_COLLAPSE,
GUI_UNDO_PATTERN_EXPAND,
GUI_UNDO_PATTERN_DRAG,
GUI_UNDO_REPLACE
};

View File

@ -2042,8 +2042,7 @@ 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);
settings.dragMovesSelection=e->getConfInt("dragMovesSelection",1);
clampSetting(settings.mainFontSize,2,96);
clampSetting(settings.patFontSize,2,96);