Write ImGui config to an appropriate folder instead of the current one.

This commit is contained in:
Patrick 2025-03-02 18:41:27 +01:00
parent f51dd5b437
commit 7a18cce60c
3 changed files with 99 additions and 1 deletions

View File

@ -6,7 +6,10 @@
#include <fmt/base.h>
#include <SDL3/SDL.h>
#include <mijin/debug/assert.hpp>
#include <mijin/platform/folders.hpp>
#include <mijin/util/scope_guard.hpp>
#include <mijin/virtual_filesystem/mapping.hpp>
#include <mijin/virtual_filesystem/relative.hpp>
#include <imgui.h>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_sdl3.h>
@ -27,6 +30,37 @@ int Application::run(int argc, char** argv)
MIJIN_SCOPE_EXIT {
cleanup();
};
using namespace mijin::vfs_pipe;
mFS.addAdapter(os()
| relative_to(mijin::getKnownFolder(mijin::KnownFolder::USER_CONFIG_ROOT) / getFolderName())
| map_to("/config")
);
mFS.addAdapter(os()
| relative_to(mijin::getKnownFolder(mijin::KnownFolder::USER_DATA_ROOT) / getFolderName())
| map_to("/data")
);
auto createUserDir = [&](const fs::path& virtualPath)
{
mijin::Optional<fs::path> pathOpt = mFS.getNativePath(virtualPath);
if (!pathOpt.empty())
{
const fs::path path = std::move(*pathOpt);
if (!fs::exists(path))
{
const bool result = fs::create_directories(path);
MIJIN_ASSERT(result, "Error creating user folder.");
}
}
else
{
MIJIN_ERROR("User folder path shouldn't be empty.");
}
};
createUserDir("/config");
createUserDir("/data");
if (!initSDL())
{
return ERR_INIT_FAILED;
@ -50,12 +84,14 @@ int Application::run(int argc, char** argv)
continue;
}
ImGuiIO& imguiIO = ImGui::GetIO();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos({0, 0});
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
ImGui::SetNextWindowSize(imguiIO.DisplaySize);
ImGui::Begin("##main", nullptr, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration);
render();
@ -68,6 +104,12 @@ int Application::run(int argc, char** argv)
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(mWindow);
if (imguiIO.WantSaveIniSettings)
{
saveImGuiConfig();
imguiIO.WantSaveIniSettings = false;
}
}
return 0;
@ -160,9 +202,12 @@ bool Application::initImGui()
return false;
}
loadImGuiConfig();
ImGuiIO& imguiIO = ImGui::GetIO();
imguiIO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
imguiIO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
imguiIO.IniFilename = nullptr; // disable automatic saving of settings
// default style
ImGui::StyleColorsDark();
@ -189,6 +234,8 @@ void Application::cleanup()
{
if (ImGui::GetCurrentContext() != nullptr)
{
saveImGuiConfig();
const ImGuiIO& imguiIO = ImGui::GetIO();
if (imguiIO.BackendRendererUserData != nullptr)
{
@ -220,6 +267,40 @@ void Application::handleSDLEvents()
}
}
void Application::loadImGuiConfig()
{
std::unique_ptr<mijin::Stream> iniFile;
if (mFS.open("/config/imgui.ini", mijin::FileOpenMode::READ, iniFile) != mijin::StreamError::SUCCESS)
{
return;
}
std::string config;
if (iniFile->readAsString(config) != mijin::StreamError::SUCCESS)
{
msgWarning("IO error reading ImGui config.");
return;
}
ImGui::LoadIniSettingsFromMemory(config.c_str());
}
void Application::saveImGuiConfig()
{
std::unique_ptr<mijin::Stream> iniFile;
if (const mijin::StreamError error = mFS.open("/config/imgui.ini", mijin::FileOpenMode::WRITE, iniFile);
error != mijin::StreamError::SUCCESS)
{
msgError("Error opening ImGui config file for writing: {}.", mijin::errorName(error));
return;
}
std::size_t length = 0;
const char* config = ImGui::SaveIniSettingsToMemory(&length);
if (const mijin::StreamError error = iniFile->writeText(config); error != mijin::StreamError::SUCCESS)
{
msgError("Error writing ImGui config: {}.", mijin::errorName(error));
}
}
void QuickApp::init(QuickAppOptions options)
{
MIJIN_ASSERT_FATAL(options.callbacks.render, "Missing render callback.");
@ -231,6 +312,11 @@ void QuickApp::render()
mOptions.callbacks.render();
}
std::string QuickApp::getFolderName()
{
return mOptions.folderName;
}
int runQuick(int argc, char* argv[], QuickAppOptions options)
{
QuickApp app;

View File

@ -8,6 +8,10 @@ namespace
void render()
{
ImGui::Text("hi");
ImGui::Begin("Test");
ImGui::Text("Test Content");
ImGui::End();
}
}

View File

@ -7,6 +7,7 @@
#include <cstdint>
#include <functional>
#include <fmt/format.h>
#include <mijin/virtual_filesystem/stacked.hpp>
#include <SDL3/SDL.h>
namespace raid
@ -33,6 +34,8 @@ private:
SDL_Window* mWindow = nullptr;
SDL_GLContext mGLContext = nullptr;
mijin::StackedFileSystemAdapter mFS;
using glClear_fn_t = void (*)(std::uint32_t);
using glClearColor_fn_t = void (*)(float, float, float, float);
@ -46,6 +49,7 @@ public:
protected:
virtual void render() = 0;
virtual std::string getFolderName() = 0;
virtual void handleMessage(const Message& message);
virtual void handleSDLEvent(const SDL_Event& event);
@ -106,6 +110,8 @@ private:
bool initImGui();
void cleanup();
void handleSDLEvents();
void loadImGuiConfig();
void saveImGuiConfig();
};
using render_cb_t = std::function<void()>;
@ -115,6 +121,7 @@ struct QuickAppOptions
{
render_cb_t render;
} callbacks;
std::string folderName = "raid";
};
class QuickApp : public Application
@ -124,6 +131,7 @@ private:
public:
void init(QuickAppOptions options);
void render() override;
std::string getFolderName() override;
};
[[nodiscard]]