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:
LybrialUI.ScanTooltip = CreateFrame("GameTooltip", LybrialUI.ADDON_NAME .. "_ScanTooltip", _G.UIParent, "GameTooltipTemplate");
local questTypesLocalized = {
["deDE"] = {
["besiegen"] = "KILL",
["besiegt"] = "KILL",
["getötet"] = "KILL",
["töten"] = "KILL",
["tötet"] = "KILL",
["zerstört"] = "KILL",
["vernichtet"] = "KILL",
["genährt"] = "KILL",
["befragt"] = "CHAT",
["sprecht"] = "CHAT",
},
["enUS"] = {
["slain"] = "KILL",
["destroy"] = "KILL",
["eleminate"] = "KILL",
["repel"] = "KILL",
["kill"] = "KILL",
["defeat"] = "KILL",
["speak"] = "CHAT",
["ask"] = "CHAT",
["talk"] = "CHAT",
},
};
local questTypes = questTypesLocalized[GetLocale()] or questTypesLocalized.enUS;
local function checkTooltipTextForQuestRequirements(text)
local x, y = STRINGS:Match(text, "(%d+)/(%d+)");
if (x and y) then
return MATH:Floor(y - x), false;
elseif (not STRINGS:Match(text, ThreatTooltip)) then
local progress = tonumber(STRINGS:Match(text, "([%d%.]+)%%"));
if (progress and (progress <= 100)) then
return MATH:Ceil(100 - progress), true;
end
end
end
function TOOLTIP:GetQuestRequirements(unitID, activeQuests)
LybrialUI.ScanTooltip:SetOwner(_G.UIParent);
LybrialUI.ScanTooltip:SetUnit(unitID);
LybrialUI.ScanTooltip:Show();
local questRequirements = {};
local isPlayersQuest = true;
for i = 3, LybrialUI.ScanTooltip:NumLines() do
local textLeft = _G[LybrialUI.ADDON_NAME .. "_ScanTooltipTextLeft" .. i];
local text = (textLeft and textLeft:GetText());
if (text and (text ~= "")) then
if (UnitIsPlayer(text)) then
isPlayersQuest = (text == PLAYER.info.name);
elseif (text and isPlayersQuest) then
local objectiveCount, isPercent = checkTooltipTextForQuestRequirements(text);
if (objectiveCount) then
local activeID = activeQuests[text];
local _, itemTexture = (activeID and GetQuestLogSpecialItemInfo(GetQuestLogIndexByID(activeID)));
local questType;
if (itemTexture) then
questType = "ITEM";
elseif (isPercent) then
questType = "PROGRESS";
else
for typeString in pairs(questTypes) do
if (STRINGS:Find(STRINGS:Lower(text), typeString, nil, true)) then
questType = questTypes[typeString];
break ;
end
end
end
TABLES:Add(questRequirements, {
text = text,
objectiveCount = objectiveCount,
isPercent = isPercent,
activeID = activeID,
itemTexture = itemTexture,
questType = questType or "LOOT",
});
end
end
end
end
LybrialUI.ScanTooltip:Hide();
return questRequirements;
end
- I have tooltips for data texts which are doing this:
Lua Code:
l--- Adds a tooltip object to the given frame and clears all lines.
--- @param frame table The actual frame to set the tooltip for.
local function InitializeTooltip(frame)
if (frame) then
if (not frame.tooltip) then
frame.tooltip = _G.GameTooltip;
end
frame.tooltip:ClearLines();
end
end
--- Sets the best position for the frames tooltip by measuring the position of the center of the frame on the Screen.
--- @param frame table The actual frame to set the best tooltip position for.
local function SetBestTooltipPosition(frame)
if (frame and frame.tooltip) then
frame.tooltip:SetOwner(frame, "ANCHOR_" .. FRAMES:FindOppositeAnchor(FRAMES:FindBestAnchor(frame)));
end
end
--- Returns the opposite anchor of a given anchor.
--- @param anchor string The anchor to get the opposite anchor for.
function FRAMES:FindOppositeAnchor(anchor)
if (anchor) then
if (anchor == "BOTTOM") then
return "TOP";
elseif (anchor == "BOTTOMLEFT") then
return "TOPRIGHT";
elseif (anchor == "BOTTOMRIGHT") then
return "TOPLEFT";
elseif (anchor == "LEFT") then
return "RIGHT";
elseif (anchor == "RIGHT") then
return "LEFT";
elseif (anchor == "TOP") then
return "BOTTOM";
elseif (anchor == "TOPLEFT") then
return "BOTTOMRIGHT";
elseif (anchor == "TOPRIGHT") then
return "BOTTOMLEFT";
else
return "CENTER";
end
end
end
--- Returns the best anchor for the frame by measuring the position of the center of the frame on the Screen.
--- @param frame table The actual frame to set get the best anchor for.
function FRAMES:FindBestAnchor(frame)
if (frame) then
local width = self.UIParent:GetWidth();
local height = self.UIParent:GetHeight();
local horizontalCenter = (width / 2);
local horizontalRange = ((width - horizontalCenter) / 2);
local verticalCenter = (height / 2);
local verticalRange = ((height - verticalCenter) / 2);
local centerX, centerY = frame:GetCenter();
local anchor = "CURSOR";
centerX = centerX or 0;
centerY = centerY or 0;
if ((centerX < horizontalRange) and (centerY < verticalRange)) then
anchor = "BOTTOMLEFT";
elseif (((centerX >= horizontalRange) and (centerX <= (width - horizontalRange))) and (centerY < verticalRange)) then
anchor = "BOTTOM";
elseif ((centerX > (width - horizontalRange)) and (centerY < verticalRange)) then
anchor = "BOTTOMRIGHT";
elseif ((centerX < horizontalRange) and ((centerY >= verticalRange) and (centerY <= (height - verticalRange)))) then
anchor = "LEFT";
elseif (((centerX >= horizontalRange) and (centerX <= (width - horizontalRange))) and ((centerY >= verticalRange) and centerY <= (height - verticalRange))) then
anchor = "CENTER";
elseif ((centerX > (width - horizontalRange)) and ((centerY >= verticalRange) and (centerY <= (height - verticalRange)))) then
anchor = "RIGHT";
elseif ((centerX < horizontalRange) and (centerY > (height - verticalRange))) then
anchor = "TOPLEFT";
elseif (((centerX >= horizontalRange) and (centerX <= (width - horizontalRange))) and (centerY > (height - verticalRange))) then
anchor = "TOP";
elseif ((centerX > (width - horizontalRange)) and (centerY > (height - verticalRange))) then
anchor = "TOPRIGHT";
end
return anchor;
end
end
function Durability:ShowTooltip()
local yr, yg, yb = CORE.VALUES.Color.Accent.r, CORE.VALUES.Color.Accent.g, CORE.VALUES.Color.Accent.b;
local wr, wg, wb = CORE.VALUES.Color.Default.r, CORE.VALUES.Color.Default.g, CORE.VALUES.Color.Default.b;
Durability.frame:InitializeTooltip();
Durability.frame:SetBestTooltipPosition();
Durability.frame.tooltip:AddLine(DURABILITY, yr, yg, yb);
Durability.frame.tooltip:AddLine(" ");
for _, v in ipairs(CORE.VALUES.Character.Durability) do
if (v.max > 0) then
local percentage = MATH:Floor((v.current / v.max) * 100);
wr, wg, wb = COLORS:Unpack(Colors:GetColorForDurability(percentage))
Durability.frame.tooltip:AddDoubleLine(v.text, string.format("%d/%d (%d%%)", v.current, v.max, percentage), yr, yg, yb, wr, wg, wb);
end
end
Durability.frame.tooltip:AddLine(" ");
Durability.frame.tooltip:AddDoubleLine(LOCALE["MOUSE_BUTTON_LEFT"], CHARACTER_INFO, yr, yg, yb, wr, wg, wb);
Durability.frame.tooltip:Show();
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....