9 Commits
Author SHA1 Message Date
Brues 94dcfb3dad Compute bar layout options instead of tabulating pfGridmath
pfGridmath listed every exact cols x rows grid per bar size; the only
live use was seeding the layout dropdown, which a divisor loop now does.

Everything else that read it was unreachable: every layout option is a
"cols x rows" string, so ResolveBarLayout's BarLayoutFormfactor lookup
never matched, and the actionbar module resets a stored layout that
isn't one before BarLayoutSize/BarButtonAnchor run, so their fallbacks
never fired. BarLayoutFormfactor and env/tables.lua go with it.
2026-10-29 14:16:43 -05:00
Brues 0890905eb6 Drop named-unit frames and the pfValidUnits global
CreateUnitFrame and CreateCastbar could take a character name instead of
a unit token, but every caller passes a token, so that mode and the
empty-label guards around it were dead. The OnClick TargetByName branch
could never run anyway: label was always a string, and "" is truthy.

With that gone, the aggro scan was the only reader of pfValidUnits, so
its unit list now lives in unitframes.lua and is built once at load.

/focusname resolves the name with UnitTokenFromName (exact first, then
prefix) instead of swapping the target and muting UIErrorsFrame.
2026-10-29 14:00:54 -05:00
Brues 6c76a88467 Draw unit frame bars with the native StatusBar
The custom bar sized its textures in Lua from GetWidth(), so it had to
track how ClassicAPI reports the UI scale (#71), and it stretched the bar
texture instead of cropping it. The engine's StatusBar does that layout
itself.

The background of the missing part is a second StatusBar that fills
from the other end (ClassicAPI's SetReverseFill), one frame level below
the fill, so the incoming-heal texture still draws between the two.
SetFrameLevel moves both, and the health and power bars now sit two
levels above their backdrops. SetStatusBarBackgroundTexture becomes
SetStatusBarBackgroundColor, as it only ever took a color.
2026-10-29 11:06:02 -05:00
Brues 35c32f365e Remove scaledsize fix 2026-10-29 10:38:28 -05:00
Brues 6dcb5162be bags: use ClassicAPI's native item search
C_Container.SetItemSearch drives the search box; slots dim from isFiltered on INVENTORY_SEARCH_UPDATE and on each slot update. Matches name, subclass, equip slot and equipment set names. Drops the tooltip-scanning full-text option.
2026-10-29 10:35:28 -05:00
Brues 8afafe71cf Drop RunMacroText fallback and dead actionbar spellslot branches
ClassicAPI 1.18 provides RunMacroText natively; bump CAPI min to 1.18.0. spellslot/booktype/scanmacro were only ever cleared, never set.
2026-10-29 10:35:28 -05:00
Brues 99ed538ee7 bump CAPI min to 1.17.10 2026-10-29 10:35:28 -05:00
Brues f382039f21 panel: show per-addon memory in FPS & Lag tooltip
Use UpdateAddOnMemoryUsage/GetAddOnMemoryUsage like Blizzard's MainMenuBar performance tooltip: total addon memory plus the top 3 consumers, formatted with the TOTAL_MEM/ADDON_MEM global strings. Guarded so the tooltip falls back gracefully on clients without these APIs.
2026-10-29 10:35:28 -05:00
Brues 8307dd757e Bump ClassicAPI minimum 1.17.4 2026-10-29 10:35:28 -05:00
22 changed files with 201 additions and 347 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ do
-- on. There pfUI does load, and will throw wherever it reaches for something
-- the installed DLL doesn't have yet -- the popup names the cause so those
-- errors aren't a mystery.
local PFUI_CLASSIC_API_MIN = 11703 -- (X*10000 + Y*100 + Z)
local PFUI_CLASSIC_API_MIN = 11800 -- (X*10000 + Y*100 + Z)
local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
+21 -48
View File
@@ -1353,15 +1353,18 @@ end
-- [ Bar Layout Options ] --
-- 'barsize' size of bar in number of buttons
-- returns: array of options as strings for pfUI.gui.bar
-- returns: array of options as strings for pfUI.gui.bar: every grid
-- that fits the bar exactly, plus common uneven ones
function pfUI.api.BarLayoutOptions(barsize)
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarLayoutOptions: barsize "..tostring(barsize).." is invalid")
local options, seen = {}, {}
local function add(option)
if not seen[option] then table.insert(options, option); seen[option] = true end
end
for i,layout in ipairs(pfGridmath[barsize]) do
add(string.format("%d x %d",layout[1],layout[2]))
for cols = 1, barsize do
if barsize % cols == 0 then
add(string.format("%d x %d", cols, barsize / cols))
end
end
for _, option in ipairs({
"1 x 12", "1 x 10", "2 x 10", "2 x 5", "3 x 10", "3 x 5", "3 x 3",
@@ -1381,49 +1384,23 @@ function pfUI.api.BarLayoutOptions(barsize)
return options
end
-- [ Bar Layout Formfactor ] --
-- 'option' string option as used in pfUI_config.bars[bar].option
-- returns: integer formfactor
local formfactors = {}
setmetatable(formfactors, {__mode = "v"}) -- weak table so values not referenced are collected on next gc
function pfUI.api.BarLayoutFormfactor(option)
if formfactors[option] then
return formfactors[option]
else
for barsize,_ in ipairs(pfGridmath) do
local options = pfUI.api.BarLayoutOptions(barsize)
for i,opt in ipairs(options) do
if opt == option then
formfactors[option] = i
return formfactors[option]
end
end
end
end
end
-- 'formfactor' has to be a "cols x rows" string; the actionbar module resets
-- a stored layout that isn't one before it lays out a bar
local function ResolveBarLayout(barsize, formfactor, uneven)
local layout = tostring(formfactor or "")
local _, _, a, b = string.find(layout, "(%d+)%s*x%s*(%d+)")
if a and b then
local cols, rows = tonumber(a), tonumber(b)
cols = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, cols))
rows = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, rows))
local orientation = string.upper(uneven or "DOWN")
local mode = (orientation == "LEFT" or orientation == "RIGHT") and "cols" or "rows"
if mode == "rows" then
cols = math.max(1, math.min(cols, barsize))
rows = math.max(1, math.ceil(barsize / cols))
else
rows = math.max(1, math.min(rows, barsize))
cols = math.max(1, math.ceil(barsize / rows))
end
return cols, rows, mode, orientation
local _, _, a, b = string.find(formfactor, "(%d+)%s*x%s*(%d+)")
local cols, rows = tonumber(a), tonumber(b)
cols = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, cols))
rows = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, rows))
local orientation = string.upper(uneven or "DOWN")
local mode = (orientation == "LEFT" or orientation == "RIGHT") and "cols" or "rows"
if mode == "rows" then
cols = math.max(1, math.min(cols, barsize))
rows = math.max(1, math.ceil(barsize / cols))
else
rows = math.max(1, math.min(rows, barsize))
cols = math.max(1, math.ceil(barsize / rows))
end
local index = pfUI.api.BarLayoutFormfactor(layout)
if not index then return nil end
local cols, rows = unpack(pfGridmath[barsize][index])
return cols, rows, "rows", "DOWN"
return cols, rows, mode, orientation
end
-- [ Bar Layout Size ] --
@@ -1434,7 +1411,6 @@ end
function pfUI.api.BarLayoutSize(bar,barsize,formfactor,iconsize,bordersize,padding,uneven,fillmode)
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarLayoutSize: barsize "..tostring(barsize).." is invalid")
local cols, rows = ResolveBarLayout(barsize, formfactor, uneven)
if not cols or not rows then cols, rows = unpack(pfGridmath[barsize][1]) end
local width = (iconsize + bordersize*2+padding) * cols + padding
local height = (iconsize + bordersize*2+padding) * rows + padding
bar._size = {width,height}
@@ -1452,9 +1428,6 @@ end
function pfUI.api.BarButtonAnchor(button,basename,buttonindex,barsize,formfactor,iconsize,bordersize,padding,uneven,fillmode)
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarButtonAnchor: barsize "..tostring(barsize).." is invalid")
local cols, rows, mode, orientation = ResolveBarLayout(barsize, formfactor, uneven)
if not cols or not rows then
cols, rows, mode, orientation = unpack(pfGridmath[barsize][1]), "rows", "DOWN"
end
-- fillmode: remap buttonindex to slotindex (grid position in native fill order)
-- only needed when fill direction differs from layout mode
-1
View File
@@ -171,7 +171,6 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("appearance", "bags", "newitem_color", "1,1,1,1")
pfUI:UpdateConfig("appearance", "bags", "borderlimit", "1")
pfUI:UpdateConfig("appearance", "bags", "borderonlygear", "0")
pfUI:UpdateConfig("appearance", "bags", "fulltext", "1")
pfUI:UpdateConfig("appearance", "bags", "movable", "0")
pfUI:UpdateConfig("appearance", "bags", "abovechat", "0")
pfUI:UpdateConfig("appearance", "bags", "hidechat", "0")
+36 -74
View File
@@ -3,19 +3,19 @@ setfenv(1, pfUI:GetEnvironment())
do -- statusbars
local animations = {}
local stepsize, val
local width, height, point
local stepsize
-- ClassicAPI before v1.18.0 leaves the UI scale in the size of an anchored
-- frame, so the bar has to divide it back out
local scaledsize = CLASSIC_API_VERSION < 11800
-- native StatusBar methods the bar overrides
local statusbar = CreateFrame("StatusBar")
local SetValue, SetMinMaxValues = statusbar.SetValue, statusbar.SetMinMaxValues
local SetOrientation, SetFrameLevel = statusbar.SetOrientation, statusbar.SetFrameLevel
local animate = CreateFrame("Frame", "pfStatusBarAnimation", UIParent)
animate:SetScript("OnUpdate", function()
stepsize = tonumber(pfUI_config.unitframes.animation_speed)
for bar in pairs(animations) do
if not bar.val_ or abs(bar.val_ - bar.val) < stepsize or bar.instant then
if not bar.val_ or abs(bar.val_ - bar.val) < stepsize then
bar:DisplayValue(bar.val)
elseif bar.val ~= bar.val_ then
bar:DisplayValue(bar.val_ + min((bar.val-bar.val_) / stepsize, max(bar.val-bar.val_, 30 / GetFramerate())))
@@ -25,7 +25,8 @@ do -- statusbars
local handlers = {
["DisplayValue"] = function(self, val)
val = Clamp(val, self.min, self.max)
local smin, smax = self:GetMinMaxValues()
val = Clamp(val, smin, smax)
-- remove animation queue
if val == self.val_ then
@@ -34,53 +35,20 @@ do -- statusbars
-- set current visible value
self.val_ = val
SetValue(self, val)
if self.mode == "vertical" then
height = self:GetHeight()
if scaledsize then height = height / self:GetEffectiveScale() end
point = height / (self.max - self.min) * (val - self.min)
-- keep values in limits
point = Clamp(point, 0, height)
-- set point to zero if value and max is zero
if val == 0 then point = 0 end
-- set status bar position/size
self.bar:SetPoint("TOPLEFT", self, "TOPLEFT", 0, - height + point)
self.bar:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0)
-- set background bar position/size
self.bg:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0)
self.bg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, point)
else
width = self:GetWidth()
if scaledsize then width = width / self:GetEffectiveScale() end
point = width / (self.max - self.min) * (val - self.min)
-- keep values in limits
point = Clamp(point, 0, width)
-- set point to zero if value and max is zero
if val == 0 then point = 0 end
-- set status bar position/size
self.bar:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0)
self.bar:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", - width + point, 0)
-- set background bar position/size
self.bg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0)
self.bg:SetPoint("TOPLEFT", self, "TOPLEFT", point, 0)
end
-- the background fills the missing part, all of an empty range
self.bg:SetValue(smax > smin and (smax - val) / (smax - smin) or 1)
end,
["SetMinMaxValues"] = function(self, smin, smax, smooth)
-- smoothen the transition by keeping the value at the same percentage as before
if smooth and self.max and self.max > 0 and smax > 0 and self.max ~= smax then
self.val_ = (self.val_ or self.val) / self.max * smax
local _, oldmax = self:GetMinMaxValues()
if smooth and oldmax > 0 and smax > 0 and oldmax ~= smax then
self.val_ = (self.val_ or self.val) / oldmax * smax
end
self.min, self.max = smin, smax
SetMinMaxValues(self, smin, smax)
self:DisplayValue(self.val_ or self.val)
end,
@@ -93,41 +61,35 @@ do -- statusbars
end
end,
["SetStatusBarTexture"] = function(self, r, g, b, a)
self.bar:SetTexture(r, g, b, a)
end,
["SetStatusBarColor"] = function(self, r, g, b, a)
self.bar:SetVertexColor(r, g, b, a)
end,
["SetStatusBarBackgroundTexture"] = function(self, r, g, b, a)
self.bg:SetTexture(r, g, b, a)
end,
["SetStatusBarBackgroundColor"] = function(self, r, g, b, a)
self.bg:SetVertexColor(r, g, b, a)
self.bg:SetColorFill(r, g, b, a)
end,
["SetOrientation"] = function(self, mode)
self.mode = strlower(mode)
["SetOrientation"] = function(self, orientation)
SetOrientation(self, orientation)
self.bg:SetOrientation(orientation)
end,
-- the background stays one level below the fill, under anything else
-- drawn on the fill's frame
["SetFrameLevel"] = function(self, level)
SetFrameLevel(self, level)
self.bg:SetFrameLevel(level - 1)
end,
}
function pfUI.api.CreateStatusBar(name, parent)
local f = CreateFrame("Button", name, parent)
f:EnableMouse(false)
local f = CreateFrame("StatusBar", name, parent)
SetMinMaxValues(f, 0, 100)
SetValue(f, 0)
f.val = 0
f.bar = f:CreateTexture(nil, "NORMAL")
f.bar:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
f.bar:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
f.bg = f:CreateTexture(nil, "BACKGROUND")
f.bg:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
f.bg:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
-- set some default values
f.min, f.max, f.val = 0, 100, 0
f.bg = CreateFrame("StatusBar", nil, f)
f.bg:SetFrameLevel(f:GetFrameLevel() - 1)
f.bg:SetAllPoints(f)
f.bg:SetReverseFill(true)
f.bg:SetMinMaxValues(0, 1)
f.bg:SetValue(1)
-- add all handler functions to the object
for name, func in pairs(handlers) do
+57 -40
View File
@@ -235,7 +235,50 @@ function pfUI.api.GetUnitStats(unitstr)
end
local aggrodata = { }
local aggroScan = nil -- static { u, t, tt } triples, built once so the hot scan allocates nothing
-- every unit whose target or target's target UnitHasAggro checks, as static
-- { u, t, tt } triples so the hot scan allocates nothing
local aggroScan = { }
do
local function add(u)
local t = u .. "target"
table.insert(aggroScan, { u = u, t = t, tt = t .. "target" })
end
add("pet")
add("player")
add("target")
add("mouseover")
add("focus")
add("focustarget")
add("focustargettarget")
add("pettarget")
add("playertarget")
add("targettarget")
add("mouseovertarget")
add("targettargettarget")
for i=1,4 do
add("party" .. i)
add("party" .. i .. "target")
add("partypet" .. i)
add("partypet" .. i .. "target")
end
for i=1,40 do
add("raid" .. i)
add("raid" .. i .. "target")
add("raidpet" .. i)
add("raidpet" .. i .. "target")
add("nameplate" .. i)
add("nameplate" .. i .. "target")
end
end
function pfUI.api.UnitHasAggro(unit)
local now = GetTime()
local data = aggrodata[unit]
@@ -250,16 +293,6 @@ function pfUI.api.UnitHasAggro(unit)
data.state = 0
if UnitExists(unit) and UnitIsFriend(unit, "player") then
-- pfValidUnits never changes after load, so precompute the "<u>target" /
-- "<u>targettarget" token strings once instead of concatenating per call.
if not aggroScan then
aggroScan = {}
for u in pairs(pfValidUnits) do
local t = u .. "target"
table.insert(aggroScan, { u = u, t = t, tt = t .. "target" })
end
end
for i = 1, table.getn(aggroScan) do
local s = aggroScan[i]
if UnitExists(s.t) and UnitIsUnit(s.t, unit) and UnitCanAttack(s.u, unit) then
@@ -349,11 +382,10 @@ function pfUI.uf:UpdateVisibility()
-- this runs for every frame five times a second, so only touch the
-- attribute when the unit actually changed
local unitstr = (self.label or "") .. (self.id or "")
local unit = unitstr ~= "" and unitstr or nil
if unit ~= self.unitstr then
self.unitstr = unit
self:SetAttribute("unit", unit)
local unitstr = self.label .. self.id
if unitstr ~= self.unitstr then
self.unitstr = unitstr
self:SetAttribute("unit", unitstr)
end
-- anything but "show"/"hide" means "show if the unit exists"
local visibility = "exists"
@@ -395,9 +427,7 @@ function pfUI.uf:UpdateVisibility()
self:RegisterUnitEvents(visibility ~= "hide" and self.unitstr or nil)
-- vanilla visibility
if self.unitname then
self:Show()
elseif visibility == "hide" then
if visibility == "hide" then
self:Hide()
elseif visibility == "show" then
self:Show()
@@ -508,6 +538,8 @@ function pfUI.uf:UpdateConfig()
if tonumber(f.config.height) < 0 then f.hp:Hide() end
pfUI.api.CreateBackdrop(f.hp, default_border)
-- one level above the backdrop for the bar's background, one more for its fill
f.hp.bar:SetFrameLevel(f.hp.backdrop:GetFrameLevel() + 2)
f.hp.bar:SetStatusBarTexture(pfUI.media[f.config.bartexture])
f.hp.bar:SetAllPoints(f.hp)
if f.config.verticalbar == "1" then
@@ -522,7 +554,7 @@ function pfUI.uf:UpdateConfig()
if custombg == "1" then
local cr, cg, cb, ca = GetStringColor(custombgcolor)
cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca)
f.hp.bar:SetStatusBarBackgroundTexture(cr,cg,cb,ca)
f.hp.bar:SetStatusBarBackgroundColor(cr,cg,cb,ca)
end
f.power:ClearAllPoints()
@@ -531,7 +563,7 @@ function pfUI.uf:UpdateConfig()
if tonumber(f.config.pheight) < 0 then f.power:Hide() end
pfUI.api.CreateBackdrop(f.power, default_border)
f.power.bar:SetFrameLevel(f.power.backdrop:GetFrameLevel() + 1)
f.power.bar:SetFrameLevel(f.power.backdrop:GetFrameLevel() + 2)
f.power.bar:SetStatusBarTexture(pfUI.media[f.config.pbartexture])
f.power.bar:SetAllPoints(f.power)
@@ -541,7 +573,7 @@ function pfUI.uf:UpdateConfig()
if custompbg == "1" then
local cr, cg, cb, ca = GetStringColor(custompbgcolor)
cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca)
f.power.bar:SetStatusBarBackgroundTexture(cr,cg,cb,ca)
f.power.bar:SetStatusBarBackgroundColor(cr,cg,cb,ca)
end
local fontname, fontsize, fontstyle
@@ -1244,8 +1276,6 @@ function pfUI.uf.OnUpdate()
end
end
if not this.label or this.label == "" then return end
-- update portrait on first visible frame
if this.portrait and this.portrait.model and this.portrait.model.update then
this.portrait.model.lastUnit = UnitName(this.portrait.model.update)
@@ -1332,11 +1362,7 @@ end
-- ============================================================
function pfUI.uf.OnClick()
if not this.label and this.unitname then
TargetByName(this.unitname, true)
else
pfUI.uf:ClickAction(arg1)
end
pfUI.uf:ClickAction(arg1)
end
function pfUI.uf:ClickAction(button)
@@ -1433,13 +1459,6 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
f.config = config or pfUI_config.unitframes.fallback
f.tick = tick
-- disable events for unknown unitstrings
if not pfValidUnits[strlower(unit) .. id] then
f.unitname = unit
f.label, f.id = "", ""
f.RegisterEvent = function() return end
end
CreateBackdropShadow(f)
f.hp = CreateFrame("Frame",nil, f)
@@ -1490,7 +1509,7 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
f.incHeal = CreateFrame("Frame", nil, f.hp)
-- Texture lives on hp.bar for correct draw order:
-- hp.bar.bg (BACKGROUND) < incHeal (BORDER) < hp.bar.bar (NORMAL)
-- hp.bar.bg (a level below) < incHeal (BORDER) < hp.bar's fill (ARTWORK)
f.incHeal.texture = f.hp.bar:CreateTexture(nil, "BORDER")
f.incHeal.texture:SetAllPoints(f.incHeal)
-- Override Show/Hide since texture lives on hp.bar, not incHeal
@@ -1556,9 +1575,7 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
f:Hide()
end
if f.label ~= "" then
f:SetAttribute("unit", f.label .. f.id)
end
f:SetAttribute("unit", f.label .. f.id)
-- register frame for clique
_G.ClickCastFrames = ClickCastFrames or {}
-50
View File
@@ -1,50 +0,0 @@
-- barlength = {[formfactor]={cols, rows}}
pfGridmath = {
[1] = {{1,1}},
[2] = {{2,1},{1,2}},
[3] = {{3,1},{1,3}},
[4] = {{4,1},{2,2},{1,4}},
[5] = {{5,1},{1,5}},
[6] = {{6,1},{3,2},{2,3},{1,6}},
[7] = {{7,1},{1,7}},
[8] = {{8,1},{4,2},{2,4},{1,8}},
[9] = {{9,1},{3,3},{1,9}},
[10] = {{10,1},{5,2},{2,5},{1,10}},
[11] = {{11,1},{1,11}},
[12] = {{12,1},{6,2},{4,3},{3,4},{2,6},{1,12}}
}
-- list of valid unitstrings
pfValidUnits = {}
pfValidUnits["pet"] = true
pfValidUnits["player"] = true
pfValidUnits["target"] = true
pfValidUnits["mouseover"] = true
pfValidUnits["focus"] = true
pfValidUnits["focustarget"] = true
pfValidUnits["focustargettarget"] = true
pfValidUnits["pettarget"] = true
pfValidUnits["playertarget"] = true
pfValidUnits["targettarget"] = true
pfValidUnits["mouseovertarget"] = true
pfValidUnits["targettargettarget"] = true
for i=1,4 do
pfValidUnits["party" .. i] = true
pfValidUnits["party" .. i .. "target"] = true
pfValidUnits["partypet" .. i] = true
pfValidUnits["partypet" .. i .. "target"] = true
end
for i=1,40 do
pfValidUnits["raid" .. i] = true
pfValidUnits["raid" .. i .. "target"] = true
pfValidUnits["raidpet" .. i] = true
pfValidUnits["raidpet" .. i .. "target"] = true
pfValidUnits["nameplate" .. i] = true
pfValidUnits["nameplate" .. i .. "target"] = true
end
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["deDE"] = {
["Enable Energy Ticks"] = nil,
["Enable Extended Guild Information"] = nil,
["Enable Frame Shadow"] = nil,
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = nil,
["Enable Item Quality Color For Equipment Only"] = nil,
["Enable \"Loot & Spam\" Chat Window"] = nil,
-1
View File
@@ -290,7 +290,6 @@ pfUI_translation["enUS"] = {
["Enable Energy Ticks"] = nil,
["Enable Extended Guild Information"] = nil,
["Enable Frame Shadow"] = nil,
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = nil,
["Enable Item Quality Color For Equipment Only"] = nil,
["Enable \"Loot & Spam\" Chat Window"] = nil,
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["esES"] = {
["Enable Energy Ticks"] = "Activar tics de energía",
["Enable Extended Guild Information"] = "Activar información de hermandad extendida",
["Enable Frame Shadow"] = "Activar sombra del marco",
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = "Activar indicadores",
["Enable Item Quality Color For Equipment Only"] = "Mostrar el color de calidad de objetos solo para equipo",
["Enable \"Loot & Spam\" Chat Window"] = "Activar ventana de chat \"Botín y spam\"",
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["frFR"] = {
["Enable Energy Ticks"] = "Activer la barre de rechargement d'énergie",
["Enable Extended Guild Information"] = "Activer les informations de guilde étendues",
["Enable Frame Shadow"] = "Activer l'ombre des cadres",
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = "Activer les indicateurs",
["Enable Item Quality Color For Equipment Only"] = "Activer la couleur de la qualité des objets seulement sur les pièces d'équipement",
["Enable \"Loot & Spam\" Chat Window"] = "Activer la fenêtre de chat \"Butins & Spam\"",
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["koKR"] = {
["Enable Energy Ticks"] = "Energy Ticks 활성화",
["Enable Extended Guild Information"] = "길드 정보 확장 사용",
["Enable Frame Shadow"] = nil,
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = nil,
["Enable Item Quality Color For Equipment Only"] = "착용장비 전용 아이템품질 색상 활성화",
["Enable \"Loot & Spam\" Chat Window"] = "\"루팅 & 스팜\"채팅 창 사용",
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["ruRU"] = {
["Enable Energy Ticks"] = "Включить восполнение энергии",
["Enable Extended Guild Information"] = "Включить расширенную информацию о гильдии",
["Enable Frame Shadow"] = "Включить тень окон",
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = "Включить индикаторы",
["Enable Item Quality Color For Equipment Only"] = "Включить цвет качества предметов только для экипировки",
["Enable \"Loot & Spam\" Chat Window"] = "Включить окно чата \"Добыча & Спам\"",
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["zhCN"] = {
["Enable Energy Ticks"] = "显示能量刻度",
["Enable Extended Guild Information"] = "公会信息扩展显示",
["Enable Frame Shadow"] = "启用框架阴影",
["Enable Full-Text Search"] = "启用全文搜索",
["Enable Indicators"] = "启用指示器",
["Enable Item Quality Color For Equipment Only"] = "仅在装备上显示品质颜色",
["Enable \"Loot & Spam\" Chat Window"] = "启用[拾取、综合]聊天窗口",
-1
View File
@@ -281,7 +281,6 @@ pfUI_translation["zhTW"] = {
["Enable Energy Ticks"] = "顯示能量刻度",
["Enable Extended Guild Information"] = "公會資訊擴展顯示",
["Enable Frame Shadow"] = "啟用框架陰影",
["Enable Full-Text Search"] = nil,
["Enable Indicators"] = nil,
["Enable Item Quality Color For Equipment Only"] = "僅在裝備上顯示品質顏色",
["Enable \"Loot & Spam\" Chat Window"] = "啟用[拾取、綜合]聊天視窗",
-1
View File
@@ -7,7 +7,6 @@
<Include file="..\env\locales_esES.lua"/>
<Include file="..\env\locales_ruRU.lua"/>
<Include file="..\env\tables.lua"/>
<Include file="..\env\profiles.lua"/>
<Include file="..\env\translations_enUS.lua"/>
+1 -14
View File
@@ -382,8 +382,6 @@ pfUI:RegisterModule("actionbar", function ()
end
elseif self.spellID then
GameTooltip:SetSpellByID(self.spellID)
elseif self.spellslot and self.booktype then
GameTooltip:SetSpell(self.spellslot, self.booktype)
else
GameTooltip:SetAction(self.id)
end
@@ -456,11 +454,6 @@ pfUI:RegisterModule("actionbar", function ()
id = self.bar == 1 and self.slot or sid-((self.bar)-1)*12
end
-- overwrite with spell macro texture where possible
if self.spellslot and self.booktype then
texture = GetSpellTexture(self.spellslot, self.booktype)
end
if not self.showempty and self.backdrop and not texture and grid == 0 then
self.backdrop:Hide()
self.hide = true
@@ -590,9 +583,6 @@ pfUI:RegisterModule("actionbar", function ()
start, duration, enable = GetShapeshiftFormCooldown(button.id)
elseif button.bar == 12 then
start, duration, enable = GetPetActionCooldown(button.id)
elseif button.spellslot and button.booktype then
start, duration = GetSpellCooldown(button.spellslot, button.booktype)
enable = 1
else
start, duration, enable = GetActionCooldown(button.id)
end
@@ -1150,8 +1140,6 @@ pfUI:RegisterModule("actionbar", function ()
f.count:SetJustifyH("RIGHT")
f.count:SetJustifyV("BOTTOM")
f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
-- range glow color
f.rangeColor = GetStringColorObject(C.bars.rangecolor)
@@ -1218,8 +1206,7 @@ pfUI:RegisterModule("actionbar", function ()
end
-- the stored layout is invalid, temporary fallback
local _, _, fcols, frows = string.find(tostring(formfactor or ""), "(%d+)%s*x%s*(%d+)")
if not ((fcols and frows) or pfGridmath[buttons][BarLayoutFormfactor(formfactor)]) then
if not fcols2 or not frows2 then
formfactor = BarLayoutOptions(buttons)[1]
end
+29 -55
View File
@@ -6,8 +6,6 @@ pfUI:RegisterModule("bags", function ()
[1804] = {frame="picklock"},
}
local scanner = libtipscan:GetScanner("input_search")
local function BagSortOpts()
return {
reverse = C.appearance.bags.sortreverse == "1",
@@ -95,6 +93,7 @@ pfUI:RegisterModule("bags", function ()
pfUI.bag:RegisterEvent("ITEM_LOCK_CHANGED")
pfUI.bag:RegisterEvent("SPELLS_CHANGED")
pfUI.bag:RegisterEvent("MERCHANT_CLOSED")
pfUI.bag:RegisterEvent("INVENTORY_SEARCH_UPDATE")
pfUI.bag.delay = { UpdateBag = {} }
@@ -122,6 +121,11 @@ pfUI:RegisterModule("bags", function ()
pfUI.bag:UpdateItemLock()
end
if this.delay.UpdateSearch then
this.delay.UpdateSearch = nil
pfUI.bag:UpdateSearch()
end
for bag in pairs(this.delay.UpdateBag) do
this.delay.UpdateBag[bag] = nil
pfUI.bag:UpdateBag(bag)
@@ -159,6 +163,10 @@ pfUI:RegisterModule("bags", function ()
this.delay.UpdateItemLock = true
end
if event == "INVENTORY_SEARCH_UPDATE" then
this.delay.UpdateSearch = true
end
if event == "PLAYERBANKSLOTS_CHANGED" then
this.delay.UpdateBag[-1] = true
end
@@ -377,6 +385,21 @@ pfUI:RegisterModule("bags", function ()
end
end
-- dim the slots that the bag search (C_Container.SetItemSearch) filters out
local searchInfo = {}
function pfUI.bag:UpdateSlotSearch(bag, slot)
local info = C_Container.GetContainerItemInfo(bag, slot, searchInfo)
pfUI.bags[bag].slots[slot].frame:SetAlpha(info and info.isFiltered and .25 or 1)
end
function pfUI.bag:UpdateSearch()
for bag = -2, 11 do
for slot in ipairs(pfUI.bags[bag].slots) do
pfUI.bag:UpdateSlotSearch(bag, slot)
end
end
end
function pfUI.bag:UpdateSlot(bag, slot)
if not pfUI.bags[bag] then return end
@@ -465,6 +488,7 @@ pfUI:RegisterModule("bags", function ()
SetItemButtonTexture(pfUI.bags[bag].slots[slot].frame, texture)
SetItemButtonCount(pfUI.bags[bag].slots[slot].frame, count)
SetItemButtonDesaturated(pfUI.bags[bag].slots[slot].frame, locked, 0.5, 0.5, 0.5)
pfUI.bag:UpdateSlotSearch(bag, slot)
local hasItem = texture and 1 or nil
pfUI.bags[bag].slots[slot].frame.hasItem = hasItem
@@ -1010,7 +1034,6 @@ pfUI:RegisterModule("bags", function ()
-- bag search
if not frame.search then
frame.search = CreateFrame("Frame", "pfBagSearch", frame)
frame.search.db = {}
frame.search:SetHeight(12)
frame.search:SetPoint("TOPLEFT", frame, "TOPLEFT", default_border, -default_border)
frame.search:SetPoint("TOPRIGHT", frame.sort, "TOPLEFT", -default_border*3, -default_border)
@@ -1035,51 +1058,12 @@ pfUI:RegisterModule("bags", function ()
frame.search.edit:SetScript("OnEditFocusLost", function()
this:SetText(T["Search"])
for bag=-2, 11 do
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
for slot=1, bagsize do
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
end
end
C_Container.SetItemSearch("")
end)
frame.search.edit:SetScript("OnTextChanged", function()
if this:GetText() == T["Search"] then return end
for bag=-2, 11 do
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
for slot=1, bagsize do
pfUI.bags[bag].slots[slot].frame:SetAlpha(.25)
local texture, itemCount, locked, quality, readable = GetContainerItemInfo(bag, slot)
if itemCount then
local itemLink = GetContainerItemLink(bag, slot)
local itemstring = string.sub(itemLink, string.find(itemLink, "%[")+1, string.find(itemLink, "%]")-1)
if C.appearance.bags.fulltext == "1" then
if not frame.search.db[itemLink] then
scanner:SetBagItem(bag, slot)
local text = scanner:Text()
local str = ""
for k, v in pairs(text) do
str = str .. (v[1] or "") .. (v[2] or "")
end
frame.search.db[itemLink] = strlower(str)
end
if strfind(frame.search.db[itemLink], strlower(this:GetText()), 1, true) then
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
end
end
if strfind(strlower(itemstring), strlower(this:GetText()), 1, true) then
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
end
end
end
end
C_Container.SetItemSearch(this:GetText())
end)
frame.search:SetScript("OnLeave", function()
@@ -1094,17 +1078,7 @@ pfUI:RegisterModule("bags", function ()
frame.search:SetScript("OnHide", function()
frame.search.edit:SetText(T["Search"])
for bag = -2, 11 do
if pfUI.bags[bag] then
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
for slot = 1, bagsize do
if pfUI.bags[bag] and pfUI.bags[bag].slots[slot] then
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
end
end
end
end
C_Container.SetItemSearch("")
end)
end
else
+6 -11
View File
@@ -150,8 +150,8 @@ pfUI:RegisterModule("castbar", function ()
-- One-shot poll: read C_Spell for the bar's unit, stamp or clear. Called
-- from event handlers (cast start, target/focus change), never per-frame.
local function RefreshBar(cb, rank)
local query = cb.unitstr ~= "" and cb.unitstr or cb.unitname
if not query or (cb.unitstr ~= "" and not UnitExists(cb.unitstr)) then
local query = cb.unitstr
if not UnitExists(query) then
ClearBar(cb)
return
end
@@ -178,7 +178,7 @@ pfUI:RegisterModule("castbar", function ()
end
end
local function CreateCastbar(name, parent, unitstr, unitname)
local function CreateCastbar(name, parent, unitstr)
local cb = CreateFrame("Frame", name, parent or UIParent)
cb:SetHeight(C.global.font_size * 1.5)
@@ -186,7 +186,6 @@ pfUI:RegisterModule("castbar", function ()
cb:SetFrameLevel(8)
cb.unitstr = unitstr
cb.unitname = unitname
-- icon
cb.icon = CreateFrame("Frame", nil, cb)
@@ -277,7 +276,7 @@ pfUI:RegisterModule("castbar", function ()
-- Non-player bars: if the unit disappears (target died / detarget),
-- drop the bar immediately.
if this.unitstr ~= "" and this.unitstr ~= "player" and not UnitExists(this.unitstr) then
if this.unitstr ~= "player" and not UnitExists(this.unitstr) then
ClearBar(this)
return
end
@@ -423,13 +422,12 @@ pfUI:RegisterModule("castbar", function ()
-- endMs. delay is a positive magnitude; OnUpdate signs it "+" for casts
-- and "-" for channels. Skipped during a tradeskill merge.
if this.endTime and not this.tradeskillTotal then
local query = this.unitstr ~= "" and this.unitstr or this.unitname
local startMs, endMs
if this.isChannel then
local _, _, _, s, e = C_Spell.UnitChannelInfo(query)
local _, _, _, s, e = C_Spell.UnitChannelInfo(unit)
startMs, endMs = s, e
else
local _, _, _, s, e = C_Spell.UnitCastingInfo(query)
local _, _, _, s, e = C_Spell.UnitCastingInfo(unit)
startMs, endMs = s, e
end
if startMs and endMs then
@@ -544,9 +542,6 @@ pfUI:RegisterModule("castbar", function ()
pfUI.castbar.focus:SetHeight(C.castbar.focus.height)
end
-- bind castbar to the "focus" unit token; the GUID resolves at read time
pfUI.castbar.focus.unitstr = "focus"
UpdateMovable(pfUI.castbar.focus)
end
end)
+5 -28
View File
@@ -29,38 +29,15 @@ pfUI:RegisterModule("focus", function ()
end)
-- /focus and /clearfocus live in ClassicAPI's SlashCommandsRegistry now.
-- /focusname is pfUI-specific because the engine has no name→GUID
-- lookup for off-screen units — we resolve via a short target-swap.
-- `/focus Name` takes the nearest prefix match; /focusname tries the exact
-- name first, so "Bob" still wins over a nearer "Bobby".
pfUI.api.RegisterSlashCommand("PFFOCUSNAME", { '/focusname', '/pffocusname' }, function(msg)
if msg == "" then return end
local prevGUID = UnitGUID("target")
local prevPlayer = UnitIsUnit("target", "player")
-- Suppress async "Unknown unit" errors fired by TargetByName misses.
UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE")
-- Try exact match first, then prefix match via /target.
TargetByName(msg, true)
if not UnitExists("target") then
SlashCmdList.TARGET(msg)
end
if UnitExists("target") then
FocusUnit("target")
end
RunNextFrame(function()
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")
end)
if prevGUID and prevGUID ~= "0x0000000000000000" then
TargetUnit(prevGUID)
elseif prevPlayer then
TargetUnit("player")
else
ClearTarget()
local unit = UnitTokenFromName(msg, true) or UnitTokenFromName(msg)
if unit then
FocusUnit(unit)
end
end, true)
-1
View File
@@ -2459,7 +2459,6 @@ pfUI:RegisterModule("gui", function ()
CreateConfig(nil, T["Hide Chat When Bags Are Opened"], C.appearance.bags, "hidechat", "checkbox")
CreateConfig(nil, T["Bagslots Per Row"], C.appearance.bags, "bagrowlength")
CreateConfig(nil, T["Bankslots Per Row"], C.appearance.bags, "bankrowlength")
CreateConfig(nil, T["Enable Full-Text Search"], C.appearance.bags, "fulltext")
CreateConfig(nil, T["Item Slot Size"], C.appearance.bags, "icon_size")
CreateConfig(Reload, T["Reverse Cooldown Animation"], C.appearance.bags, "cooldown_reverse", "checkbox")
CreateConfig(nil, T["Auto Sell Grey Items"], C.global, "autosell", "checkbox")
+45
View File
@@ -128,6 +128,51 @@ pfUI:RegisterModule("panel", function()
GameTooltip:AddLine(" ")
GameTooltip:AddDoubleLine(T["Memory Usage"], "|cffffffff" .. memmb)
GameTooltip:AddDoubleLine(T["Next Memory Cleanup"], "|cffffffff" .. gcmb)
-- AddOn memory usage (see MainMenuBarPerformanceBarFrame_OnEnter in MainMenuBar.lua)
local ADDON_MEM_KB_ABBR = _G.ADDON_MEM_KB_ABBR or "(%.0f KB) %s";
local ADDON_MEM_MB_ABBR = _G.ADDON_MEM_MB_ABBR or "(%.2f MB) %s";
local TOTAL_MEM_KB_ABBR = _G.TOTAL_MEM_KB_ABBR or "AddOn Memory: %.0f KB";
local TOTAL_MEM_MB_ABBR = _G.TOTAL_MEM_MB_ABBR or "AddOn Memory: %.2f MB";
UpdateAddOnMemoryUsage()
local totalMem = 0
local topAddOns = {}
for i = 1, GetNumAddOns() do
local mem = GetAddOnMemoryUsage(i)
if mem and mem > 0 then
totalMem = totalMem + mem
for j = 1, 3 do
if not topAddOns[j] or mem > topAddOns[j].value then
for k = 3, j + 1, -1 do
topAddOns[k] = topAddOns[k - 1]
end
topAddOns[j] = { value = mem, name = C_AddOns.GetAddOnName(i) }
break
end
end
end
end
if totalMem > 0 then
local str
if totalMem > 1000 then
str = format(TOTAL_MEM_MB_ABBR, totalMem / 1000)
else
str = format(TOTAL_MEM_KB_ABBR, totalMem)
end
GameTooltip:AddLine(" ")
GameTooltip:AddLine(str, 1, 1, 1)
for i = 1, 3 do
if not topAddOns[i] then break end
if topAddOns[i].value > 1000 then
str = format(ADDON_MEM_MB_ABBR, topAddOns[i].value / 1000, topAddOns[i].name)
else
str = format(ADDON_MEM_KB_ABBR, topAddOns[i].value, topAddOns[i].name)
end
GameTooltip:AddLine(str, 1, 1, 1)
end
end
GameTooltip:AddLine(" ")
GameTooltip:AddDoubleLine(T["Network Down"], "|cffffffff" .. round(nin,1) .. "KB/s")
GameTooltip:AddDoubleLine(T["Network Up"], "|cffffffff" .. round(nout,1) .. "KB/s")
-15
View File
@@ -497,19 +497,4 @@ function pfUI.SetupCVars()
UIParentLoadAddOn("Blizzard_CombatText")
end
if not RunMacroText then
local obj = setmetatable({ ["GetText"] = function(self) return self.text end }, {
__index = function(tab,key)
local value = function() return end
rawset(tab,key,value)
return value
end
})
function RunMacroText(text)
obj.text = text
ChatEdit_ParseText(obj, 1)
end
end
_G.PLAYER_BUFF_START_ID = -1