GUI: improve drag-and-drop, part 3

This commit is contained in:
tildearrow 2023-01-30 15:58:59 -05:00
parent 311c66ff9f
commit d1d92ac018
4 changed files with 57 additions and 98 deletions

View File

@ -386,10 +386,10 @@ void FurnaceGUI::doAction(int what) {
doSelectAll();
break;
case GUI_ACTION_PAT_CUT:
doCopy(true);
doCopy(true,true,selStart,selEnd);
break;
case GUI_ACTION_PAT_COPY:
doCopy(false);
doCopy(false,true,selStart,selEnd);
break;
case GUI_ACTION_PAT_PASTE:
doPaste();

View File

@ -358,66 +358,75 @@ void FurnaceGUI::doTranspose(int amount, OperationMask& mask) {
makeUndo(GUI_UNDO_PATTERN_DELETE);
}
void FurnaceGUI::doCopy(bool cut) {
finishSelection();
if (cut) {
curNibble=false;
prepareUndo(GUI_UNDO_PATTERN_CUT);
String FurnaceGUI::doCopy(bool cut, bool writeClipboard, const SelectionPoint& sStart, const SelectionPoint& sEnd) {
if (writeClipboard) {
finishSelection();
if (cut) {
curNibble=false;
prepareUndo(GUI_UNDO_PATTERN_CUT);
}
}
clipboard=fmt::sprintf("org.tildearrow.furnace - Pattern Data (%d)\n%d",DIV_ENGINE_VERSION,selStart.xFine);
String clipb=fmt::sprintf("org.tildearrow.furnace - Pattern Data (%d)\n%d",DIV_ENGINE_VERSION,sStart.xFine);
for (int j=selStart.y; j<=selEnd.y; j++) {
int iCoarse=selStart.xCoarse;
int iFine=selStart.xFine;
for (int j=sStart.y; j<=sEnd.y; j++) {
int iCoarse=sStart.xCoarse;
int iFine=sStart.xFine;
if (iFine>3 && !(iFine&1)) {
iFine--;
}
clipboard+='\n';
for (; iCoarse<=selEnd.xCoarse; iCoarse++) {
clipb+='\n';
for (; iCoarse<=sEnd.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 (; iFine<3+e->curPat[iCoarse].effectCols*2 && (iCoarse<sEnd.xCoarse || iFine<=sEnd.xFine); iFine++) {
if (iFine==0) {
clipboard+=noteNameNormal(pat->data[j][0],pat->data[j][1]);
clipb+=noteNameNormal(pat->data[j][0],pat->data[j][1]);
if (cut) {
pat->data[j][0]=0;
pat->data[j][1]=0;
}
} else {
if (pat->data[j][iFine+1]==-1) {
clipboard+="..";
clipb+="..";
} else {
clipboard+=fmt::sprintf("%.2X",pat->data[j][iFine+1]);
clipb+=fmt::sprintf("%.2X",pat->data[j][iFine+1]);
}
if (cut) {
pat->data[j][iFine+1]=-1;
}
}
}
clipboard+='|';
clipb+='|';
iFine=0;
}
}
SDL_SetClipboardText(clipboard.c_str());
if (cut) {
makeUndo(GUI_UNDO_PATTERN_CUT);
if (writeClipboard) {
SDL_SetClipboardText(clipb.c_str());
if (cut) {
makeUndo(GUI_UNDO_PATTERN_CUT);
}
clipboard=clipb;
}
return clipb;
}
void FurnaceGUI::doPaste(PasteMode mode, int arg) {
finishSelection();
prepareUndo(GUI_UNDO_PATTERN_PASTE);
char* clipText=SDL_GetClipboardText();
if (clipText!=NULL) {
if (clipText[0]) {
clipboard=clipText;
void FurnaceGUI::doPaste(PasteMode mode, int arg, bool readClipboard, String clipb) {
if (readClipboard) {
finishSelection();
prepareUndo(GUI_UNDO_PATTERN_PASTE);
char* clipText=SDL_GetClipboardText();
if (clipText!=NULL) {
if (clipText[0]) {
clipboard=clipText;
}
SDL_free(clipText);
}
SDL_free(clipText);
clipb=clipboard;
}
std::vector<String> data;
String tempS;
for (char i: clipboard) {
for (char i: clipb) {
if (i=='\r') continue;
if (i=='\n') {
data.push_back(tempS);
@ -562,15 +571,18 @@ void FurnaceGUI::doPaste(PasteMode mode, int arg) {
i=1;
}
}
if (settings.cursorPastePos) {
cursor.y=j;
if (cursor.y>=e->curSubSong->patLen) cursor.y=e->curSubSong->patLen-1;
selStart=cursor;
selEnd=cursor;
updateScroll(cursor.y);
}
makeUndo(GUI_UNDO_PATTERN_PASTE);
if (readClipboard) {
if (settings.cursorPastePos) {
cursor.y=j;
if (cursor.y>=e->curSubSong->patLen) cursor.y=e->curSubSong->patLen-1;
selStart=cursor;
selEnd=cursor;
updateScroll(cursor.y);
}
makeUndo(GUI_UNDO_PATTERN_PASTE);
}
}
void FurnaceGUI::doChangeIns(int ins) {
@ -926,72 +938,19 @@ void FurnaceGUI::doExpand(int multiplier) {
}
void FurnaceGUI::doDrag() {
DivPattern* patBuffer=NULL;
int len=dragEnd.xCoarse-dragStart.xCoarse+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++;
}
}
String c=doCopy(true,false,dragStart,dragEnd);
// 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++;
}
}
cursor=selStart;
doPaste(GUI_PASTE_MODE_NORMAL,0,false,c);
delete[] patBuffer;
makeUndo(GUI_UNDO_PATTERN_DRAG);
}

View File

@ -2303,8 +2303,8 @@ void FurnaceGUI::editOptions(bool topMenu) {
char id[4096];
editOptsVisible=true;
if (ImGui::MenuItem("cut",BIND_FOR(GUI_ACTION_PAT_CUT))) doCopy(true);
if (ImGui::MenuItem("copy",BIND_FOR(GUI_ACTION_PAT_COPY))) doCopy(false);
if (ImGui::MenuItem("cut",BIND_FOR(GUI_ACTION_PAT_CUT))) doCopy(true,true,selStart,selEnd);
if (ImGui::MenuItem("copy",BIND_FOR(GUI_ACTION_PAT_COPY))) doCopy(false,true,selStart,selEnd);
if (ImGui::MenuItem("paste",BIND_FOR(GUI_ACTION_PAT_PASTE))) doPaste();
if (ImGui::BeginMenu("paste special...")) {
if (ImGui::MenuItem("paste mix",BIND_FOR(GUI_ACTION_PAT_PASTE_MIX))) doPaste(GUI_PASTE_MODE_MIX_FG);

View File

@ -1889,8 +1889,8 @@ class FurnaceGUI {
void doPullDelete();
void doInsert();
void doTranspose(int amount, OperationMask& mask);
void doCopy(bool cut);
void doPaste(PasteMode mode=GUI_PASTE_MODE_NORMAL, int arg=0);
String doCopy(bool cut, bool writeClipboard, const SelectionPoint& sStart, const SelectionPoint& sEnd);
void doPaste(PasteMode mode=GUI_PASTE_MODE_NORMAL, int arg=0, bool readClipboard=true, String clipb="");
void doChangeIns(int ins);
void doInterpolate();
void doFade(int p0, int p1, bool mode);