From 014b722963f3ca2184b594439d6184ece4078de0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 2 Oct 2024 18:26:02 +0200 Subject: [PATCH] Tooltips, Drag and Drop: Stabilized name of drag and drop tooltip window. (#8036) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 28 +++++++++++++++++----------- imgui.h | 2 +- imgui_internal.h | 1 + 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index f9fb75866..489d010d8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -73,6 +73,9 @@ Other changes: Set io.ConfigScrollbarScrollByPage=false to enforce always scrolling to clicked location. - Tooltips, Drag and Drop: Fixed an issue where the fallback drag and drop payload tooltip appeared during drag and drop release. +- Tooltips, Drag and Drop: Stabilized name of drag and drop tooltip window so that + transitioning from an item tooltip to a drag tooltip doesn't leak window auto-sizing + info from one to the other. (#8036) - Backends: SDL3: Update for API changes: SDL_bool removal. SDL_INIT_TIMER removal. - Backends: WebGPU: Fixed DAWN api change using WGPUStringView in WGPUShaderSourceWGSL. (#8009, #8010) [@blitz-research] diff --git a/imgui.cpp b/imgui.cpp index 059a7ec56..eae120fd7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3964,6 +3964,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) DisabledStackSize = 0; LockMarkEdited = 0; TooltipOverrideCount = 0; + TooltipPreviousWindow = NULL; PlatformImeData.InputPos = ImVec2(0.0f, 0.0f); PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f); // Different to ensure initial submission @@ -5152,6 +5153,7 @@ void ImGui::NewFrame() g.DragDropWithinSource = false; g.DragDropWithinTarget = false; g.DragDropHoldJustPressedId = 0; + g.TooltipPreviousWindow = NULL; // Close popups on focus lost (currently wip/opt-in) //if (g.IO.AppFocusLost) @@ -7549,6 +7551,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Clear hit test shape every frame window->HitTestHoleSize.x = window->HitTestHoleSize.y = 0; + if (flags & ImGuiWindowFlags_Tooltip) + g.TooltipPreviousWindow = window; + // Pressing CTRL+C while holding on a window copy its content to the clipboard // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. // Maybe we can support CTRL+C on every element? @@ -11504,7 +11509,8 @@ bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags ext { ImGuiContext& g = *GImGui; - if (g.DragDropWithinSource || g.DragDropWithinTarget) + const bool is_dragdrop_tooltip = g.DragDropWithinSource || g.DragDropWithinTarget; + if (is_dragdrop_tooltip) { // Drag and Drop tooltips are positioning differently than other tooltips: // - offset visibility to increase visibility around mouse. @@ -11520,16 +11526,16 @@ bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags ext tooltip_flags |= ImGuiTooltipFlags_OverridePrevious; } - char window_name[16]; - ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount); - if (tooltip_flags & ImGuiTooltipFlags_OverridePrevious) - if (ImGuiWindow* window = FindWindowByName(window_name)) - if (window->Active) - { - // Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one. - SetWindowHiddenAndSkipItemsForCurrentFrame(window); - ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); - } + const char* window_name_template = is_dragdrop_tooltip ? "##Tooltip_DragDrop_%02d" : "##Tooltip_%02d"; + char window_name[32]; + ImFormatString(window_name, IM_ARRAYSIZE(window_name), window_name_template, g.TooltipOverrideCount); + if ((tooltip_flags & ImGuiTooltipFlags_OverridePrevious) && g.TooltipPreviousWindow != NULL && g.TooltipPreviousWindow->Active) + { + // Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one. + //IMGUI_DEBUG_LOG("[tooltip] '%s' already active, using +1 for this frame\n", window_name); + SetWindowHiddenAndSkipItemsForCurrentFrame(g.TooltipPreviousWindow); + ImFormatString(window_name, IM_ARRAYSIZE(window_name), window_name_template, ++g.TooltipOverrideCount); + } ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize; Begin(window_name, NULL, flags | extra_window_flags); // 2023-03-09: Added bool return value to the API, but currently always returning true. diff --git a/imgui.h b/imgui.h index 59ea4baac..0eebcafb3 100644 --- a/imgui.h +++ b/imgui.h @@ -29,7 +29,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.91.3 WIP" -#define IMGUI_VERSION_NUM 19123 +#define IMGUI_VERSION_NUM 19124 #define IMGUI_HAS_TABLE /* diff --git a/imgui_internal.h b/imgui_internal.h index 113b05426..044ff18c2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2283,6 +2283,7 @@ struct ImGuiContext short DisabledStackSize; short LockMarkEdited; short TooltipOverrideCount; + ImGuiWindow* TooltipPreviousWindow; // Window of last tooltip submitted during the frame ImVector ClipboardHandlerData; // If no custom clipboard handler is defined ImVector MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once ImGuiTypingSelectState TypingSelectState; // State for GetTypingSelectRequest()