From 3f8430b0d6f0ad5f97f8b38294d7837bfa8ef9d7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 30 Jun 2023 23:37:22 -0500 Subject: [PATCH] add ability to duplicate sub-songs --- src/engine/engine.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++ src/engine/engine.h | 3 +++ src/gui/subSongs.cpp | 24 ++++++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 5afc54078..1aa8188e0 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1678,6 +1678,51 @@ int DivEngine::addSubSong() { return song.subsong.size()-1; } +int DivEngine::duplicateSubSong(int index) { + if (song.subsong.size()>=127) return -1; + BUSY_BEGIN; + saveLock.lock(); + DivSubSong* theCopy=new DivSubSong; + DivSubSong* theOrig=song.subsong[index]; + + theCopy->name=theOrig->name; + theCopy->notes=theOrig->notes; + theCopy->hilightA=theOrig->hilightA; + theCopy->hilightB=theOrig->hilightB; + theCopy->timeBase=theOrig->timeBase; + theCopy->arpLen=theOrig->arpLen; + theCopy->speeds=theOrig->speeds; + theCopy->virtualTempoN=theOrig->virtualTempoN; + theCopy->virtualTempoD=theOrig->virtualTempoD; + theCopy->hz=theOrig->hz; + theCopy->patLen=theOrig->patLen; + theCopy->ordersLen=theOrig->ordersLen; + theCopy->orders=theOrig->orders; + + memcpy(theCopy->chanShow,theOrig->chanShow,DIV_MAX_CHANS*sizeof(bool)); + memcpy(theCopy->chanCollapse,theOrig->chanCollapse,DIV_MAX_CHANS); + + for (int i=0; ichanName[i]=theOrig->chanName[i]; + theCopy->chanShortName[i]=theOrig->chanShortName[i]; + + theCopy->pat[i].effectCols=theOrig->pat[i].effectCols; + + for (int j=0; jpat[i].data[j]==NULL) continue; + DivPattern* origPat=theOrig->pat[i].getPattern(j,false); + DivPattern* copyPat=theCopy->pat[i].getPattern(j,true); + origPat->copyOn(copyPat); + } + } + + song.subsong.push_back(theCopy); + + saveLock.unlock(); + BUSY_END; + return song.subsong.size()-1; +} + bool DivEngine::removeSubSong(int index) { if (song.subsong.size()<=1) return false; stop(); diff --git a/src/engine/engine.h b/src/engine/engine.h index 85e8f6415..21e15b562 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -1052,6 +1052,9 @@ class DivEngine { // add subsong int addSubSong(); + // duplicate subsong + int duplicateSubSong(int index); + // remove subsong bool removeSubSong(int index); diff --git a/src/gui/subSongs.cpp b/src/gui/subSongs.cpp index 86fb2cb3c..5d34c23fd 100644 --- a/src/gui/subSongs.cpp +++ b/src/gui/subSongs.cpp @@ -17,7 +17,7 @@ void FurnaceGUI::drawSubSongs(bool asChild) { bool began=asChild?ImGui::BeginChild("Subsongs"):ImGui::Begin("Subsongs",&subSongsOpen,globalWinFlags); if (began) { char id[1024]; - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*2.0f-ImGui::GetStyle().ItemSpacing.x); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing()*3.0f-ImGui::GetStyle().ItemSpacing.x*2.0f); if (e->curSubSong->name.empty()) { snprintf(id,1023,"%d. ",(int)e->getCurrentSubSong()+1); } else { @@ -92,6 +92,28 @@ void FurnaceGUI::drawSubSongs(bool asChild) { ImGui::SetTooltip("Add"); } ImGui::SameLine(); + if (ImGui::Button(ICON_FA_FILES_O "##SubSongDuplicate")) { + if (!e->duplicateSubSong(e->getCurrentSubSong())) { + showError("too many subsongs!"); + } else { + e->changeSongP(e->song.subsong.size()-1); + updateScroll(0); + oldOrder=0; + oldOrder1=0; + oldRow=0; + cursor.xCoarse=0; + cursor.xFine=0; + cursor.y=0; + selStart=cursor; + selEnd=cursor; + curOrder=0; + MARK_MODIFIED; + } + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Duplicate"); + } + ImGui::SameLine(); pushDestColor(); if (ImGui::Button(ICON_FA_MINUS "##SubSongDel")) { if (e->song.subsong.size()<=1) {