Persist the "Debug details" toggle in the layout .ini
The View-menu verbosity switch reset to off on every launch. Register a custom ImGui settings handler (a [CoopUI][State] section in coop_layout.ini, alongside the window layout) so the operator's choice survives restarts. Toggling it marks settings dirty so ImGui's auto-save writes it back. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -152,6 +152,9 @@ int run()
|
|||||||
bool show_overlay = true;
|
bool show_overlay = true;
|
||||||
double overlay_hidden_at = 0.0;
|
double overlay_hidden_at = 0.0;
|
||||||
coop::UiState ui;
|
coop::UiState ui;
|
||||||
|
// Persist the "Debug details" verbosity in the .ini. Register before the first
|
||||||
|
// begin_frame() below, which is when ImGui loads the .ini and replays our handler.
|
||||||
|
coop::register_ui_settings(ui);
|
||||||
coop::FrameStats stats;
|
coop::FrameStats stats;
|
||||||
|
|
||||||
// Frame-sync: the hook generation we last presented (so we wait for the next one).
|
// Frame-sync: the hook generation we last presented (so we wait for the next one).
|
||||||
|
|||||||
@@ -2,14 +2,51 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
#include "imgui_internal.h" // ImGuiSettingsHandler / AddSettingsHandler (custom .ini section)
|
||||||
|
|
||||||
namespace coop
|
namespace coop
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
// --- Custom .ini persistence for the UI switches ---------------------------
|
||||||
|
// We piggy-back on ImGui's .ini so the "Debug details" verbosity survives restarts
|
||||||
|
// without inventing a separate settings file. The section looks like:
|
||||||
|
// [CoopUI][State]
|
||||||
|
// DebugDetails=1
|
||||||
|
// ImGui calls ReadOpenFn once per "[CoopUI][<name>]" entry; we return the bound
|
||||||
|
// UiState* as the entry handle so ReadLineFn can write into it.
|
||||||
|
constexpr const char* kUiSettingsType = "CoopUI";
|
||||||
|
|
||||||
|
void* ui_settings_read_open(ImGuiContext*, ImGuiSettingsHandler* handler, const char* name)
|
||||||
|
{
|
||||||
|
// Only one entry ("State"); hand back the UiState* so ReadLineFn can fill it.
|
||||||
|
return std::strcmp(name, "State") == 0 ? handler->UserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_settings_read_line(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line)
|
||||||
|
{
|
||||||
|
auto* ui = static_cast<UiState*>(entry);
|
||||||
|
// Manual parse (avoids the sscanf CRT-secure deprecation for a single int key).
|
||||||
|
constexpr char kKey[] = "DebugDetails=";
|
||||||
|
if (std::strncmp(line, kKey, sizeof(kKey) - 1) == 0)
|
||||||
|
{
|
||||||
|
ui->debug_details = std::atoi(line + sizeof(kKey) - 1) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_settings_write_all(ImGuiContext*, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
|
||||||
|
{
|
||||||
|
const auto* ui = static_cast<const UiState*>(handler->UserData);
|
||||||
|
buf->appendf("[%s][State]\n", kUiSettingsType);
|
||||||
|
buf->appendf("DebugDetails=%d\n", ui->debug_details ? 1 : 0);
|
||||||
|
buf->append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Set by "View -> Reset layout"; true for the one frame in which panels re-apply
|
// Set by "View -> Reset layout"; true for the one frame in which panels re-apply
|
||||||
// their default position/size, then cleared by apply_layout_end_frame().
|
// their default position/size, then cleared by apply_layout_end_frame().
|
||||||
bool g_layout_reset = false;
|
bool g_layout_reset = false;
|
||||||
@@ -22,6 +59,23 @@ int g_startup_force = 4;
|
|||||||
bool g_had_persisted_layout = false;
|
bool g_had_persisted_layout = false;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
void register_ui_settings(UiState& ui)
|
||||||
|
{
|
||||||
|
// Idempotent: don't stack a second handler if this is somehow called twice.
|
||||||
|
if (ImGui::FindSettingsHandler(kUiSettingsType) != nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ImGuiSettingsHandler handler;
|
||||||
|
handler.TypeName = kUiSettingsType;
|
||||||
|
handler.TypeHash = ImHashStr(kUiSettingsType);
|
||||||
|
handler.ReadOpenFn = ui_settings_read_open;
|
||||||
|
handler.ReadLineFn = ui_settings_read_line;
|
||||||
|
handler.WriteAllFn = ui_settings_write_all;
|
||||||
|
handler.UserData = &ui;
|
||||||
|
ImGui::AddSettingsHandler(&handler); // copied into the context
|
||||||
|
}
|
||||||
|
|
||||||
void request_layout_reset()
|
void request_layout_reset()
|
||||||
{
|
{
|
||||||
g_layout_reset = true;
|
g_layout_reset = true;
|
||||||
@@ -123,7 +177,10 @@ float draw_main_menu_bar(UiState& ui, const FrameStats& stats)
|
|||||||
ImGui::MenuItem("Audio mirror", nullptr, &ui.show_audio);
|
ImGui::MenuItem("Audio mirror", nullptr, &ui.show_audio);
|
||||||
ImGui::MenuItem("Log", nullptr, &ui.show_log);
|
ImGui::MenuItem("Log", nullptr, &ui.show_log);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::MenuItem("Debug details", nullptr, &ui.debug_details);
|
if (ImGui::MenuItem("Debug details", nullptr, &ui.debug_details))
|
||||||
|
{
|
||||||
|
ImGui::MarkIniSettingsDirty(); // persist the new verbosity to coop_layout.ini
|
||||||
|
}
|
||||||
if (ImGui::MenuItem("Reset layout"))
|
if (ImGui::MenuItem("Reset layout"))
|
||||||
{
|
{
|
||||||
request_layout_reset();
|
request_layout_reset();
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ struct UiState
|
|||||||
bool debug_details = false; // off = general status; on = full diagnostics
|
bool debug_details = false; // off = general status; on = full diagnostics
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Persist the verbosity-affecting UI switches (currently the "Debug details" toggle)
|
||||||
|
// into ImGui's .ini, alongside the window layout, so the operator's choice survives
|
||||||
|
// restarts. Registers a custom .ini settings handler bound to `ui`; call once after
|
||||||
|
// the ImGui context exists but before the first NewFrame (which loads the .ini), and
|
||||||
|
// keep `ui` alive for the program's lifetime (the handler stores a pointer to it).
|
||||||
|
void register_ui_settings(UiState& ui);
|
||||||
|
|
||||||
// The overlay panels, for the shared default layout below.
|
// The overlay panels, for the shared default layout below.
|
||||||
enum class Panel
|
enum class Panel
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user