-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathTipHooker.lua
125 lines (109 loc) · 3.14 KB
/
TipHooker.lua
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
local addonName, addon = ...
local handler
local enabled = false
local RunHandler = function(tooltip)
if enabled then
handler(tooltip)
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,
}
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
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