|
@@ -1147,7 +1147,9 @@ static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduc
|
|
|
static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved.
|
|
|
|
|
|
// Tooltip offset
|
|
|
-static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10); // Multiplied by g.Style.MouseCursorScale
|
|
|
+static const ImVec2 TOOLTIP_DEFAULT_OFFSET_MOUSE = ImVec2(16, 10); // Multiplied by g.Style.MouseCursorScale
|
|
|
+static const ImVec2 TOOLTIP_DEFAULT_OFFSET_TOUCH = ImVec2(0, -20); // Multiplied by g.Style.MouseCursorScale
|
|
|
+static const ImVec2 TOOLTIP_DEFAULT_PIVOT_TOUCH = ImVec2(0.5f, 1.0f); // Multiplied by g.Style.MouseCursorScale
|
|
|
|
|
|
// Docking
|
|
|
static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f; // For use with io.ConfigDockingTransparentPayload. Apply to Viewport _or_ WindowBg in host viewport.
|
|
@@ -4042,6 +4044,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
|
|
@@ -5334,6 +5337,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)
|
|
@@ -5767,7 +5771,7 @@ void ImGui::EndFrame()
|
|
|
// in the BeginDragDropSource() block of the dragged item, you can submit them from a safe single spot
|
|
|
// (e.g. end of your item loop, or before EndFrame) by reading payload data.
|
|
|
// In the typical case, the contents of drag tooltip should be possible to infer solely from payload data.
|
|
|
- if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
|
|
|
+ if (g.DragDropActive && g.DragDropSourceFrameCount + 1 < g.FrameCount && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
|
|
|
{
|
|
|
g.DragDropWithinSource = true;
|
|
|
SetTooltip("...");
|
|
@@ -8061,6 +8065,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?
|
|
@@ -11192,7 +11199,7 @@ void ImGui::ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryStat
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
- while (g.CurrentTable != NULL && g.CurrentTable->InnerWindow == g.CurrentWindow)
|
|
|
+ while (g.CurrentTable != NULL && g.CurrentTable->InnerWindow == g.CurrentWindow) //-V1044
|
|
|
{
|
|
|
IM_ASSERT_USER_ERROR(0, "Missing EndTable()");
|
|
|
EndTable();
|
|
@@ -11206,7 +11213,7 @@ void ImGui::ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryStat
|
|
|
IM_ASSERT_USER_ERROR(0, "Missing EndTabBar()");
|
|
|
EndTabBar();
|
|
|
}
|
|
|
- while (g.CurrentMultiSelect != NULL && g.CurrentMultiSelect->Storage->Window == window)
|
|
|
+ while (g.CurrentMultiSelect != NULL && g.CurrentMultiSelect->Storage->Window == window) //-V1044
|
|
|
{
|
|
|
IM_ASSERT_USER_ERROR(0, "Missing EndMultiSelect()");
|
|
|
EndMultiSelect();
|
|
@@ -11239,7 +11246,7 @@ void ImGui::ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryStat
|
|
|
}
|
|
|
}
|
|
|
IM_ASSERT(g.DisabledStackSize == state_in->SizeOfDisabledStack);
|
|
|
- while (g.ColorStack.Size > state_in->SizeOfColorStack)
|
|
|
+ while (g.ColorStack.Size > state_in->SizeOfColorStack) //-V1044
|
|
|
{
|
|
|
IM_ASSERT_USER_ERROR(0, "Missing PopStyleColor()");
|
|
|
PopStyleColor();
|
|
@@ -12181,7 +12188,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.
|
|
@@ -12189,24 +12197,30 @@ bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags ext
|
|
|
// We call SetNextWindowPos() to enforce position and disable clamping.
|
|
|
// See FindBestWindowPosForPopup() for positionning logic of other tooltips (not drag and drop ones).
|
|
|
//ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding;
|
|
|
- ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET * g.Style.MouseCursorScale;
|
|
|
+ const bool is_touchscreen = (g.IO.MouseSource == ImGuiMouseSource_TouchScreen);
|
|
|
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0)
|
|
|
- SetNextWindowPos(tooltip_pos);
|
|
|
+ {
|
|
|
+ ImVec2 tooltip_pos = is_touchscreen ? (g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_TOUCH * g.Style.MouseCursorScale) : (g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_MOUSE * g.Style.MouseCursorScale);
|
|
|
+ ImVec2 tooltip_pivot = is_touchscreen ? TOOLTIP_DEFAULT_PIVOT_TOUCH : ImVec2(0.0f, 0.0f);
|
|
|
+ SetNextWindowPos(tooltip_pos, ImGuiCond_None, tooltip_pivot);
|
|
|
+ }
|
|
|
+
|
|
|
SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f);
|
|
|
//PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :(
|
|
|
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 | ImGuiWindowFlags_NoDocking;
|
|
|
Begin(window_name, NULL, flags | extra_window_flags);
|
|
|
// 2023-03-09: Added bool return value to the API, but currently always returning true.
|
|
@@ -12808,18 +12822,30 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
|
|
if (window->Flags & ImGuiWindowFlags_Tooltip)
|
|
|
{
|
|
|
// Position tooltip (always follows mouse + clamp within outer boundaries)
|
|
|
- // Note that drag and drop tooltips are NOT using this path: BeginTooltipEx() manually sets their position.
|
|
|
- // In theory we could handle both cases in same location, but requires a bit of shuffling as drag and drop tooltips are calling SetWindowPos() leading to 'window_pos_set_by_api' being set in Begin()
|
|
|
+ // FIXME:
|
|
|
+ // - Too many paths. One problem is that FindBestWindowPosForPopupEx() doesn't allow passing a suggested position (so touch screen path doesn't use it by default).
|
|
|
+ // - Drag and drop tooltips are not using this path either: BeginTooltipEx() manually sets their position.
|
|
|
+ // - Require some tidying up. In theory we could handle both cases in same location, but requires a bit of shuffling
|
|
|
+ // as drag and drop tooltips are calling SetNextWindowPos() leading to 'window_pos_set_by_api' being set in Begin().
|
|
|
IM_ASSERT(g.CurrentWindow == window);
|
|
|
const float scale = g.Style.MouseCursorScale;
|
|
|
const ImVec2 ref_pos = NavCalcPreferredRefPos();
|
|
|
- const ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET * scale;
|
|
|
+
|
|
|
+ if (g.IO.MouseSource == ImGuiMouseSource_TouchScreen)
|
|
|
+ {
|
|
|
+ ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_TOUCH * scale - (TOOLTIP_DEFAULT_PIVOT_TOUCH * window->Size);
|
|
|
+ if (r_outer.Contains(ImRect(tooltip_pos, tooltip_pos + window->Size)))
|
|
|
+ return tooltip_pos;
|
|
|
+ }
|
|
|
+
|
|
|
+ ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_MOUSE * scale;
|
|
|
ImRect r_avoid;
|
|
|
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
|
|
|
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
|
|
|
else
|
|
|
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * scale, ref_pos.y + 24 * scale); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
|
|
|
//GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255, 0, 255, 255));
|
|
|
+
|
|
|
return FindBestWindowPosForPopupEx(tooltip_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip);
|
|
|
}
|
|
|
IM_ASSERT(0);
|
|
@@ -20896,7 +20922,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
DebugBreakClearData();
|
|
|
|
|
|
// Basic info
|
|
|
- Text("Dear ImGui %s", GetVersion());
|
|
|
+ Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM);
|
|
|
if (g.ContextName[0] != 0)
|
|
|
{
|
|
|
SameLine();
|