From 2cd7de56666531d729e4dbe06af3e3c0a2e5aaf9 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 15:24:01 +0100 Subject: [PATCH] Internal: Log/Capture: Rework to add an internal LogToBuffer() function which is useful for writing automated tests. Clarified logging state by adding an enum. --- imgui.cpp | 70 +++++++++++++++++++++++++++++++++--------------- imgui_internal.h | 16 ++++++++++- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ce7494d99..22696b17a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3615,7 +3615,7 @@ void ImGui::Shutdown(ImGuiContext* context) fclose(g.LogFile); g.LogFile = NULL; } - g.LogClipboard.clear(); + g.LogBuffer.clear(); g.Initialized = false; } @@ -8786,7 +8786,7 @@ void ImGui::LogText(const char* fmt, ...) if (g.LogFile) vfprintf(g.LogFile, fmt, args); else - g.LogClipboard.appendfv(fmt, args); + g.LogBuffer.appendfv(fmt, args); va_end(args); } @@ -8830,7 +8830,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* } } -// Start logging ImGui output to TTY +// Start logging/capturing text output to TTY void ImGui::LogToTTY(int max_depth) { ImGuiContext& g = *GImGui; @@ -8841,12 +8841,13 @@ void ImGui::LogToTTY(int max_depth) IM_ASSERT(g.LogFile == NULL); g.LogFile = stdout; g.LogEnabled = true; + g.LogType = ImGuiLogType_TTY; g.LogStartDepth = window->DC.TreeDepth; if (max_depth >= 0) g.LogAutoExpandMaxDepth = max_depth; } -// Start logging ImGui output to given file +// Start logging/capturing text output to given file void ImGui::LogToFile(int max_depth, const char* filename) { ImGuiContext& g = *GImGui; @@ -8855,26 +8856,25 @@ void ImGui::LogToFile(int max_depth, const char* filename) ImGuiWindow* window = g.CurrentWindow; if (!filename) - { filename = g.IO.LogFilename; - if (!filename) - return; - } + if (!filename || !filename[0]) + return; IM_ASSERT(g.LogFile == NULL); - g.LogFile = ImFileOpen(filename, "ab"); + g.LogFile = ImFileOpen(filename, "ab"); // FIXME: Why not logging in text mode? Then we don't need to bother the user with IM_NEWLINE.. if (!g.LogFile) { IM_ASSERT(0); return; } g.LogEnabled = true; + g.LogType = ImGuiLogType_File; g.LogStartDepth = window->DC.TreeDepth; if (max_depth >= 0) g.LogAutoExpandMaxDepth = max_depth; } -// Start logging ImGui output to clipboard +// Start logging/capturing text output to clipboard void ImGui::LogToClipboard(int max_depth) { ImGuiContext& g = *GImGui; @@ -8883,8 +8883,27 @@ void ImGui::LogToClipboard(int max_depth) ImGuiWindow* window = g.CurrentWindow; IM_ASSERT(g.LogFile == NULL); - g.LogFile = NULL; + IM_ASSERT(g.LogBuffer.empty()); g.LogEnabled = true; + g.LogType = ImGuiLogType_Clipboard; + g.LogFile = NULL; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +void ImGui::LogToBuffer(int max_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = g.CurrentWindow; + + IM_ASSERT(g.LogFile == NULL); + IM_ASSERT(g.LogBuffer.empty()); + g.LogEnabled = true; + g.LogType = ImGuiLogType_Clipboard; + g.LogFile = NULL; g.LogStartDepth = window->DC.TreeDepth; if (max_depth >= 0) g.LogAutoExpandMaxDepth = max_depth; @@ -8897,23 +8916,30 @@ void ImGui::LogFinish() return; LogText(IM_NEWLINE); - if (g.LogFile != NULL) + switch (g.LogType) { - if (g.LogFile == stdout) - fflush(g.LogFile); - else - fclose(g.LogFile); - g.LogFile = NULL; - } - if (g.LogClipboard.size() > 1) - { - SetClipboardText(g.LogClipboard.begin()); - g.LogClipboard.clear(); + case ImGuiLogType_TTY: + fflush(g.LogFile); + break; + case ImGuiLogType_File: + fclose(g.LogFile); + break; + case ImGuiLogType_Buffer: + break; + case ImGuiLogType_Clipboard: + if (!g.LogBuffer.empty()) + SetClipboardText(g.LogBuffer.begin()); + break; } + g.LogEnabled = false; + g.LogType = ImGuiLogType_None; + g.LogFile = NULL; + g.LogBuffer.clear(); } // Helper to display logging buttons +// FIXME-OBSOLETE: We should probably obsolete this and let the user have their own helper (this is one of the oldest function alive!) void ImGui::LogButtons() { ImGuiContext& g = *GImGui; diff --git a/imgui_internal.h b/imgui_internal.h index cc355e95b..c79aeabc1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -384,6 +384,15 @@ enum ImGuiLayoutType_ ImGuiLayoutType_Vertical = 1 }; +enum ImGuiLogType +{ + ImGuiLogType_None = 0, + ImGuiLogType_TTY, + ImGuiLogType_File, + ImGuiLogType_Buffer, + ImGuiLogType_Clipboard +}; + // X/Y enums are fixed to 0/1 so they may be used to index ImVec2 enum ImGuiAxis { @@ -928,8 +937,9 @@ struct ImGuiContext // Logging bool LogEnabled; + ImGuiLogType LogType; FILE* LogFile; // If != NULL log to stdout/ file - ImGuiTextBuffer LogClipboard; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. int LogStartDepth; int LogAutoExpandMaxDepth; @@ -1041,6 +1051,7 @@ struct ImGuiContext SettingsDirtyTimer = 0.0f; LogEnabled = false; + LogType = ImGuiLogType_None; LogFile = NULL; LogStartDepth = 0; LogAutoExpandMaxDepth = 2; @@ -1396,6 +1407,9 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); + // Logging/Capture + IMGUI_API void LogToBuffer(int max_depth = -1); // Start logging to internal buffer + // Popups, Modals, Tooltips IMGUI_API void OpenPopupEx(ImGuiID id); IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under);