You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
8.8 KiB
227 lines
8.8 KiB
|
2 years ago
|
local _,rematch = ...
|
||
|
|
local L = rematch.localization
|
||
|
|
local C = rematch.constants
|
||
|
|
local settings = rematch.settings
|
||
|
|
rematch.tooltip = {} -- note this isn't RematchTooltip
|
||
|
|
local tooltip -- but this will be after PLAYER_LOGIN
|
||
|
|
|
||
|
|
-- forgive the NIH syndrome, but recreating a GameTooltip in-house rather than using the templates
|
||
|
|
|
||
|
|
local currentLine = 0 -- the line number added to the tooltip (increments to 1 for first line)
|
||
|
|
local isAnchored = false -- true when a SetPoint is used (if false when showing, will choose an anchor)
|
||
|
|
|
||
|
|
rematch.events:Register(rematch.tooltip,"PLAYER_LOGIN",function(self)
|
||
|
|
tooltip = RematchTooltip
|
||
|
|
rematch.tooltipManager:AddBehavior(tooltip) -- makes tooltips delayed based on settings.TooltipBehavior
|
||
|
|
end)
|
||
|
|
|
||
|
|
-- call this to start a tooltip; make noTitle true if there's no title text that's slightly larger than the rest
|
||
|
|
function rematch.tooltip:SetOwner(parent,noTitle)
|
||
|
|
-- not doing a SetParent since clipped content like scrollframes need the tooltip to appear outside it
|
||
|
|
tooltip.parent = parent
|
||
|
|
-- hide any previous lines shown
|
||
|
|
for _,line in ipairs(tooltip.Lines) do
|
||
|
|
line:Hide()
|
||
|
|
end
|
||
|
|
if noTitle then -- if noTitle, then the first line has the same style/color text as the body
|
||
|
|
tooltip.Lines[1]:SetFontObject("GameFontNormal")
|
||
|
|
tooltip.Lines[1]:SetTextColor(1,0.82,0)
|
||
|
|
else -- otherwise, first line has a slightly larger font colored white
|
||
|
|
tooltip.Lines[1]:SetFontObject("GameTooltipHeaderText")
|
||
|
|
tooltip.Lines[1]:SetTextColor(1,1,1)
|
||
|
|
end
|
||
|
|
currentLine = 0
|
||
|
|
isAnchored = false
|
||
|
|
end
|
||
|
|
|
||
|
|
function rematch.tooltip:GetOwner()
|
||
|
|
return tooltip.parent
|
||
|
|
end
|
||
|
|
|
||
|
|
-- returns the number of lines in the tooltip
|
||
|
|
function rematch.tooltip:GetNumLines()
|
||
|
|
return currentLine
|
||
|
|
end
|
||
|
|
|
||
|
|
-- adds a line of text
|
||
|
|
function rematch.tooltip:AddLine(text,r,g,b)
|
||
|
|
if not text then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
currentLine = currentLine + 1
|
||
|
|
if not tooltip.Lines[currentLine] then
|
||
|
|
tooltip.Lines[currentLine] = tooltip:CreateFontString(nil,"ARTWORK","GameFontNormal")
|
||
|
|
tooltip.Lines[currentLine]:SetPoint("TOPLEFT",tooltip.Lines[currentLine-1],"BOTTOMLEFT",0,-C.TOOLTIP_LINE_SPACING)
|
||
|
|
tooltip.Lines[currentLine]:SetJustifyH("LEFT")
|
||
|
|
end
|
||
|
|
local line = tooltip.Lines[currentLine]
|
||
|
|
if r and g and b then
|
||
|
|
line:SetTextColor(r,g,b)
|
||
|
|
elseif currentLine>1 then
|
||
|
|
line:SetTextColor(1,0.82,0)
|
||
|
|
end
|
||
|
|
line:SetText(text)
|
||
|
|
line:Show()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- replacement for SetPoint
|
||
|
|
function rematch.tooltip:SetPoint(anchorPoint,relativeTo,relativePoint,xoff,yoff)
|
||
|
|
tooltip:ClearAllPoints() -- this means a tooltip can only have one anchor!
|
||
|
|
tooltip:SetPoint(anchorPoint,relativeTo,relativePoint,xoff,yoff)
|
||
|
|
isAnchored = true
|
||
|
|
end
|
||
|
|
|
||
|
|
-- before showing the tooltip, go through and adjust for wrapping lines and resize lines/tooltip based on the tooltip content
|
||
|
|
function rematch.tooltip:Show()
|
||
|
|
-- determine the width (first pass), between the maximum of all lines' widths to at most C.TOOLTIP_MAX_WIDTH
|
||
|
|
local width = 0
|
||
|
|
for i=1,currentLine do
|
||
|
|
width = min(max(tooltip.Lines[i]:GetUnboundedStringWidth(),width),C.TOOLTIP_MAX_WIDTH)
|
||
|
|
end
|
||
|
|
-- set all lines to that width (first pass) to get them to wrap if any wrap
|
||
|
|
for i=1,currentLine do
|
||
|
|
tooltip.Lines[i]:SetWidth(width)
|
||
|
|
end
|
||
|
|
-- second pass to to get maximum wrapped width (to trim the excess whitespace to the right of unfortunate spacing)
|
||
|
|
width = 0
|
||
|
|
for i=1,currentLine do
|
||
|
|
width = max(tooltip.Lines[i]:GetWrappedWidth(),width)
|
||
|
|
end
|
||
|
|
-- set final widths and total up height while we're at it
|
||
|
|
local height = C.TOOLTIP_PADDING*2-2 + (currentLine-1)*C.TOOLTIP_LINE_SPACING
|
||
|
|
for i=1,currentLine do
|
||
|
|
tooltip.Lines[i]:SetWidth(width)
|
||
|
|
height = height + tooltip.Lines[i]:GetStringHeight()
|
||
|
|
end
|
||
|
|
tooltip:SetSize(width+C.TOOLTIP_PADDING*2,height)
|
||
|
|
tooltip:Show()
|
||
|
|
end
|
||
|
|
|
||
|
|
function rematch.tooltip:Hide()
|
||
|
|
tooltip:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- using a custom GameTooltip to use as a tooltip source for stuff we can't easily build
|
||
|
|
function rematch.tooltip:GetSourceTooltip()
|
||
|
|
local source = RematchGameTooltip
|
||
|
|
source:SetOwner(UIParent,"ANCHOR_NONE")
|
||
|
|
return source
|
||
|
|
end
|
||
|
|
|
||
|
|
-- mimics the GameTooltip:SetSpellID(spellID), except that it has no right columns. For now only Revive Battle Pets is
|
||
|
|
-- using this, so it just uses the right text if it exists first
|
||
|
|
function rematch.tooltip:SetSpellByID(spellID)
|
||
|
|
local source = rematch.tooltip:GetSourceTooltip()
|
||
|
|
source:SetSpellByID(spellID)
|
||
|
|
rematch.tooltip:CloneGameTooltip()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- mimics GameTooltip:SetItemByID(itemID)
|
||
|
|
function rematch.tooltip:SetItemByID(itemID)
|
||
|
|
local source = rematch.tooltip:GetSourceTooltip()
|
||
|
|
itemID = type(itemID)=="string" and itemID:match("item:(%d+)") or itemID
|
||
|
|
source:SetItemByID(itemID)
|
||
|
|
rematch.tooltip:CloneGameTooltip()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- mimics GameTooltip:SetUnitBuff("player",index)
|
||
|
|
function rematch.tooltip:SetUnitBuff(unit,index)
|
||
|
|
local source = rematch.tooltip:GetSourceTooltip()
|
||
|
|
source:SetUnitBuff(unit,index)
|
||
|
|
rematch.tooltip:CloneGameTooltip()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- mimics GameTooltip:SetToyByItemID(itemID)
|
||
|
|
function rematch.tooltip:SetToyByItemID(itemID)
|
||
|
|
local source = rematch.tooltip:GetSourceTooltip()
|
||
|
|
source:SetToyByItemID(itemID)
|
||
|
|
rematch.tooltip:CloneGameTooltip()
|
||
|
|
end
|
||
|
|
|
||
|
|
function rematch.tooltip:CloneGameTooltip()
|
||
|
|
local source = RematchGameTooltip
|
||
|
|
if source:NumLines()>0 then
|
||
|
|
for i=1,source:NumLines() do
|
||
|
|
local line = _G["RematchGameTooltipTextRight"..i]
|
||
|
|
local text = line:GetText()
|
||
|
|
if not text then
|
||
|
|
line = _G["RematchGameTooltipTextLeft"..i]
|
||
|
|
text = line:GetText()
|
||
|
|
end
|
||
|
|
if text and text:trim()~="" then -- skipping empty lines
|
||
|
|
local r,g,b = line:GetTextColor()
|
||
|
|
rematch.tooltip:AddLine(text,r,g,b)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
source:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
-- for simpler tooltips with a title/body; anchorPoint can be "cursor" to float the tooltip
|
||
|
|
-- at the cursor, or a full anchor can be defined. if no anchor at all, it will choose an
|
||
|
|
-- anchor to parent. if no title/body passed, it will look for tooltipTitle/Body on the parent,
|
||
|
|
-- or on the parent of the given parent if tooltipAtParent is true.
|
||
|
|
-- force is true (must nil every optional arg) if the tooltip should be shown (when options may hide it)
|
||
|
|
function rematch.tooltip:ShowSimpleTooltip(parent,title,body,anchorPoint,relativeTo,relativePoint,xoff,yoff,force)
|
||
|
|
if rematch.utils:GetUIJustChanged() then
|
||
|
|
return -- if ui just reconfigured or menu/dialog disappeared, don't show this tooltip
|
||
|
|
end
|
||
|
|
-- cursor tooltips can't be suppressed; others can
|
||
|
|
if anchorPoint~="cursor" and ((settings.HideTooltips and not parent.isOption) or (settings.HideOptionTooltips and parent.isOption)) and not force then
|
||
|
|
rematch.tooltip:Hide()
|
||
|
|
return -- user doesn't want to see tooltips
|
||
|
|
end
|
||
|
|
if not title and not body then
|
||
|
|
if parent.tooltipAtParent then -- if tooltipAtParent is true, move up to parent for the tooltip
|
||
|
|
parent = parent:GetParent()
|
||
|
|
end
|
||
|
|
title = parent.tooltipTitle -- title/body wasn't passed, pick it up from the parent
|
||
|
|
body = parent.tooltipBody
|
||
|
|
end
|
||
|
|
if not title and not body then
|
||
|
|
return -- no title or body still, nothing to show, leave
|
||
|
|
end
|
||
|
|
|
||
|
|
rematch.tooltip:SetOwner(parent,not title)
|
||
|
|
|
||
|
|
if title then
|
||
|
|
rematch.tooltip:AddLine(title)
|
||
|
|
end
|
||
|
|
if body then
|
||
|
|
rematch.tooltip:AddLine(body)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- finally position it
|
||
|
|
if anchorPoint=="cursor" then
|
||
|
|
tooltip:SetScript("OnUpdate",rematch.tooltip.FollowCursor)
|
||
|
|
elseif not anchorPoint then -- no anchor, pick one based on the parent's reference
|
||
|
|
local corner,opposite = rematch.utils:GetCorner(rematch.utils:GetFrameForReference(parent),UIParent)
|
||
|
|
rematch.tooltip:SetPoint(corner,parent,opposite)
|
||
|
|
else -- and anchor was defined, use it
|
||
|
|
rematch.tooltip:SetPoint(anchorPoint,relativeTo,relativePoint,xoff,yoff)
|
||
|
|
end
|
||
|
|
|
||
|
|
rematch.tooltip:Show()
|
||
|
|
|
||
|
|
-- if displaying tooltip at cursor, then skip any potential delay and show it immediately
|
||
|
|
if anchorPoint=="cursor" then
|
||
|
|
tooltip:Show(true)
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
-- the OnUpdate function when the tooltip is show at cursor
|
||
|
|
function rematch.tooltip:FollowCursor(elapsed)
|
||
|
|
local x,y = GetCursorPosition()
|
||
|
|
local scale = UIParent:GetEffectiveScale()
|
||
|
|
tooltip:ClearAllPoints()
|
||
|
|
tooltip:SetPoint("BOTTOMLEFT",UIParent,"BOTTOMLEFT",x/scale,y/scale)
|
||
|
|
if self.fadeWait > 0 then
|
||
|
|
self.fadeWait = self.fadeWait - elapsed
|
||
|
|
elseif self.fadeAlpha > 0 then
|
||
|
|
self.fadeAlpha = self.fadeAlpha - elapsed/C.TOOLTIP_FADE_ALPHA
|
||
|
|
self:SetAlpha(max(self.fadeAlpha,0))
|
||
|
|
else
|
||
|
|
self:Hide()
|
||
|
|
end
|
||
|
|
end
|