mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 07:36:56 +00:00
434 lines
17 KiB
Lua
434 lines
17 KiB
Lua
pfUI:RegisterModule("addonbuttons", "vanilla", function ()
|
|
if not pfUI.minimap then return end
|
|
if C.abuttons.enable == "0" then return end
|
|
|
|
local default_border = C.appearance.border.default
|
|
if C.appearance.border.panels ~= "-1" then
|
|
default_border = C.appearance.border.panels
|
|
end
|
|
|
|
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",
|
|
}
|
|
|
|
pfUI.addonbuttons = CreateFrame("Frame", "pfMinimapButtons", UIParent)
|
|
pfUI.addonbuttons:SetFrameStrata("HIGH")
|
|
pfUI.addonbuttons:Hide()
|
|
CreateBackdrop(pfUI.addonbuttons)
|
|
CreateBackdropShadow(pfUI.addonbuttons)
|
|
|
|
pfUI.addonbuttons.minimapbutton = CreateFrame("Button", "pfMinimapButton", pfUI.minimap or UIParent)
|
|
pfUI.addonbuttons.minimapbutton:SetFrameStrata("MEDIUM")
|
|
pfUI.addonbuttons.minimapbutton:SetWidth(12)
|
|
pfUI.addonbuttons.minimapbutton:SetHeight(12)
|
|
|
|
pfUI.addonbuttons.minimapbutton:SetScript("OnClick", function()
|
|
if pfUI.addonbuttons:IsShown() then
|
|
pfUI.addonbuttons:Hide()
|
|
else
|
|
pfUI.addonbuttons:Show()
|
|
end
|
|
end)
|
|
|
|
pfUI.addonbuttons.buttons = {}
|
|
pfUI.addonbuttons.overrides = {}
|
|
pfUI.addonbuttons.last_updated = 0
|
|
pfUI.addonbuttons.rows = 1
|
|
pfUI.addonbuttons.effective_scale = Minimap:GetEffectiveScale()
|
|
pfUI.addonbuttons.max_button_size = 40
|
|
|
|
pfUI.addonbuttons:RegisterEvent("PLAYER_LOGIN")
|
|
pfUI.addonbuttons:RegisterEvent("PLAYER_REGEN_DISABLED")
|
|
|
|
|
|
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)
|
|
if frame:GetName() ~= nil then
|
|
if frame:IsVisible() then
|
|
if frame:IsFrameType("Button") then
|
|
if frame:GetScript("OnClick") ~= nil or frame:GetScript("OnMouseDown") ~= nil or frame:GetScript("OnMouseUp") ~= nil then
|
|
if frame:GetHeight() < pfUI.addonbuttons.max_button_size and frame:GetWidth() < pfUI.addonbuttons.max_button_size then
|
|
if not TablePartialMatch(ignored_icons, frame:GetName()) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
elseif frame:IsFrameType("Frame") and (strfind(strlower(frame:GetName()), "icon") or strfind(strlower(frame:GetName()), "button")) then
|
|
if frame:GetScript("OnMouseDown") ~= nil or frame:GetScript("OnMouseUp") ~= nil then
|
|
if frame:GetHeight() < pfUI.addonbuttons.max_button_size and frame:GetWidth() < pfUI.addonbuttons.max_button_size then
|
|
if not TablePartialMatch(ignored_icons, frame:GetName()) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
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()
|
|
if C.abuttons.position == "bottom" then
|
|
pfUI.addonbuttons:SetWidth(pfUI.minimap:GetWidth())
|
|
pfUI.addonbuttons:SetHeight(ceil((GetNumButtons() > 0 and GetNumButtons() or 1) / tonumber(C.abuttons.rowsize)) * GetStringSize() + tonumber(C.abuttons.spacing))
|
|
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:SetWidth(ceil((GetNumButtons() > 0 and GetNumButtons() or 1) / tonumber(C.abuttons.rowsize)) * GetStringSize() + tonumber(C.abuttons.spacing))
|
|
pfUI.addonbuttons:SetHeight(pfUI.minimap:GetHeight())
|
|
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:SetWidth(pfUI.minimap:GetWidth())
|
|
pfUI.addonbuttons:SetHeight(ceil((GetNumButtons() > 0 and GetNumButtons() or 1) / tonumber(C.abuttons.rowsize)) * GetStringSize() + tonumber(C.abuttons.spacing))
|
|
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:SetWidth(ceil((GetNumButtons() > 0 and GetNumButtons() or 1) / tonumber(C.abuttons.rowsize)) * GetStringSize() + tonumber(C.abuttons.spacing))
|
|
pfUI.addonbuttons:SetHeight(pfUI.minimap:GetHeight())
|
|
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 function GetTopFrame(frame)
|
|
if frame:GetParent() == Minimap or frame:GetParent() == UIParent then
|
|
return frame
|
|
else
|
|
return GetTopFrame(frame:GetParent())
|
|
end
|
|
end
|
|
|
|
local function BackupButton(frame)
|
|
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:GetHeight(), frame:GetWidth()}
|
|
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:SetHeight(frame.backup.size[1])
|
|
frame:SetWidth(frame.backup.size[2])
|
|
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)
|
|
local top_frame, row_index, offsetX, offsetY, final_scale
|
|
top_frame = GetTopFrame(frame)
|
|
final_scale = GetScale() / pfUI.addonbuttons.effective_scale
|
|
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()
|
|
for i, button_name in ipairs(pfUI.addonbuttons.buttons) do
|
|
if _G[button_name] ~= nil then
|
|
BackupButton(_G[button_name])
|
|
MoveButton(i, _G[button_name])
|
|
end
|
|
end
|
|
end
|
|
|
|
function pfUI.addonbuttons:UpdateConfig()
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
pfUI.addonbuttons:GetScript("OnEvent")()
|
|
end
|
|
|
|
pfUI.addonbuttons.scanner = CreateFrame("Frame", "pfAddonButtonScanner", UIParent)
|
|
pfUI.addonbuttons.scanner:SetScript("OnUpdate", function()
|
|
-- throttle updates to once per 3 seconds
|
|
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + 3 end
|
|
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
for k, v in pfUI.addonbuttons.overrides do
|
|
_G[k] = v
|
|
end
|
|
end)
|
|
|
|
pfUI.addonbuttons:SetScript("OnEvent", function()
|
|
if event == "PLAYER_REGEN_DISABLED" then
|
|
if C.abuttons.hideincombat == "1" and pfUI.addonbuttons:IsShown() then
|
|
pfUI.addonbuttons:Hide()
|
|
end
|
|
else
|
|
pfUI.addonbuttons:ProcessButtons()
|
|
if event == "PLAYER_LOGIN" then
|
|
if C.abuttons.showdefault == "1" and GetNumButtons() > 0 then
|
|
pfUI.addonbuttons:Show()
|
|
else
|
|
pfUI.addonbuttons:Hide()
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
pfUI.addonbuttons:UpdateConfig()
|
|
|
|
_G.SLASH_PFABP1, _G.SLASH_PFABP2 = "/abp", "/pfabp"
|
|
_G.SlashCmdList.PFABP = ManualAddOrRemove
|
|
|
|
end)
|