-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathTipHooker.lua
More file actions
141 lines (123 loc) · 3.73 KB
/
TipHooker.lua
File metadata and controls
141 lines (123 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
local addonName, addon = ...
local handler
local enabled = false
local runningHandler = {}
local RunHandler = function(tooltip)
if enabled and not runningHandler[tooltip] then
runningHandler[tooltip] = true
handler(tooltip)
runningHandler[tooltip] = nil
end
end
local queuedTooltips = {}
local function HandleUpdate(tooltip)
if queuedTooltips[tooltip] then
RunHandler(tooltip)
queuedTooltips[tooltip] = nil
end
end
local function QueueUpdate(tooltip)
queuedTooltips[tooltip] = true
end
local directUpdateTypes = {
["GameTooltip"] = true,
["CheckButton"] = true,
["Button"] = true,
}
local function HandleTooltipSetItem(tooltip)
local owner = tooltip:GetOwner()
-- Hacky workaround for ShoppingTooltip and InspectFrame,
-- which fire OnUpdate before OnTooltipSetItem each frame
if (owner and owner.GetObjectType and directUpdateTypes[owner:GetObjectType()]) or debugstack():find("OnUpdate") then
RunHandler(tooltip)
elseif owner then
-- OnTooltipSetItem can be fired several times per frame,
-- So we defer the actual update until OnUpdate
QueueUpdate(tooltip)
if not tooltip:GetScript("OnUpdate") then
-- Workaround for ItemRefTooltip cannibalizing its OnUpdate handler
tooltip:SetScript("OnUpdate", function(self)
HandleUpdate(self)
self:SetScript("OnUpdate", nil)
end)
end
end
end
local tooltips = {
["GameTooltip"] = true,
["ShoppingTooltip1"] = true,
["ShoppingTooltip2"] = true,
["ItemRefTooltip"] = true,
["ItemRefShoppingTooltip1"] = true,
["ItemRefShoppingTooltip2"] = true,
["AtlasLootTooltip"] = true,
}
local staticItemSetters = {
["SetHyperlink"] = true,
["SetItemByID"] = true,
}
local tooltipNeedsRepaint = {}
local initialized = false
local function InitializeHook()
for tooltipName in pairs(tooltips) do
local tooltip = _G[tooltipName]
if tooltip then
tooltip:HookScript("OnTooltipSetItem", HandleTooltipSetItem)
tooltip:HookScript("OnUpdate", HandleUpdate)
-- Tooltips set by location (bag slot, inventory slot, etc.)
-- are usually automatically redrawn every TOOLTIP_UPDATE_TIME.
-- Tooltips set by link or ID are not, so we manually repaint them.
for functionName in pairs(staticItemSetters) do
hooksecurefunc(tooltip, functionName, function(self)
tooltipNeedsRepaint[self] = true
end)
tooltip:HookScript("OnHide", function(self)
tooltipNeedsRepaint[self] = nil
end)
end
for i = 1, 30 do
local fontString = _G[tooltipName .. "TextLeft" .. i]
if not fontString then
local leftName = tooltipName .. "TextLeft" .. i
local rightName = tooltipName .. "TextRight" .. i
local left = tooltip:CreateFontString(leftName, "ARTWORK", "GameTooltipText")
local right = tooltip:CreateFontString(rightName, "ARTWORK", "GameTooltipText")
tooltip:AddFontStrings(left, right)
end
end
end
end
initialized = true
end
local variablesLoaded = false
EventRegistry:RegisterFrameEventAndCallbackWithHandle("VARIABLES_LOADED", function()
variablesLoaded = true
if handler and not initialized then
InitializeHook()
end
if LinkWrangler then
LinkWrangler.RegisterCallback(addonName, RunHandler, "item", "refreshcomp");
end
end)
function addon.RepaintStaticTooltips()
---@type GameTooltip?
for tooltip in pairs(tooltipNeedsRepaint) do
if tooltip and tooltip.GetItem then
local _, itemLink = tooltip:GetItem()
if itemLink then
tooltip:ClearLines()
tooltip:SetHyperlink(itemLink)
end
end
end
end
function addon:EnableHook(h)
handler = h
if variablesLoaded and not initialized then
InitializeHook()
end
enabled = true
end
function addon:DisableHook()
enabled = false
end