Files
pfUI/modules/thirdparty.lua
T
Brues 3ef78044fb bags: third-party sort addons rebind existing buttons
pfUI's built-in sorter (modules/bags.lua) always creates the sort
buttons on the right/left bag frames now, so the third-party
RegisterBagSort path's "if not pfUI.bag.right.sort" guard would skip
button-creation entirely — yet still set pfUI.thirdparty.bagsort to
the registering addon's name. Net effect: user installed SortBags or
MrPlow, our internal sort runs anyway. Silent override of user intent.

Strip the dead button-creation paths; rebind the existing buttons'
OnClick + OnEnter to the registered third-party functions instead.
Third-party addons now actually fire when the user clicks. -53 lines.
2026-05-27 23:30:01 -05:00

364 lines
13 KiB
Lua

pfUI:RegisterModule("thirdparty", function()
-- This module includes the core logic of thirdparty modules.
-- Right now, in particular the functions to register addons to the
-- dockframe of the chat panel aswell as the thirdparty root-table.
-- For vanilla-specific glue, see: thirdparty-vanilla.
pfUI.thirdparty = {}
do -- addon dockframe
pfUI.thirdparty.meters = CreateFrame("Frame")
pfUI.thirdparty.meters:SetScript("OnEvent", function()
if C.thirdparty.showmeter == "1" then
pfUI.thirdparty.meters.state = nil
else
pfUI.thirdparty.meters.state = true
end
pfUI.thirdparty.meters:Toggle()
this:UnregisterAllEvents()
end)
pfUI.thirdparty.meters.damage = nil
pfUI.thirdparty.meters.threat = nil
pfUI.thirdparty.meters.state = nil
function pfUI.thirdparty.meters:RegisterMeter(side, data)
-- abort when one addon is already register on the side
if pfUI.thirdparty.meters[side] then return end
-- load addon table
local config, addon, frame, single, dual, show, hide, once = unpack(data)
-- put addon into dockmode when enabled
if C.thirdparty[config] and C.thirdparty[config].dock == "1" then
pfUI.thirdparty.meters[side] = data
-- initialize and hide the frame in the beginning
if once then once() end
if hide then hide() end
-- enable toggle event on the panel button
if pfUI.panel then
pfUI.panel.right.hide:SetScript("OnClick", function()
pfUI.thirdparty.meters:Toggle()
end)
end
-- show/hide meter on login by default
self:RegisterEvent("PLAYER_ENTERING_WORLD")
end
end
function pfUI.thirdparty.meters:Resize()
if not pfUI.chat or not pfUI.panel then return end
if self.damage then -- resize damage meter
local config, addon, frame, single, dual, show, hide = unpack(self.damage)
if frame and C.thirdparty[config].dock == "1" then
if not self.threat then single() else dual() end
end
end
if self.threat then -- resize threat meter
local config, addon, frame, single, dual, show, hide = unpack(self.threat)
if frame and C.thirdparty[config].dock == "1" then
if not self.damage then single() else dual() end
end
end
end
function pfUI.thirdparty.meters:Toggle()
self:Resize()
-- show/hide right chatframe
if pfUI.chat and C.chat.right.enable == "1" then
-- make sure the panel header stays hidden
if self.state then
pfUI.chat.right.panelTop:Show()
else
pfUI.chat.right.panelTop:Hide()
end
-- set chat visibility
pfUI.chat.right:SetAlpha(self.state and 1 or 0)
end
-- show/hide damage meters
if self.damage then
local config, addon, frame, single, dual, show, hide = unpack(self.damage)
if not self.state then show() else hide() end
end
-- show/hide threat meters
if self.threat then
local config, addon, frame, single, dual, show, hide = unpack(self.threat)
if not self.state then show() else hide() end
end
-- show meters
if not self.state then
self.state = true
else
self.state = nil
end
end
end
do -- bag sort addon
pfUI.thirdparty.bagsort = nil
-- Third-party sort addons (SortBags, MrPlow, etc.) override pfUI's built-
-- in sorter by rebinding the existing pfUI.bag.{right,left}.sort buttons
-- created in modules/bags.lua. First-come-first-served — if multiple
-- third-party sorters are installed, the first to register wins.
function pfUI.thirdparty.RegisterBagSort(name, bag, bagtooltip, bank, banktooltip)
if pfUI.thirdparty.bagsort then return end
if not pfUI.bag or not pfUI.bag.right or not pfUI.bag.right.sort then return end
pfUI.thirdparty.bagsort = name
-- Rebind bag (right) button
local rb = pfUI.bag.right.sort
rb:SetScript("OnClick", bag)
rb:SetScript("OnEnter", function()
rb.backdrop:SetBackdropBorderColor(1,1,.25,1)
rb.texture:SetVertexColor(1,1,.25,1)
if bagtooltip then bagtooltip() end
end)
-- Rebind bank (left) button
if pfUI.bag.left and pfUI.bag.left.sort then
local lb = pfUI.bag.left.sort
lb:SetScript("OnClick", bank)
lb:SetScript("OnEnter", function()
lb.backdrop:SetBackdropBorderColor(1,1,.25,1)
lb.texture:SetVertexColor(1,1,.25,1)
if banktooltip then banktooltip() end
end)
end
end
end
-- MrPlow Bag Sorting Addon.
-- Vanilla: https://www.wowace.com/projects/mr-plow/files/288059
-- TBC: https://www.wowace.com/projects/mr-plow/files/136162
HookAddonOrVariable("MrPlow", function()
if C.thirdparty.mrplow.enable == "0" then return end
local sort = CreateFrame("Frame", nil)
sort:RegisterEvent("PLAYER_ENTERING_WORLD")
sort:SetScript("OnEvent", function()
this:UnregisterAllEvents()
local MrPlowL = AceLibrary and AceLibrary("AceLocale-2.2"):new("MrPlow")
if not (MrPlowL and MrPlowL["Bank"]) then return end
pfUI.thirdparty.RegisterBagSort("MrPlow",
function()
MrPlow:Works()
end,
function()
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(MrPlowL["Mr Plow"])
GameTooltip:AddLine(MrPlowL["The Works"],1,1,1)
GameTooltip:Show()
end,
function()
MrPlow:Works(MrPlowL["Bank"])
end,
function()
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(MrPlowL["Mr Plow"])
GameTooltip:AddLine(MrPlowL["Bank"],1,1,1)
GameTooltip:Show()
end)
end)
end)
-- ShaguDPS Damage Meter
-- Vanilla: https://github.com/shagu/ShaguDPS
-- TBC: https://github.com/shagu/ShaguDPS
HookAddonOrVariable("ShaguDPS", function()
local docktable = { "shagudps", "ShaguDPS", "ShaguDPSWindow",
function() -- single
ShaguDPSWindow:ClearAllPoints()
ShaguDPSWindow:SetAllPoints(pfUI.chat.right)
ShaguDPSWindow:SetWidth(pfUI.chat.right:GetWidth())
if ShaguDPSWindow.Resize then ShaguDPSWindow:Resize() end
end,
function() -- dual
ShaguDPSWindow:ClearAllPoints()
ShaguDPSWindow:SetPoint("TOPLEFT", pfUI.chat.right, "TOP", 0, 0)
ShaguDPSWindow:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 0)
ShaguDPSWindow:SetWidth(pfUI.chat.right:GetWidth() / 2)
if ShaguDPSWindow.Resize then ShaguDPSWindow:Resize() end
end,
function() -- show
ShaguDPS.config.visible = 1
ShaguDPS.window.Refresh(true)
end,
function() -- hide
ShaguDPS.config.visible = 0
ShaguDPS.window.Refresh(true)
end
}
pfUI.thirdparty.meters:RegisterMeter("damage", docktable)
if C.thirdparty.shagudps.skin == "1" then
local hookRefresh = ShaguDPS.window.Refresh
ShaguDPS.window.Refresh = function (arg1, arg2)
hookRefresh(arg1, arg2)
for wid=1,10 do
local window = ShaguDPS.window[wid]
-- legacy single-window support
if wid == 1 and not window then
window = ShaguDPS.window
end
if window then
local _, chat_border = GetBorderSize("chat")
window.title:Hide()
window.title:SetPoint("TOPLEFT", 1, -1)
window.title:SetPoint("TOPRIGHT", -1, -1)
CreateBackdrop(window, chat_border, nil, (C.thirdparty.chatbg == "1" and .8))
CreateBackdropShadow(window)
local hook = window.Refresh
if not window.pfRefreshHook then
window.pfRefreshHook = window.Refresh
window.Refresh = function(self, arg1, arg2)
window.pfRefreshHook(self, arg1, arg2)
-- keep backdrop hidden
if C.thirdparty.shagudps.skin == "1" then
window:SetBackdrop(nil)
window.border:SetBackdrop(nil)
end
end
end
if C.thirdparty.chatbg == "1" and C.chat.global.custombg == "1" then
local r, g, b, a = strsplit(",", C.chat.global.background)
window.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
local r, g, b, a = strsplit(",", C.chat.global.border)
window.backdrop:SetBackdropBorderColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
end
-- skin buttons
local buttons = {
window.btnAnnounce, window.btnReset, window.btnSegment, window.btnMode,
window.btnDamage, window.btnDPS, window.btnHeal, window.btnHPS,
window.btnCurrent, window.btnOverall, window.btnWindow, window.btnSettings,
}
for _, button in pairs(buttons) do
if button then
button:SetHeight(14)
CreateBackdrop(button, -1, true, .75)
button:SetBackdropBorderColor(.4,.4,.4,1)
if button:GetWidth() == 16 then
button:SetWidth(14)
end
end
end
window.border:Hide()
end
end
end
end
end)
-- DPSMate Damage Meter
-- Vanilla: https://github.com/Geigerkind/DPSMate
-- TBC: https://github.com/Geigerkind/DPSMateTBC
HookAddonOrVariable("DPSMate_DPSMate", function()
local docktable = { "dpsmate", "DPSMate", "DPSMate_DPSMate",
function() -- single
DPSMate_DPSMate:ClearAllPoints()
DPSMate_DPSMate:SetAllPoints(pfUI.chat.right)
DPSMate_DPSMate:SetWidth(pfUI.chat.right:GetWidth())
DPSMate_DPSMate_ScrollFrame:ClearAllPoints()
DPSMate_DPSMate_ScrollFrame:SetWidth(pfUI.chat.right:GetWidth())
DPSMate_DPSMate_ScrollFrame:SetPoint("TOPLEFT", DPSMate_DPSMate_Head, "BOTTOMLEFT", 0, 0)
DPSMate_DPSMate_ScrollFrame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, pfUI.panel.right:GetHeight())
DPSMate_DPSMate_ScrollFrame_Child:SetWidth(pfUI.chat.right:GetWidth())
DPSMate_DPSMate_Resize:Hide()
end,
function() -- dual
DPSMate_DPSMate:ClearAllPoints()
DPSMate_DPSMate:SetPoint("TOPLEFT", pfUI.chat.right, "TOP", 0, 0)
DPSMate_DPSMate:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 0)
DPSMate_DPSMate:SetWidth(pfUI.chat.right:GetWidth() / 2)
DPSMate_DPSMate_ScrollFrame:ClearAllPoints()
DPSMate_DPSMate_ScrollFrame:SetWidth(pfUI.chat.right:GetWidth() / 2)
DPSMate_DPSMate_ScrollFrame:SetPoint("TOPLEFT", DPSMate_DPSMate_Head, "BOTTOMLEFT", 0, 0)
DPSMate_DPSMate_ScrollFrame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, pfUI.panel.right:GetHeight())
DPSMate_DPSMate_ScrollFrame_Child:SetWidth(pfUI.chat.right:GetWidth() / 2)
DPSMate_DPSMate_Resize:Hide()
end,
function() -- show
DPSMate_DPSMate:Show()
end,
function() -- hide
DPSMate_DPSMate:Hide()
end
}
pfUI.thirdparty.meters:RegisterMeter("damage", docktable)
if C.thirdparty.dpsmate.skin == "1" then
if DPSMateSettings then
-- set DPSMate appearance to match pfUI
for w in pairs(DPSMateSettings["windows"]) do
DPSMateSettings["windows"][w]["titlebarheight"] = 20
DPSMateSettings["windows"][w]["titlebarfontsize"] = 12
DPSMateSettings["windows"][w]["titlebarfont"] = "Accidental Presidency"
DPSMateSettings["windows"][w]["titlebaropacity"] = 0
DPSMateSettings["windows"][w]["titlebarfontcolor"][1] = 1
DPSMateSettings["windows"][w]["titlebarfontcolor"][2] = 1
DPSMateSettings["windows"][w]["titlebarfontcolor"][3] = 1
DPSMateSettings["windows"][w]["barheight"] = 11
DPSMateSettings["windows"][w]["barfontsize"] = 13
DPSMateSettings["windows"][w]["bartexture"] = "normTex"
DPSMateSettings["windows"][w]["barfont"] = "Accidental Presidency"
DPSMateSettings["windows"][w]["opacity"] = 1
DPSMateSettings["windows"][w]["contentbgtexture"] = "Solid Background"
DPSMateSettings["windows"][w]["bgopacity"] = 0
DPSMateSettings["windows"][w]["borderopacity"] = 0
end
if DPSMate.UpdatePointer then
DPSMate:UpdatePointer()
end
DPSMate:InitializeFrames()
for k, val in pairs(DPSMateSettings["windows"]) do
local frame = _G["DPSMate_"..val["name"]]
CreateBackdrop(frame, nil, nil, (C.thirdparty.chatbg == "1" and .8))
CreateBackdropShadow(frame)
if C.thirdparty.chatbg == "1" and C.chat.global.custombg == "1" then
local r, g, b, a = strsplit(",", C.chat.global.background)
frame.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
local r, g, b, a = strsplit(",", C.chat.global.border)
frame.backdrop:SetBackdropBorderColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
end
end
end
end
end)
end)