diff --git a/src/gui/dataList.cpp b/src/gui/dataList.cpp index 168a87ca8..b973c434f 100644 --- a/src/gui/dataList.cpp +++ b/src/gui/dataList.cpp @@ -30,7 +30,36 @@ const char* sampleNote[12]={ "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; -void FurnaceGUI::insListItem(int i) { +#define DRAG_SOURCE(_d,_a) \ + if (ImGui::BeginDragDropSource()) { \ + dirToMove=_d; \ + assetToMove=_a; \ + ImGui::SetDragDropPayload("FUR_DIR",NULL,0,ImGuiCond_Once); \ + ImGui::Button(ICON_FA_ARROWS "##AssetDrag"); \ + ImGui::EndDragDropSource(); \ + } + +#define DRAG_TARGET(_d,_a,_type) \ + if (ImGui::BeginDragDropTarget()) { \ + const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_DIR"); \ + if (dragItem!=NULL) { \ + if (dragItem->IsDataType("FUR_DIR")) { \ + if (dirToMove!=_d || assetToMove!=_a) { \ + logV("%d/%d -> %d/%d",dirToMove,assetToMove,_d,_a); \ + e->lockEngine([&]() { \ + int val=e->song.insDir[dirToMove].entries[assetToMove]; \ + e->song.insDir[dirToMove].entries.erase(e->song.insDir[dirToMove].entries.begin()+assetToMove); \ + e->song.insDir[_d].entries.insert(e->song.insDir[_d].entries.begin()+_a,val); \ + }); \ + } \ + dirToMove=-1; \ + assetToMove=-1; \ + } \ + } \ + ImGui::EndDragDropTarget(); \ + } + +void FurnaceGUI::insListItem(int i, int dir, int asset) { ImGui::PushID(i); String name=ICON_FA_CIRCLE_O; const char* insType="Bug!"; @@ -270,24 +299,8 @@ void FurnaceGUI::insListItem(int i) { } if (i>=0) { if (insListDir) { - if (ImGui::BeginDragDropSource()) { - chanToMove=i; - ImGui::SetDragDropPayload("FUR_DIR",NULL,0,ImGuiCond_Once); - //ImGui::Button(ICON_FA_ARROWS "##ChanDrag"); - ImGui::EndDragDropSource(); - } - if (ImGui::BeginDragDropTarget()) { - const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_DIR"); - if (dragItem!=NULL) { - if (dragItem->IsDataType("FUR_DIR")) { - if (chanToMove!=i && chanToMove>=0) { - } - logV("TO %d",i); - chanToMove=-1; - } - } - ImGui::EndDragDropTarget(); - } + DRAG_SOURCE(dir,asset); + DRAG_TARGET(dir,asset,e->song.insDir); } if (ImGui::BeginPopupContextItem("InsRightMenu")) { @@ -562,14 +575,20 @@ void FurnaceGUI::drawInsList(bool asChild) { if (insListDir) { ImGui::TableNextRow(); ImGui::TableNextColumn(); - insListItem(-1); + insListItem(-1,-1,-1); + int dirIndex=0; for (DivAssetDir& i: e->song.insDir) { if (ImGui::TreeNode(i.name.empty()?"":i.name.c_str())) { + int assetIndex=0; for (int j: i.entries) { - insListItem(j); + insListItem(j,dirIndex,assetIndex); + assetIndex++; } ImGui::TreePop(); } + DRAG_SOURCE(dirIndex,-1); + DRAG_TARGET(dirIndex,-1,e->song.insDir); + dirIndex++; } } else { int curRow=0; @@ -580,7 +599,7 @@ void FurnaceGUI::drawInsList(bool asChild) { } else if (curRow==0) { ImGui::TableNextColumn(); } - insListItem(i); + insListItem(i,-1,-1); if (settings.horizontalDataView) { if (++curRow>=availableRows) curRow=0; } diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index e6a244139..7520162f7 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -561,17 +561,17 @@ void FurnaceGUI::doAction(int what) { doFlip(); break; case GUI_ACTION_PAT_COLLAPSE_ROWS: - doCollapse(2,selStart,selEnd); + doCollapse(collapseAmount,selStart,selEnd); break; case GUI_ACTION_PAT_EXPAND_ROWS: - doExpand(2,selStart,selEnd); + doExpand(collapseAmount,selStart,selEnd); break; case GUI_ACTION_PAT_COLLAPSE_PAT: { SelectionPoint selEndPat; selEndPat.xCoarse=e->getTotalChannelCount()-1; selEndPat.xFine=2+e->curPat[selEndPat.xCoarse].effectCols*2; selEndPat.y=e->curSubSong->patLen-1; - doCollapse(2,SelectionPoint(0,0,0),selEndPat); + doCollapse(collapseAmount,SelectionPoint(0,0,0),selEndPat); break; } case GUI_ACTION_PAT_EXPAND_PAT: { @@ -579,14 +579,14 @@ void FurnaceGUI::doAction(int what) { selEndPat.xCoarse=e->getTotalChannelCount()-1; selEndPat.xFine=2+e->curPat[selEndPat.xCoarse].effectCols*2; selEndPat.y=e->curSubSong->patLen-1; - doExpand(2,SelectionPoint(0,0,0),selEndPat); + doExpand(collapseAmount,SelectionPoint(0,0,0),selEndPat); break; } case GUI_ACTION_PAT_COLLAPSE_SONG: - doCollapseSong(2); + doCollapseSong(collapseAmount); break; case GUI_ACTION_PAT_EXPAND_SONG: - doExpandSong(2); + doExpandSong(collapseAmount); break; case GUI_ACTION_PAT_LATCH: // TODO break; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 3e0399fcc..7b0a26e67 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2852,8 +2852,14 @@ void FurnaceGUI::editOptions(bool topMenu) { ImGui::Separator(); if (ImGui::MenuItem("flip selection",BIND_FOR(GUI_ACTION_PAT_FLIP_SELECTION))) doFlip(); - if (ImGui::MenuItem("collapse",BIND_FOR(GUI_ACTION_PAT_COLLAPSE_ROWS))) doCollapse(2,selStart,selEnd); - if (ImGui::MenuItem("expand",BIND_FOR(GUI_ACTION_PAT_EXPAND_ROWS))) doExpand(2,selStart,selEnd); + + ImGui::SetNextItemWidth(120.0f*dpiScale); + if (ImGui::InputInt("collapse/expand amount##CollapseAmount",&collapseAmount,1,1)) { + if (collapseAmount<2) collapseAmount=2; + if (collapseAmount>256) collapseAmount=256; + } + if (ImGui::MenuItem("collapse",BIND_FOR(GUI_ACTION_PAT_COLLAPSE_ROWS))) doCollapse(collapseAmount,selStart,selEnd); + if (ImGui::MenuItem("expand",BIND_FOR(GUI_ACTION_PAT_EXPAND_ROWS))) doExpand(collapseAmount,selStart,selEnd); if (topMenu) { ImGui::Separator(); @@ -6720,11 +6726,14 @@ FurnaceGUI::FurnaceGUI(): sysToMove(-1), sysToDelete(-1), opToMove(-1), + assetToMove(-1), + dirToMove(-1), transposeAmount(0), randomizeMin(0), randomizeMax(255), fadeMin(0), fadeMax(255), + collapseAmount(2), scaleMax(100.0f), fadeMode(false), randomMode(false), diff --git a/src/gui/gui.h b/src/gui/gui.h index d4462413c..7efc8c927 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1792,6 +1792,7 @@ class FurnaceGUI { std::map images; int chanToMove, sysToMove, sysToDelete, opToMove; + int assetToMove, dirToMove; ImVec2 patWindowPos, patWindowSize; @@ -1800,7 +1801,7 @@ class FurnaceGUI { ImVec2 noteCellSize, insCellSize, volCellSize, effectCellSize, effectValCellSize; SelectionPoint sel1, sel2; int dummyRows, demandX; - int transposeAmount, randomizeMin, randomizeMax, fadeMin, fadeMax; + int transposeAmount, randomizeMin, randomizeMax, fadeMin, fadeMax, collapseAmount; float scaleMax; bool fadeMode, randomMode, haveHitBounds, pendingStepUpdate; @@ -2000,9 +2001,9 @@ class FurnaceGUI { void actualWaveList(); void actualSampleList(); - void insListItem(int index); - void waveListItem(int index); - void sampleListItem(int index); + void insListItem(int index, int dir, int asset); + void waveListItem(int index, int dir, int asset); + void sampleListItem(int index, int dir, int asset); void toggleMobileUI(bool enable, bool force=false);