Skip to content

Commit 5109a77

Browse files
committed
Tooltips: Tooltips triggered from touch inputs are positionned above the item. (#8036)
1 parent 014b722 commit 5109a77

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

docs/CHANGELOG.txt

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Other changes:
7676
- Tooltips, Drag and Drop: Stabilized name of drag and drop tooltip window so that
7777
transitioning from an item tooltip to a drag tooltip doesn't leak window auto-sizing
7878
info from one to the other. (#8036)
79+
- Tooltips: Tooltips triggered from touch inputs are positionned above the item. (#8036)
7980
- Backends: SDL3: Update for API changes: SDL_bool removal. SDL_INIT_TIMER removal.
8081
- Backends: WebGPU: Fixed DAWN api change using WGPUStringView in WGPUShaderSourceWGSL.
8182
(#8009, #8010) [@blitz-research]

imgui.cpp

+25-6
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,9 @@ static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduc
11361136
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.
11371137

11381138
// Tooltip offset
1139-
static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10); // Multiplied by g.Style.MouseCursorScale
1139+
static const ImVec2 TOOLTIP_DEFAULT_OFFSET_MOUSE = ImVec2(16, 10); // Multiplied by g.Style.MouseCursorScale
1140+
static const ImVec2 TOOLTIP_DEFAULT_OFFSET_TOUCH = ImVec2(0, -20); // Multiplied by g.Style.MouseCursorScale
1141+
static const ImVec2 TOOLTIP_DEFAULT_PIVOT_TOUCH = ImVec2(0.5f, 1.0f); // Multiplied by g.Style.MouseCursorScale
11401142

11411143
//-------------------------------------------------------------------------
11421144
// [SECTION] FORWARD DECLARATIONS
@@ -11518,9 +11520,14 @@ bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags ext
1151811520
// We call SetNextWindowPos() to enforce position and disable clamping.
1151911521
// See FindBestWindowPosForPopup() for positionning logic of other tooltips (not drag and drop ones).
1152011522
//ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding;
11521-
ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET * g.Style.MouseCursorScale;
11523+
const bool is_touchscreen = (g.IO.MouseSource == ImGuiMouseSource_TouchScreen);
1152211524
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0)
11523-
SetNextWindowPos(tooltip_pos);
11525+
{
11526+
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);
11527+
ImVec2 tooltip_pivot = is_touchscreen ? TOOLTIP_DEFAULT_PIVOT_TOUCH : ImVec2(0.0f, 0.0f);
11528+
SetNextWindowPos(tooltip_pos, ImGuiCond_None, tooltip_pivot);
11529+
}
11530+
1152411531
SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f);
1152511532
//PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :(
1152611533
tooltip_flags |= ImGuiTooltipFlags_OverridePrevious;
@@ -12126,18 +12133,30 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
1212612133
if (window->Flags & ImGuiWindowFlags_Tooltip)
1212712134
{
1212812135
// Position tooltip (always follows mouse + clamp within outer boundaries)
12129-
// Note that drag and drop tooltips are NOT using this path: BeginTooltipEx() manually sets their position.
12130-
// 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()
12136+
// FIXME:
12137+
// - 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).
12138+
// - Drag and drop tooltips are not using this path either: BeginTooltipEx() manually sets their position.
12139+
// - Require some tidying up. In theory we could handle both cases in same location, but requires a bit of shuffling
12140+
// as drag and drop tooltips are calling SetNextWindowPos() leading to 'window_pos_set_by_api' being set in Begin().
1213112141
IM_ASSERT(g.CurrentWindow == window);
1213212142
const float scale = g.Style.MouseCursorScale;
1213312143
const ImVec2 ref_pos = NavCalcPreferredRefPos();
12134-
const ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET * scale;
12144+
12145+
if (g.IO.MouseSource == ImGuiMouseSource_TouchScreen)
12146+
{
12147+
ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_TOUCH * scale - (TOOLTIP_DEFAULT_PIVOT_TOUCH * window->Size);
12148+
if (r_outer.Contains(ImRect(tooltip_pos, tooltip_pos + window->Size)))
12149+
return tooltip_pos;
12150+
}
12151+
12152+
ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_MOUSE * scale;
1213512153
ImRect r_avoid;
1213612154
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
1213712155
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
1213812156
else
1213912157
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.
1214012158
//GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255, 0, 255, 255));
12159+
1214112160
return FindBestWindowPosForPopupEx(tooltip_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip);
1214212161
}
1214312162
IM_ASSERT(0);

0 commit comments

Comments
 (0)