Merge branch 'master' of https://github.com/tildearrow/furnace into scc
This commit is contained in:
commit
2c6267bd6b
47 changed files with 3473 additions and 205 deletions
106
src/gui/fileDialog.cpp
Normal file
106
src/gui/fileDialog.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include "fileDialog.h"
|
||||
#include "ImGuiFileDialog.h"
|
||||
#include "../ta-log.h"
|
||||
|
||||
#include "../../extern/pfd-fixed/portable-file-dialogs.h"
|
||||
|
||||
bool FurnaceGUIFileDialog::openLoad(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale) {
|
||||
if (opened) return false;
|
||||
saving=false;
|
||||
curPath=path;
|
||||
if (sysDialog) {
|
||||
dialogO=new pfd::open_file(header,path,filter);
|
||||
} else {
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::openSave(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale) {
|
||||
if (opened) return false;
|
||||
saving=true;
|
||||
curPath=path;
|
||||
if (sysDialog) {
|
||||
dialogS=new pfd::save_file(header,path,filter);
|
||||
} else {
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
}
|
||||
opened=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::accepted() {
|
||||
if (sysDialog) {
|
||||
return (fileName!="");
|
||||
} else {
|
||||
return ImGuiFileDialog::Instance()->IsOk();
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUIFileDialog::close() {
|
||||
if (sysDialog) {
|
||||
if (saving) {
|
||||
if (dialogS!=NULL) {
|
||||
delete dialogS;
|
||||
dialogS=NULL;
|
||||
}
|
||||
} else {
|
||||
if (dialogO!=NULL) {
|
||||
delete dialogO;
|
||||
dialogO=NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
opened=false;
|
||||
}
|
||||
|
||||
bool FurnaceGUIFileDialog::render(const ImVec2& min, const ImVec2& max) {
|
||||
if (sysDialog) {
|
||||
if (saving) {
|
||||
if (dialogS!=NULL) {
|
||||
if (dialogS->ready(1)) {
|
||||
fileName=dialogS->result();
|
||||
logD("returning %s\n",fileName.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dialogO!=NULL) {
|
||||
if (dialogO->ready(1)) {
|
||||
if (dialogO->result().empty()) {
|
||||
fileName="";
|
||||
logD("returning nothing\n");
|
||||
} else {
|
||||
fileName=dialogO->result()[0];
|
||||
logD("returning %s\n",fileName.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return ImGuiFileDialog::Instance()->Display("FileDialog",ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove,min,max);
|
||||
}
|
||||
}
|
||||
|
||||
String FurnaceGUIFileDialog::getPath() {
|
||||
if (sysDialog) {
|
||||
return curPath;
|
||||
} else {
|
||||
return ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
}
|
||||
}
|
||||
|
||||
String FurnaceGUIFileDialog::getFileName() {
|
||||
if (sysDialog) {
|
||||
return fileName;
|
||||
} else {
|
||||
return ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
}
|
||||
}
|
||||
32
src/gui/fileDialog.h
Normal file
32
src/gui/fileDialog.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include "../ta-utils.h"
|
||||
#include "imgui.h"
|
||||
#include <vector>
|
||||
|
||||
namespace pfd {
|
||||
class open_file;
|
||||
class save_file;
|
||||
}
|
||||
|
||||
class FurnaceGUIFileDialog {
|
||||
bool sysDialog;
|
||||
bool opened;
|
||||
bool saving;
|
||||
String curPath;
|
||||
String fileName;
|
||||
pfd::open_file* dialogO;
|
||||
pfd::save_file* dialogS;
|
||||
public:
|
||||
bool openLoad(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale);
|
||||
bool openSave(String header, std::vector<String> filter, const char* noSysFilter, String path, double dpiScale);
|
||||
bool accepted();
|
||||
void close();
|
||||
bool render(const ImVec2& min, const ImVec2& max);
|
||||
String getPath();
|
||||
String getFileName();
|
||||
FurnaceGUIFileDialog(bool system):
|
||||
sysDialog(system),
|
||||
opened(false),
|
||||
saving(false),
|
||||
dialogO(NULL),
|
||||
dialogS(NULL) {}
|
||||
};
|
||||
412
src/gui/gui.cpp
412
src/gui/gui.cpp
|
|
@ -32,6 +32,7 @@
|
|||
#include "ImGuiFileDialog.h"
|
||||
#include "IconsFontAwesome4.h"
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
#include "plot_nolerp.h"
|
||||
#include "guiConst.h"
|
||||
#include "intConst.h"
|
||||
#include <stdint.h>
|
||||
|
|
@ -1090,6 +1091,13 @@ void FurnaceGUI::drawInsList() {
|
|||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("InsListScroll",1,ImGuiTableFlags_ScrollY)) {
|
||||
if (settings.unifiedDataView) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(ICON_FA_TASKS " Instruments");
|
||||
ImGui::Indent();
|
||||
}
|
||||
|
||||
for (int i=0; i<(int)e->song.ins.size(); i++) {
|
||||
DivInstrument* ins=e->song.ins[i];
|
||||
String name;
|
||||
|
|
@ -1214,12 +1222,32 @@ void FurnaceGUI::drawInsList() {
|
|||
}
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s",(ins->type>DIV_INS_MAX)?"Unknown":insTypes[ins->type]);
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
insEditOpen=true;
|
||||
nextWindow=GUI_WINDOW_INS_EDIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.unifiedDataView) {
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(ICON_FA_AREA_CHART " Wavetables");
|
||||
ImGui::Indent();
|
||||
actualWaveList();
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(ICON_FA_VOLUME_UP " Samples");
|
||||
ImGui::Indent();
|
||||
actualSampleList();
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
|
@ -1231,6 +1259,47 @@ const char* sampleNote[12]={
|
|||
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
|
||||
};
|
||||
|
||||
|
||||
void FurnaceGUI::actualWaveList() {
|
||||
float wavePreview[256];
|
||||
for (int i=0; i<(int)e->song.wave.size(); i++) {
|
||||
DivWavetable* wave=e->song.wave[i];
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wavePreview[i]=wave->data[i];
|
||||
}
|
||||
if (wave->len>0) wavePreview[wave->len]=wave->data[wave->len-1];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(fmt::sprintf("%d##_WAVE%d\n",i,i).c_str(),curWave==i)) {
|
||||
curWave=i;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
waveEditOpen=true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
PlotNoLerp(fmt::sprintf("##_WAVEP%d",i).c_str(),wavePreview,wave->len+1,0,NULL,0,wave->max);
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::actualSampleList() {
|
||||
for (int i=0; i<(int)e->song.sample.size(); i++) {
|
||||
DivSample* sample=e->song.sample[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(fmt::sprintf("%d: %s##_SAM%d",i,sample->name,i).c_str(),curSample==i)) {
|
||||
curSample=i;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Bank %d: %s",i/12,sampleNote[i%12]);
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
sampleEditOpen=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawSampleList() {
|
||||
if (nextWindow==GUI_WINDOW_SAMPLE_LIST) {
|
||||
sampleListOpen=true;
|
||||
|
|
@ -1272,24 +1341,7 @@ void FurnaceGUI::drawSampleList() {
|
|||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("SampleListScroll",1,ImGuiTableFlags_ScrollY)) {
|
||||
for (int i=0; i<(int)e->song.sample.size(); i++) {
|
||||
DivSample* sample=e->song.sample[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if ((i%12)==0) {
|
||||
if (i>0) ImGui::Unindent();
|
||||
ImGui::Text("Bank %d",i/12);
|
||||
ImGui::Indent();
|
||||
}
|
||||
if (ImGui::Selectable(fmt::sprintf("%s: %s##_SAM%d",sampleNote[i%12],sample->name,i).c_str(),curSample==i)) {
|
||||
curSample=i;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
sampleEditOpen=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
actualSampleList();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
|
@ -2164,6 +2216,10 @@ void FurnaceGUI::drawCompatFlags() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6");
|
||||
}
|
||||
ImGui::Checkbox("Allow instrument change during slides",&e->song.newInsTriggersInPorta);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6");
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_COMPAT_FLAGS;
|
||||
ImGui::End();
|
||||
|
|
@ -3330,6 +3386,31 @@ void FurnaceGUI::doFlip() {
|
|||
finishSelection();
|
||||
prepareUndo(GUI_UNDO_PATTERN_FLIP);
|
||||
|
||||
DivPattern patBuffer;
|
||||
int iCoarse=selStart.xCoarse;
|
||||
int iFine=selStart.xFine;
|
||||
int ord=e->getOrder();
|
||||
for (; iCoarse<=selEnd.xCoarse; iCoarse++) {
|
||||
if (!e->song.chanShow[iCoarse]) continue;
|
||||
DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true);
|
||||
for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarse<selEnd.xCoarse || iFine<=selEnd.xFine); iFine++) {
|
||||
maskOut(iFine);
|
||||
for (int j=selStart.y; j<=selEnd.y; j++) {
|
||||
if (iFine==0) {
|
||||
patBuffer.data[j][0]=pat->data[j][0];
|
||||
}
|
||||
patBuffer.data[j][iFine+1]=pat->data[j][iFine+1];
|
||||
}
|
||||
for (int j=selStart.y; j<=selEnd.y; j++) {
|
||||
if (iFine==0) {
|
||||
pat->data[j][0]=patBuffer.data[selEnd.y-j+selStart.y][0];
|
||||
}
|
||||
pat->data[j][iFine+1]=patBuffer.data[selEnd.y-j+selStart.y][iFine+1];
|
||||
}
|
||||
}
|
||||
iFine=0;
|
||||
}
|
||||
|
||||
makeUndo(GUI_UNDO_PATTERN_FLIP);
|
||||
}
|
||||
|
||||
|
|
@ -3337,13 +3418,99 @@ void FurnaceGUI::doCollapse(int divider) {
|
|||
finishSelection();
|
||||
prepareUndo(GUI_UNDO_PATTERN_COLLAPSE);
|
||||
|
||||
DivPattern patBuffer;
|
||||
int iCoarse=selStart.xCoarse;
|
||||
int iFine=selStart.xFine;
|
||||
int ord=e->getOrder();
|
||||
for (; iCoarse<=selEnd.xCoarse; iCoarse++) {
|
||||
if (!e->song.chanShow[iCoarse]) continue;
|
||||
DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true);
|
||||
for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarse<selEnd.xCoarse || iFine<=selEnd.xFine); iFine++) {
|
||||
maskOut(iFine);
|
||||
for (int j=selStart.y; j<=selEnd.y; j++) {
|
||||
if (iFine==0) {
|
||||
patBuffer.data[j][0]=pat->data[j][0];
|
||||
}
|
||||
patBuffer.data[j][iFine+1]=pat->data[j][iFine+1];
|
||||
}
|
||||
for (int j=0; j<=selEnd.y-selStart.y; j++) {
|
||||
if (j*divider>=selEnd.y-selStart.y) {
|
||||
if (iFine==0) {
|
||||
pat->data[j+selStart.y][0]=0;
|
||||
pat->data[j+selStart.y][1]=0;
|
||||
} else {
|
||||
pat->data[j+selStart.y][iFine+1]=-1;
|
||||
}
|
||||
} else {
|
||||
if (iFine==0) {
|
||||
pat->data[j+selStart.y][0]=patBuffer.data[j*divider+selStart.y][0];
|
||||
}
|
||||
pat->data[j+selStart.y][iFine+1]=patBuffer.data[j*divider+selStart.y][iFine+1];
|
||||
|
||||
if (iFine==0) {
|
||||
for (int k=1; k<divider; k++) {
|
||||
if ((j*divider+k)>=selEnd.y-selStart.y) break;
|
||||
if (!(pat->data[j+selStart.y][0]==0 && pat->data[j+selStart.y][1]==0)) break;
|
||||
pat->data[j+selStart.y][0]=patBuffer.data[j*divider+selStart.y+k][0];
|
||||
pat->data[j+selStart.y][1]=patBuffer.data[j*divider+selStart.y+k][1];
|
||||
}
|
||||
} else {
|
||||
for (int k=1; k<divider; k++) {
|
||||
if ((j*divider+k)>=selEnd.y-selStart.y) break;
|
||||
if (pat->data[j+selStart.y][iFine+1]!=-1) break;
|
||||
pat->data[j+selStart.y][iFine+1]=patBuffer.data[j*divider+selStart.y+k][iFine+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
iFine=0;
|
||||
}
|
||||
|
||||
makeUndo(GUI_UNDO_PATTERN_COLLAPSE);
|
||||
}
|
||||
|
||||
void FurnaceGUI::doExpand(int multiplier) {
|
||||
if (multiplier<1) return;
|
||||
|
||||
finishSelection();
|
||||
prepareUndo(GUI_UNDO_PATTERN_EXPAND);
|
||||
|
||||
DivPattern patBuffer;
|
||||
int iCoarse=selStart.xCoarse;
|
||||
int iFine=selStart.xFine;
|
||||
int ord=e->getOrder();
|
||||
for (; iCoarse<=selEnd.xCoarse; iCoarse++) {
|
||||
if (!e->song.chanShow[iCoarse]) continue;
|
||||
DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true);
|
||||
for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarse<selEnd.xCoarse || iFine<=selEnd.xFine); iFine++) {
|
||||
maskOut(iFine);
|
||||
for (int j=selStart.y; j<=selEnd.y; j++) {
|
||||
if (iFine==0) {
|
||||
patBuffer.data[j][0]=pat->data[j][0];
|
||||
}
|
||||
patBuffer.data[j][iFine+1]=pat->data[j][iFine+1];
|
||||
}
|
||||
for (int j=0; j<=(selEnd.y-selStart.y)*multiplier; j++) {
|
||||
if ((j+selStart.y)>=e->song.patLen) break;
|
||||
if ((j%multiplier)!=0) {
|
||||
if (iFine==0) {
|
||||
pat->data[j+selStart.y][0]=0;
|
||||
pat->data[j+selStart.y][1]=0;
|
||||
} else {
|
||||
pat->data[j+selStart.y][iFine+1]=-1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (iFine==0) {
|
||||
pat->data[j+selStart.y][0]=patBuffer.data[j/multiplier+selStart.y][0];
|
||||
}
|
||||
pat->data[j+selStart.y][iFine+1]=patBuffer.data[j/multiplier+selStart.y][iFine+1];
|
||||
}
|
||||
}
|
||||
iFine=0;
|
||||
}
|
||||
|
||||
makeUndo(GUI_UNDO_PATTERN_EXPAND);
|
||||
}
|
||||
|
||||
|
|
@ -4221,6 +4388,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
int num=12*curOctave+key;
|
||||
|
||||
if (edit) {
|
||||
// TODO: separate when adding MIDI input.
|
||||
DivPattern* pat=e->song.pat[cursor.xCoarse].getPattern(e->song.orders.ord[cursor.xCoarse][e->getOrder()],true);
|
||||
|
||||
prepareUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
|
|
@ -4242,7 +4410,17 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
pat->data[cursor.y][1]--;
|
||||
}
|
||||
pat->data[cursor.y][1]=(unsigned char)pat->data[cursor.y][1];
|
||||
pat->data[cursor.y][2]=curIns;
|
||||
if (latchIns==-2) {
|
||||
pat->data[cursor.y][2]=curIns;
|
||||
} else if (latchIns!=-1 && !e->song.ins.empty()) {
|
||||
pat->data[cursor.y][2]=MIN(((int)e->song.ins.size())-1,latchIns);
|
||||
}
|
||||
if (latchVol!=-1) {
|
||||
int maxVol=e->getMaxVolumeChan(cursor.xCoarse);
|
||||
pat->data[cursor.y][3]=MIN(maxVol,latchVol);
|
||||
}
|
||||
if (latchEffect!=-1) pat->data[cursor.y][4]=latchEffect;
|
||||
if (latchEffectVal!=-1) pat->data[cursor.y][5]=latchEffectVal;
|
||||
previewNote(cursor.xCoarse,num);
|
||||
}
|
||||
makeUndo(GUI_UNDO_PATTERN_EDIT);
|
||||
|
|
@ -4463,73 +4641,168 @@ bool dirExists(String what) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||
ImGuiFileDialog::Instance()->DpiScale=dpiScale;
|
||||
bool hasOpened=false;
|
||||
switch (type) {
|
||||
case GUI_FILE_OPEN:
|
||||
if (!dirExists(workingDirSong)) workingDirSong=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Open File","compatible files{.fur,.dmf},.*",workingDirSong);
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Open File",
|
||||
{"compatible files", "*.fur *.dmf",
|
||||
"all files", ".*"},
|
||||
"compatible files{.fur,.dmf},.*",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_SAVE:
|
||||
if (!dirExists(workingDirSong)) workingDirSong=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save File","Furnace song{.fur},DefleMask 1.1 module{.dmf}",workingDirSong,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Save File",
|
||||
{"Furnace song", "*.fur",
|
||||
"DefleMask 1.1 module", "*.dmf"},
|
||||
"Furnace song{.fur},DefleMask 1.1 module{.dmf}",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_SAVE_DMF_LEGACY:
|
||||
if (!dirExists(workingDirSong)) workingDirSong=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save File","DefleMask 1.0/legacy module{.dmf}",workingDirSong,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Save File",
|
||||
{"DefleMask 1.0/legacy module", "*.dmf"},
|
||||
"DefleMask 1.0/legacy module{.dmf}",
|
||||
workingDirSong,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_INS_OPEN:
|
||||
if (!dirExists(workingDirIns)) workingDirIns=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Load Instrument","compatible files{.fui,.dmp,.tfi,.vgi},.*",workingDirIns);
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Load Instrument",
|
||||
{"compatible files", "*.fui *.dmp *.tfi *.vgi",
|
||||
"all files", ".*"},
|
||||
"compatible files{.fui,.dmp,.tfi,.vgi},.*",
|
||||
workingDirIns,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_INS_SAVE:
|
||||
if (!dirExists(workingDirIns)) workingDirIns=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save Instrument","Furnace instrument{.fui}",workingDirIns,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Save Instrument",
|
||||
{"Furnace instrument", "*.fui"},
|
||||
"Furnace instrument{.fui}",
|
||||
workingDirIns,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_WAVE_OPEN:
|
||||
if (!dirExists(workingDirWave)) workingDirWave=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Load Wavetable","compatible files{.fuw,.dmw},.*",workingDirWave);
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Load Wavetable",
|
||||
{"compatible files", "*.fuw *.dmw",
|
||||
"all files", ".*"},
|
||||
"compatible files{.fuw,.dmw},.*",
|
||||
workingDirWave,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_WAVE_SAVE:
|
||||
if (!dirExists(workingDirWave)) workingDirWave=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save Wavetable","Furnace wavetable{.fuw}",workingDirWave,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Save Wavetable",
|
||||
{"Furnace wavetable", ".fuw"},
|
||||
"Furnace wavetable{.fuw}",
|
||||
workingDirWave,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_OPEN:
|
||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Load Sample","Wave file{.wav},.*",workingDirSample);
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Load Sample",
|
||||
{"Wave file", "*.wav",
|
||||
"all files", ".*"},
|
||||
"Wave file{.wav},.*",
|
||||
workingDirSample,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_SAVE:
|
||||
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Save Sample","Wave file{.wav}",workingDirSample,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Save Sample",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirSample,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_EXPORT_AUDIO_ONE:
|
||||
if (!dirExists(workingDirAudioExport)) workingDirAudioExport=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Export Audio","Wave file{.wav}",workingDirAudioExport,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Export Audio",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirAudioExport,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_EXPORT_AUDIO_PER_SYS:
|
||||
if (!dirExists(workingDirAudioExport)) workingDirAudioExport=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Export Audio","Wave file{.wav}",workingDirAudioExport,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Export Audio",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirAudioExport,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_EXPORT_AUDIO_PER_CHANNEL:
|
||||
if (!dirExists(workingDirAudioExport)) workingDirAudioExport=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Export Audio","Wave file{.wav}",workingDirAudioExport,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Export Audio",
|
||||
{"Wave file", "*.wav"},
|
||||
"Wave file{.wav}",
|
||||
workingDirAudioExport,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_EXPORT_VGM:
|
||||
if (!dirExists(workingDirVGMExport)) workingDirVGMExport=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Export VGM",".vgm",workingDirVGMExport,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);
|
||||
hasOpened=fileDialog->openSave(
|
||||
"Export VGM",
|
||||
{"VGM file", "*.vgm"},
|
||||
"VGM file{.vgm}",
|
||||
workingDirVGMExport,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_EXPORT_ROM:
|
||||
showError("Coming soon!");
|
||||
break;
|
||||
case GUI_FILE_LOAD_MAIN_FONT:
|
||||
if (!dirExists(workingDirFont)) workingDirFont=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Select Font","compatible files{.ttf,.otf,.ttc}",workingDirFont);
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Select Font",
|
||||
{"compatible files", "*.ttf *.otf *.ttc"},
|
||||
"compatible files{.ttf,.otf,.ttc}",
|
||||
workingDirFont,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
case GUI_FILE_LOAD_PAT_FONT:
|
||||
if (!dirExists(workingDirFont)) workingDirFont=getHomeDir();
|
||||
ImGuiFileDialog::Instance()->OpenModal("FileDialog","Select Font","compatible files{.ttf,.otf,.ttc}",workingDirFont);
|
||||
hasOpened=fileDialog->openLoad(
|
||||
"Select Font",
|
||||
{"compatible files", "*.ttf *.otf *.ttc"},
|
||||
"compatible files{.ttf,.otf,.ttc}",
|
||||
workingDirFont,
|
||||
dpiScale
|
||||
);
|
||||
break;
|
||||
}
|
||||
curFileDialog=type;
|
||||
if (hasOpened) curFileDialog=type;
|
||||
//ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_NavEnableKeyboard;
|
||||
}
|
||||
|
||||
|
|
@ -4654,7 +4927,7 @@ int FurnaceGUI::load(String path) {
|
|||
}
|
||||
if (len<1) {
|
||||
if (len==0) {
|
||||
printf("that file is empty!\n");
|
||||
logE("that file is empty!\n");
|
||||
lastError="file is empty";
|
||||
} else {
|
||||
perror("tell error");
|
||||
|
|
@ -4810,6 +5083,15 @@ void FurnaceGUI::processDrags(int dragX, int dragY) {
|
|||
fileName+=x; \
|
||||
}
|
||||
|
||||
#define checkExtensionDual(x,y,fallback) \
|
||||
String lowerCase=fileName; \
|
||||
for (char& i: lowerCase) { \
|
||||
if (i>='A' && i<='Z') i+='a'-'A'; \
|
||||
} \
|
||||
if (lowerCase.size()<4 || (lowerCase.rfind(x)!=lowerCase.size()-4 && lowerCase.rfind(y)!=lowerCase.size()-4)) { \
|
||||
fileName+=fallback; \
|
||||
}
|
||||
|
||||
#define BIND_FOR(x) getKeyName(actionKeys[x],true).c_str()
|
||||
|
||||
void FurnaceGUI::editOptions(bool topMenu) {
|
||||
|
|
@ -5475,6 +5757,10 @@ bool FurnaceGUI::loop() {
|
|||
e->setSysFlags(i,(flags&(~0x30))|32,restart);
|
||||
updateWindowTitle();
|
||||
}
|
||||
if (ImGui::RadioButton("AY-3-8914",(flags&0x30)==48)) {
|
||||
e->setSysFlags(i,(flags&(~0x30))|48,restart);
|
||||
updateWindowTitle();
|
||||
}
|
||||
}
|
||||
bool stereo=flags&0x40;
|
||||
ImGui::BeginDisabled((flags&0x30)==32);
|
||||
|
|
@ -5819,49 +6105,47 @@ bool FurnaceGUI::loop() {
|
|||
if (patternOpen) nextWindow=GUI_WINDOW_PATTERN;
|
||||
}
|
||||
|
||||
if (ImGuiFileDialog::Instance()->Display("FileDialog",ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove,ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale))) {
|
||||
if (fileDialog->render(ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale))) {
|
||||
//ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_NavEnableKeyboard;
|
||||
switch (curFileDialog) {
|
||||
case GUI_FILE_OPEN:
|
||||
case GUI_FILE_SAVE:
|
||||
case GUI_FILE_SAVE_DMF_LEGACY:
|
||||
workingDirSong=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirSong=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_INS_OPEN:
|
||||
case GUI_FILE_INS_SAVE:
|
||||
workingDirIns=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirIns=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_WAVE_OPEN:
|
||||
case GUI_FILE_WAVE_SAVE:
|
||||
workingDirWave=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirWave=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_SAMPLE_OPEN:
|
||||
case GUI_FILE_SAMPLE_SAVE:
|
||||
workingDirSample=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirSample=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_EXPORT_AUDIO_ONE:
|
||||
case GUI_FILE_EXPORT_AUDIO_PER_SYS:
|
||||
case GUI_FILE_EXPORT_AUDIO_PER_CHANNEL:
|
||||
workingDirAudioExport=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirAudioExport=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_EXPORT_VGM:
|
||||
case GUI_FILE_EXPORT_ROM:
|
||||
workingDirVGMExport=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirVGMExport=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
case GUI_FILE_LOAD_MAIN_FONT:
|
||||
case GUI_FILE_LOAD_PAT_FONT:
|
||||
workingDirFont=ImGuiFileDialog::Instance()->GetCurrentPath()+DIR_SEPARATOR_STR;
|
||||
workingDirFont=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||
break;
|
||||
}
|
||||
if (ImGuiFileDialog::Instance()->IsOk()) {
|
||||
fileName=ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
if (fileDialog->accepted()) {
|
||||
fileName=fileDialog->getFileName();
|
||||
if (fileName!="") {
|
||||
if (curFileDialog==GUI_FILE_SAVE) {
|
||||
if (ImGuiFileDialog::Instance()->GetCurrentFilter()=="Furnace song") {
|
||||
checkExtension(".fur");
|
||||
} else {
|
||||
checkExtension(".dmf");
|
||||
}
|
||||
// we can't tell whether the user chose .dmf or .fur in the system file picker
|
||||
const char* fallbackExt=(settings.sysFileDialog || ImGuiFileDialog::Instance()->GetCurrentFilter()=="Furnace song")?".fur":".dmf";
|
||||
checkExtensionDual(".fur",".dmf",fallbackExt);
|
||||
}
|
||||
if (curFileDialog==GUI_FILE_SAVE_DMF_LEGACY) {
|
||||
checkExtension(".dmf");
|
||||
|
|
@ -5888,9 +6172,13 @@ bool FurnaceGUI::loop() {
|
|||
showError(fmt::sprintf("Error while loading file! (%s)",lastError));
|
||||
}
|
||||
break;
|
||||
case GUI_FILE_SAVE:
|
||||
printf("saving: %s\n",copyOfName.c_str());
|
||||
if (ImGuiFileDialog::Instance()->GetCurrentFilter()=="Furnace song") {
|
||||
case GUI_FILE_SAVE: {
|
||||
logD("saving: %s\n",copyOfName.c_str());
|
||||
String lowerCase=fileName;
|
||||
for (char& i: lowerCase) {
|
||||
if (i>='A' && i<='Z') i+='a'-'A';
|
||||
}
|
||||
if ((lowerCase.size()<4 || lowerCase.rfind(".dmf")!=lowerCase.size()-4)) {
|
||||
if (save(copyOfName,0)>0) {
|
||||
showError(fmt::sprintf("Error while saving file! (%s)",lastError));
|
||||
}
|
||||
|
|
@ -5900,8 +6188,9 @@ bool FurnaceGUI::loop() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUI_FILE_SAVE_DMF_LEGACY:
|
||||
printf("saving: %s\n",copyOfName.c_str());
|
||||
logD("saving: %s\n",copyOfName.c_str());
|
||||
if (save(copyOfName,24)>0) {
|
||||
showError(fmt::sprintf("Error while saving file! (%s)",lastError));
|
||||
}
|
||||
|
|
@ -5980,7 +6269,7 @@ bool FurnaceGUI::loop() {
|
|||
curFileDialog=GUI_FILE_OPEN;
|
||||
}
|
||||
}
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
fileDialog->close();
|
||||
}
|
||||
|
||||
if (warnQuit) {
|
||||
|
|
@ -6458,6 +6747,9 @@ void FurnaceGUI::applyUISettings() {
|
|||
if ((bigFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(font_plexSans_compressed_data,font_plexSans_compressed_size,40*dpiScale))==NULL) {
|
||||
logE("could not load big UI font!\n");
|
||||
}
|
||||
|
||||
if (fileDialog!=NULL) delete fileDialog;
|
||||
fileDialog=new FurnaceGUIFileDialog(settings.sysFileDialog);
|
||||
}
|
||||
|
||||
bool FurnaceGUI::init() {
|
||||
|
|
@ -6587,6 +6879,7 @@ bool FurnaceGUI::init() {
|
|||
ImGui::GetIO().IniFilename=finalLayoutPath;
|
||||
ImGui::LoadIniSettingsFromDisk(finalLayoutPath);
|
||||
|
||||
// TODO: allow changing these colors.
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir,"",ImVec4(0.0f,1.0f,1.0f,1.0f),ICON_FA_FOLDER_O);
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile,"",ImVec4(0.7f,0.7f,0.7f,1.0f),ICON_FA_FILE_O);
|
||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".fur",ImVec4(0.5f,1.0f,0.5f,1.0f),ICON_FA_FILE);
|
||||
|
|
@ -6682,6 +6975,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
displayNew(false),
|
||||
curFileDialog(GUI_FILE_OPEN),
|
||||
warnAction(GUI_WARN_OPEN),
|
||||
fileDialog(NULL),
|
||||
scrW(1280),
|
||||
scrH(800),
|
||||
dpiScale(1),
|
||||
|
|
@ -6750,7 +7044,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
opMaskEffect(true),
|
||||
opMaskEffectVal(true),
|
||||
latchNote(-1),
|
||||
latchIns(-1),
|
||||
latchIns(-2),
|
||||
latchVol(-1),
|
||||
latchEffect(-1),
|
||||
latchEffectVal(-1),
|
||||
|
|
@ -7058,7 +7352,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
));
|
||||
cat.systems.push_back(FurnaceGUISysDef(
|
||||
"Mattel Intellivision", {
|
||||
DIV_SYSTEM_AY8910, 64, 0, 6,
|
||||
DIV_SYSTEM_AY8910, 64, 0, 48,
|
||||
0
|
||||
}
|
||||
));
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "fileDialog.h"
|
||||
|
||||
#define rightClickable if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) ImGui::SetKeyboardFocusHere(-1);
|
||||
|
||||
#define handleUnimportant if (settings.insFocusesPattern && patternOpen) {nextWindow=GUI_WINDOW_PATTERN;}
|
||||
|
|
@ -476,6 +478,8 @@ class FurnaceGUI {
|
|||
FurnaceGUIFileDialogs curFileDialog;
|
||||
FurnaceGUIWarnings warnAction;
|
||||
|
||||
FurnaceGUIFileDialog* fileDialog;
|
||||
|
||||
int scrW, scrH;
|
||||
|
||||
double dpiScale;
|
||||
|
|
@ -534,6 +538,10 @@ class FurnaceGUI {
|
|||
int avoidRaisingPattern;
|
||||
int insFocusesPattern;
|
||||
int stepOnInsert;
|
||||
// TODO flags
|
||||
int unifiedDataView;
|
||||
int sysFileDialog;
|
||||
// end
|
||||
unsigned int maxUndoSteps;
|
||||
String mainFontPath;
|
||||
String patFontPath;
|
||||
|
|
@ -578,6 +586,8 @@ class FurnaceGUI {
|
|||
avoidRaisingPattern(0),
|
||||
insFocusesPattern(1),
|
||||
stepOnInsert(0),
|
||||
unifiedDataView(0),
|
||||
sysFileDialog(1),
|
||||
maxUndoSteps(100),
|
||||
mainFontPath(""),
|
||||
patFontPath(""),
|
||||
|
|
@ -663,6 +673,7 @@ class FurnaceGUI {
|
|||
bool macroDragInitialValueSet;
|
||||
bool macroDragInitialValue;
|
||||
bool macroDragChar;
|
||||
bool macroDragLineMode; // TODO
|
||||
bool macroDragActive;
|
||||
|
||||
ImVec2 macroLoopDragStart;
|
||||
|
|
@ -710,6 +721,9 @@ class FurnaceGUI {
|
|||
|
||||
void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord);
|
||||
|
||||
void actualWaveList();
|
||||
void actualSampleList();
|
||||
|
||||
void drawEditControls();
|
||||
void drawSongInfo();
|
||||
void drawOrders();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// guiConst: constants used in the GUI like arrays, strings and other stuff
|
||||
#include "guiConst.h"
|
||||
#include "../engine/instrument.h"
|
||||
|
||||
const int opOrder[4]={
|
||||
0, 2, 1, 3
|
||||
|
|
@ -64,3 +65,31 @@ const char* pitchLabel[11]={
|
|||
"1/6", "1/5", "1/4", "1/3", "1/2", "1x", "2x", "3x", "4x", "5x", "6x"
|
||||
};
|
||||
|
||||
const char* insTypes[DIV_INS_MAX]={
|
||||
"Standard",
|
||||
"FM (4-operator)",
|
||||
"Game Boy",
|
||||
"C64",
|
||||
"Amiga/Sample",
|
||||
"PC Engine",
|
||||
"AY-3-8910/SSG",
|
||||
"AY8930",
|
||||
"TIA",
|
||||
"SAA1099",
|
||||
"VIC",
|
||||
"PET",
|
||||
"VRC6",
|
||||
"FM (OPLL)",
|
||||
"FM (OPL)",
|
||||
"FDS",
|
||||
"Virtual Boy",
|
||||
"Namco 163",
|
||||
"Konami SCC",
|
||||
"FM (OPZ)",
|
||||
"POKEY",
|
||||
"PC Beeper",
|
||||
"WonderSwan",
|
||||
"Atari Lynx",
|
||||
"VERA",
|
||||
"X1-010"
|
||||
};
|
||||
|
|
@ -23,3 +23,4 @@ extern const int opOrder[4];
|
|||
extern const char* noteNames[180];
|
||||
extern const char* noteNamesG[180];
|
||||
extern const char* pitchLabel[11];
|
||||
extern const char* insTypes[];
|
||||
|
|
@ -27,35 +27,6 @@
|
|||
#include <imgui.h>
|
||||
#include "plot_nolerp.h"
|
||||
|
||||
const char* insTypes[DIV_INS_MAX]={
|
||||
"Standard",
|
||||
"FM (4-operator)",
|
||||
"Game Boy",
|
||||
"C64",
|
||||
"Amiga/Sample",
|
||||
"PC Engine",
|
||||
"AY-3-8910/SSG",
|
||||
"AY8930",
|
||||
"TIA",
|
||||
"SAA1099",
|
||||
"VIC",
|
||||
"PET",
|
||||
"VRC6",
|
||||
"FM (OPLL)",
|
||||
"FM (OPL)",
|
||||
"FDS",
|
||||
"Virtual Boy",
|
||||
"Namco 163",
|
||||
"Konami SCC",
|
||||
"FM (OPZ)",
|
||||
"POKEY",
|
||||
"PC Beeper",
|
||||
"WonderSwan",
|
||||
"Atari Lynx",
|
||||
"VERA",
|
||||
"X1-010"
|
||||
};
|
||||
|
||||
const char* ssgEnvTypes[8]={
|
||||
"Down Down Down", "Down.", "Down Up Down Up", "Down UP", "Up Up Up", "Up.", "Up Down Up Down", "Up DOWN"
|
||||
};
|
||||
|
|
@ -1787,7 +1758,6 @@ void FurnaceGUI::drawWaveList() {
|
|||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!waveListOpen) return;
|
||||
float wavePreview[256];
|
||||
if (ImGui::Begin("Wavetables",&waveListOpen)) {
|
||||
if (ImGui::Button(ICON_FA_PLUS "##WaveAdd")) {
|
||||
doAction(GUI_ACTION_WAVE_LIST_ADD);
|
||||
|
|
@ -1818,25 +1788,7 @@ void FurnaceGUI::drawWaveList() {
|
|||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("WaveListScroll",1,ImGuiTableFlags_ScrollY)) {
|
||||
for (int i=0; i<(int)e->song.wave.size(); i++) {
|
||||
DivWavetable* wave=e->song.wave[i];
|
||||
for (int i=0; i<wave->len; i++) {
|
||||
wavePreview[i]=wave->data[i];
|
||||
}
|
||||
if (wave->len>0) wavePreview[wave->len]=wave->data[wave->len-1];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(fmt::sprintf("%d##_WAVE%d\n",i,i).c_str(),curWave==i)) {
|
||||
curWave=i;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
waveEditOpen=true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
PlotNoLerp(fmt::sprintf("##_WAVEP%d",i).c_str(),wavePreview,wave->len+1,0,NULL,0,wave->max);
|
||||
}
|
||||
actualWaveList();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,11 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.restartOnFlagChange=restartOnFlagChangeB;
|
||||
}
|
||||
|
||||
bool sysFileDialogB=settings.sysFileDialog;
|
||||
if (ImGui::Checkbox("Use system file picker",&sysFileDialogB)) {
|
||||
settings.sysFileDialog=sysFileDialogB;
|
||||
}
|
||||
|
||||
ImGui::Text("Wrap pattern cursor horizontally:");
|
||||
if (ImGui::RadioButton("No##wrapH0",settings.wrapHorizontal==0)) {
|
||||
settings.wrapHorizontal=0;
|
||||
|
|
@ -403,6 +408,11 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.macroView=macroViewB;
|
||||
}
|
||||
|
||||
bool unifiedDataViewB=settings.unifiedDataView;
|
||||
if (ImGui::Checkbox("Unified instrument/wavetable/sample list",&unifiedDataViewB)) {
|
||||
settings.unifiedDataView=unifiedDataViewB;
|
||||
}
|
||||
|
||||
bool chipNamesB=settings.chipNames;
|
||||
if (ImGui::Checkbox("Use chip names instead of system names",&chipNamesB)) {
|
||||
settings.chipNames=chipNamesB;
|
||||
|
|
@ -892,6 +902,8 @@ void FurnaceGUI::syncSettings() {
|
|||
settings.avoidRaisingPattern=e->getConfInt("avoidRaisingPattern",0);
|
||||
settings.insFocusesPattern=e->getConfInt("insFocusesPattern",1);
|
||||
settings.stepOnInsert=e->getConfInt("stepOnInsert",0);
|
||||
settings.unifiedDataView=e->getConfInt("unifiedDataView",0);
|
||||
settings.sysFileDialog=e->getConfInt("sysFileDialog",1);
|
||||
|
||||
clampSetting(settings.mainFontSize,2,96);
|
||||
clampSetting(settings.patFontSize,2,96);
|
||||
|
|
@ -930,6 +942,8 @@ void FurnaceGUI::syncSettings() {
|
|||
clampSetting(settings.avoidRaisingPattern,0,1);
|
||||
clampSetting(settings.insFocusesPattern,0,1);
|
||||
clampSetting(settings.stepOnInsert,0,1);
|
||||
clampSetting(settings.unifiedDataView,0,1);
|
||||
clampSetting(settings.sysFileDialog,0,1);
|
||||
|
||||
// keybinds
|
||||
LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o);
|
||||
|
|
@ -1129,6 +1143,8 @@ void FurnaceGUI::commitSettings() {
|
|||
e->setConf("avoidRaisingPattern",settings.avoidRaisingPattern);
|
||||
e->setConf("insFocusesPattern",settings.insFocusesPattern);
|
||||
e->setConf("stepOnInsert",settings.stepOnInsert);
|
||||
e->setConf("unifiedDataView",settings.unifiedDataView);
|
||||
e->setConf("sysFileDialog",settings.sysFileDialog);
|
||||
|
||||
PUT_UI_COLOR(GUI_COLOR_BACKGROUND);
|
||||
PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue