mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-30 18:29:04 +08:00
Error handling: rework error tooltip logic (will be reused by upcoming feature). (#7961, #7669, #1651)
+ Comments
This commit is contained in:
parent
d0107f5da2
commit
9644c51183
83
imgui.cpp
83
imgui.cpp
@ -3978,6 +3978,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
|||||||
LogDepthRef = 0;
|
LogDepthRef = 0;
|
||||||
LogDepthToExpand = LogDepthToExpandDefault = 2;
|
LogDepthToExpand = LogDepthToExpandDefault = 2;
|
||||||
|
|
||||||
|
DebugDrawIdConflictsCount = 0;
|
||||||
DebugLogFlags = ImGuiDebugLogFlags_OutputToTTY;
|
DebugLogFlags = ImGuiDebugLogFlags_OutputToTTY;
|
||||||
DebugLocateId = 0;
|
DebugLocateId = 0;
|
||||||
DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
|
DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
|
||||||
@ -5054,6 +5055,7 @@ void ImGui::NewFrame()
|
|||||||
KeepAliveID(g.DragDropPayload.SourceId);
|
KeepAliveID(g.DragDropPayload.SourceId);
|
||||||
|
|
||||||
// [DEBUG]
|
// [DEBUG]
|
||||||
|
if (!g.IO.ConfigDebugHighlightIdConflicts || !g.IO.KeyCtrl) // Count is locked while holding CTRL
|
||||||
g.DebugDrawIdConflicts = 0;
|
g.DebugDrawIdConflicts = 0;
|
||||||
if (g.IO.ConfigDebugHighlightIdConflicts && g.HoveredIdPreviousFrameItemCount > 1)
|
if (g.IO.ConfigDebugHighlightIdConflicts && g.HoveredIdPreviousFrameItemCount > 1)
|
||||||
g.DebugDrawIdConflicts = g.HoveredIdPreviousFrame;
|
g.DebugDrawIdConflicts = g.HoveredIdPreviousFrame;
|
||||||
@ -5461,32 +5463,10 @@ void ImGui::EndFrame()
|
|||||||
return;
|
return;
|
||||||
IM_ASSERT(g.WithinFrameScope && "Forgot to call ImGui::NewFrame()?");
|
IM_ASSERT(g.WithinFrameScope && "Forgot to call ImGui::NewFrame()?");
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
||||||
if (g.DebugDrawIdConflicts != 0)
|
|
||||||
{
|
|
||||||
PushStyleColor(ImGuiCol_PopupBg, ImLerp(g.Style.Colors[ImGuiCol_PopupBg], ImVec4(1.0f, 0.0f, 0.0f, 1.0f), 0.10f));
|
|
||||||
if (g.DebugItemPickerActive == false && BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None))
|
|
||||||
{
|
|
||||||
SeparatorText("MESSAGE FROM DEAR IMGUI");
|
|
||||||
Text("Programmer error: %d visible items with conflicting ID!", g.HoveredIdPreviousFrameItemCount);
|
|
||||||
BulletText("Code should use PushID()/PopID() in loops, or append \"##xx\" to same-label identifiers!");
|
|
||||||
BulletText("Empty label e.g. Button(\"\") == same ID as parent widget/node. Use Button(\"##xx\") instead!");
|
|
||||||
BulletText("Press F1 to open \"FAQ -> About the ID Stack System\" and read details.");
|
|
||||||
BulletText("Press CTRL+P to activate Item Picker and debug-break in item call-stack.");
|
|
||||||
BulletText("Set io.ConfigDebugDetectIdConflicts=false to disable this warning in non-programmers builds.");
|
|
||||||
EndTooltip();
|
|
||||||
}
|
|
||||||
PopStyleColor();
|
|
||||||
if (Shortcut(ImGuiMod_Ctrl | ImGuiKey_P, ImGuiInputFlags_RouteGlobal))
|
|
||||||
DebugStartItemPicker();
|
|
||||||
if (Shortcut(ImGuiKey_F1, ImGuiInputFlags_RouteGlobal) && g.PlatformIO.Platform_OpenInShellFn != NULL)
|
|
||||||
g.PlatformIO.Platform_OpenInShellFn(&g, "https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#qa-usage");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CallContextHooks(&g, ImGuiContextHookType_EndFramePre);
|
CallContextHooks(&g, ImGuiContextHookType_EndFramePre);
|
||||||
|
|
||||||
ErrorCheckEndFrameSanityChecks();
|
ErrorCheckEndFrameSanityChecks();
|
||||||
|
ErrorCheckEndFrameFinalizeErrorTooltip();
|
||||||
|
|
||||||
// Notify Platform/OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
|
// Notify Platform/OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
|
||||||
ImGuiPlatformImeData* ime_data = &g.PlatformImeData;
|
ImGuiPlatformImeData* ime_data = &g.PlatformImeData;
|
||||||
@ -10587,6 +10567,63 @@ void ImGuiStackSizes::CompareWithContextState(ImGuiContext* ctx)
|
|||||||
IM_ASSERT(SizeOfFocusScopeStack == g.FocusScopeStack.Size && "PushFocusScope/PopFocusScope Mismatch!");
|
IM_ASSERT(SizeOfFocusScopeStack == g.FocusScopeStack.Size && "PushFocusScope/PopFocusScope Mismatch!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::ErrorCheckEndFrameFinalizeErrorTooltip()
|
||||||
|
{
|
||||||
|
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (g.DebugDrawIdConflicts != 0 && g.IO.KeyCtrl == false)
|
||||||
|
g.DebugDrawIdConflictsCount = g.HoveredIdPreviousFrameItemCount;
|
||||||
|
if (g.DebugDrawIdConflicts != 0 && g.DebugItemPickerActive == false && BeginErrorTooltip())
|
||||||
|
{
|
||||||
|
Text("Programmer error: %d visible items with conflicting ID!", g.DebugDrawIdConflictsCount);
|
||||||
|
BulletText("Code should use PushID()/PopID() in loops, or append \"##xx\" to same-label identifiers!");
|
||||||
|
BulletText("Empty label e.g. Button(\"\") == same ID as parent widget/node. Use Button(\"##xx\") instead!");
|
||||||
|
BulletText("Set io.ConfigDebugDetectIdConflicts=false to disable this warning in non-programmers builds.");
|
||||||
|
Separator();
|
||||||
|
Text("(Hold CTRL and: use");
|
||||||
|
SameLine();
|
||||||
|
if (SmallButton("Item Picker"))
|
||||||
|
DebugStartItemPicker();
|
||||||
|
SameLine();
|
||||||
|
Text("to break in item call-stack, or");
|
||||||
|
SameLine();
|
||||||
|
if (SmallButton("Open FAQ->About ID Stack System") && g.PlatformIO.Platform_OpenInShellFn != NULL)
|
||||||
|
g.PlatformIO.Platform_OpenInShellFn(&g, "https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#qa-usage");
|
||||||
|
EndErrorTooltip();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pseudo-tooltip. Follow mouse until CTRL is held. When CTRL is held we lock position, allowing to click it.
|
||||||
|
bool ImGui::BeginErrorTooltip()
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = FindWindowByName("##Tooltip_Error");
|
||||||
|
const bool use_locked_pos = (g.IO.KeyCtrl && window && window->WasActive);
|
||||||
|
PushStyleColor(ImGuiCol_PopupBg, ImLerp(g.Style.Colors[ImGuiCol_PopupBg], ImVec4(1.0f, 0.0f, 0.0f, 1.0f), 0.15f));
|
||||||
|
if (use_locked_pos)
|
||||||
|
SetNextWindowPos(g.ErrorTooltipLockedPos);
|
||||||
|
bool is_visible = Begin("##Tooltip_Error", NULL, ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize);
|
||||||
|
PopStyleColor();
|
||||||
|
if (is_visible && g.CurrentWindow->BeginCount == 1)
|
||||||
|
{
|
||||||
|
SeparatorText("MESSAGE FROM DEAR IMGUI");
|
||||||
|
BringWindowToDisplayFront(g.CurrentWindow);
|
||||||
|
BringWindowToFocusFront(g.CurrentWindow);
|
||||||
|
g.ErrorTooltipLockedPos = GetWindowPos();
|
||||||
|
}
|
||||||
|
else if (!is_visible)
|
||||||
|
{
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
return is_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::EndErrorTooltip()
|
||||||
|
{
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] ITEM SUBMISSION
|
// [SECTION] ITEM SUBMISSION
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -2312,8 +2312,12 @@ struct ImGuiContext
|
|||||||
int LogDepthToExpand;
|
int LogDepthToExpand;
|
||||||
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
|
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
ImVec2 ErrorTooltipLockedPos;
|
||||||
|
|
||||||
// Debug Tools
|
// Debug Tools
|
||||||
// (some of the highly frequently used data are interleaved in other structures above: DebugBreakXXX fields, DebugHookIdInfo, DebugLocateId etc.)
|
// (some of the highly frequently used data are interleaved in other structures above: DebugBreakXXX fields, DebugHookIdInfo, DebugLocateId etc.)
|
||||||
|
int DebugDrawIdConflictsCount; // Locked count (preserved when holding CTRL)
|
||||||
ImGuiDebugLogFlags DebugLogFlags;
|
ImGuiDebugLogFlags DebugLogFlags;
|
||||||
ImGuiTextBuffer DebugLogBuf;
|
ImGuiTextBuffer DebugLogBuf;
|
||||||
ImGuiTextIndex DebugLogIndex;
|
ImGuiTextIndex DebugLogIndex;
|
||||||
@ -3412,11 +3416,14 @@ namespace ImGui
|
|||||||
IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window);
|
IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window);
|
||||||
IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window);
|
IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window);
|
||||||
|
|
||||||
// Error Checking, State Recovery
|
// Error handling, State Recovery
|
||||||
IMGUI_API void ErrorLogCallbackToDebugLog(void* user_data, const char* fmt, ...);
|
IMGUI_API void ErrorLogCallbackToDebugLog(void* user_data, const char* fmt, ...);
|
||||||
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
|
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
|
||||||
IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
|
IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
|
||||||
IMGUI_API void ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
|
IMGUI_API void ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
|
||||||
|
IMGUI_API void ErrorCheckEndFrameFinalizeErrorTooltip();
|
||||||
|
IMGUI_API bool BeginErrorTooltip();
|
||||||
|
IMGUI_API void EndErrorTooltip();
|
||||||
|
|
||||||
// Debug Tools
|
// Debug Tools
|
||||||
IMGUI_API void DebugAllocHook(ImGuiDebugAllocInfo* info, int frame_count, void* ptr, size_t size); // size >= 0 : alloc, size = -1 : free
|
IMGUI_API void DebugAllocHook(ImGuiDebugAllocInfo* info, int frame_count, void* ptr, size_t size); // size >= 0 : alloc, size = -1 : free
|
||||||
|
@ -7391,6 +7391,7 @@ void ImGui::EndBoxSelect(const ImRect& scope_rect, ImGuiMultiSelectFlags ms_flag
|
|||||||
static void DebugLogMultiSelectRequests(const char* function, const ImGuiMultiSelectIO* io)
|
static void DebugLogMultiSelectRequests(const char* function, const ImGuiMultiSelectIO* io)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_UNUSED(function);
|
||||||
for (const ImGuiSelectionRequest& req : io->Requests)
|
for (const ImGuiSelectionRequest& req : io->Requests)
|
||||||
{
|
{
|
||||||
if (req.Type == ImGuiSelectionRequestType_SetAll) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: Request: SetAll %d (= %s)\n", function, req.Selected, req.Selected ? "SelectAll" : "Clear");
|
if (req.Type == ImGuiSelectionRequestType_SetAll) IMGUI_DEBUG_LOG_SELECTION("[selection] %s: Request: SetAll %d (= %s)\n", function, req.Selected, req.Selected ? "SelectAll" : "Clear");
|
||||||
@ -8157,6 +8158,13 @@ void ImGuiSelectionExternalStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
|
|||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
// This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
// This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||||
|
// This handle some subtleties with capturing info from the label, but for 99% uses it could essentially be rewritten as:
|
||||||
|
// if (ImGui::BeginChild("...", ImVec2(ImGui::CalcItemWidth(), ImGui::GetTextLineHeight() * 7.5f), ImGuiChildFlags_FrameStyle))
|
||||||
|
// { .... }
|
||||||
|
// ImGui::EndChild();
|
||||||
|
// ImGui::SameLine();
|
||||||
|
// ImGui::AlignTextToFramePadding();
|
||||||
|
// ImGui::Text("Label");
|
||||||
// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty"
|
// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty"
|
||||||
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height).
|
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height).
|
||||||
bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
|
bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
|
||||||
|
Loading…
Reference in New Issue
Block a user