mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 15:46:56 +00:00
6b458c9e27
* Migrate player castbar to ClassicAPI UNIT_SPELLCAST_* events
Drive the player cast path off ClassicAPI's synthesized, player-only
UNIT_SPELLCAST_* events instead of the vanilla SPELLCAST_* plus nampower
SPELL_{START,GO,DELAYED}_SELF mix. START/CHANNEL_START poll UnitCastingInfo/
UnitChannelInfo and stamp; STOP/CHANNEL_STOP/FAILED/INTERRUPTED clear;
SUCCEEDED drives tradeskill craft counting; DELAYED/CHANNEL_UPDATE re-poll.
Since UNIT_SPELLCAST_START fires for chained same-spell recasts, the nampower
SELF deps and their RunNextFrame co-hook-ordering workarounds are gone.
Remote target/focus bars keep SPELL_*_OTHER (the new events are player-only).
Fix the cast-start flash: StampBar now primes the fill on the stamp frame,
and ClearBar no longer snaps the bar to full (that snap lingered in the fade
tail and flashed when the next cast stamped).
Add a red flash on a cancelled cast: new appearance.castbar.failcolor,
flashed by ClearBar only when a cast was actually in progress.
Handle pushback Quartz-style: DELAYED/CHANNEL_UPDATE re-poll just the times
and accumulate the endMs shift into this.delay for the +/- indicator (cast
+X, channel -X), rather than a full restamp.
* Route target/focus castbars through remote UNIT_SPELLCAST_*
ClassicAPI now fires UNIT_SPELLCAST_* for remote tokens (target/focus/...)
via PollRemote, so drop the nampower SPELL_*_OTHER path and drive all three
bars off one event model. The gate is now token-based (arg1 == this.unitstr,
plus the arg1=="player" + UnitIsUnit case for target=self); the RunNextFrame
defer is gone since the remote poll fires after UnitCastingInfo is readable.
Cast detection is now nampower-free across every bar.
Use the event's rank payload (arg5): thread it through RefreshBar into
StampBar, which now only calls C_Spell.GetSpellSubtext as a fallback on the
retarget re-poll (PLAYER_TARGET/FOCUS_CHANGED) where no event is in hand.
* Drive nameplate castbars off UNIT_SPELLCAST_*
ClassicAPI now fires UNIT_SPELLCAST_* for nameplate tokens, so populate the
per-GUID castState cache from UNIT_SPELLCAST_{START,CHANNEL_START} (poll
PollCastInfo for the timing the payload omits) and clear it on
{STOP,CHANNEL_STOP} -- the remote poll fires STOP for natural end, interrupt,
and cancel alike. Replaces the nampower SPELL_{START,FAILED}_OTHER path; the
^nameplate arg1 gate ignores the target/focus/party fires of the same events,
and the NAME_PLATE_UNIT_ADDED seed still catches a plate spawning mid-cast.
Nameplate cast detection is now nampower-free.
* We no longer use these features from SuperWoW/Nampower
* Use secure unit attributes; remove mouseover scripts
Switch unitframes to attribute-driven clicks and remove mouseover tooltip handlers. Adds SetAttribute("unit") in UpdateVisibility and sets frame attributes (unit and type1='target') when creating frames. Removes OnEnter/OnLeave functions and their SetScript registrations and eliminates direct TargetUnit calls in ClickAction
* Use SetShown and simplify component default
Replace explicit Show/Hide conditionals in api/unitframes.lua with SetShown(...) for ressIcon, leaderIcon, lootIcon, pvpIcon, and restIcon to reduce branching and improve readability. Also remove the local shadowing of the parameter 'component' by using assignment (component = component or ""). No intended behavior changes.
* Drive unit-frame clicks via secure attributes
Replace the Lua OnClick dispatch (OnClick/ClickAction/RightClickAction) with
secure frame attributes: default type1=target / type2=menu, and EnableClickCast
now writes type/spell/macrotext/menu/target/focus attributes per button+modifier
instead of caching a clickactions table read at click time. Drops the now-dead
clickactions table and buttons list.
Also set a "unit" attribute on each frame (at creation and re-synced in
UpdateVisibility to the live token, so a party shown on the raid grid reports
partyN, not raidN) so the hovered unit resolves from the frame.
Match the target/focus/menu click keywords exactly rather than by prefix, so a
spell whose name starts with "focus"/"target"/"menu" (e.g. Focus Magic) casts
instead of being swallowed as the keyword action.
* Simplify marktracking colors and refresh per mark
Replace the hand-rolled ParseColor plus its default-color table with
GetStringColor -- the raidmarkercolor_* config keys already carry those same
defaults, so the fallback was dead code.
Restructure the refresh off observed mark tokens: UNIT_HEALTH/UNIT_MAXHEALTH
now arrive as arg1 == "markN", so refresh just that one row (UpdateRow) instead
of rescanning all eight on every nearby unit's health tick. A visibility flip
(into range / death / hp crossing 0) re-packs the rows, so UpdateRow hands off
to a full UpdateDisplay; RAID_TARGET_UPDATE / PLAYER_ENTERING_WORLD stay full
refreshes, with the 1s poll as the range-change backstop.
* not true anymore
* Poll marktracking fallback via C_Timer instead of OnUpdate
The 1s range-change safety net ran a per-frame OnUpdate that no-oped ~59 of
every 60 frames. Replace it with C_Timer.NewTicker(FALLBACK_INTERVAL,
UpdateDisplay) -- one wakeup per second off the shared timer driver -- and drop
the elapsed accumulator. The scanner frame is now purely event-driven.
* SuperWoW is now optional
* Update README feature list
Add 'Mouseover Unit Frames' and 'Click-casting' to the main features list. Update the SuperWoW entry to reflect that it tracks party/raid units on the minimap (replacing the prior SetMouseoverUnit note).
* Replace fixed-interval OnUpdate polls with C_Timer/RunNextFrame
Swap hand-rolled per-frame throttles for the modern timer primitives:
- turtle-wow: one-shot next-frame defer (self-hiding OnUpdate frame) -> RunNextFrame
- panel: clock, combat, and fps widgets -> NewTicker(1); guild roster -> NewTicker(60)
- minimap: coordinates text -> NewTicker(0.1)
- addonbuttons: one-shot init -> RunNextFrame; 5s button rescan -> NewTicker(5),
guarded by IsShown() to preserve the old "paused while hidden" behavior
Ticker callbacks reference frames via upvalue since 'this' is unbound outside
OnUpdate. Genuine per-frame work (bar fills, fades, drag) and polls already
coordinated through pfUI.throttle are left as-is.
* update pfQuest link
* Use SetShown/SetSize in panel module
Replace manual Show/Hide toggles with SetShown(not ... ) and replace SetWidth/SetHeight with SetSize in modules/panel.lua. Changes simplify toggle logic (timer, WorldMap, chat hide buttons) and unify sizing calls for timer, frames, textures, and microbutton. No behavior changes intended; purely refactor for conciseness and consistency.
* Bump ClassicAPI min version to 1.9.0
* Drive reagent counter from events instead of a polling OnUpdate
The pfReagentCounter frame ran an OnUpdate that (1) progressively rescanned
all 120 action slots one-per-100ms on any slot change and (2) recounted
reagent inventory on a 1s throttle. Replace both with direct event handling:
- ACTIONBAR_SLOT_CHANGED updates just the changed slot (arg1), full-scanning
only when arg1 is 0/nil, instead of restarting a ~12s rescan on every edit
- BAG_UPDATE_DELAYED recounts tracked reagents directly (it is already
Blizzard's coalesced bag event, so the extra 1s throttle was redundant)
- PLAYER_ENTERING_WORLD seeds the full reagent map once
UpdateSlot now seeds a new reagent's real count via GetItemCount so a freshly
placed reagent spell shows the correct number immediately. The updatecache ->
BarsUpdate render path and the IsReagentAction/GetReagentCount accessors are
unchanged.
440 lines
17 KiB
Lua
440 lines
17 KiB
Lua
pfUI:RegisterModule("addonbuttons", function ()
|
|
if not pfUI.minimap then return end
|
|
if C.abuttons.enable == "0" then return end
|
|
|
|
local rawborder, default_border = GetBorderSize("panels")
|
|
|
|
pfUI_cache["abuttons"] = pfUI_cache["abuttons"] or {}
|
|
pfUI_cache["abuttons"]["add"] = pfUI_cache["abuttons"]["add"] or {}
|
|
pfUI_cache["abuttons"]["del"] = pfUI_cache["abuttons"]["del"] or {}
|
|
|
|
local ignored_icons = {
|
|
"Note",
|
|
"JQuest",
|
|
"Naut_",
|
|
"MinimapIcon",
|
|
"GatherMatePin",
|
|
"WestPointer",
|
|
"Chinchilla_",
|
|
"SmartMinimapZoom",
|
|
"QuestieNote",
|
|
"smm",
|
|
"pfMiniMapPin",
|
|
"MiniMapBattlefieldFrame",
|
|
"pfMinimapButton",
|
|
"GatherNote",
|
|
"MiniNotePOI",
|
|
"FWGMinimapPOI",
|
|
"RecipeRadarMinimapIcon",
|
|
"MiniMapTracking",
|
|
"CartographerNotesPOI"
|
|
}
|
|
|
|
pfUI.addonbuttons = CreateFrame("Frame", "pfMinimapButtons", UIParent)
|
|
pfUI.addonbuttons:SetFrameStrata("HIGH")
|
|
CreateBackdrop(pfUI.addonbuttons)
|
|
CreateBackdropShadow(pfUI.addonbuttons)
|
|
|
|
pfUI.addonbuttons.minimapbutton = CreateFrame("Button", "pfMinimapButton", pfUI.minimap or UIParent)
|
|
pfUI.addonbuttons.minimapbutton:SetFrameLevel(24)
|
|
pfUI.addonbuttons.minimapbutton:SetSize(12, 12)
|
|
|
|
pfUI.addonbuttons.minimapbutton:SetScript("OnClick", function()
|
|
pfUI.addonbuttons:SetShown(not pfUI.addonbuttons:IsShown())
|
|
end)
|
|
|
|
pfUI.addonbuttons.buttons = {}
|
|
pfUI.addonbuttons.overrides = {}
|
|
pfUI.addonbuttons.last_updated = 0
|
|
pfUI.addonbuttons.rows = 1
|
|
pfUI.addonbuttons.max_button_size = 40
|
|
|
|
local function GetButtonSize()
|
|
if C.abuttons.position == "bottom" or C.abuttons.position == "top" then
|
|
return (pfUI.minimap:GetWidth() - (tonumber(C.abuttons.spacing) * (tonumber(C.abuttons.rowsize) + 1))) / tonumber(C.abuttons.rowsize)
|
|
else
|
|
return (pfUI.minimap:GetHeight() - (tonumber(C.abuttons.spacing) * (tonumber(C.abuttons.rowsize) + 1))) / tonumber(C.abuttons.rowsize)
|
|
end
|
|
end
|
|
|
|
local function GetNumButtons()
|
|
local total_buttons = 0
|
|
for i, v in ipairs(pfUI.addonbuttons.buttons) do
|
|
total_buttons = total_buttons + 1
|
|
end
|
|
return total_buttons
|
|
end
|
|
|
|
local function GetStringSize()
|
|
return (GetButtonSize() + tonumber(C.abuttons.spacing))
|
|
end
|
|
|
|
local function TableMatch(table, needle)
|
|
for i,v in ipairs(table) do
|
|
if (strlower(v) == strlower(needle)) then
|
|
return i
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function TablePartialMatch(table, needle)
|
|
for i,v in ipairs(table) do
|
|
local pos_start, pos_end = strfind(strlower(needle), strlower(v))
|
|
if pos_start == 1 then
|
|
return i
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function IsButtonValid(frame)
|
|
-- ignore invalid and invisible frames
|
|
if not frame:GetName() then return false end
|
|
if not frame:IsVisible() then return false end
|
|
|
|
-- ignore frames with invalid sizes
|
|
if frame:GetHeight() > pfUI.addonbuttons.max_button_size then return false end
|
|
if frame:GetWidth() > pfUI.addonbuttons.max_button_size then return false end
|
|
|
|
-- ignore other frame types
|
|
if not frame:IsFrameType("Button") and not frame:IsFrameType("Frame") then return false end
|
|
|
|
-- ignore manually selected frames
|
|
if TablePartialMatch(ignored_icons, frame:GetName()) then return false end
|
|
|
|
-- check button/frame script handlers
|
|
if frame:IsFrameType("Button") then
|
|
if frame:GetScript("OnClick") or frame:GetScript("OnMouseDown") or frame:GetScript("OnMouseUp") then
|
|
return true
|
|
end
|
|
elseif frame:IsFrameType("Frame") and (strfind(strlower(frame:GetName()), "icon") or strfind(strlower(frame:GetName()), "button")) then
|
|
if frame:GetScript("OnMouseDown") or frame:GetScript("OnMouseUp") then
|
|
return true
|
|
end
|
|
end
|
|
|
|
-- ignore everything else
|
|
return false
|
|
end
|
|
|
|
local function FindButtons(frame)
|
|
for i, frame_child in ipairs({frame:GetChildren()}) do
|
|
-- check first level children
|
|
if IsButtonValid(frame_child) and not TableMatch(pfUI.addonbuttons.buttons, frame_child:GetName()) then
|
|
table.insert(pfUI.addonbuttons.buttons, frame_child:GetName())
|
|
else
|
|
if frame_child:GetNumChildren() > 0 then
|
|
for j, child_child in ipairs({frame_child:GetChildren()}) do
|
|
if IsButtonValid(child_child) and not TableMatch(pfUI.addonbuttons.buttons, child_child:GetName()) then
|
|
table.insert(pfUI.addonbuttons.buttons, child_child:GetName())
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function GetScale()
|
|
local sum_size, buttons_count, calculated_scale
|
|
sum_size = 0
|
|
buttons_count = GetNumButtons()
|
|
for i, button_name in ipairs(pfUI.addonbuttons.buttons) do
|
|
if _G[button_name] ~= nil then
|
|
sum_size = sum_size + _G[button_name]:GetHeight()
|
|
end
|
|
end
|
|
calculated_scale = GetButtonSize() / (sum_size / buttons_count)
|
|
return calculated_scale > 1 and 1 or calculated_scale
|
|
end
|
|
|
|
local function ScanForButtons()
|
|
FindButtons(Minimap)
|
|
FindButtons(MinimapBackdrop)
|
|
end
|
|
|
|
local function SetupMainFrame()
|
|
pfUI.addonbuttons:ClearAllPoints()
|
|
pfUI.addonbuttons:SetScale(pfUI.minimap:GetScale())
|
|
|
|
pfUI.addonbuttons.minimapbutton:ClearAllPoints()
|
|
local mbtnWidth, mbtnHeight = pfUI.minimap:GetSize()
|
|
local dynamicSize = ceil((GetNumButtons() > 0 and GetNumButtons() or 1) / tonumber(C.abuttons.rowsize)) * GetStringSize() + tonumber(C.abuttons.spacing)
|
|
if C.abuttons.position == "bottom" then
|
|
pfUI.addonbuttons:SetSize(mbtnWidth, dynamicSize)
|
|
pfUI.addonbuttons:SetPoint("TOP", pfUI.minimap, "BOTTOM", 0 , -default_border * 3)
|
|
SkinArrowButton(pfUI.addonbuttons.minimapbutton, "down")
|
|
pfUI.addonbuttons.minimapbutton:SetPoint("BOTTOM", pfUI.minimap, "BOTTOM", 0, 4)
|
|
elseif C.abuttons.position == "left" then
|
|
pfUI.addonbuttons:SetSize(dynamicSize, mbtnHeight)
|
|
pfUI.addonbuttons:SetPoint("TOPRIGHT", pfUI.minimap, "TOPLEFT", -default_border * 3, 0)
|
|
SkinArrowButton(pfUI.addonbuttons.minimapbutton, "left")
|
|
pfUI.addonbuttons.minimapbutton:SetPoint("LEFT", pfUI.minimap, "LEFT", 4, 0)
|
|
elseif C.abuttons.position == "top" then
|
|
pfUI.addonbuttons:SetSize(mbtnWidth, dynamicSize)
|
|
pfUI.addonbuttons:SetPoint("BOTTOM", pfUI.minimap, "TOP", 0 , default_border * 3)
|
|
SkinArrowButton(pfUI.addonbuttons.minimapbutton, "up")
|
|
pfUI.addonbuttons.minimapbutton:SetPoint("TOP", pfUI.minimap, "TOP", 0, -4)
|
|
elseif C.abuttons.position == "right" then
|
|
pfUI.addonbuttons:SetSize(dynamicSize, mbtnHeight)
|
|
pfUI.addonbuttons:SetPoint("TOPLEFT", pfUI.minimap, "TOPRIGHT", default_border * 3, 0)
|
|
SkinArrowButton(pfUI.addonbuttons.minimapbutton, "right")
|
|
pfUI.addonbuttons.minimapbutton:SetPoint("RIGHT", pfUI.minimap, "RIGHT", -4, 0)
|
|
end
|
|
end
|
|
|
|
local function UpdatePanel()
|
|
ScanForButtons()
|
|
for i, button_name in ipairs(pfUI_cache["abuttons"]["add"]) do
|
|
if not TableMatch(pfUI.addonbuttons.buttons, button_name) then
|
|
if _G[button_name] ~= nil then
|
|
table.insert(pfUI.addonbuttons.buttons, button_name)
|
|
end
|
|
end
|
|
end
|
|
for i, button_name in ipairs(pfUI_cache["abuttons"]["del"]) do
|
|
if TableMatch(pfUI.addonbuttons.buttons, button_name) then
|
|
table.remove(pfUI.addonbuttons.buttons, TableMatch(pfUI.addonbuttons.buttons, button_name))
|
|
end
|
|
end
|
|
for i, button_name in ipairs(pfUI.addonbuttons.buttons) do
|
|
if _G[button_name] == nil then
|
|
table.remove(pfUI.addonbuttons.buttons, TableMatch(pfUI.addonbuttons.buttons, button_name))
|
|
end
|
|
end
|
|
SetupMainFrame()
|
|
end
|
|
|
|
local parent
|
|
local function GetTopFrame(frame)
|
|
parent = frame:GetParent()
|
|
if not parent or parent == Minimap or parent == MinimapBackdrop or parent == UIParent then
|
|
return frame
|
|
else
|
|
return GetTopFrame(parent)
|
|
end
|
|
end
|
|
|
|
local function BackupButton(frame)
|
|
if not frame then return end
|
|
if frame.backup == nil then
|
|
frame.backup = {}
|
|
frame.backup.top_frame_name = GetTopFrame(frame):GetName()
|
|
frame.backup.parent_name = GetTopFrame(frame):GetParent():GetName()
|
|
frame.backup.is_clamped_to_screen = frame:IsClampedToScreen()
|
|
frame.backup.is_movable = frame:IsMovable()
|
|
frame.backup.point = {frame:GetPoint()}
|
|
frame.backup.size = {frame:GetSize()}
|
|
frame.backup.scale = frame:GetScale()
|
|
if frame:HasScript("OnDragStart") then
|
|
frame.backup.on_drag_start = frame:GetScript("OnDragStart")
|
|
end
|
|
if frame:HasScript("OnDragStop") then
|
|
frame.backup.on_drag_stop = frame:GetScript("OnDragStop")
|
|
end
|
|
if frame:HasScript("OnUpdate") then
|
|
frame.backup.on_update = frame:GetScript("OnUpdate")
|
|
end
|
|
-- TODO: find a way to avoid such hardcoding
|
|
if frame:GetName() == "MetaMapButton" then
|
|
frame.backup.MetaMapButton_UpdatePosition = MetaMapButton_UpdatePosition
|
|
pfUI.addonbuttons.overrides.MetaMapButton_UpdatePosition = function () return end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function RestoreButton(frame)
|
|
if frame.backup ~= nil then
|
|
_G[frame.backup.top_frame_name]:SetParent(frame.backup.parent_name)
|
|
frame:SetClampedToScreen(frame.backup.is_clamped_to_screen)
|
|
frame:SetMovable(frame.backup.is_movable)
|
|
frame:SetScale(frame.backup.scale)
|
|
frame:SetSize(frame.backup.size[2], frame.backup.size[1])
|
|
frame:ClearAllPoints()
|
|
frame:SetPoint(frame.backup.point[1], frame.backup.point[2], frame.backup.point[3], frame.backup.point[4], frame.backup.point[5])
|
|
if frame.backup.on_drag_start ~= nil then
|
|
frame:SetScript("OnDragStart", frame.backup.on_drag_start)
|
|
end
|
|
if frame.backup.on_drag_stop ~= nil then
|
|
frame:SetScript("OnDragStop", frame.backup.on_drag_stop)
|
|
end
|
|
if frame.backup.on_update ~= nil then
|
|
frame:SetScript("OnUpdate", frame.backup.on_update)
|
|
end
|
|
if frame.backup.MetaMapButton_UpdatePosition ~= nil then
|
|
pfUI.addonbuttons.overrides.MetaMapButton_UpdatePosition = frame.backup.MetaMapButton_UpdatePosition
|
|
end
|
|
end
|
|
end
|
|
|
|
local function MoveButton(index, frame)
|
|
if not frame then return end
|
|
local top_frame, row_index, offsetX, offsetY, final_scale
|
|
top_frame = GetTopFrame(frame)
|
|
final_scale = GetScale()
|
|
row_index = floor((index-1)/tonumber(C.abuttons.rowsize))
|
|
frame:SetFrameStrata("HIGH")
|
|
frame:SetClampedToScreen(true)
|
|
frame:SetMovable(false)
|
|
frame:SetScript("OnDragStart", nil)
|
|
frame:SetScript("OnDragStop", nil)
|
|
frame:SetScript("OnUpdate", nil)
|
|
frame:SetClampedToScreen(true)
|
|
frame:SetMovable(false)
|
|
frame:ClearAllPoints()
|
|
|
|
if top_frame ~= pfUI.addonbuttons then
|
|
top_frame:SetScale(final_scale)
|
|
top_frame:ClearAllPoints()
|
|
top_frame:SetParent(pfUI.addonbuttons)
|
|
end
|
|
|
|
if C.abuttons.position == "bottom" or C.abuttons.position == "top" then
|
|
offsetX = ((index - row_index * tonumber(C.abuttons.rowsize)) * (tonumber(C.abuttons.spacing))) + (((index - row_index * tonumber(C.abuttons.rowsize)) - 1) * GetButtonSize()) + (GetButtonSize() / 2)
|
|
offsetY = -(((row_index + 1) * tonumber(C.abuttons.spacing)) + (row_index * GetButtonSize()) + (GetButtonSize() / 2))
|
|
frame:SetPoint("CENTER", pfUI.addonbuttons, "TOPLEFT", offsetX/final_scale, offsetY/final_scale)
|
|
if top_frame ~= pfUI.addonbuttons then
|
|
top_frame:SetPoint("CENTER", pfUI.addonbuttons, "TOPLEFT", offsetX/final_scale, offsetY/final_scale)
|
|
end
|
|
else
|
|
offsetX = -(((row_index + 1) * tonumber(C.abuttons.spacing)) + (row_index * GetButtonSize()) + (GetButtonSize() / 2))
|
|
offsetY = -(((index - row_index * tonumber(C.abuttons.rowsize)) * (tonumber(C.abuttons.spacing))) + (((index - row_index * tonumber(C.abuttons.rowsize)) - 1) * GetButtonSize()) + (GetButtonSize() / 2))
|
|
frame:SetPoint("CENTER", pfUI.addonbuttons, "TOPRIGHT", offsetX/final_scale, offsetY/final_scale)
|
|
if top_frame ~= pfUI.addonbuttons then
|
|
top_frame:SetPoint("CENTER", pfUI.addonbuttons, "TOPRIGHT", offsetX/final_scale, offsetY/final_scale)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ManualAddOrRemove(msg)
|
|
local _, _, action, arg = string.find(msg, "%s?(%w+)%s?(.*)")
|
|
|
|
local button
|
|
if arg and arg ~= "" then
|
|
button = _G[arg]
|
|
else
|
|
button = GetMouseFocus()
|
|
end
|
|
|
|
if action == "" or (action ~= "reset" and action ~= "add" and action ~= "del") then
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI Addon Button Panel:")
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc/abp add|r - " .. T["Add button to the frame"])
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc/abp del|r - " .. T["Remove button from the frame"])
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc/abp reset|r - " .. T["Reset all manually added or ignored buttons"])
|
|
return
|
|
end
|
|
|
|
if action == "reset" then
|
|
for i, button_name in ipairs(pfUI_cache["abuttons"]["add"]) do
|
|
if _G[button_name] ~= nil then
|
|
if TableMatch(pfUI.addonbuttons.buttons, button_name) then
|
|
table.remove(pfUI.addonbuttons.buttons, TableMatch(pfUI.addonbuttons.buttons, button_name))
|
|
end
|
|
RestoreButton(_G[button_name])
|
|
end
|
|
end
|
|
pfUI_cache["abuttons"]["add"] = {}
|
|
pfUI_cache["abuttons"]["del"] = {}
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI ABP|r: " .. T["Lists of added and deleted buttons are cleared"])
|
|
return
|
|
else
|
|
if IsButtonValid(button) then
|
|
if action == "add" then
|
|
if TableMatch(pfUI_cache["abuttons"]["del"], button:GetName()) then
|
|
table.remove(pfUI_cache["abuttons"]["del"], TableMatch(pfUI_cache["abuttons"]["del"], button:GetName()))
|
|
end
|
|
if not TableMatch(pfUI.addonbuttons.buttons, button:GetName()) and not TableMatch(pfUI_cache["abuttons"]["add"], button:GetName()) then
|
|
table.insert(pfUI_cache["abuttons"]["add"], button:GetName())
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI ABP|r: " .. T["Added button"] .. ": " .. button:GetName())
|
|
else
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI ABP|r: " .. T["Button already exists in pfMinimapButtons frame"])
|
|
return
|
|
end
|
|
elseif action == "del" then
|
|
if TableMatch(pfUI_cache["abuttons"]["add"], button:GetName()) then
|
|
table.remove(pfUI_cache["abuttons"]["add"], TableMatch(pfUI_cache["abuttons"]["add"], button:GetName()))
|
|
end
|
|
if TableMatch(pfUI.addonbuttons.buttons, button:GetName()) then
|
|
table.remove(pfUI.addonbuttons.buttons, TableMatch(pfUI.addonbuttons.buttons, button:GetName()))
|
|
else
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI ABP|r: " .. T["Button not found in pfMinimapButtons frame"])
|
|
return
|
|
end
|
|
if not TableMatch(pfUI_cache["abuttons"]["del"], button:GetName()) then
|
|
table.insert(pfUI_cache["abuttons"]["del"], button:GetName())
|
|
RestoreButton(button)
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI ABP|r: " .. T["Removed button"] .. ": " .. button:GetName())
|
|
end
|
|
end
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
return
|
|
else
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpf|rUI ABP|r: " .. T["Not a valid button!"])
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
function pfUI.addonbuttons:ProcessButtons()
|
|
UpdatePanel()
|
|
|
|
local i = 1
|
|
for _, button_name in ipairs(pfUI.addonbuttons.buttons) do
|
|
if _G[button_name] and _G[button_name]:IsVisible() then
|
|
BackupButton(_G[button_name])
|
|
MoveButton(i, _G[button_name])
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
function pfUI.addonbuttons:UpdateConfig()
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
end
|
|
|
|
pfUI.addonbuttons:SetScript("OnShow", function()
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
end)
|
|
|
|
-- Initial setup on the next frame, once other addons' minimap buttons exist
|
|
RunNextFrame(function()
|
|
-- check if the panel should be shown by default
|
|
if C.abuttons.showdefault == "1" and GetNumButtons() > 0 then
|
|
pfUI.addonbuttons:Show()
|
|
else
|
|
pfUI.addonbuttons:Hide()
|
|
end
|
|
|
|
-- update all buttons and apply workarounds
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
for k, v in pairs(pfUI.addonbuttons.overrides) do
|
|
_G[k] = v
|
|
end
|
|
end)
|
|
|
|
-- Rescan minimap buttons every 5 seconds while the panel is shown
|
|
C_Timer.NewTicker(5, function()
|
|
if not pfUI.addonbuttons:IsShown() then return end
|
|
|
|
-- reload/rescan minimap buttons
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
|
|
-- re-apply addon button workarounds
|
|
for k, v in pairs(pfUI.addonbuttons.overrides) do
|
|
_G[k] = v
|
|
end
|
|
end)
|
|
|
|
pfUI.addonbuttons:RegisterEvent("PLAYER_REGEN_DISABLED")
|
|
pfUI.addonbuttons:SetScript("OnEvent", function()
|
|
if C.abuttons.hideincombat == "1" and pfUI.addonbuttons:IsShown() then
|
|
pfUI.addonbuttons:Hide()
|
|
end
|
|
end)
|
|
|
|
pfUI.addonbuttons:UpdateConfig()
|
|
|
|
pfUI.api.RegisterSlashCommand("PFABP", { "/abp", "/pfabp" }, ManualAddOrRemove, true)
|
|
end)
|