mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-22 12:35:11 +00:00
GUI: user preset saving and prepare edit window
This commit is contained in:
parent
b04ddaa20a
commit
e7a638fdd5
5 changed files with 150 additions and 5 deletions
|
@ -319,6 +319,9 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_WINDOW_CS_PLAYER:
|
||||
nextWindow=GUI_WINDOW_CS_PLAYER;
|
||||
break;
|
||||
case GUI_ACTION_WINDOW_USER_PRESETS:
|
||||
nextWindow=GUI_WINDOW_USER_PRESETS;
|
||||
break;
|
||||
|
||||
case GUI_ACTION_COLLAPSE_WINDOW:
|
||||
collapseWindow=true;
|
||||
|
@ -424,6 +427,8 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_WINDOW_CS_PLAYER:
|
||||
csPlayerOpen=false;
|
||||
break;
|
||||
case GUI_WINDOW_USER_PRESETS:
|
||||
userPresetsOpen=false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3479,6 +3479,7 @@ bool FurnaceGUI::loop() {
|
|||
DECLARE_METRIC(regView)
|
||||
DECLARE_METRIC(log)
|
||||
DECLARE_METRIC(effectList)
|
||||
DECLARE_METRIC(userPresets)
|
||||
DECLARE_METRIC(popup)
|
||||
|
||||
#ifdef IS_MOBILE
|
||||
|
@ -4051,6 +4052,7 @@ bool FurnaceGUI::loop() {
|
|||
IMPORT_CLOSE(xyOscOpen);
|
||||
IMPORT_CLOSE(memoryOpen);
|
||||
IMPORT_CLOSE(csPlayerOpen);
|
||||
IMPORT_CLOSE(userPresetsOpen);
|
||||
} else if (pendingLayoutImportStep==1) {
|
||||
// let the UI settle
|
||||
} else if (pendingLayoutImportStep==2) {
|
||||
|
@ -4383,6 +4385,9 @@ bool FurnaceGUI::loop() {
|
|||
toggleMobileUI(!mobileUI);
|
||||
}
|
||||
#endif
|
||||
if (ImGui::MenuItem("manage presets...",BIND_FOR(GUI_ACTION_WINDOW_USER_PRESETS))) {
|
||||
userPresetsOpen=true;
|
||||
}
|
||||
if (ImGui::MenuItem("settings...",BIND_FOR(GUI_ACTION_WINDOW_SETTINGS))) {
|
||||
syncSettings();
|
||||
settingsOpen=true;
|
||||
|
@ -4664,6 +4669,7 @@ bool FurnaceGUI::loop() {
|
|||
MEASURE(grooves,drawGrooves());
|
||||
MEASURE(regView,drawRegView());
|
||||
MEASURE(memory,drawMemory());
|
||||
MEASURE(userPresets,drawUserPresets());
|
||||
} else {
|
||||
globalWinFlags=0;
|
||||
ImGui::DockSpaceOverViewport(NULL,lockLayout?(ImGuiDockNodeFlags_NoWindowMenuButton|ImGuiDockNodeFlags_NoMove|ImGuiDockNodeFlags_NoResize|ImGuiDockNodeFlags_NoCloseButton|ImGuiDockNodeFlags_NoDocking|ImGuiDockNodeFlags_NoDockingSplitMe|ImGuiDockNodeFlags_NoDockingSplitOther):0);
|
||||
|
@ -4706,6 +4712,7 @@ bool FurnaceGUI::loop() {
|
|||
MEASURE(regView,drawRegView());
|
||||
MEASURE(log,drawLog());
|
||||
MEASURE(effectList,drawEffectList());
|
||||
MEASURE(userPresets,drawUserPresets());
|
||||
}
|
||||
|
||||
// NEW CODE - REMOVE WHEN DONE
|
||||
|
@ -6610,6 +6617,7 @@ bool FurnaceGUI::init() {
|
|||
subSongsOpen=e->getConfBool("subSongsOpen",true);
|
||||
findOpen=e->getConfBool("findOpen",false);
|
||||
spoilerOpen=e->getConfBool("spoilerOpen",false);
|
||||
userPresetsOpen=e->getConfBool("userPresetsOpen",false);
|
||||
|
||||
insListDir=e->getConfBool("insListDir",false);
|
||||
waveListDir=e->getConfBool("waveListDir",false);
|
||||
|
@ -7007,6 +7015,8 @@ bool FurnaceGUI::init() {
|
|||
ImGui::CreateContext();
|
||||
rend->initGUI(sdlWin);
|
||||
|
||||
loadUserPresets(true);
|
||||
|
||||
// NEW CODE - REMOVE WHEN DONE
|
||||
newOscFragment=rend->getStupidFragment();
|
||||
|
||||
|
@ -7169,6 +7179,7 @@ void FurnaceGUI::commitState() {
|
|||
e->setConf("subSongsOpen",subSongsOpen);
|
||||
e->setConf("findOpen",findOpen);
|
||||
e->setConf("spoilerOpen",spoilerOpen);
|
||||
e->setConf("userPresetsOpen",userPresetsOpen);
|
||||
|
||||
// commit dir state
|
||||
e->setConf("insListDir",insListDir);
|
||||
|
@ -7271,6 +7282,9 @@ void FurnaceGUI::commitState() {
|
|||
|
||||
bool FurnaceGUI::finish(bool saveConfig) {
|
||||
commitState();
|
||||
if (userPresetsOpen) {
|
||||
saveUserPresets(true);
|
||||
}
|
||||
if (saveConfig) {
|
||||
logI("saving config.");
|
||||
e->saveConf();
|
||||
|
@ -7521,6 +7535,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
xyOscOpen(false),
|
||||
memoryOpen(false),
|
||||
csPlayerOpen(false),
|
||||
userPresetsOpen(false),
|
||||
shortIntro(false),
|
||||
insListDir(false),
|
||||
waveListDir(false),
|
||||
|
|
|
@ -485,6 +485,7 @@ enum FurnaceGUIWindows {
|
|||
GUI_WINDOW_INTRO_MON,
|
||||
GUI_WINDOW_MEMORY,
|
||||
GUI_WINDOW_CS_PLAYER,
|
||||
GUI_WINDOW_USER_PRESETS,
|
||||
GUI_WINDOW_SPOILER
|
||||
};
|
||||
|
||||
|
@ -677,6 +678,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_WINDOW_XY_OSC,
|
||||
GUI_ACTION_WINDOW_MEMORY,
|
||||
GUI_ACTION_WINDOW_CS_PLAYER,
|
||||
GUI_ACTION_WINDOW_USER_PRESETS,
|
||||
|
||||
GUI_ACTION_COLLAPSE_WINDOW,
|
||||
GUI_ACTION_CLOSE_WINDOW,
|
||||
|
@ -2081,7 +2083,7 @@ class FurnaceGUI {
|
|||
bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen;
|
||||
bool pianoOpen, notesOpen, channelsOpen, regViewOpen, logOpen, effectListOpen, chanOscOpen;
|
||||
bool subSongsOpen, findOpen, spoilerOpen, patManagerOpen, sysManagerOpen, clockOpen, speedOpen;
|
||||
bool groovesOpen, xyOscOpen, memoryOpen, csPlayerOpen;
|
||||
bool groovesOpen, xyOscOpen, memoryOpen, csPlayerOpen, userPresetsOpen;
|
||||
|
||||
bool shortIntro;
|
||||
bool insListDir, waveListDir, sampleListDir;
|
||||
|
@ -2610,6 +2612,7 @@ class FurnaceGUI {
|
|||
void drawClock();
|
||||
void drawTutorial();
|
||||
void drawXYOsc();
|
||||
void drawUserPresets();
|
||||
|
||||
void parseKeybinds();
|
||||
void promptKey(int which);
|
||||
|
|
|
@ -610,6 +610,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("WINDOW_XY_OSC", "Oscilloscope (X-Y)", 0),
|
||||
D("WINDOW_MEMORY", "Memory Composition", 0),
|
||||
D("WINDOW_CS_PLAYER", "Command Stream Player", 0),
|
||||
D("WINDOW_USER_PRESETS", "User Presets", 0),
|
||||
|
||||
D("COLLAPSE_WINDOW", "Collapse/expand current window", 0),
|
||||
D("CLOSE_WINDOW", "Close current window", FURKMOD_SHIFT|SDLK_ESCAPE),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../baseutils.h"
|
||||
#include "../fileutils.h"
|
||||
#include <fmt/printf.h>
|
||||
#include <imgui.h>
|
||||
|
||||
// add system configurations here.
|
||||
// every entry is written in the following format:
|
||||
|
@ -3164,6 +3165,20 @@ FurnaceGUISysDef::FurnaceGUISysDef(const char* n, const char* def, DivEngine* e)
|
|||
#define REDUNDANCY_NUM_ATTEMPTS 5
|
||||
#define CHECK_BUF_SIZE 8192
|
||||
|
||||
std::vector<FurnaceGUISysDef>* digDeep(std::vector<FurnaceGUISysDef>& entries, int depth) {
|
||||
if (depth==0) return &entries;
|
||||
std::vector<FurnaceGUISysDef>& result=entries;
|
||||
|
||||
for (int i=0; i<depth; i++) {
|
||||
if (result.empty()) {
|
||||
logW("digDeep: %d is as far as it goes!",depth);
|
||||
break;
|
||||
}
|
||||
result=result.at(result.size()).subDefs;
|
||||
}
|
||||
return &result;
|
||||
}
|
||||
|
||||
bool FurnaceGUI::loadUserPresets(bool redundancy) {
|
||||
String path=e->getConfigPath()+PRESETS_FILE;
|
||||
String line;
|
||||
|
@ -3231,13 +3246,13 @@ bool FurnaceGUI::loadUserPresets(bool redundancy) {
|
|||
|
||||
// we couldn't read at all
|
||||
if (f==NULL) {
|
||||
logD("config does not exist");
|
||||
logD("presets file does not exist");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
f=ps_fopen(path.c_str(),"rb");
|
||||
if (f==NULL) {
|
||||
logD("config does not exist");
|
||||
logD("presets file does not exist");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3258,6 +3273,8 @@ bool FurnaceGUI::loadUserPresets(bool redundancy) {
|
|||
return false;
|
||||
}
|
||||
|
||||
userCategory->systems.clear();
|
||||
|
||||
char nextLine[4096];
|
||||
while (!feof(f)) {
|
||||
if (fgets(nextLine,4095,f)==NULL) {
|
||||
|
@ -3289,10 +3306,11 @@ bool FurnaceGUI::loadUserPresets(bool redundancy) {
|
|||
}
|
||||
}
|
||||
}
|
||||
indent>>=1;
|
||||
|
||||
// TODO: nesting
|
||||
if (!key.empty() && !value.empty()) {
|
||||
userCategory->systems.push_back(FurnaceGUISysDef(key.c_str(),value.c_str(),e));
|
||||
std::vector<FurnaceGUISysDef>* where=digDeep(userCategory->systems,indent);
|
||||
where->push_back(FurnaceGUISysDef(key.c_str(),value.c_str(),e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3300,6 +3318,109 @@ bool FurnaceGUI::loadUserPresets(bool redundancy) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void writeSubEntries(FILE* f, std::vector<FurnaceGUISysDef>& entries, int depth) {
|
||||
for (FurnaceGUISysDef& i: entries) {
|
||||
String safeName;
|
||||
safeName.reserve(i.name.size());
|
||||
bool beginning=false;
|
||||
for (char j: i.name) {
|
||||
if (beginning && j==' ') continue;
|
||||
if (j=='=') continue;
|
||||
if (j<0x20) continue;
|
||||
safeName+=j;
|
||||
}
|
||||
|
||||
String data;
|
||||
for (int i=0; i<depth; i++) {
|
||||
data+=" ";
|
||||
}
|
||||
data+=fmt::sprintf("%s=%s\n",safeName,i.definition);
|
||||
fputs(data.c_str(),f);
|
||||
|
||||
writeSubEntries(f,i.subDefs,depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceGUI::saveUserPresets(bool redundancy) {
|
||||
String path=e->getConfigPath()+PRESETS_FILE;
|
||||
FurnaceGUISysCategory* userCategory=NULL;
|
||||
|
||||
for (FurnaceGUISysCategory& i: sysCategories) {
|
||||
if (strcmp(i.name,"User")==0) {
|
||||
userCategory=&i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (userCategory==NULL) {
|
||||
logE("could not find user category!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (redundancy) {
|
||||
char oldPath[4096];
|
||||
char newPath[4096];
|
||||
|
||||
if (fileExists(path.c_str())==1) {
|
||||
logD("rotating preset files...");
|
||||
for (int i=4; i>=0; i--) {
|
||||
if (i>0) {
|
||||
snprintf(oldPath,4095,"%s.%d",path.c_str(),i);
|
||||
} else {
|
||||
strncpy(oldPath,path.c_str(),4095);
|
||||
}
|
||||
snprintf(newPath,4095,"%s.%d",path.c_str(),i+1);
|
||||
|
||||
if (i>=4) {
|
||||
logV("remove %s",oldPath);
|
||||
deleteFile(oldPath);
|
||||
} else {
|
||||
logV("move %s to %s",oldPath,newPath);
|
||||
moveFiles(oldPath,newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logD("saving user presets: %s",path);
|
||||
FILE* f=ps_fopen(path.c_str(),"wb");
|
||||
if (f==NULL) {
|
||||
logW("could not write presets! %s",strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
writeSubEntries(f,userCategory->systems,0);
|
||||
|
||||
fclose(f);
|
||||
logD("presets written successfully.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// user presets management
|
||||
void FurnaceGUI::drawUserPresets() {
|
||||
if (nextWindow==GUI_WINDOW_USER_PRESETS) {
|
||||
userPresetsOpen=true;
|
||||
ImGui::SetNextWindowFocus();
|
||||
nextWindow=GUI_WINDOW_NOTHING;
|
||||
}
|
||||
if (!userPresetsOpen) return;
|
||||
if (ImGui::Begin("User Presets",&userPresetsOpen,globalWinFlags)) {
|
||||
if (ImGui::BeginTable("UserPresets",2,ImGuiTableFlags_BordersInnerV)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Presets...");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Edit...");
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Save and Close")) {
|
||||
userPresetsOpen=false;
|
||||
}
|
||||
}
|
||||
if (!userPresetsOpen) {
|
||||
saveUserPresets(true);
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_USER_PRESETS;
|
||||
ImGui::End();
|
||||
}
|
Loading…
Reference in a new issue