From 588dfd96b3fb6d189c67b3b2895cc64d7dba9638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Sat, 23 Feb 2019 20:43:29 -0800 Subject: [PATCH] Updated ImGui. --- 3rdparty/dear-imgui/imgui.cpp | 161 +++++++++++++++----------- 3rdparty/dear-imgui/imgui.h | 6 +- 3rdparty/dear-imgui/imgui_internal.h | 35 ++++-- 3rdparty/dear-imgui/imgui_widgets.cpp | 6 +- 4 files changed, 129 insertions(+), 79 deletions(-) diff --git a/3rdparty/dear-imgui/imgui.cpp b/3rdparty/dear-imgui/imgui.cpp index 11c715aac..28a6d8bf8 100644 --- a/3rdparty/dear-imgui/imgui.cpp +++ b/3rdparty/dear-imgui/imgui.cpp @@ -3617,7 +3617,7 @@ void ImGui::Shutdown(ImGuiContext* context) fclose(g.LogFile); g.LogFile = NULL; } - g.LogClipboard.clear(); + g.LogBuffer.clear(); g.Initialized = false; } @@ -5327,7 +5327,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; @@ -6552,7 +6551,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; @@ -6561,14 +6559,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(); @@ -6581,7 +6580,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) { @@ -7593,9 +7593,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)); @@ -8785,7 +8788,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); } @@ -8799,17 +8802,20 @@ 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.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. + // 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); @@ -8818,9 +8824,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) @@ -8829,64 +8844,71 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* } } -// Start logging ImGui output to TTY -void ImGui::LogToTTY(int max_depth) +// Start logging/capturing text output +void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth) { ImGuiContext& g = *GImGui; - if (g.LogEnabled) - return; ImGuiWindow* window = g.CurrentWindow; - + IM_ASSERT(g.LogEnabled == false); IM_ASSERT(g.LogFile == NULL); - g.LogFile = stdout; + IM_ASSERT(g.LogBuffer.empty()); g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + 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; } -// Start logging ImGui output to given file -void ImGui::LogToFile(int max_depth, const char* filename) +void ImGui::LogToTTY(int auto_open_depth) { ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = g.CurrentWindow; + LogBegin(ImGuiLogType_TTY, auto_open_depth); + g.LogFile = stdout; +} +// Start logging/capturing text output to given file +void ImGui::LogToFile(int auto_open_depth, const char* filename) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + + // 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) - return; - } - - IM_ASSERT(g.LogFile == NULL); - g.LogFile = ImFileOpen(filename, "ab"); - if (!g.LogFile) + if (!filename || !filename[0]) + return; + FILE* f = ImFileOpen(filename, "ab"); + if (f == NULL) { IM_ASSERT(0); return; } - g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + + LogBegin(ImGuiLogType_File, auto_open_depth); + g.LogFile = f; } -// Start logging ImGui output to clipboard -void ImGui::LogToClipboard(int max_depth) +// Start logging/capturing text output to clipboard +void ImGui::LogToClipboard(int auto_open_depth) { ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = g.CurrentWindow; + LogBegin(ImGuiLogType_Clipboard, auto_open_depth); +} - IM_ASSERT(g.LogFile == NULL); - g.LogFile = NULL; - g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; +void ImGui::LogToBuffer(int auto_open_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + LogBegin(ImGuiLogType_Buffer, auto_open_depth); } void ImGui::LogFinish() @@ -8896,23 +8918,32 @@ 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; + case ImGuiLogType_None: + 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; @@ -8923,18 +8954,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/3rdparty/dear-imgui/imgui.h b/3rdparty/dear-imgui/imgui.h index e508f3e8c..29b785853 100644 --- a/3rdparty/dear-imgui/imgui.h +++ b/3rdparty/dear-imgui/imgui.h @@ -573,9 +573,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/3rdparty/dear-imgui/imgui_internal.h b/3rdparty/dear-imgui/imgui_internal.h index cc355e95b..a76c386aa 100644 --- a/3rdparty/dear-imgui/imgui_internal.h +++ b/3rdparty/dear-imgui/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 { @@ -538,7 +547,6 @@ struct ImGuiGroupData ImVec1 BackupGroupOffset; ImVec2 BackupCurrentLineSize; float BackupCurrentLineTextBaseOffset; - float BackupLogLinePosY; ImGuiID BackupActiveIdIsAlive; bool BackupActiveIdPreviousFrameIsAlive; bool AdvanceCursor; @@ -928,10 +936,14 @@ 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. - 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. + float LogLinePosY; + bool LogLineFirstItem; + 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. @@ -1025,6 +1037,8 @@ struct ImGuiContext DragDropAcceptFrameCount = -1; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); + CurrentTabBar = NULL; + ScalarAsInputTextId = 0; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; DragCurrentAccumDirty = false; @@ -1041,9 +1055,12 @@ struct ImGuiContext SettingsDirtyTimer = 0.0f; LogEnabled = false; + LogType = ImGuiLogType_None; LogFile = NULL; - LogStartDepth = 0; - LogAutoExpandMaxDepth = 2; + LogLinePosY = FLT_MAX; + LogLineFirstItem = false; + LogDepthRef = 0; + LogDepthToExpand = LogDepthToExpandDefault = 2; memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = 0; @@ -1069,7 +1086,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; @@ -1109,7 +1125,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; @@ -1396,6 +1411,10 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); + // Logging/Capture + 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); IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under); diff --git a/3rdparty/dear-imgui/imgui_widgets.cpp b/3rdparty/dear-imgui/imgui_widgets.cpp index 8b7761dc8..d45070fd7 100644 --- a/3rdparty/dear-imgui/imgui_widgets.cpp +++ b/3rdparty/dear-imgui/imgui_widgets.cpp @@ -3662,7 +3662,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; @@ -4810,7 +4810,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; @@ -4937,7 +4937,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 {