mirror of
https://github.com/brues-code/pfUI.git
synced 2026-11-06 10:38:58 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5626ceb92 | ||
|
|
80d6f1f94b |
+91
-127
@@ -586,19 +586,42 @@ end
|
|||||||
-- Compatibility shim for pfUI plugins (e.g. pfUI-addonskinner) that still
|
-- Compatibility shim for pfUI plugins (e.g. pfUI-addonskinner) that still
|
||||||
-- call the pre-rewrite API. Routes addon names through HookAddon, and keeps
|
-- call the pre-rewrite API. Routes addon names through HookAddon, and keeps
|
||||||
-- the legacy "or variable" fallback for callers that pass a global name.
|
-- the legacy "or variable" fallback for callers that pass a global name.
|
||||||
|
-- Pending variable hooks share one ADDON_LOADED/PLAYER_LOGIN listener on
|
||||||
|
-- pfUI.events, which unregisters once every hook has run.
|
||||||
|
local variableHooks, variableHandles = {}, nil
|
||||||
|
|
||||||
|
local function DrainVariableHooks()
|
||||||
|
local ready = {}
|
||||||
|
for name in pairs(variableHooks) do
|
||||||
|
if _G[name] then table.insert(ready, name) end
|
||||||
|
end
|
||||||
|
-- run after the scan: a hook may queue another and grow the table
|
||||||
|
for _, name in ipairs(ready) do
|
||||||
|
local funcs = variableHooks[name]
|
||||||
|
variableHooks[name] = nil
|
||||||
|
for _, func in ipairs(funcs) do func() end
|
||||||
|
end
|
||||||
|
if variableHandles and not next(variableHooks) then
|
||||||
|
for _, handle in ipairs(variableHandles) do handle:Unregister() end
|
||||||
|
variableHandles = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function pfUI.api.HookAddonOrVariable(addon, func)
|
function pfUI.api.HookAddonOrVariable(addon, func)
|
||||||
if C_AddOns.DoesAddOnExist(addon) then
|
if C_AddOns.DoesAddOnExist(addon) then
|
||||||
return pfUI.api.HookAddon(addon, func)
|
return pfUI.api.HookAddon(addon, func)
|
||||||
end
|
end
|
||||||
local lurker = CreateFrame("Frame")
|
if IsLoggedIn() and _G[addon] then return func() end
|
||||||
lurker:RegisterEvent("ADDON_LOADED")
|
|
||||||
lurker:RegisterEvent("PLAYER_LOGIN")
|
variableHooks[addon] = variableHooks[addon] or {}
|
||||||
lurker:SetScript("OnEvent", function()
|
table.insert(variableHooks[addon], func)
|
||||||
if _G[addon] then
|
|
||||||
func()
|
if not variableHandles then
|
||||||
lurker:UnregisterAllEvents()
|
variableHandles = {
|
||||||
end
|
pfUI.events:RegisterFrameEventAndCallbackWithHandle("ADDON_LOADED", DrainVariableHooks),
|
||||||
end)
|
pfUI.events:RegisterFrameEventAndCallbackWithHandle("PLAYER_LOGIN", DrainVariableHooks),
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
_G.HookAddonOrVariable = pfUI.api.HookAddonOrVariable
|
_G.HookAddonOrVariable = pfUI.api.HookAddonOrVariable
|
||||||
|
|
||||||
@@ -761,25 +784,40 @@ end
|
|||||||
-- 'anchor' [frame] the frame where it should be aligned to
|
-- 'anchor' [frame] the frame where it should be aligned to
|
||||||
-- 'position' [string] where it should appear, takes the following:
|
-- 'position' [string] where it should appear, takes the following:
|
||||||
-- "TOP", "RIGHT", "BOTTOM", "LEFT"
|
-- "TOP", "RIGHT", "BOTTOM", "LEFT"
|
||||||
|
local alignments = {
|
||||||
|
-- frame corners anchor corners spacing x/y
|
||||||
|
TOP = { "BOTTOMLEFT", "BOTTOMRIGHT", "TOPLEFT", "TOPRIGHT", 0, 1 },
|
||||||
|
RIGHT = { "TOPLEFT", "BOTTOMLEFT", "TOPRIGHT", "BOTTOMRIGHT", 1, 0 },
|
||||||
|
BOTTOM = { "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT", 0, -1 },
|
||||||
|
LEFT = { "TOPRIGHT", "BOTTOMRIGHT", "TOPLEFT", "BOTTOMLEFT", -1, 0 },
|
||||||
|
}
|
||||||
|
|
||||||
function pfUI.api.AlignToPosition(frame, anchor, position, spacing)
|
function pfUI.api.AlignToPosition(frame, anchor, position, spacing)
|
||||||
if frame == anchor then return end
|
if frame == anchor then return end
|
||||||
frame:ClearAllPoints()
|
frame:ClearAllPoints()
|
||||||
if position == "TOP" and anchor then
|
|
||||||
frame:SetPoint("BOTTOMLEFT", anchor, "TOPLEFT", 0, (spacing or 0))
|
local align = anchor and alignments[position]
|
||||||
frame:SetPoint("BOTTOMRIGHT", anchor, "TOPRIGHT", 0, (spacing or 0))
|
if not align then
|
||||||
elseif position == "RIGHT" and anchor then
|
-- no usable anchor: stretch along the right screen edge
|
||||||
frame:SetPoint("TOPLEFT", anchor, "TOPRIGHT", (spacing or 0), 0)
|
frame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT")
|
||||||
frame:SetPoint("BOTTOMLEFT", anchor, "BOTTOMRIGHT", (spacing or 0), 0)
|
frame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT")
|
||||||
elseif position == "BOTTOM" and anchor then
|
return
|
||||||
frame:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -(spacing or 0))
|
|
||||||
frame:SetPoint("TOPRIGHT", anchor, "BOTTOMRIGHT", 0, -(spacing or 0))
|
|
||||||
elseif position == "LEFT" and anchor then
|
|
||||||
frame:SetPoint("TOPRIGHT", anchor, "TOPLEFT", -(spacing or 0), 0)
|
|
||||||
frame:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMLEFT", -(spacing or 0), 0)
|
|
||||||
else
|
|
||||||
frame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", 0, 0)
|
|
||||||
frame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", 0, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local point1, point2, rel1, rel2, dx, dy = unpack(align)
|
||||||
|
local x, y = dx * (spacing or 0), dy * (spacing or 0)
|
||||||
|
frame:SetPoint(point1, anchor, rel1, x, y)
|
||||||
|
frame:SetPoint(point2, anchor, rel2, x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Splits the screen into a 3x3 grid and returns the cell that (x, y) falls in
|
||||||
|
-- as a row ("TOP", "" or "BOTTOM") and a column ("LEFT", "" or "RIGHT").
|
||||||
|
local function GetScreenCell(x, y, scale)
|
||||||
|
local w = GetScreenWidth() / scale / 3
|
||||||
|
local h = GetScreenHeight() / scale / 3
|
||||||
|
local row = y > 2 * h and "TOP" or y < h and "BOTTOM" or ""
|
||||||
|
local col = x < w and "LEFT" or x > 2 * w and "RIGHT" or ""
|
||||||
|
return row, col
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [ SetAutoPoint ]
|
-- [ SetAutoPoint ]
|
||||||
@@ -789,67 +827,22 @@ end
|
|||||||
-- 'spacing' [number] the padding that should be used between the
|
-- 'spacing' [number] the padding that should be used between the
|
||||||
-- frame and its parent frame
|
-- frame and its parent frame
|
||||||
function pfUI.api.SetAutoPoint(frame, parent, spacing)
|
function pfUI.api.SetAutoPoint(frame, parent, spacing)
|
||||||
--[[
|
|
||||||
|
|
||||||
a b max
|
|
||||||
+-----------------+
|
|
||||||
| 1 | 2 | 3 |
|
|
||||||
|-----+-----+-----| c
|
|
||||||
| 4 | 5 | 6 |
|
|
||||||
|-----+-----+-----| d
|
|
||||||
| 7 | 8 | 9 |
|
|
||||||
+-----------------+
|
|
||||||
0
|
|
||||||
|
|
||||||
]]--
|
|
||||||
|
|
||||||
local a = GetScreenWidth() / 3
|
|
||||||
local b = GetScreenWidth() / 3 * 2
|
|
||||||
|
|
||||||
local c = GetScreenHeight() / 3 * 2
|
|
||||||
local d = GetScreenHeight() / 3
|
|
||||||
|
|
||||||
local x, y = parent:GetCenter()
|
local x, y = parent:GetCenter()
|
||||||
|
if not x then return end
|
||||||
|
|
||||||
if not x or not y then return end
|
-- open the frame toward the screen center
|
||||||
|
local row, col = GetScreenCell(x, y, 1)
|
||||||
local off = spacing or 0
|
local off = spacing or 0
|
||||||
|
|
||||||
frame:ClearAllPoints()
|
frame:ClearAllPoints()
|
||||||
|
if row == "TOP" then
|
||||||
if x < a and y > c then
|
frame:SetPoint("TOP" .. col, parent, "BOTTOM" .. col, 0, -off)
|
||||||
-- TOPLEFT
|
elseif row == "" and col == "LEFT" then
|
||||||
frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 0, -off)
|
|
||||||
elseif x > a and x < b and y > c then
|
|
||||||
-- TOP
|
|
||||||
frame:SetPoint("TOP", parent, "BOTTOM", 0, -off)
|
|
||||||
elseif x > b and y > c then
|
|
||||||
-- TOPRIGHT
|
|
||||||
frame:SetPoint("TOPRIGHT", parent, "BOTTOMRIGHT", 0, -off)
|
|
||||||
|
|
||||||
elseif x < a and y > d and y < c then
|
|
||||||
-- LEFT
|
|
||||||
frame:SetPoint("LEFT", parent, "RIGHT", off, 0)
|
frame:SetPoint("LEFT", parent, "RIGHT", off, 0)
|
||||||
|
elseif row == "" and col == "RIGHT" then
|
||||||
elseif x > a and x < b and y > d and y < c then
|
|
||||||
-- CENTER
|
|
||||||
frame:SetPoint("BOTTOM", parent, "TOP", 0, off)
|
|
||||||
|
|
||||||
elseif x > b and y > d and y < c then
|
|
||||||
-- RIGHT
|
|
||||||
frame:SetPoint("RIGHT", parent, "LEFT", -off, 0)
|
frame:SetPoint("RIGHT", parent, "LEFT", -off, 0)
|
||||||
|
else
|
||||||
elseif x < a and y < d then
|
frame:SetPoint("BOTTOM" .. col, parent, "TOP" .. col, 0, off)
|
||||||
-- BOTTOMLEFT
|
|
||||||
frame:SetPoint("BOTTOMLEFT", parent, "TOPLEFT", 0, off)
|
|
||||||
|
|
||||||
elseif x > a and x < b and y < d then
|
|
||||||
-- BOTTOM
|
|
||||||
frame:SetPoint("BOTTOM", parent, "TOP", 0, off)
|
|
||||||
|
|
||||||
elseif x > b and y < d then
|
|
||||||
-- BOTTOMRIGHT
|
|
||||||
frame:SetPoint("BOTTOMRIGHT", parent, "TOPRIGHT", 0, off)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -858,33 +851,12 @@ end
|
|||||||
-- 'self' [frame] the frame that should be checked
|
-- 'self' [frame] the frame that should be checked
|
||||||
-- returns: [string] the name of the best anchor
|
-- returns: [string] the name of the best anchor
|
||||||
function pfUI.api.GetBestAnchor(self)
|
function pfUI.api.GetBestAnchor(self)
|
||||||
local scale = self:GetScale()
|
|
||||||
local x, y = self:GetCenter()
|
local x, y = self:GetCenter()
|
||||||
local a = GetScreenWidth() / scale / 3
|
if not x then return end
|
||||||
local b = GetScreenWidth() / scale / 3 * 2
|
|
||||||
local c = GetScreenHeight() / scale / 3 * 2
|
|
||||||
local d = GetScreenHeight() / scale / 3
|
|
||||||
if not x or not y then return end
|
|
||||||
|
|
||||||
if x < a and y > c then
|
local row, col = GetScreenCell(x, y, self:GetScale())
|
||||||
return "TOPLEFT"
|
local anchor = row .. col
|
||||||
elseif x > a and x < b and y > c then
|
return anchor ~= "" and anchor or "CENTER"
|
||||||
return "TOP"
|
|
||||||
elseif x > b and y > c then
|
|
||||||
return "TOPRIGHT"
|
|
||||||
elseif x < a and y > d and y < c then
|
|
||||||
return "LEFT"
|
|
||||||
elseif x > a and x < b and y > d and y < c then
|
|
||||||
return "CENTER"
|
|
||||||
elseif x > b and y > d and y < c then
|
|
||||||
return "RIGHT"
|
|
||||||
elseif x < a and y < d then
|
|
||||||
return "BOTTOMLEFT"
|
|
||||||
elseif x > a and x < b and y < d then
|
|
||||||
return "BOTTOM"
|
|
||||||
elseif x > b and y < d then
|
|
||||||
return "BOTTOMRIGHT"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [ ConvertFrameAnchor ]
|
-- [ ConvertFrameAnchor ]
|
||||||
@@ -893,31 +865,23 @@ end
|
|||||||
-- 'anchor' [string] the new anchor that shall be used
|
-- 'anchor' [string] the new anchor that shall be used
|
||||||
-- returns: anchor, x, y can directly be used in SetPoint()
|
-- returns: anchor, x, y can directly be used in SetPoint()
|
||||||
function pfUI.api.ConvertFrameAnchor(self, anchor)
|
function pfUI.api.ConvertFrameAnchor(self, anchor)
|
||||||
local scale, x, y, _ = self:GetScale(), nil, nil, nil
|
local scale = self:GetScale()
|
||||||
|
local w, h = GetScreenWidth() / scale, GetScreenHeight() / scale
|
||||||
|
|
||||||
if anchor == "CENTER" then
|
-- offsets from the matching point of the screen, axis by axis
|
||||||
x, y = self:GetCenter()
|
local x, y = self:GetCenter()
|
||||||
x, y = x - GetScreenWidth()/2/scale, y - GetScreenHeight()/2/scale
|
x, y = x - w / 2, y - h / 2
|
||||||
elseif anchor == "TOPLEFT" then
|
|
||||||
x, y = self:GetLeft(), self:GetTop() - GetScreenHeight()/scale
|
if anchor:find("LEFT") then
|
||||||
elseif anchor == "TOP" then
|
x = self:GetLeft()
|
||||||
x, _ = self:GetCenter()
|
elseif anchor:find("RIGHT") then
|
||||||
x, y = x - GetScreenWidth()/2/scale, self:GetTop() - GetScreenHeight()/scale
|
x = self:GetRight() - w
|
||||||
elseif anchor == "TOPRIGHT" then
|
end
|
||||||
x, y = self:GetRight() - GetScreenWidth()/scale, self:GetTop() - GetScreenHeight()/scale
|
|
||||||
elseif anchor == "RIGHT" then
|
if anchor:find("TOP") then
|
||||||
_, y = self:GetCenter()
|
y = self:GetTop() - h
|
||||||
x, y = self:GetRight() - GetScreenWidth()/scale, y - GetScreenHeight()/2/scale
|
elseif anchor:find("BOTTOM") then
|
||||||
elseif anchor == "BOTTOMRIGHT" then
|
y = self:GetBottom()
|
||||||
x, y = self:GetRight() - GetScreenWidth()/scale, self:GetBottom()
|
|
||||||
elseif anchor == "BOTTOM" then
|
|
||||||
x, _ = self:GetCenter()
|
|
||||||
x, y = x - GetScreenWidth()/2/scale, self:GetBottom()
|
|
||||||
elseif anchor == "BOTTOMLEFT" then
|
|
||||||
x, y = self:GetLeft(), self:GetBottom()
|
|
||||||
elseif anchor == "LEFT" then
|
|
||||||
_, y = self:GetCenter()
|
|
||||||
x, y = self:GetLeft(), y - GetScreenHeight()/2/scale
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return anchor, round(x, 2), round(y, 2)
|
return anchor, round(x, 2), round(y, 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user