GUI: deduplicate a lot of code

This commit is contained in:
tildearrow 2022-04-12 02:39:03 -05:00
parent ffef40c098
commit 5a5f800297

View file

@ -42,7 +42,7 @@ void FurnaceGUI::drawSampleEdit() {
if (ImGui::Begin("Sample Editor",&sampleEditOpen,settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking)) {
if (curSample<0 || curSample>=(int)e->song.sample.size()) {
ImGui::Text("no sample selected");
} else if (!settings.sampleLayout) {
} else {
DivSample* sample=e->song.sample[curSample];
String sampleType="Invalid";
if (sample->depth<17) {
@ -50,6 +50,7 @@ void FurnaceGUI::drawSampleEdit() {
sampleType=sampleDepths[sample->depth];
}
}
if (!settings.sampleLayout) {
ImGui::Text("Name");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
@ -555,313 +556,7 @@ void FurnaceGUI::drawSampleEdit() {
updateSampleTex=true;
}
}
ImGui::Separator();
ImVec2 avail=ImGui::GetContentRegionAvail();
if(ImGui::GetContentRegionAvail().y > (ImGui::GetContentRegionAvail().x / 2.0f)) {
avail=ImVec2(ImGui::GetContentRegionAvail().x,ImGui::GetContentRegionAvail().x / 2.0f);
}
avail.y-=ImGui::GetFontSize()+ImGui::GetStyle().ItemSpacing.y+ImGui::GetStyle().ScrollbarSize;
if (avail.y < 1.0){ //Prevents crash
avail.y = 1.0;
}
int availX=avail.x;
int availY=avail.y;
if (sampleZoomAuto) {
samplePos=0;
if (sample->samples<1 || avail.x<=0) {
sampleZoom=1.0;
} else {
sampleZoom=(double)sample->samples/avail.x;
}
if (sampleZoom!=prevSampleZoom) {
prevSampleZoom=sampleZoom;
updateSampleTex=true;
}
}
if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y) {
if (sampleTex!=NULL) {
SDL_DestroyTexture(sampleTex);
sampleTex=NULL;
}
if (avail.x>=1 && avail.y>=1) {
logD("recreating sample texture.");
sampleTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,avail.x,avail.y);
sampleTexW=avail.x;
sampleTexH=avail.y;
if (sampleTex==NULL) {
logE("error while creating sample texture! %s",SDL_GetError());
} else {
updateSampleTex=true;
}
}
}
if (sampleTex!=NULL) {
if (updateSampleTex) {
unsigned int* data=NULL;
int pitch=0;
logD("updating sample texture.");
if (SDL_LockTexture(sampleTex,NULL,(void**)&data,&pitch)!=0) {
logE("error while locking sample texture! %s",SDL_GetError());
} else {
ImU32 bgColor=ImGui::GetColorU32(ImGuiCol_FrameBg);
ImU32 bgColorLoop=ImAlphaBlendColors(bgColor,ImGui::GetColorU32(ImGuiCol_FrameBgHovered,0.5));
ImU32 lineColor=ImGui::GetColorU32(ImGuiCol_PlotLines);
ImU32 centerLineColor=ImAlphaBlendColors(bgColor,ImGui::GetColorU32(ImGuiCol_PlotLines,0.25));
for (int i=0; i<availY; i++) {
for (int j=0; j<availX; j++) {
if (sample->loopStart>=0 && sample->loopStart<(int)sample->samples && ((j+samplePos)*sampleZoom)>sample->loopStart) {
data[i*availX+j]=bgColorLoop;
} else {
data[i*availX+j]=bgColor;
}
}
}
if (availY>0) {
for (int i=availX*(availY>>1); i<availX*(1+(availY>>1)); i++) {
data[i]=centerLineColor;
}
}
unsigned int xCoarse=samplePos;
unsigned int xFine=0;
unsigned int xAdvanceCoarse=sampleZoom;
unsigned int xAdvanceFine=fmod(sampleZoom,1.0)*16777216;
for (unsigned int i=0; i<(unsigned int)availX; i++) {
if (xCoarse>=sample->samples) break;
int y1, y2;
int totalAdvance=0;
if (sample->depth==8) {
y1=((unsigned char)sample->data8[xCoarse]^0x80)*availY/256;
} else {
y1=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536;
}
xFine+=xAdvanceFine;
if (xFine>=16777216) {
xFine-=16777216;
totalAdvance++;
}
totalAdvance+=xAdvanceCoarse;
if (xCoarse>=sample->samples) break;
do {
if (sample->depth==8) {
y2=((unsigned char)sample->data8[xCoarse]^0x80)*availY/256;
} else {
y2=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536;
}
if (y1>y2) {
y2^=y1;
y1^=y2;
y2^=y1;
}
if (y1<0) y1=0;
if (y1>=availY) y1=availY-1;
if (y2<0) y2=0;
if (y2>=availY) y2=availY-1;
for (int j=y1; j<=y2; j++) {
data[i+availX*(availY-j-1)]=lineColor;
}
if (totalAdvance>0) xCoarse++;
} while ((totalAdvance--)>0);
}
SDL_UnlockTexture(sampleTex);
}
updateSampleTex=false;
}
ImGui::ImageButton(sampleTex,avail,ImVec2(0,0),ImVec2(1,1),0);
ImVec2 rectMin=ImGui::GetItemRectMin();
ImVec2 rectMax=ImGui::GetItemRectMax();
ImVec2 rectSize=ImGui::GetItemRectSize();
if (ImGui::IsItemClicked()) {
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
sampleDragActive=false;
sampleSelStart=0;
sampleSelEnd=sample->samples;
} else {
if (sample->samples>0 && (sample->depth==16 || sample->depth==8)) {
sampleDragStart=rectMin;
sampleDragAreaSize=rectSize;
sampleDrag16=(sample->depth==16);
sampleDragTarget=(sample->depth==16)?((void*)sample->data16):((void*)sample->data8);
sampleDragLen=sample->samples;
sampleDragActive=true;
sampleSelStart=-1;
sampleSelEnd=-1;
if (sampleDragMode) sample->prepareUndo(true);
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
}
}
}
if (!sampleDragMode && ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
ImGui::OpenPopup("SRightClick");
}
if (ImGui::BeginPopup("SRightClick",ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize)) {
if (ImGui::MenuItem("cut",BIND_FOR(GUI_ACTION_SAMPLE_CUT))) {
doAction(GUI_ACTION_SAMPLE_CUT);
}
if (ImGui::MenuItem("copy",BIND_FOR(GUI_ACTION_SAMPLE_COPY))) {
doAction(GUI_ACTION_SAMPLE_COPY);
}
if (ImGui::MenuItem("paste",BIND_FOR(GUI_ACTION_SAMPLE_PASTE))) {
doAction(GUI_ACTION_SAMPLE_PASTE);
}
if (ImGui::MenuItem("paste (replace)",BIND_FOR(GUI_ACTION_SAMPLE_PASTE_REPLACE))) {
doAction(GUI_ACTION_SAMPLE_PASTE_REPLACE);
}
if (ImGui::MenuItem("paste (mix)",BIND_FOR(GUI_ACTION_SAMPLE_PASTE_MIX))) {
doAction(GUI_ACTION_SAMPLE_PASTE_MIX);
}
if (ImGui::MenuItem("select all",BIND_FOR(GUI_ACTION_SAMPLE_SELECT_ALL))) {
doAction(GUI_ACTION_SAMPLE_SELECT_ALL);
}
ImGui::EndPopup();
}
String statusBar=sampleDragMode?"Draw":"Select";
bool drawSelection=false;
if (!sampleDragMode) {
if (sampleSelStart>=0 && sampleSelEnd>=0) {
int start=sampleSelStart;
int end=sampleSelEnd;
if (start>end) {
start^=end;
end^=start;
start^=end;
}
statusBar+=fmt::sprintf(" (%d-%d)",start,end);
drawSelection=true;
}
}
if (ImGui::IsItemHovered()) {
int posX=-1;
int posY=0;
ImVec2 pos=ImGui::GetMousePos();
pos.x-=rectMin.x;
pos.y-=rectMin.y;
if (sampleZoom>0) {
posX=samplePos+pos.x*sampleZoom;
if (posX>(int)sample->samples) posX=-1;
}
posY=(0.5-pos.y/rectSize.y)*((sample->depth==8)?255:32767);
if (posX>=0) {
statusBar+=fmt::sprintf(" | (%d, %d)",posX,posY);
}
}
if (drawSelection) {
int start=sampleSelStart;
int end=sampleSelEnd;
if (start>end) {
start^=end;
end^=start;
start^=end;
}
ImDrawList* dl=ImGui::GetWindowDrawList();
ImVec2 p1=rectMin;
p1.x+=(start-samplePos)/sampleZoom;
ImVec2 p2=ImVec2(rectMin.x+(end-samplePos)/sampleZoom,rectMax.y);
ImVec4 boundColor=uiColors[GUI_COLOR_ACCENT_PRIMARY];
ImVec4 selColor=uiColors[GUI_COLOR_ACCENT_SECONDARY];
boundColor.w*=0.5;
selColor.w*=0.25;
if (p1.x<rectMin.x) p1.x=rectMin.x;
if (p1.x>rectMax.x) p1.x=rectMax.x;
if (p2.x<rectMin.x) p2.x=rectMin.x;
if (p2.x>rectMax.x) p2.x=rectMax.x;
dl->AddRectFilled(p1,p2,ImGui::GetColorU32(selColor));
dl->AddLine(ImVec2(p1.x,p1.y),ImVec2(p1.x,p2.y),ImGui::GetColorU32(boundColor));
if (start!=end) {
dl->AddLine(ImVec2(p2.x,p1.y),ImVec2(p2.x,p2.y),ImGui::GetColorU32(boundColor));
}
}
ImS64 scrollV=samplePos;
ImS64 availV=round(rectSize.x*sampleZoom);
ImS64 contentsV=MAX(sample->samples,MAX(availV,1));
if (ImGui::ScrollbarEx(ImRect(ImVec2(rectMin.x,rectMax.y),ImVec2(rectMax.x,rectMax.y+ImGui::GetStyle().ScrollbarSize)),ImGui::GetID("sampleScroll"),ImGuiAxis_X,&scrollV,availV,contentsV,0)) {
if (!sampleZoomAuto && samplePos!=scrollV) {
samplePos=scrollV;
updateSampleTex=true;
}
}
if (sample->depth!=8 && sample->depth!=16) {
statusBar="Non-8/16-bit samples cannot be edited without prior conversion.";
}
ImGui::EndDisabled();
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+ImGui::GetStyle().ScrollbarSize);
ImGui::Text("%s",statusBar.c_str());
}
/*
bool considerations=false;
ImGui::Text("notes:");
if (sample->loopStart>=0) {
considerations=true;
ImGui::Text("- sample won't loop on Neo Geo ADPCM-A and X1-010");
if (sample->loopStart&1) {
ImGui::Text("- sample loop start will be aligned to the nearest even sample on Amiga");
}
if (sample->loopStart>0) {
ImGui::Text("- sample loop start will be ignored on Neo Geo ADPCM-B");
}
}
if (sample->samples&1) {
considerations=true;
ImGui::Text("- sample length will be aligned to the nearest even sample on Amiga");
}
if (sample->samples&511) {
considerations=true;
ImGui::Text("- sample length will be aligned and padded to 512 sample units on Neo Geo ADPCM.");
}
if (sample->samples&4095) {
considerations=true;
ImGui::Text("- sample length will be aligned and padded to 4096 sample units on X1-010.");
}
if (sample->samples>65535) {
considerations=true;
ImGui::Text("- maximum sample length on Sega PCM and QSound is 65536 samples");
}
if (sample->samples>131071) {
considerations=true;
ImGui::Text("- maximum sample length on X1-010 is 131072 samples");
}
if (sample->samples>2097151) {
considerations=true;
ImGui::Text("- maximum sample length on Neo Geo ADPCM is 2097152 samples");
}
if (!considerations) {
ImGui::Text("- none");
}*/
}
else {
DivSample* sample=e->song.sample[curSample];
String sampleType="Invalid";
if (sample->depth<17) {
if (sampleDepths[sample->depth]!=NULL) {
sampleType=sampleDepths[sample->depth];
}
}
ImGui::Text("Name");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
@ -1371,21 +1066,22 @@ void FurnaceGUI::drawSampleEdit() {
updateSampleTex=true;
}
}
}
ImGui::Separator();
ImVec2 avail=ImGui::GetContentRegionAvail(); // graph size determined here
if (ImGui::GetContentRegionAvail().y > (ImGui::GetContentRegionAvail().x / 2.0f)) {
avail=ImVec2(ImGui::GetContentRegionAvail().x,ImGui::GetContentRegionAvail().x / 2.0f);
if (ImGui::GetContentRegionAvail().y>(ImGui::GetContentRegionAvail().x*0.5f)) {
avail=ImVec2(ImGui::GetContentRegionAvail().x,ImGui::GetContentRegionAvail().x*0.5f);
}
avail.y-=ImGui::GetFontSize()+ImGui::GetStyle().ItemSpacing.y+ImGui::GetStyle().ScrollbarSize;
if (avail.y < 1.0){ //Prevents crash
avail.y = 1.0;
if (avail.y<1.0) { // Prevents crash
avail.y=1.0;
}
int availX=avail.x;
int availY=avail.y;
if (sampleZoomAuto) {
samplePos=0;
if (sample->samples<1 || avail.x<=0) {