From 3eba84005372734297700212cbf31c8b400bef3d Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 14:49:36 +0100 Subject: [PATCH 1/8] Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigation to the menu layer. (follow and extend on e.g #369, #370) --- docs/CHANGELOG.txt | 1 + imgui.cpp | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 73a59691..7c415766 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,7 @@ HOW TO UPDATE? Other Changes: +- Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigation to the menu layer. - InputInt, InputFloat, InputScalar: Fix to keep the label of the +/- buttons centered when style.FramePadding.x is abnormally larger than style.FramePadding.y. Since the buttons are meant to be square (to align with e.g. color button) we always use FramePadding.y. (#2367) diff --git a/imgui.cpp b/imgui.cpp index ddcd10c2..ce7494d9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7591,9 +7591,12 @@ static void ImGui::NavUpdate() NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_); NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ ); NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ ); - if (g.IO.KeyCtrl) g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; - if (g.IO.KeyShift) g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; - if (g.IO.KeyAlt) g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f; + if (g.IO.KeyCtrl) + g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; + if (g.IO.KeyShift) + g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; + if (g.IO.KeyAlt && !g.IO.KeyCtrl) // AltGR is Alt+Ctrl, also even on keyboards without AltGR we don't want Alt+Ctrl to open menu. + g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f; #undef NAV_MAP_KEY } memcpy(g.IO.NavInputsDownDurationPrev, g.IO.NavInputsDownDuration, sizeof(g.IO.NavInputsDownDuration)); From 2cd7de56666531d729e4dbe06af3e3c0a2e5aaf9 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 15:24:01 +0100 Subject: [PATCH 2/8] 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 ce7494d9..22696b17 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 cc355e95..c79aeabc 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); From cd67d4d3c18f1f5c0b94a6a09ed35b748e5a2cc4 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 15:39:18 +0100 Subject: [PATCH 3/8] Log/Capture: Fixed LogXXX functions 'auto_open_depth' parameter being treated as an absolute tree depth instead of a relative one. Fixed CollapsingHeader trailing ascii representation being "#" instead of "##". Minor tidying up the of code. --- docs/CHANGELOG.txt | 3 +++ docs/TODO.txt | 5 +++-- imgui.cpp | 42 +++++++++++++++++++----------------------- imgui.h | 6 +++--- imgui_internal.h | 13 +++++++------ imgui_widgets.cpp | 4 ++-- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7c415766..eba02739 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -44,6 +44,9 @@ Other Changes: - TabBar: Fixed a crash when using BeginTabBar() recursively (didn't affect docking). (#2371) - TabBar: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to hard crashes any more, facilitating integration with scripting languages. (#1651) +- Log/Capture: Fixed LogXXX functions 'auto_open_depth' parameter being treated as an absolute + tree depth instead of a relative one. +- Log/Capture: Fixed CollapsingHeader trailing ascii representation being "#" instead of "##". - Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if the OpenGL headers/loader happens to define the value. (#2366, #2186) diff --git a/docs/TODO.txt b/docs/TODO.txt index 01b54716..d0fa9755 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -217,11 +217,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners. - style editor: color child window height expressed in multiple of line height. - - log: LogButtons() options for specifying depth and/or hiding depth slider - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - + - log: obsolete LogButtons() all together. + - log: LogButtons() options for specifying depth and/or hiding depth slider + - filters: set a current filter that tree node can automatically query to hide themselves - filters: handle wild-cards (with implicit leading/trailing *), reg-exprs - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) diff --git a/imgui.cpp b/imgui.cpp index 22696b17..d6fbc1ce 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8805,9 +8805,9 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* window->DC.LogLinePosY = ref_pos->y; const char* text_remaining = text; - if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth - g.LogStartDepth = window->DC.TreeDepth; - const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); + if (g.LogDepthRef > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth + g.LogDepthRef = window->DC.TreeDepth; + const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef); for (;;) { // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. @@ -8831,7 +8831,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* } // Start logging/capturing text output to TTY -void ImGui::LogToTTY(int max_depth) +void ImGui::LogToTTY(int auto_open_depth) { ImGuiContext& g = *GImGui; if (g.LogEnabled) @@ -8842,13 +8842,12 @@ void ImGui::LogToTTY(int max_depth) g.LogFile = stdout; g.LogEnabled = true; g.LogType = ImGuiLogType_TTY; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + g.LogDepthRef = window->DC.TreeDepth; + g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); } // Start logging/capturing text output to given file -void ImGui::LogToFile(int max_depth, const char* filename) +void ImGui::LogToFile(int auto_open_depth, const char* filename) { ImGuiContext& g = *GImGui; if (g.LogEnabled) @@ -8869,13 +8868,12 @@ void ImGui::LogToFile(int max_depth, const char* filename) } g.LogEnabled = true; g.LogType = ImGuiLogType_File; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + g.LogDepthRef = window->DC.TreeDepth; + g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); } // Start logging/capturing text output to clipboard -void ImGui::LogToClipboard(int max_depth) +void ImGui::LogToClipboard(int auto_open_depth) { ImGuiContext& g = *GImGui; if (g.LogEnabled) @@ -8887,12 +8885,11 @@ void ImGui::LogToClipboard(int max_depth) g.LogEnabled = true; g.LogType = ImGuiLogType_Clipboard; g.LogFile = NULL; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + g.LogDepthRef = window->DC.TreeDepth; + g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); } -void ImGui::LogToBuffer(int max_depth) +void ImGui::LogToBuffer(int auto_open_depth) { ImGuiContext& g = *GImGui; if (g.LogEnabled) @@ -8904,9 +8901,8 @@ void ImGui::LogToBuffer(int max_depth) g.LogEnabled = true; g.LogType = ImGuiLogType_Clipboard; g.LogFile = NULL; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + g.LogDepthRef = window->DC.TreeDepth; + g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); } void ImGui::LogFinish() @@ -8950,18 +8946,18 @@ void ImGui::LogButtons() const bool log_to_clipboard = Button("Log To Clipboard"); SameLine(); PushItemWidth(80.0f); PushAllowKeyboardFocus(false); - SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); + SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL); PopAllowKeyboardFocus(); PopItemWidth(); PopID(); // Start logging at the end of the function so that the buttons don't appear in the log if (log_to_tty) - LogToTTY(g.LogAutoExpandMaxDepth); + LogToTTY(); if (log_to_file) - LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); + LogToFile(); if (log_to_clipboard) - LogToClipboard(g.LogAutoExpandMaxDepth); + LogToClipboard(); } //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index e109f3a4..dd1e67dc 100644 --- a/imgui.h +++ b/imgui.h @@ -572,9 +572,9 @@ namespace ImGui // Logging/Capture // - All text output from the interface can be captured into tty/file/clipboard. By default, tree nodes are automatically opened during logging. - IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty (stdout) - IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file - IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard + IMGUI_API void LogToTTY(int auto_open_depth = -1); // start logging to tty (stdout) + IMGUI_API void LogToFile(int auto_open_depth = -1, const char* filename = NULL); // start logging to file + IMGUI_API void LogToClipboard(int auto_open_depth = -1); // start logging to OS clipboard IMGUI_API void LogFinish(); // stop logging (close file, etc.) IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) diff --git a/imgui_internal.h b/imgui_internal.h index c79aeabc..96827b70 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -939,9 +939,10 @@ struct ImGuiContext bool LogEnabled; ImGuiLogType LogType; FILE* LogFile; // If != NULL log to stdout/ file - 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; + ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + int LogDepthRef; + int LogDepthToExpand; + int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call. // Misc float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. @@ -1053,8 +1054,8 @@ struct ImGuiContext LogEnabled = false; LogType = ImGuiLogType_None; LogFile = NULL; - LogStartDepth = 0; - LogAutoExpandMaxDepth = 2; + LogDepthRef = 0; + LogDepthToExpand = LogDepthToExpandDefault = 2; memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = 0; @@ -1408,7 +1409,7 @@ namespace ImGui IMGUI_API void PopItemFlag(); // Logging/Capture - IMGUI_API void LogToBuffer(int max_depth = -1); // Start logging to internal buffer + IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging to internal buffer // Popups, Modals, Tooltips IMGUI_API void OpenPopupEx(ImGuiID id); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index f49fa46d..26eb5c24 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4795,7 +4795,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) // When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). // NB- If we are above max depth we still allow manually opened nodes to be logged. - if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) + if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && (window->DC.TreeDepth - g.LogDepthRef) < g.LogDepthToExpand) is_open = true; return is_open; @@ -4922,7 +4922,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l const char log_suffix[] = "##"; LogRenderedText(&text_pos, log_prefix, log_prefix+3); RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); - LogRenderedText(&text_pos, log_suffix+1, log_suffix+3); + LogRenderedText(&text_pos, log_suffix, log_suffix+2); } else { From 9558e327d2c68c27b7aac4384c892ef4f316a5c1 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 16:22:55 +0100 Subject: [PATCH 4/8] Log/Capture: Fixed extraneous leading carriage return. Fixed an issue when empty string on a new line would not emit a carriage return. --- docs/CHANGELOG.txt | 2 + imgui.cpp | 92 ++++++++++++++++++++++++---------------------- imgui_internal.h | 10 +++-- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index eba02739..9ef37fab 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -44,6 +44,8 @@ Other Changes: - TabBar: Fixed a crash when using BeginTabBar() recursively (didn't affect docking). (#2371) - TabBar: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to hard crashes any more, facilitating integration with scripting languages. (#1651) +- Log/Capture: Fixed extraneous leading carriage return. +- Log/Capture: Fixed an issue when empty string on a new line would not emit a carriage return. - Log/Capture: Fixed LogXXX functions 'auto_open_depth' parameter being treated as an absolute tree depth instead of a relative one. - Log/Capture: Fixed CollapsingHeader trailing ascii representation being "#" instead of "##". diff --git a/imgui.cpp b/imgui.cpp index d6fbc1ce..830e14a7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5325,7 +5325,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; window->DC.NavLayerActiveMaskNext = 0x00; window->DC.MenuBarAppending = false; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; window->DC.ChildWindows.resize(0); window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; @@ -6550,7 +6549,6 @@ void ImGui::BeginGroup() group_data.BackupGroupOffset = window->DC.GroupOffset; group_data.BackupCurrentLineSize = window->DC.CurrentLineSize; group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; - group_data.BackupLogLinePosY = window->DC.LogLinePosY; group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive; group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive; group_data.AdvanceCursor = true; @@ -6559,14 +6557,15 @@ void ImGui::BeginGroup() window->DC.Indent = window->DC.GroupOffset; window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.CurrentLineSize = ImVec2(0.0f, 0.0f); - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; // To enforce Log carriage return + if (g.LogEnabled) + g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return } void ImGui::EndGroup() { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls + IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls ImGuiGroupData& group_data = window->DC.GroupStack.back(); @@ -6579,7 +6578,8 @@ void ImGui::EndGroup() window->DC.GroupOffset = group_data.BackupGroupOffset; window->DC.CurrentLineSize = group_data.BackupCurrentLineSize; window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; // To enforce Log carriage return + if (g.LogEnabled) + g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return if (group_data.AdvanceCursor) { @@ -8800,9 +8800,11 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* if (!text_end) text_end = FindRenderedTextEnd(text, text_end); - const bool log_new_line = ref_pos && (ref_pos->y > window->DC.LogLinePosY + 1); + const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + 1); if (ref_pos) - window->DC.LogLinePosY = ref_pos->y; + g.LogLinePosY = ref_pos->y; + if (log_new_line) + g.LogLineFirstItem = true; const char* text_remaining = text; if (g.LogDepthRef > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth @@ -8811,6 +8813,7 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* for (;;) { // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. + // We don't add a trailing \n to allow a subsequent item on the same line to be captured. const char* line_start = text_remaining; const char* line_end = ImStreolRange(line_start, text_end); const bool is_first_line = (line_start == text); @@ -8819,9 +8822,18 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* { const int char_count = (int)(line_end - line_start); if (log_new_line || !is_first_line) - LogText(IM_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, line_start); - else + LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, line_start); + else if (g.LogLineFirstItem) + LogText("%*s%.*s", tree_depth * 4, "", char_count, line_start); + else LogText(" %.*s", char_count, line_start); + g.LogLineFirstItem = false; + } + else if (log_new_line) + { + // An empty "" string at a different Y position should output a carriage return. + LogText(IM_NEWLINE); + break; } if (is_last_line) @@ -8830,20 +8842,29 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* } } -// Start logging/capturing text output to TTY +// Start logging/capturing text output +void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(g.LogEnabled == false); + IM_ASSERT(g.LogFile == NULL); + IM_ASSERT(g.LogBuffer.empty()); + g.LogEnabled = true; + g.LogType = type; + g.LogDepthRef = window->DC.TreeDepth; + g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); + g.LogLinePosY = FLT_MAX; + g.LogLineFirstItem = true; +} + void ImGui::LogToTTY(int auto_open_depth) { ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = g.CurrentWindow; - - IM_ASSERT(g.LogFile == NULL); + LogBegin(ImGuiLogType_TTY, auto_open_depth); g.LogFile = stdout; - g.LogEnabled = true; - g.LogType = ImGuiLogType_TTY; - g.LogDepthRef = window->DC.TreeDepth; - g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); } // Start logging/capturing text output to given file @@ -8852,24 +8873,23 @@ void ImGui::LogToFile(int auto_open_depth, const char* filename) ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = g.CurrentWindow; + // FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still + // be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE. + // By opening the file in binary mode "ab" we have consistent output everywhere. if (!filename) filename = g.IO.LogFilename; if (!filename || !filename[0]) return; - - IM_ASSERT(g.LogFile == NULL); - 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) + FILE* f = ImFileOpen(filename, "ab"); + if (f == NULL) { IM_ASSERT(0); return; } - g.LogEnabled = true; - g.LogType = ImGuiLogType_File; - g.LogDepthRef = window->DC.TreeDepth; - g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); + + LogBegin(ImGuiLogType_File, auto_open_depth); + g.LogFile = f; } // Start logging/capturing text output to clipboard @@ -8878,15 +8898,7 @@ void ImGui::LogToClipboard(int auto_open_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.LogDepthRef = window->DC.TreeDepth; - g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); + LogBegin(ImGuiLogType_Clipboard, auto_open_depth); } void ImGui::LogToBuffer(int auto_open_depth) @@ -8894,15 +8906,7 @@ void ImGui::LogToBuffer(int auto_open_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.LogDepthRef = window->DC.TreeDepth; - g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); + LogBegin(ImGuiLogType_Buffer, auto_open_depth); } void ImGui::LogFinish() diff --git a/imgui_internal.h b/imgui_internal.h index 96827b70..fa172834 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -547,7 +547,6 @@ struct ImGuiGroupData ImVec1 BackupGroupOffset; ImVec2 BackupCurrentLineSize; float BackupCurrentLineTextBaseOffset; - float BackupLogLinePosY; ImGuiID BackupActiveIdIsAlive; bool BackupActiveIdPreviousFrameIsAlive; bool AdvanceCursor; @@ -940,6 +939,8 @@ struct ImGuiContext ImGuiLogType LogType; FILE* LogFile; // If != NULL log to stdout/ file ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + float LogLinePosY; + bool LogLineFirstItem; int LogDepthRef; int LogDepthToExpand; int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call. @@ -1054,6 +1055,8 @@ struct ImGuiContext LogEnabled = false; LogType = ImGuiLogType_None; LogFile = NULL; + LogLinePosY = FLT_MAX; + LogLineFirstItem = false; LogDepthRef = 0; LogDepthToExpand = LogDepthToExpandDefault = 2; @@ -1081,7 +1084,6 @@ struct IMGUI_API ImGuiWindowTempData float CurrentLineTextBaseOffset; ImVec2 PrevLineSize; float PrevLineTextBaseOffset; - float LogLinePosY; int TreeDepth; ImU32 TreeDepthMayJumpToParentOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31 ImGuiID LastItemId; @@ -1121,7 +1123,6 @@ struct IMGUI_API ImGuiWindowTempData CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); CurrentLineSize = PrevLineSize = ImVec2(0.0f, 0.0f); CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; - LogLinePosY = -1.0f; TreeDepth = 0; TreeDepthMayJumpToParentOnPop = 0x00; LastItemId = 0; @@ -1409,7 +1410,8 @@ namespace ImGui IMGUI_API void PopItemFlag(); // Logging/Capture - IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging to internal buffer + IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. + IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer // Popups, Modals, Tooltips IMGUI_API void OpenPopupEx(ImGuiID id); From 6cbf4b81210204736a844a9519b0fde72df35cad Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 17:00:59 +0100 Subject: [PATCH 5/8] Fixed uninitialized variable (leading to asserts in the docking branch). (#2376, #2371) --- imgui_internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui_internal.h b/imgui_internal.h index fa172834..a76c386a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1037,6 +1037,8 @@ struct ImGuiContext DragDropAcceptFrameCount = -1; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); + CurrentTabBar = NULL; + ScalarAsInputTextId = 0; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; DragCurrentAccumDirty = false; From 6f80179a1d45753e7065ea7f79360e8e30e5d115 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Feb 2019 17:04:54 +0100 Subject: [PATCH 6/8] InputText: Fixed deactivated but-last-active InputText instance holding on displaying the last active version of the text and not reflecting change in the source. Fix/amend 2e9a175. [+test] --- imgui_widgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 26eb5c24..8ad51a28 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3647,7 +3647,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const int buf_display_max_length = 2 * 1024 * 1024; // Select which buffer we are going to display. We set buf to NULL to prevent accidental usage from now on. - const char* buf_display = (state != NULL && !is_readonly) ? state->TextA.Data : buf; + const char* buf_display = (g.ActiveId == id && state && !is_readonly) ? state->TextA.Data : buf; IM_ASSERT(buf_display); buf = NULL; From c3ea1748dc124ca4a209d54219d9b55b7817244e Mon Sep 17 00:00:00 2001 From: Elias Daler Date: Sun, 24 Feb 2019 20:35:52 +0300 Subject: [PATCH 7/8] Fix -Wconversion warning (#2379) The warning was caused by implicit conversion from pointer type which NULL has to non-pointer type, e.g. if ImTextureID is long int --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 37e8ff51..25ce75fe 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -407,7 +407,7 @@ ImDrawList* ImDrawList::CloneOutput() const // Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds #define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen) -#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) +#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : (ImTextureID)NULL) void ImDrawList::AddDrawCmd() { From 5d7bd2309b19e451710f4a906ad99cb4d7fe02e5 Mon Sep 17 00:00:00 2001 From: David Wingrove Date: Sun, 24 Feb 2019 17:19:36 -0500 Subject: [PATCH 8/8] Fixes warning caused by a missing switch/case. (#2382, #2381) --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 830e14a7..80fb3e33 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8930,6 +8930,9 @@ void ImGui::LogFinish() if (!g.LogBuffer.empty()) SetClipboardText(g.LogBuffer.begin()); break; + case ImGuiLogType_None: + IM_ASSERT(0); + break; } g.LogEnabled = false;