mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-31 07:56:57 +00:00
Each if/else that only showed one object in one branch and hid it in the other is now ClassicAPI's SetShown, which shows on any truthy value. 21 sites across 10 modules.
457 lines
17 KiB
Lua
457 lines
17 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
|
|
pfUI.chat.right.panelTop:SetShown(self.state)
|
|
|
|
-- 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 = GetStringColor(C.chat.global.background)
|
|
window.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
|
|
|
|
local r, g, b, a = GetStringColor(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)
|
|
|
|
-- GreedMeter Damage Meter
|
|
-- Vanilla: https://github.com/iGreed/GreedMeter
|
|
-- GreedMeter builds its windows lazily and supports several of them, so the
|
|
-- frames are resolved at call time. The primary window takes the "damage"
|
|
-- dock slot; a second window (GreedMeter.UI.frames[2]) takes the "threat"
|
|
-- slot so the two tile the panel side-by-side. Docking triggers a
|
|
-- LayoutBars/RefreshFrame so the bars refit the new width.
|
|
HookAddonOrVariable("GreedMeter", function()
|
|
local UI = GreedMeter.UI
|
|
|
|
local function frameAt(i)
|
|
return UI and UI.frames and UI.frames[i]
|
|
end
|
|
local function primary()
|
|
return (UI and UI.mainFrame) or getglobal("GreedMeterFrame1")
|
|
end
|
|
local function relayout(frame)
|
|
if not UI then return end
|
|
if UI.LayoutBars then UI:LayoutBars(frame) end
|
|
if UI.RefreshFrame then UI:RefreshFrame(frame) end
|
|
end
|
|
|
|
-- Builds a docktable for a window resolved through getframe(). left picks
|
|
-- the left half in split mode; the primary window uses the right half.
|
|
local function BuildDock(name, getframe, left)
|
|
return { "greedmeter", "GreedMeter", name,
|
|
function() -- single: fill the panel
|
|
local frame = getframe()
|
|
if not frame then return end
|
|
frame:ClearAllPoints()
|
|
frame:SetAllPoints(pfUI.chat.right)
|
|
frame:SetWidth(pfUI.chat.right:GetWidth())
|
|
relayout(frame)
|
|
end,
|
|
function() -- dual: take one half
|
|
local frame = getframe()
|
|
if not frame then return end
|
|
frame:ClearAllPoints()
|
|
if left then
|
|
frame:SetPoint("TOPLEFT", pfUI.chat.right, "TOPLEFT", 0, 0)
|
|
frame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOM", 0, 0)
|
|
else
|
|
frame:SetPoint("TOPLEFT", pfUI.chat.right, "TOP", 0, 0)
|
|
frame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 0)
|
|
end
|
|
frame:SetWidth(pfUI.chat.right:GetWidth() / 2)
|
|
relayout(frame)
|
|
end,
|
|
function() -- show
|
|
local frame = getframe()
|
|
if frame then frame:Show() relayout(frame) end
|
|
end,
|
|
function() -- hide
|
|
local frame = getframe()
|
|
if frame then frame:Hide() end
|
|
end
|
|
}
|
|
end
|
|
|
|
local threatdock = BuildDock("GreedMeterFrame2", function() return frameAt(2) end, true)
|
|
pfUI.thirdparty.meters:RegisterMeter("damage", BuildDock("GreedMeterFrame1", primary, false))
|
|
|
|
-- pfUI's dock decides fill-vs-split by whether the threat slot is filled,
|
|
-- not by counting windows, so reconcile that slot whenever GreedMeter adds
|
|
-- or removes one. Only the first two windows fit; any beyond that float.
|
|
local function SyncSecond()
|
|
if not pfUI.thirdparty.meters.damage then return end -- dock disabled
|
|
local has2 = frameAt(2) ~= nil
|
|
if has2 and not pfUI.thirdparty.meters.threat then
|
|
pfUI.thirdparty.meters.threat = threatdock
|
|
elseif not has2 and pfUI.thirdparty.meters.threat == threatdock then
|
|
pfUI.thirdparty.meters.threat = nil
|
|
end
|
|
pfUI.thirdparty.meters:Resize()
|
|
|
|
-- match the second window's visibility to the panel (the primary tracks it)
|
|
local f1, f2 = primary(), frameAt(2)
|
|
if f2 then
|
|
if f1 and f1:IsShown() then f2:Show() relayout(f2) else f2:Hide() end
|
|
end
|
|
end
|
|
|
|
-- AddFrame and the login-time layout restore both go through
|
|
-- CreateMeterFrame; RemoveFrame handles closing a window.
|
|
local origCreate = UI.CreateMeterFrame
|
|
UI.CreateMeterFrame = function(self, isPrimary, copyFrom)
|
|
local frame = origCreate(self, isPrimary, copyFrom)
|
|
SyncSecond()
|
|
return frame
|
|
end
|
|
local origRemove = UI.RemoveFrame
|
|
UI.RemoveFrame = function(self, frame)
|
|
origRemove(self, frame)
|
|
SyncSecond()
|
|
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 = GetStringColor(C.chat.global.background)
|
|
frame.backdrop:SetBackdropColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
|
|
|
|
local r, g, b, a = GetStringColor(C.chat.global.border)
|
|
frame.backdrop:SetBackdropBorderColor(tonumber(r), tonumber(g), tonumber(b), tonumber(a))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end)
|