Thread Tools Display Modes
11-28-20, 01:18 PM   #1
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
How to clamp tooltip to the screen?

How can I setup the tooltip to clamp to the screen?
It occurs to me that after some time playing the tooltips are starting to leave the screen.
I have already spent weeks (im not kidding) trying to find the problem but I cant find
the source and I also cant find a solution or a workaround.

Do you guys have an idea? Most of you are much more experienced than I am.
  Reply With Quote
11-28-20, 01:29 PM   #2
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Which tooltip? The regular GameTooltip? Are you using any addons that affect it? The default tooltips are clamped to the screen already.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
11-28-20, 08:51 PM   #3
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
Hi,

yes, the Gametooltip. And yes Im doing stuff with the Gametooltip. For example:

- I have a scan tooltip to get quest informations

Lua Code:
  1. LybrialUI.ScanTooltip = CreateFrame("GameTooltip", LybrialUI.ADDON_NAME .. "_ScanTooltip", _G.UIParent, "GameTooltipTemplate");
  2.  
  3. local questTypesLocalized = {
  4.     ["deDE"] = {
  5.         ["besiegen"] = "KILL",
  6.         ["besiegt"] = "KILL",
  7.         ["getötet"] = "KILL",
  8.         ["töten"] = "KILL",
  9.         ["tötet"] = "KILL",
  10.         ["zerstört"] = "KILL",
  11.         ["vernichtet"] = "KILL",
  12.         ["genährt"] = "KILL",
  13.         ["befragt"] = "CHAT",
  14.         ["sprecht"] = "CHAT",
  15.     },
  16.     ["enUS"] = {
  17.         ["slain"] = "KILL",
  18.         ["destroy"] = "KILL",
  19.         ["eleminate"] = "KILL",
  20.         ["repel"] = "KILL",
  21.         ["kill"] = "KILL",
  22.         ["defeat"] = "KILL",
  23.         ["speak"] = "CHAT",
  24.         ["ask"] = "CHAT",
  25.         ["talk"] = "CHAT",
  26.     },
  27. };
  28. local questTypes = questTypesLocalized[GetLocale()] or questTypesLocalized.enUS;
  29.  
  30. local function checkTooltipTextForQuestRequirements(text)
  31.     local x, y = STRINGS:Match(text, "(%d+)/(%d+)");
  32.  
  33.     if (x and y) then
  34.         return MATH:Floor(y - x), false;
  35.     elseif (not STRINGS:Match(text, ThreatTooltip)) then
  36.         local progress = tonumber(STRINGS:Match(text, "([%d%.]+)%%"));
  37.  
  38.         if (progress and (progress <= 100)) then
  39.             return MATH:Ceil(100 - progress), true;
  40.         end
  41.     end
  42. end
  43.  
  44. function TOOLTIP:GetQuestRequirements(unitID, activeQuests)
  45.     LybrialUI.ScanTooltip:SetOwner(_G.UIParent);
  46.     LybrialUI.ScanTooltip:SetUnit(unitID);
  47.     LybrialUI.ScanTooltip:Show();
  48.  
  49.     local questRequirements = {};
  50.     local isPlayersQuest = true;
  51.  
  52.     for i = 3, LybrialUI.ScanTooltip:NumLines() do
  53.         local textLeft = _G[LybrialUI.ADDON_NAME .. "_ScanTooltipTextLeft" .. i];
  54.         local text = (textLeft and textLeft:GetText());
  55.  
  56.         if (text and (text ~= "")) then
  57.             if (UnitIsPlayer(text)) then
  58.                 isPlayersQuest = (text == PLAYER.info.name);
  59.             elseif (text and isPlayersQuest) then
  60.                 local objectiveCount, isPercent = checkTooltipTextForQuestRequirements(text);
  61.  
  62.                 if (objectiveCount) then
  63.                     local activeID = activeQuests[text];
  64.                     local _, itemTexture = (activeID and GetQuestLogSpecialItemInfo(GetQuestLogIndexByID(activeID)));
  65.                     local questType;
  66.  
  67.                     if (itemTexture) then
  68.                         questType = "ITEM";
  69.                     elseif (isPercent) then
  70.                         questType = "PROGRESS";
  71.                     else
  72.                         for typeString in pairs(questTypes) do
  73.                             if (STRINGS:Find(STRINGS:Lower(text), typeString, nil, true)) then
  74.                                 questType = questTypes[typeString];
  75.                                 break ;
  76.                             end
  77.                         end
  78.                     end
  79.  
  80.                     TABLES:Add(questRequirements, {
  81.                         text = text,
  82.                         objectiveCount = objectiveCount,
  83.                         isPercent = isPercent,
  84.                         activeID = activeID,
  85.                         itemTexture = itemTexture,
  86.                         questType = questType or "LOOT",
  87.                     });
  88.                 end
  89.             end
  90.         end
  91.     end
  92.  
  93.     LybrialUI.ScanTooltip:Hide();
  94.  
  95.     return questRequirements;
  96. end

- I have tooltips for data texts which are doing this:

Lua Code:
  1. l--- Adds a tooltip object to the given frame and clears all lines.
  2. --- @param frame table The actual frame to set the tooltip for.
  3. local function InitializeTooltip(frame)
  4.     if (frame) then
  5.         if (not frame.tooltip) then
  6.             frame.tooltip = _G.GameTooltip;
  7.         end
  8.  
  9.         frame.tooltip:ClearLines();
  10.     end
  11. end
  12.  
  13. --- Sets the best position for the frames tooltip by measuring the position of the center of the frame on the Screen.
  14. --- @param frame table The actual frame to set the best tooltip position for.
  15. local function SetBestTooltipPosition(frame)
  16.     if (frame and frame.tooltip) then
  17.         frame.tooltip:SetOwner(frame, "ANCHOR_" .. FRAMES:FindOppositeAnchor(FRAMES:FindBestAnchor(frame)));
  18.     end
  19. end
  20.  
  21. --- Returns the opposite anchor of a given anchor.
  22. --- @param anchor string The anchor to get the opposite anchor for.
  23. function FRAMES:FindOppositeAnchor(anchor)
  24.     if (anchor) then
  25.         if (anchor == "BOTTOM") then
  26.             return "TOP";
  27.         elseif (anchor == "BOTTOMLEFT") then
  28.             return "TOPRIGHT";
  29.         elseif (anchor == "BOTTOMRIGHT") then
  30.             return "TOPLEFT";
  31.         elseif (anchor == "LEFT") then
  32.             return "RIGHT";
  33.         elseif (anchor == "RIGHT") then
  34.             return "LEFT";
  35.         elseif (anchor == "TOP") then
  36.             return "BOTTOM";
  37.         elseif (anchor == "TOPLEFT") then
  38.             return "BOTTOMRIGHT";
  39.         elseif (anchor == "TOPRIGHT") then
  40.             return "BOTTOMLEFT";
  41.         else
  42.             return "CENTER";
  43.         end
  44.     end
  45. end
  46.  
  47. --- Returns the best anchor for the frame by measuring the position of the center of the frame on the Screen.
  48. --- @param frame table The actual frame to set get the best anchor for.
  49. function FRAMES:FindBestAnchor(frame)
  50.     if (frame) then
  51.         local width = self.UIParent:GetWidth();
  52.         local height = self.UIParent:GetHeight();
  53.  
  54.         local horizontalCenter = (width / 2);
  55.         local horizontalRange = ((width - horizontalCenter) / 2);
  56.  
  57.         local verticalCenter = (height / 2);
  58.         local verticalRange = ((height - verticalCenter) / 2);
  59.  
  60.         local centerX, centerY = frame:GetCenter();
  61.         local anchor = "CURSOR";
  62.  
  63.         centerX = centerX or 0;
  64.         centerY = centerY or 0;
  65.  
  66.         if ((centerX < horizontalRange) and (centerY < verticalRange)) then
  67.             anchor = "BOTTOMLEFT";
  68.         elseif (((centerX >= horizontalRange) and (centerX <= (width - horizontalRange))) and (centerY < verticalRange)) then
  69.             anchor = "BOTTOM";
  70.         elseif ((centerX > (width - horizontalRange)) and (centerY < verticalRange)) then
  71.             anchor = "BOTTOMRIGHT";
  72.         elseif ((centerX < horizontalRange) and ((centerY >= verticalRange) and (centerY <= (height - verticalRange)))) then
  73.             anchor = "LEFT";
  74.         elseif (((centerX >= horizontalRange) and (centerX <= (width - horizontalRange))) and ((centerY >= verticalRange) and centerY <= (height - verticalRange))) then
  75.             anchor = "CENTER";
  76.         elseif ((centerX > (width - horizontalRange)) and ((centerY >= verticalRange) and (centerY <= (height - verticalRange)))) then
  77.             anchor = "RIGHT";
  78.         elseif ((centerX < horizontalRange) and (centerY > (height - verticalRange))) then
  79.             anchor = "TOPLEFT";
  80.         elseif (((centerX >= horizontalRange) and (centerX <= (width - horizontalRange))) and (centerY > (height - verticalRange))) then
  81.             anchor = "TOP";
  82.         elseif ((centerX > (width - horizontalRange)) and (centerY > (height - verticalRange))) then
  83.             anchor = "TOPRIGHT";
  84.         end
  85.  
  86.         return anchor;
  87.     end
  88. end
  89.  
  90. function Durability:ShowTooltip()
  91.     local yr, yg, yb = CORE.VALUES.Color.Accent.r, CORE.VALUES.Color.Accent.g, CORE.VALUES.Color.Accent.b;
  92.     local wr, wg, wb = CORE.VALUES.Color.Default.r, CORE.VALUES.Color.Default.g, CORE.VALUES.Color.Default.b;
  93.  
  94.     Durability.frame:InitializeTooltip();
  95.     Durability.frame:SetBestTooltipPosition();
  96.     Durability.frame.tooltip:AddLine(DURABILITY, yr, yg, yb);
  97.     Durability.frame.tooltip:AddLine(" ");
  98.  
  99.     for _, v in ipairs(CORE.VALUES.Character.Durability) do
  100.         if (v.max > 0) then
  101.             local percentage = MATH:Floor((v.current / v.max) * 100);
  102.  
  103.             wr, wg, wb = COLORS:Unpack(Colors:GetColorForDurability(percentage))
  104.  
  105.             Durability.frame.tooltip:AddDoubleLine(v.text, string.format("%d/%d (%d%%)", v.current, v.max, percentage), yr, yg, yb, wr, wg, wb);
  106.         end
  107.     end
  108.  
  109.     Durability.frame.tooltip:AddLine(" ");
  110.     Durability.frame.tooltip:AddDoubleLine(LOCALE["MOUSE_BUTTON_LEFT"], CHARACTER_INFO, yr, yg, yb, wr, wg, wb);
  111.     Durability.frame.tooltip:Show();
  112. end

And that is already it. That is basically everything I do.
I wanted to track it down by disabling everything related to tooltips but the behavior still
occurred. And it is always the same: At first everything works fine but after a variable amount
of time (1 to 20 minutes) the tooltip starts to leave the screen.

Im also use Ace3 and oUF which both are doing minor stuff with tooltips but thousands of
people are using them and I havent found topics regarding bugs like that in those libs so
im guessing its not them.

I do not even have an idea what could make tooltips leave the screen because I cant
find API functions to manipulate that behavior....

Last edited by Lybrial : 11-28-20 at 08:54 PM.
  Reply With Quote
11-29-20, 01:56 AM   #4
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
Update:

Even though im not using the addons "NameplateAuras" or "TinyTooltip" I found one person who described the exact same problem that I have: https://github.com/casualshammy/Name...uras/issues/39
Unfortunately in that github issue there is no solution.
  Reply With Quote
01-01-21, 11:59 PM   #5
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
I finally found out what is causing it. It is oUF Aura Tooltips.
I created a nameplate addon using oUF and I configured the auras to have enabled mouse events:

Lua Code:
  1. auras.disableMouse = false

So what's happening now is the following:

1. Tooltips are not leaving screen:



2. I hover an aura on a nameplate to check the aura tooltip



3. Tooltips are now leaving screen:



After a UI Reload this is fixed again.

Does somebody else have this problem with oUF Auras and knows how to fix it?

Last edited by Lybrial : 01-02-21 at 12:27 AM.
  Reply With Quote
01-04-21, 08:30 AM   #6
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
Solved: https://github.com/oUF-wow/oUF/issues/570
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » How to clamp tooltip to the screen?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off