GUI: user preset saving and prepare edit window

This commit is contained in:
tildearrow 2024-03-30 03:33:38 -05:00
parent b04ddaa20a
commit e7a638fdd5
5 changed files with 150 additions and 5 deletions

View file

@ -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;
}

View file

@ -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),

View file

@ -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);

View file

@ -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),

View file

@ -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();
}