From ef1fa475394f3b9db37950131470509619225f46 Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:52:52 -0500 Subject: [PATCH] Dock GreedMeter into the chat panel Register GreedMeter's primary window on the meter dock's damage slot, mirroring the ShaguDPS integration. GreedMeter builds its windows lazily and supports several, so frames are resolved at call time. A second GreedMeter window docks into the panel's other half: pfUI's dock decides fill-vs-split by whether the threat slot is filled, so hook GreedMeter's window add/remove to reconcile that slot and re-run the resize. Only the first two windows fit the panel; any beyond that float. --- api/config.lua | 1 + modules/gui.lua | 1 + modules/thirdparty.lua | 97 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) diff --git a/api/config.lua b/api/config.lua index 65c32764..74427087 100644 --- a/api/config.lua +++ b/api/config.lua @@ -964,6 +964,7 @@ function pfUI:LoadConfig() pfUI:UpdateConfig("thirdparty", "dpsmate", "dock", "0") pfUI:UpdateConfig("thirdparty", "shagudps", "skin", "0") pfUI:UpdateConfig("thirdparty", "shagudps", "dock", "0") + pfUI:UpdateConfig("thirdparty", "greedmeter", "dock", "0") pfUI:UpdateConfig("thirdparty", "swstats", "skin", "0") pfUI:UpdateConfig("thirdparty", "swstats", "dock", "0") pfUI:UpdateConfig("thirdparty", "ktm", "skin", "0") diff --git a/modules/gui.lua b/modules/gui.lua index 2618d030..fd0217df 100644 --- a/modules/gui.lua +++ b/modules/gui.lua @@ -2997,6 +2997,7 @@ pfUI:RegisterModule("gui", function () CreateConfig(nil, T["Use Chat Colors for Meters"], C.thirdparty, "chatbg", "checkbox") CreateConfig(nil, "ShaguDPS (" .. T["Skin"] .. ")", C.thirdparty.shagudps, "skin", "checkbox") CreateConfig(nil, "ShaguDPS (" .. T["Dock"] .. ")", C.thirdparty.shagudps, "dock", "checkbox") + CreateConfig(nil, "GreedMeter (" .. T["Dock"] .. ")", C.thirdparty.greedmeter, "dock", "checkbox") CreateConfig(nil, "DPSMate (" .. T["Skin"] .. ")", C.thirdparty.dpsmate, "skin", "checkbox") CreateConfig(nil, "DPSMate (" .. T["Dock"] .. ")", C.thirdparty.dpsmate, "dock", "checkbox") CreateConfig(nil, "SWStats (" .. T["Skin"] .. ")", C.thirdparty.swstats, "skin", "checkbox") diff --git a/modules/thirdparty.lua b/modules/thirdparty.lua index 9b39330b..821cd665 100644 --- a/modules/thirdparty.lua +++ b/modules/thirdparty.lua @@ -277,6 +277,103 @@ pfUI:RegisterModule("thirdparty", function() 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