-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathItemTooltipIcons.lua
More file actions
162 lines (136 loc) · 8.74 KB
/
ItemTooltipIcons.lua
File metadata and controls
162 lines (136 loc) · 8.74 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
---@type LibStubDef
local LibStub = getglobal("LibStub")
assert(LibStub ~= nil, "LibStub is required to run this addon")
local LibCraftingProfessions = --[[---@type LibCraftingProfessions]] LibStub("LibCraftingProfessions-1.0")
local LibCrafts = --[[---@type LibCrafts]] LibStub("LibCrafts-1.0")
local LibItemTooltip = --[[---@type LibItemTooltip]] LibStub("LibItemTooltip-1.0")
---@class Addon
---@field professionNameToIcon table<string, Frame>
local Addon = {}
local ICON_SIZE = 15
local getn = table.getn
local unpack = unpack
-- ========================= helpers =========================
local function ITI_HideAll()
if not Addon or not Addon.professionNameToIcon then return end
for _, icon in pairs(Addon.professionNameToIcon) do icon:Hide() end
end
-- Hook a tooltip so that NON-item tooltips wipe our icons.
-- We DO NOT purge on :Show() (pfUI may call it multiple times).
local function ITI_HookNonItem(tt)
if not tt or tt.__iti_nonitem_hooked then return end
tt.__iti_nonitem_hooked = true
-- clear when tooltip hides
local oldHide = tt:GetScript("OnHide")
tt:SetScript("OnHide", function()
ITI_HideAll()
if oldHide then oldHide() end
end)
-- clear on manual ClearLines
local origClear = tt.ClearLines
if type(origClear) == "function" then
tt.ClearLines = function(self, ...)
ITI_HideAll()
return origClear(self, unpack(arg))
end
end
-- clear on common non-item builders
local function wrap(method)
local orig = tt[method]
if type(orig) ~= "function" then return end
tt[method] = function(self, ...)
ITI_HideAll()
return orig(self, unpack(arg))
end
end
wrap("SetUnit")
wrap("SetSpell")
wrap("SetTrainerService")
-- optional: starting a new tooltip session
local origOwner = tt.SetOwner
if type(origOwner) == "function" then
tt.SetOwner = function(self, ...)
ITI_HideAll()
return origOwner(self, unpack(arg))
end
end
end
-- ========================= addon logic =========================
function Addon:CreateIcons()
local nameToIcon = {}
for _, profession in ipairs(LibCraftingProfessions:GetSupportedProfessions()) do
local icon = CreateFrame("Frame", nil, UIParent)
icon:SetWidth(ICON_SIZE); icon:SetHeight(ICON_SIZE)
local tex = icon:CreateTexture(nil, "BACKGROUND")
tex:SetAllPoints(icon)
tex:SetTexture(profession.icon_texture_path)
nameToIcon[profession.localized_name] = icon
end
self.professionNameToIcon = nameToIcon
end
---@param tooltip GameTooltip
---@param itemId number
---@return boolean
function Addon:EnhanceTooltip(tooltip, itemId)
-- ensure this tooltip is hooked to clear on non-item use
ITI_HookNonItem(tooltip)
self:HideAllIcons()
return self:DrawIcons(self:GetIcons(itemId), tooltip)
end
function Addon:HideAllIcons()
for _, icon in pairs(self.professionNameToIcon) do icon:Hide() end
end
---@param itemId number
---@return Frame[]
function Addon:GetIcons(itemId)
local nameSet = {}
for _, craft in ipairs(LibCrafts:GetCraftsByReagentId(itemId)) do
nameSet[craft.localized_profession_name] = true
end
local names = {}
for name in pairs(nameSet) do table.insert(names, name) end
table.sort(names)
local icons = {}
for _, name in ipairs(names) do
local icon = self.professionNameToIcon[name]
if icon then table.insert(icons, icon) end
end
return icons
end
---@param icons Frame[]
---@param tooltip GameTooltip
---@return boolean
function Addon:DrawIcons(icons, tooltip)
if next(icons) == nil then return false end
-- spacer line to make room for icons
local spacer = ""
for i = 1, getn(icons) do spacer = spacer .. "....." end
tooltip:AddLine(spacer, 0.01, 0.01, 0.01)
local line = tooltip:NumLines()
for i, icon in ipairs(icons) do
icon:SetParent(tooltip)
icon:ClearAllPoints()
if i == 1 then
icon:SetPoint("LEFT", getglobal(tooltip:GetName().."TextLeft"..line), "LEFT", 0, -1)
else
icon:SetPoint("LEFT", icons[i-1], "RIGHT", 2, 0)
end
icon:Show()
end
return true
end
Addon:CreateIcons()
LibItemTooltip:RegisterEvent("OnShow", function(tooltip, itemLink, itemId)
if Addon:EnhanceTooltip(tooltip, itemId) then
tooltip:Show() -- redraw so spacer+icons appear immediately
end
end)
-- hook stock + pfUI tooltip frames at login so non-item tooltips purge icons
local hooker = CreateFrame("Frame")
hooker:RegisterEvent("PLAYER_LOGIN")
hooker:RegisterEvent("ADDON_LOADED")
hooker:SetScript("OnEvent", function()
ITI_HookNonItem(GameTooltip)
if pfUITooltip then ITI_HookNonItem(pfUITooltip) end
if pfTooltip then ITI_HookNonItem(pfTooltip) end
end)