View Single Post
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