Make Equip Compare event-driven with ClassicAPI

This commit is contained in:
Dusk-92
2026-08-24 14:37:56 +02:00
parent 7ddd451df4
commit 19824a09a5
+124 -61
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API
local module = ShaguTweaks:register({
title = T["Equip Compare"],
@@ -102,10 +103,11 @@ module.enable = function(self)
["INVTYPE_CROSSBOW"] = "弩",
["INVTYPE_PROJECTILE"] = "弹药",
}
}
}
-- set globals for all inventory types
for key, value in pairs(itemtypes[GetLocale()]) do setglobal(key, value) end
-- Vanilla misses a few inventory type labels in some locales.
local localeTypes = itemtypes[GetLocale()] or {}
for key, value in pairs(localeTypes) do setglobal(key, value) end
INVTYPE_WEAPON_OTHER = INVTYPE_WEAPON.."_other"
INVTYPE_FINGER_OTHER = INVTYPE_FINGER.."_other"
INVTYPE_TRINKET_OTHER = INVTYPE_TRINKET.."_other"
@@ -147,72 +149,133 @@ module.enable = function(self)
ShoppingTooltip1:SetClampedToScreen(true)
ShoppingTooltip2:SetClampedToScreen(true)
local function ShowCompare(tooltip)
-- abort if shift is not pressed
if not IsShiftKeyDown() then
ShoppingTooltip1:Hide()
ShoppingTooltip2:Hide()
return
local function GetSlotType(tooltip)
-- Prefer ClassicAPI's cache-backed inventory type. This avoids depending on
-- localized tooltip text and works for Turtle WoW custom items when the
-- tooltip exposes its item link.
if API and tooltip.GetItem and API.GetItemIDFromLink
and API.GetItemInventoryTypeByID and API.GetItemInventorySlotKey then
local _, link = tooltip:GetItem()
local itemID = API.GetItemIDFromLink(link)
local inventoryType = itemID and API.GetItemInventoryTypeByID(itemID)
local slotKey = inventoryType and API.GetItemInventorySlotKey(inventoryType)
local slotType = slotKey and _G[slotKey]
if slotType and slots[slotType] then
return slotType
end
end
-- 1.12 fallback: find the localized inventory type in the tooltip text.
local tooltipName = tooltip:GetName()
for i=1,tooltip:NumLines() do
local tmpText = _G[tooltip:GetName() .. "TextLeft"..i]
for slotType, slotName in pairs(slots) do
if tmpText:GetText() == slotType then
local slotID = GetInventorySlotInfo(slotName)
-- determine screen part
local x = GetCursorPosition() / UIParent:GetEffectiveScale()
local anchor = x < GetScreenWidth() / 2 and "TOPLEFT" or "TOPRIGHT"
local relative = x < GetScreenWidth() / 2 and "TOPRIGHT" or "TOPLEFT"
-- overwrite position for tooltips without owner
local pos, parent = tooltip:GetPoint()
if parent and parent == UIParent and pos == "TOPRIGHT" then
anchor = "TOPRIGHT"
relative = "TOPLEFT"
end
-- first tooltip
ShoppingTooltip1:SetOwner(tooltip, "ANCHOR_NONE")
ShoppingTooltip1:ClearAllPoints()
ShoppingTooltip1:SetPoint(anchor, tooltip, relative, 0, 0)
ShoppingTooltip1:SetInventoryItem("player", slotID)
ShoppingTooltip1:Show()
AddHeader(ShoppingTooltip1)
-- second tooltip
if slots[slotType .. "_other"] then
local slotID_other = GetInventorySlotInfo(slots[slotType .. "_other"])
ShoppingTooltip2:SetOwner(tooltip, "ANCHOR_NONE")
ShoppingTooltip2:ClearAllPoints()
if ShoppingTooltip1:IsShown() then
ShoppingTooltip2:SetPoint(anchor, ShoppingTooltip1, relative, 0, 0)
else
ShoppingTooltip2:SetPoint(anchor, tooltip, relative, 0, 0)
end
ShoppingTooltip2:SetInventoryItem("player", slotID_other)
ShoppingTooltip2:Show()
AddHeader(ShoppingTooltip2)
end
end
local tmpText = _G[tooltipName .. "TextLeft"..i]
local text = tmpText and tmpText:GetText()
if text and slots[text] then
return text
end
end
end
-- show item compare on default tooltips
local default = CreateFrame("Frame", nil, GameTooltip)
default:SetScript("OnUpdate", function()
ShowCompare(GameTooltip)
end)
local function ShowCompare(tooltip)
if not tooltip then return end
-- show compare on atlas tooltips
ShaguTweaks.HookAddonOrVariable("AtlasLoot", function()
local atlas = CreateFrame("Frame", nil, AtlasLootTooltip)
atlas:SetScript("OnUpdate", function()
ShowCompare(AtlasLootTooltip)
ShowCompare(AtlasLootTooltip2)
-- Always clear previous comparisons first so switching from a ring/trinket
-- to a single-slot item cannot leave ShoppingTooltip2 behind.
ShoppingTooltip1:Hide()
ShoppingTooltip2:Hide()
if not IsShiftKeyDown() then return end
local slotType = GetSlotType(tooltip)
local slotName = slotType and slots[slotType]
if not slotName then return end
local slotID = GetInventorySlotInfo(slotName)
-- determine screen part
local x = GetCursorPosition() / UIParent:GetEffectiveScale()
local anchor = x < GetScreenWidth() / 2 and "TOPLEFT" or "TOPRIGHT"
local relative = x < GetScreenWidth() / 2 and "TOPRIGHT" or "TOPLEFT"
-- overwrite position for tooltips without owner
local pos, parent = tooltip:GetPoint()
if parent and parent == UIParent and pos == "TOPRIGHT" then
anchor = "TOPRIGHT"
relative = "TOPLEFT"
end
-- first tooltip
ShoppingTooltip1:SetOwner(tooltip, "ANCHOR_NONE")
ShoppingTooltip1:ClearAllPoints()
ShoppingTooltip1:SetPoint(anchor, tooltip, relative, 0, 0)
ShoppingTooltip1:SetInventoryItem("player", slotID)
ShoppingTooltip1:Show()
AddHeader(ShoppingTooltip1)
-- second tooltip for rings, trinkets and one-hand weapons
if slots[slotType .. "_other"] then
local slotID_other = GetInventorySlotInfo(slots[slotType .. "_other"])
ShoppingTooltip2:SetOwner(tooltip, "ANCHOR_NONE")
ShoppingTooltip2:ClearAllPoints()
if ShoppingTooltip1:IsShown() then
ShoppingTooltip2:SetPoint(anchor, ShoppingTooltip1, relative, 0, 0)
else
ShoppingTooltip2:SetPoint(anchor, tooltip, relative, 0, 0)
end
ShoppingTooltip2:SetInventoryItem("player", slotID_other)
ShoppingTooltip2:Show()
AddHeader(ShoppingTooltip2)
end
end
-- Recalculate only when a tooltip is actually shown/updated. The original
-- module scanned every tooltip line on every rendered frame.
local trackedTooltips = {}
local function TrackTooltip(tooltip)
if not tooltip or trackedTooltips[tooltip] then return end
trackedTooltips[tooltip] = true
ShaguTweaks.hooksecurefunc(tooltip, "Show", function()
ShowCompare(tooltip)
end)
end
TrackTooltip(GameTooltip)
-- ClassicAPI exposes modifier transitions, so pressing/releasing Shift can
-- refresh an already visible tooltip without an always-running OnUpdate.
local modifier = CreateFrame("Frame")
if API and API.modifierstate then
modifier:RegisterEvent("MODIFIER_STATE_CHANGED")
modifier:SetScript("OnEvent", function()
if arg1 == "LSHIFT" or arg1 == "RSHIFT" then
for tooltip in pairs(trackedTooltips) do
if tooltip:IsShown() then
ShowCompare(tooltip)
end
end
end
end)
else
-- Compatibility fallback for an older ClassicAPI build: poll only the
-- Shift boolean, not all tooltip lines every frame.
local previousShift = IsShiftKeyDown()
modifier:SetScript("OnUpdate", function()
local currentShift = IsShiftKeyDown()
if currentShift ~= previousShift then
previousShift = currentShift
for tooltip in pairs(trackedTooltips) do
if tooltip:IsShown() then
ShowCompare(tooltip)
end
end
end
end)
end
-- AtlasLoot uses its own tooltip frames; hook their Show calls the same way.
ShaguTweaks.HookAddonOrVariable("AtlasLoot", function()
TrackTooltip(AtlasLootTooltip)
TrackTooltip(AtlasLootTooltip2)
end)
end