Files
brues-code 75c4657ab9 ClassicAPI flavor TOCs, and drop the multi-client scaffolding (#53)
* nameplates: source totem icons from UnitCreatedBySpell

Read the totem's icon from the totem-drop spell (UnitCreatedBySpell +
GetSpellTexture) instead of the self-aura at index 1 plus a
UNIT_SPELLCAST_SUCCEEDED capture for active totems. The drop spell is a
broadcast descriptor field present for every summoned unit in range, so
it resolves immediately for passive and active totems alike and gives the
totem's own icon rather than the attack-spell proxy. Drops the
UNIT_SPELLCAST_SUCCEEDED registration and handler.

Re-read the spell each render and key the cached texture on the spell id
so an in-place totem swap (same unit, new drop spell -- no plate re-add)
refreshes the icon without needing the plate to leave and re-enter view.

* CAPI min bumped to 1.13.1

* Gracefully disable pfUI when ClassicAPI is missing

Add API_Check.lua as the first TOC entry. When the ClassicAPI DLL is
absent or below the minimum version it sets pfUI_disabled and stands up
an inert stub so the rest of the addon no-ops instead of flooding load
errors: modules and skins register their bodies into no-ops, and the
setfenv'd api/lib files run inside an environment where CreateFrame and
any missing global resolve to a null object -- so no real frames or live
handlers are created and missing API calls just return null. pfUI.lua
bails early on pfUI_disabled.

* auras: scan through GetAuraSlots instead of by-index loops

Every aura scan loop (unit frame buffs/debuffs, dispel indicators, buff and
custom indicators, player buff frame, buffwatch bars, tooltip buff row) now
enumerates a unit's auras once with C_UnitAuras.GetAuraSlots and reads each
aura by slot id via the positional C_UnitAuras.UnitAuraBySlot. The by-index
getters re-walk the aura array from slot 0 on every call, so a per-button
loop over them was quadratic in the aura count; one enumeration plus a
by-slot read per aura is linear.

pfUI.api.ScanAuraSlots(unit, filter, buf, max) wraps GetAuraSlots' fill-a-
table form (table as the 5th argument) so no vararg Lua frame is involved:
Lua 5.0 allocates an `arg` table for every vararg call, which showed up as
nameplate OnUpdate/OnEvent memory growth in the first cut of this change.

Single by-index reads in tooltip and click handlers are unchanged (one call
each, and SetUnitAura takes the same index).

Requires the ClassicAPI build that adds GetAuraSlots' fill form; on an older
DLL the 5th argument is ignored and ScanAuraSlots would read the first slot
id as the count.

* Show Faction/Race icons in chat

* Load pfUI through ClassicAPI's flavor TOCs

ClassicAPI redirects the read of pfUI\pfUI.toc to a flavored file whenever
the DLL is installed, so which TOC the client opens already answers whether
ClassicAPI is there. Split the manifest three ways and let that do the work:

  pfUI.toc             fallback, reached only when ClassicAPI is missing;
                       loads API_Check.lua and nothing else
  pfUI_ClassicAPI.toc  full addon, every non-Turtle client
  pfUI_Turtle.toc      full addon plus init\turtle.xml, on Turtle

The fallback TOC declares no SavedVariables. It used to, while API_Check.lua
reset pfUI_profiles to an empty table on the disabled path -- which truncated
the player's profiles on logout.

With the missing-DLL case handled by TOC selection, API_Check.lua drops the
null object stub that kept the other ~140 files quiet, along with
pfUI_disabled and the now unreachable early return in pfUI.lua. It keeps the
version gate, which still matters: the flavor redirect landed in ClassicAPI
v1.11.0, below the v1.13.1 pfUI needs, so an old DLL still gets served a
flavor TOC. pfUI.lua also loses a verbatim duplicate of the whole check.

Turtle-only files move to init\turtle.xml: modules\turtle-wow.lua (its
TURTLE_WOW_VERSION guard is now redundant) and the lft, turtle_shop,
barbershop, transmog and ebc skins. turtle-wow registers last instead of
75th of 84; the only ordering it relies on is pfUI.chat, registered 8th.

pfSellData moves to env\selldata.lua, listed only in pfUI_ClassicAPI.toc,
since turtle-wow.lua replaces the table wholesale on Turtle. env\tables.lua
keeps an empty declaration so sellvalue.lua has something to index when the
turtle-wow module is disabled.

The release workflow pinned PFUI_CLASSIC_API_LATEST in pfUI.lua, which has
not held that constant since it moved to API_Check.lua, so the pin was
silently doing nothing. It also switches to brues-code/packager@vCAPI, which
recognizes the _ClassicAPI and _Turtle suffixes and applies the TOC build
type filters to them.

* Split the vendor price tables into their own manifests

Turtle's pfSellData moves out of modules\turtle-wow.lua into
env\selldata_turtle.lua, matching env\selldata.lua for the stock list, and
each is pulled in by the manifest for its client: init\stock.xml from
pfUI_ClassicAPI.toc, init\turtle.xml from pfUI_Turtle.toc. Either way it
loads after init\env.xml and replaces the empty pfSellData declared there.

Turtle's prices used to be assigned inside the turtle-wow module body, which
put them on pfUI.env and skipped them entirely when that module was
disabled. At file scope they land on _G and apply either way.

* Drop the vanilla compat layer

compat\vanilla.lua named the handful of things that differed between clients
back when pfUI targeted several. Only one client remains, so every constant
had exactly one value. Inline each at its use site and delete the file,
init\compat.xml, and both TOC entries.

  COOLDOWN_FRAME_TYPE                    -> "Model"
  LOOT_BUTTON_FRAME_TYPE                 -> "LootButton"
  MINIMAP_TRACKING_FRAME                 -> _G.MiniMapTrackingFrame
  FRIENDS_NAME_LOCATION                  -> "ButtonTextNameLocation"
  EVENTS_MINIMAP_ZONE_UPDATE             -> the event list, in panel.lua
  MICRO_BUTTONS                          -> a local in panel.lua
  NAMEPLATE_OBJECTORDER                  -> a local in nameplates.lua
  ACTIONBAR_SECURE_TEMPLATE_BAR/_BUTTON  -> nil, so the argument goes away

NAMEPLATE_FRAMETYPE and PLAYER_BUFF_START_ID had no readers left.

RunMacroText moves to pfUI.lua. compat\vanilla.lua was setfenv'd into the
pfUI environment, so the function only ever existed on pfUI.env; at file
scope it lands on _G as a real export instead. Nothing in pfUI calls it, and
ClassicAPI neither defines nor looks for a RunMacroText global -- it does
the same throwaway edit box natively in src/macro/Execute.cpp and only
defers to a global RunMacro.

* bump CAPI min to 11303

* auras: uncap the self-debuff tooltip lookup

With selfdebuff on, the displayed debuff list is PLAYER-filtered while
GameTooltip:SetUnitAura indexes the unfiltered HARMFUL list, so both
handlers map one to the other by matching name + sourceGUID. That mapping
scanned slots 1..16 only.

The unfiltered harmful list is not capped at 16. Once a unit's 16 debuff
slots are full the server parks further debuffs in buff slots, and
C_UnitAuras classifies by the aura's polarity flag rather than its slot
range, so it reports those as harmful too -- verified live at 18 harmful on
a 20-aura target. Past the sixteenth the lookup found nothing and fell
through to the raw filtered index, opening the wrong tooltip or none.

Both now enumerate however many harmful auras the unit actually has, via
ScanAuraSlots, which also drops the per-index rescan the by-index accessor
was doing. Each handler gets its own slot buffer: OnEnter can fire while a
refresh is showing/hiding frames under the cursor, so sharing the refresh
buffer could clobber a scan mid-walk.

The nameplate module still collects at most 16 debuffs per plate. That one
is a display cap matching its 16 configured icon frames, not an aura-count
assumption, so it is left alone.

* bump CAPI min to 11304
2026-09-04 19:57:57 -05:00

1214 lines
44 KiB
Lua

pfUI:RegisterModule("bags", function ()
local rawborder, default_border = GetBorderSize("bags")
local extractSpells = {
[13262] = {frame="disenchant"},
[1804] = {frame="picklock"},
}
local scanner = libtipscan:GetScanner("input_search")
local function BagSortOpts()
return {
reverse = C.appearance.bags.sortreverse == "1",
reversePrio = C.appearance.bags.sortprioreverse == "1",
}
end
-- function to detect openable items in inventory
local openable = { bag = nil, slot = nil, icon = nil }
local function GetNextOpenable()
if openable.icon and openable.icon == GetContainerItemInfo(openable.bag, openable.slot) then
return openable.bag, openable.slot
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
local _, canOpen = C_Container.IsContainerItemOpenable(bag, slot)
if canOpen then
openable.bag = bag
openable.slot = slot
openable.icon = GetContainerItemInfo(bag, slot)
return openable.bag, openable.slot
end
end
end
end
-- prevent from being placed offscreen
_G.StackSplitFrame:SetClampedToScreen(true)
-- overwrite some bag functions
function _G.OpenAllBags()
if pfUI.bag.right:IsShown() then
pfUI.bag.right:Hide()
else
pfUI.bag.right:Show()
end
end
function _G.CloseAllBags()
pfUI.bag.right:Hide()
end
function _G.ToggleBackpack()
if pfUI.bag.right:IsShown() then
pfUI.bag.right:Hide()
else
pfUI.bag.right:Show()
end
end
function _G.OpenBackpack()
if ( pfUI.bag.right:IsShown() ) then
ContainerFrame1.backpackWasOpen = 1
return
else
ContainerFrame1.backpackWasOpen = nil
end
if ( not ContainerFrame1.backpackWasOpen ) then
ToggleBackpack()
end
end
function _G.ToggleBag()
return
end
-- hide blizzard's bankframe
BankFrame:SetScale(0.001)
BankFrame:SetPoint("TOPLEFT", 0,0)
BankFrame:SetAlpha(0)
pfUI.bag = CreateFrame("Frame", "pfUIBag")
pfUI.bag:RegisterEvent("PLAYER_ENTERING_WORLD")
pfUI.bag:RegisterEvent("BAG_UPDATE")
pfUI.bag:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
pfUI.bag:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED")
pfUI.bag:RegisterEvent("BAG_UPDATE_COOLDOWN")
pfUI.bag:RegisterEvent("BAG_CLOSED")
pfUI.bag:RegisterEvent("BANKFRAME_CLOSED")
pfUI.bag:RegisterEvent("BANKFRAME_OPENED")
pfUI.bag:RegisterEvent("ITEM_LOCK_CHANGED")
pfUI.bag:RegisterEvent("SPELLS_CHANGED")
pfUI.bag:RegisterEvent("MERCHANT_CLOSED")
pfUI.bag.delay = { UpdateBag = {} }
pfUI.bag:SetScript("OnUpdate", function()
-- update delayed ones every 0.1s
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
if this.delay.RefreshSpells then
this.delay.RefreshSpells = nil
pfUI.bag:RefreshSpells()
end
if this.delay.CheckFullUpdate then
this.delay.CheckFullUpdate = nil
pfUI.bag:CheckFullUpdate()
end
if this.delay.UpdateCooldowns then
this.delay.UpdateCooldowns = nil
pfUI.bag:UpdateCooldowns()
end
if this.delay.UpdateItemLock then
this.delay.UpdateItemLock = nil
pfUI.bag:UpdateItemLock()
end
for bag in pairs(this.delay.UpdateBag) do
this.delay.UpdateBag[bag] = nil
pfUI.bag:UpdateBag(bag)
end
end)
pfUI.bag:SetScript("OnEvent", function()
if event == "PLAYER_ENTERING_WORLD" then
pfUI.bag:CreateBags()
pfUI.bag.right:Hide()
pfUI.bag:CreateBags("bank")
pfUI.bag.left:Hide()
pfUI.bag:CreateBagSlots(pfUI.bag.right)
pfUI.bag:CreateBagSlots(pfUI.bag.left)
pfUI.bag:RefreshSpells()
end
if event == "SPELLS_CHANGED" then
this.delay.RefreshSpells = true
end
if event == "BAG_CLOSED" or event == "PLAYERBANKSLOTS_CHANGED" or
event == "PLAYERBANKBAGSLOTS_CHANGED" or event == "BAG_UPDATE" or
event == "BANKFRAME_OPENED" or event == "BANKFRAME_CLOSED" then
this.delay.CheckFullUpdate = true
end
if event == "BAG_UPDATE_COOLDOWN" then
this.delay.UpdateCooldowns = true
end
if event == "ITEM_LOCK_CHANGED" then
this.delay.UpdateItemLock = true
end
if event == "PLAYERBANKSLOTS_CHANGED" then
this.delay.UpdateBag[-1] = true
end
if event == "BAG_UPDATE" then
this.delay.UpdateBag[arg1] = true
end
if event == "PLAYERBANKBAGSLOTS_CHANGED" then
pfUI.bag:CreateBagSlots(pfUI.bag.left)
end
if event == "BANKFRAME_OPENED" then
pfUI.bag.left:Show()
OpenBackpack()
end
if event == "BANKFRAME_CLOSED" then
pfUI.bag.left:Hide()
end
if event == "MERCHANT_CLOSED" then
if not ContainerFrame1.backpackWasOpen then
pfUI.bag.right:Hide()
end
end
end)
tinsert(UISpecialFrames,"pfBag")
pfUI.BACKPACK = { -2, 0, 1, 2, 3, 4 }
pfUI.BANK = { -1, 5, 6, 7, 8, 9, 10, 11 }
pfUI.bags = {}
pfUI.slots = {}
function pfUI.bag:CheckFullUpdate()
local maxslots = 0
for bag = -2,11 do
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
maxslots = maxslots + bagsize
end
if maxslots ~= pfUI.bag.maxslots then
for bag = -2,11 do
for slot, f in ipairs(pfUI.bags[bag].slots) do
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
if slot > bagsize then
pfUI.bags[bag].slots[slot].frame:Hide()
end
end
end
pfUI.bag:CreateBags()
pfUI.bag:CreateBags("bank")
pfUI.bag.maxslots = maxslots
end
end
function pfUI.bag:CreateBags(object)
local x = 0
local y = 0
local frame = {}
local iterate = {}
local anchor, rowlength, cwidth
if object == "bank" then
if not pfUI.bag.left then pfUI.bag.left = CreateFrame("Frame", "pfBank", UIParent) end
anchor = { "BOTTOMLEFT", (pfUI.chat and pfUI.chat.left or nil), "BOTTOMRIGHT", "TOPLEFT", "TOPRIGHT" }
rowlength = tonumber(C.appearance.bags.bankrowlength)
cwidth = C.chat.left.width
iterate = pfUI.BANK
frame = pfUI.bag.left
else
if not pfUI.bag.right then pfUI.bag.right = CreateFrame("Frame", "pfBag", UIParent) end
rowlength = tonumber(C.appearance.bags.bagrowlength)
anchor = { "BOTTOMRIGHT", (pfUI.chat and pfUI.chat.right or nil), "BOTTOMLEFT", "TOPRIGHT", "TOPLEFT" }
cwidth = C.chat.right.width
iterate = pfUI.BACKPACK
frame = pfUI.bag.right
end
if not frame.init then
pfUI.bag:CreateAdditions(frame)
frame:SetFrameStrata("HIGH")
CreateBackdrop(frame, default_border)
CreateBackdropShadow(frame)
frame.init = true
end
if pfUI.chat and C.appearance.bags.icon_size == "-1" then
-- align bags to chat if no custom size is set
frame:SetWidth(cwidth * anchor[2]:GetScale())
elseif C.appearance.bags.icon_size ~= "-1" then
-- use custom size if set
frame:SetWidth((C.appearance.bags.icon_size + default_border*3) * rowlength - default_border)
else
-- fallback to 22px without any anchor or custom setting
frame:SetWidth((22 + default_border*3) * rowlength - default_border)
end
if pfUI.chat and C.appearance.bags.icon_size ~= "-1" then
-- ignore custom icon size
frame:SetPoint(anchor[1], anchor[2], anchor[1], 0, 0)
elseif pfUI.chat then
-- use chat frame as anchor if existing
if C.appearance.bags.abovechat == "0" then
frame:SetPoint(anchor[1], anchor[2], anchor[1], 0, 0)
frame:SetPoint(anchor[3], anchor[2], anchor[3], 0, 0)
else
frame:SetPoint(anchor[3], anchor[2], anchor[5], 0, 3*default_border)
frame:SetPoint(anchor[1], anchor[2], anchor[4], 0, 3*default_border)
end
else
-- align frame to UIParent if no anchor is available
frame:SetPoint(anchor[1], UIParent, anchor[1], 5, 5)
end
if C.appearance.bags.movable == "1" then
-- enable movable bag frames
LoadMovable(frame)
frame:EnableMouse(1)
frame:SetMovable(1)
frame:RegisterForDrag("LeftButton")
frame:SetScript("OnDragStart", function()
this:StartMoving()
end)
frame:SetScript("OnDragStop", function()
this:StopMovingOrSizing()
SaveMovable(this)
end)
end
frame:EnableMouse(1)
if C.appearance.bags.movable == "1" and C.appearance.bags.icon_size ~= "-1" then
frame.button_size = C.appearance.bags.icon_size
else
frame.button_size = (frame:GetWidth() - 2*default_border - (rowlength-1)*default_border*3)/ rowlength
end
local topspace = pfUI.bag.right.close:GetHeight() + default_border * 2
local bottomspace = pfUI.panel and pfUI.panel.right:IsShown() and pfUI.panel.right:GetHeight() + default_border or 16 + default_border
for id, bag in pairs(iterate) do
if not pfUI.bags[bag] then
pfUI.bags[bag] = CreateFrame("Frame", "pfBag" .. bag, frame)
pfUI.bags[bag]:SetAllPoints(frame)
pfUI.bags[bag].slots = {}
end
pfUI.bags[bag]:SetID(bag)
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
for slot=1, bagsize do
pfUI.bag:UpdateSlot(bag, slot)
pfUI.bags[bag].slots[slot].frame:ClearAllPoints()
pfUI.bags[bag].slots[slot].frame:SetPoint("TOPLEFT",
default_border + x*(frame.button_size+default_border*3),
-default_border*2 - y*(frame.button_size+default_border*3) - topspace)
pfUI.bags[bag].slots[slot].frame:SetSize(frame.button_size, frame.button_size)
if x >= rowlength - 1 then
y = y + 1
x = 0
else
x = x + 1
end
end
end
if x > 0 then y = y + 1 end
frame:SetHeight( default_border*2 + y*(frame.button_size+default_border*3) + topspace + bottomspace)
local chat = pfUI.chat and ( object == "bank" and pfUI.chat.left or pfUI.chat.right) or nil
frame:SetScript("OnShow", function()
frame.opened = true
if C.appearance.bags.hidechat == "1" and chat and chat:IsVisible() then
frame.chatWasOpen = true
chat:Hide()
end
if C.appearance.bags.autoSortOnOpen == "1" then
libbagsort:Sort({0, 1, 2, 3, 4}, BagSortOpts())
end
pfUI.bag:CreateBags(object)
PlaySound("INTERFACESOUND_BACKPACKOPEN")
end)
frame:SetScript("OnHide", function()
if C.appearance.bags.hidechat == "1" and chat and frame.chatWasOpen then
chat:Show()
frame.chatWasOpen = false
end
pfUI.bag:CreateBags(object)
PlaySound("INTERFACESOUND_BACKPACKCLOSE")
if frame.opened then
frame.opened = nil
pfUI.events:TriggerEvent("bag:closed", object)
end
end)
end
function pfUI.bag:UpdateBag(bag)
local bagsize = GetContainerNumSlots(bag)
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
for slot=1, bagsize do
pfUI.bag:UpdateSlot(bag, slot)
end
end
function pfUI.bag:UpdateSlot(bag, slot)
if not pfUI.bags[bag] then return end
if not pfUI.bags[bag].slots[slot] then
local tpl = "ContainerFrameItemButtonTemplate"
if bag == -1 then tpl = "BankItemButtonGenericTemplate" end
pfUI.bags[bag].slots[slot] = {}
pfUI.bags[bag].slots[slot].frame = CreateFrame("Button", "pfBag" .. bag .. "item" .. slot, pfUI.bags[bag], tpl)
pfUI.bags[bag].slots[slot].frame.qtext = pfUI.bags[bag].slots[slot].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
pfUI.bags[bag].slots[slot].frame:SetNormalTexture("")
pfUI.bags[bag].slots[slot].bag = bag
pfUI.bags[bag].slots[slot].slot = slot
pfUI.bags[bag].slots[slot].frame:SetID(slot)
-- add cooldown frame to bankslots
if tpl == "BankItemButtonGenericTemplate" then
local bankslot = pfUI.bags[bag].slots[slot].frame
local name = "pfBag" .. bag .. "item" .. slot .. "Cooldown"
bankslot.cd = CreateFrame("Model", name, bankslot, "CooldownFrameTemplate")
bankslot.cd:SetAllPoints(bankslot)
bankslot.cd.pfCooldownStyleAnimation = 1
bankslot.cd.pfCooldownType = "ALL"
else
local bagslot = pfUI.bags[bag].slots[slot].frame
bagslot.cd = _G[bagslot:GetName().."Cooldown"]
bagslot.cd.pfCooldownType = "ALL"
end
if not pfUI.bags[bag].slots[slot].frame.backdrop then
CreateBackdrop(pfUI.bags[bag].slots[slot].frame, default_border)
end
local highlight = pfUI.bags[bag].slots[slot].frame:GetHighlightTexture()
highlight:SetTexture(.5, .5, .5, .5)
local pushed = pfUI.bags[bag].slots[slot].frame:GetPushedTexture()
pushed:SetTexture(.5, .5, .5, .5)
local questText = pfUI.bags[bag].slots[slot].frame.qtext
questText:SetFont(pfUI.font_default, 13, "THICKOUTLINE")
questText:SetPoint("TOPLEFT", 0, 0)
questText:SetTextColor(1, .8, .2, 1)
local countFrame = _G[pfUI.bags[bag].slots[slot].frame:GetName() .. "Count"]
countFrame:SetFont(pfUI.font_unit, C.global.font_unit_size, "OUTLINE")
countFrame:SetAllPoints()
countFrame:SetJustifyH("RIGHT")
countFrame:SetJustifyV("BOTTOM")
local icon = _G[pfUI.bags[bag].slots[slot].frame:GetName() .. "IconTexture"]
icon:SetTexCoord(.08, .92, .08, .92)
icon:ClearAllPoints()
icon:SetPoint("TOPLEFT", 1, -1)
icon:SetPoint("BOTTOMRIGHT", -1, 1)
local border = _G[pfUI.bags[bag].slots[slot].frame:GetName() .. "NormalTexture"]
border:SetTexture("")
if ShaguScore then
pfUI.bags[bag].slots[slot].frame.scoreText = pfUI.bags[bag].slots[slot].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
pfUI.bags[bag].slots[slot].frame.scoreText:SetFont(pfUI.font_default, 12, "OUTLINE")
pfUI.bags[bag].slots[slot].frame.scoreText:SetPoint("TOPRIGHT", 0, 0)
end
end
local itemID = C_Container.GetContainerItemID(bag, slot)
local texture, count, locked, quality = GetContainerItemInfo(bag, slot)
if count == 1 then
local charges = C_Container.GetContainerItemCharges(bag, slot)
if charges > 1 then
count = charges
end
end
local _, _, q, _, _, _, itype = C_Item.GetItemInfo(itemID)
-- running advanced item color scan
if C.appearance.bags.borderonlygear == "0" and texture and quality and quality < 1 then
if quality then quality = q end
end
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)
local hasItem = texture and 1 or nil
pfUI.bags[bag].slots[slot].frame.hasItem = hasItem
pfUI.bags[bag].slots[slot].frame.qtext:SetText("")
ContainerFrame_UpdateCooldown(bag, pfUI.bags[bag].slots[slot].frame)
-- detect backdrop border color
if texture and itype == "Quest" then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(1, .8, .2, .8)
pfUI.bags[bag].slots[slot].frame.qtext:SetText("?")
elseif texture and quality and quality > tonumber(C.appearance.bags.borderlimit) then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(GetItemQualityColor(quality))
elseif texture and quality then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(.5,.5,.5,1)
else
local bagtype = GetBagFamily(bag)
if bagtype == "QUIVER" then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(1,1,.5,.5)
elseif bagtype == "SOULBAG" then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(1,.5,.5,.5)
elseif bagtype == "SPECIAL" then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(.5,.5,1,.5)
elseif bagtype == "KEYRING" then
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(.5,1,1,.5)
else
pfUI.bags[bag].slots[slot].frame.backdrop:SetBackdropBorderColor(1,1,1,.2)
end
end
-- add shaguscore if we have it
if ShaguScore and pfUI.bags[bag].slots[slot].frame.scoreText then
if quality and quality > 0 then
local item = Item:CreateFromBagAndSlot(bag, slot)
local r,g,b = item:GetItemQualityColorRGB()
local itemID = item:GetItemID()
local itemLevel = ShaguScore.Database[itemID] or 0
local score = ShaguScore:Calculate(vslot, quality, itemLevel)
if score and score > 0 and count and count == 1 then
pfUI.bags[bag].slots[slot].frame.scoreText:SetText(score)
pfUI.bags[bag].slots[slot].frame.scoreText:SetTextColor(r, g, b)
else
pfUI.bags[bag].slots[slot].frame.scoreText:SetText("")
end
else
pfUI.bags[bag].slots[slot].frame.scoreText:SetText("")
end
end
pfUI.bags[bag].slots[slot].frame:Show()
end
function pfUI.bag:CreateBagSlots(frame)
if not frame.bagslots then
frame.bagslots = CreateFrame("Frame", "pfBagSlots", frame)
frame.bagslots.slots = {}
frame.bagslots:Hide()
end
local min, max = 0, 3
local tpl = "BagSlotButtonTemplate"
local name, append = "pfUIBagsBBag", "Slot"
local position = "RIGHT"
if frame == pfUI.bag.left then
min, max = 1, math.min(NUM_BANKBAGSLOTS, (GetNumBankSlots() or 0))
tpl = "BankItemButtonBagTemplate"
name, append = "pfUIBankBBag", ""
position = "LEFT"
end
frame.bagslots:SetPoint("BOTTOM"..position, frame, "TOP"..position, 0, default_border*3)
CreateBackdrop(frame.bagslots, default_border)
CreateBackdropShadow(frame.bagslots)
local extra = frame == pfUI.bag.left and GetNumBankSlots() < NUM_BANKBAGSLOTS and 1 or 0
local width = (frame.button_size/5*4 + default_border*2) * (max-min+1+extra)
local height = default_border + (frame.button_size/5*4 + default_border)
frame.bagslots:SetSize(width, height)
for slot=min, max do
if not frame.bagslots.slots[slot] then
frame.bagslots.slots[slot] = {}
frame.bagslots.slots[slot].frame = CreateFrame("CheckButton", name .. slot .. append, frame.bagslots, tpl)
local icon = _G[frame.bagslots.slots[slot].frame:GetName() .. "IconTexture"]
local border = _G[frame.bagslots.slots[slot].frame:GetName() .. "NormalTexture"]
icon:SetTexCoord(.08, .92, .08, .92)
icon:ClearAllPoints()
icon:SetPoint("TOPLEFT", 1, -1)
icon:SetPoint("BOTTOMRIGHT", -1, 1)
border:SetTexture("")
local highlight = frame.bagslots.slots[slot].frame:GetHighlightTexture()
highlight:SetTexture(.5, .5, .5, .5)
local pushed = frame.bagslots.slots[slot].frame:GetPushedTexture()
pushed:SetTexture(.5, .5, .5, .5)
if frame == pfUI.bag.left then
frame.bagslots.slots[slot].frame:SetID(slot + 4)
frame.bagslots.slots[slot].frame.slot = slot + 3
else
frame.bagslots.slots[slot].frame.slot = slot
frame.bagslots.slots[slot].slot = slot
end
local SlotEnter = frame.bagslots.slots[slot].frame:GetScript("OnEnter")
frame.bagslots.slots[slot].frame:SetScript("OnEnter", function()
for slot, f in ipairs(pfUI.bags[this.slot + 1].slots) do
CreateBackdrop(f.frame, default_border)
f.frame.backdrop:SetBackdropBorderColor(.2,1,.8,1)
end
SlotEnter(this)
end)
local SlotLeave = frame.bagslots.slots[slot].frame:GetScript("OnLeave")
frame.bagslots.slots[slot].frame:SetScript("OnLeave", function()
pfUI.bag:UpdateBag(this.slot + 1)
SlotLeave()
end)
-- On TBC, the OnEvent function of the template scans for framenames,
-- and obviously doesn't know the pf-Names. Therefore, triggering
-- the update function on each frame manually
if frame == pfUI.bag.left and BankFrameItemButton_Update then
local SlotUpdate = frame.bagslots.slots[slot].frame:GetScript("OnUpdate")
frame.bagslots.slots[slot].frame:SetScript("OnUpdate", function()
if SlotUpdate then SlotUpdate(this) end
BankFrameItemButton_Update(this)
end)
end
end
local left = (slot-min)*(frame.button_size/5*4+default_border*2) + default_border
local top = -default_border
frame.bagslots.slots[slot].frame:ClearAllPoints()
frame.bagslots.slots[slot].frame:SetPoint("TOPLEFT", frame.bagslots, "TOPLEFT", left, top)
frame.bagslots.slots[slot].frame:SetSize(frame.button_size/5*4, frame.button_size/5*4)
CreateBackdrop(frame.bagslots.slots[slot].frame, default_border)
frame.bagslots.slots[slot].frame:Show()
if ( slot <= GetNumBankSlots() ) then
frame.bagslots.slots[slot].frame.tooltipText = BANK_BAG
else
frame.bagslots.slots[slot].frame.tooltipText = BANK_BAG_PURCHASE
end
end
if frame == pfUI.bag.left then
if GetNumBankSlots() < NUM_BANKBAGSLOTS then
if not frame.bagslots.buy then
frame.bagslots.buy = CreateFrame("Button", "pfBagSlotBuy", frame.bagslots)
end
frame.bagslots.buy:SetPoint("RIGHT", frame.bagslots, "RIGHT", -default_border, 0)
CreateBackdrop(frame.bagslots.buy, default_border)
frame.bagslots.buy:SetSize(frame.button_size/5*4, frame.button_size/5*4)
frame.bagslots.buy:SetText("+")
frame.bagslots.buy:SetTextColor(.5,.5,1,1)
frame.bagslots.buy:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.bagslots.buy:SetScript("OnEnter", function ()
frame.bagslots.buy:SetTextColor(1,1,1,1)
end)
frame.bagslots.buy:SetScript("OnLeave", function ()
frame.bagslots.buy:SetTextColor(.5,.5,1,1)
end)
frame.bagslots.buy:SetScript("OnClick", function()
StaticPopup_Show("CONFIRM_BUY_BANK_SLOT")
end)
else
if frame.bagslots.buy then frame.bagslots.buy:Hide() end
end
end
end
function pfUI.bag:ReanchorAdditions()
local frame = pfUI.bag.right
local show_disenchant = (frame.disenchant:GetID() > 0)
local show_picklock = (frame.picklock:GetID() > 0)
if not show_disenchant then
frame.disenchant:Hide()
frame.picklock:SetPoint("TOPRIGHT", frame.open, "TOPLEFT", -default_border*3, 0)
else
frame.disenchant:Show()
frame.picklock:SetPoint("TOPRIGHT", frame.disenchant, "TOPLEFT", -default_border*3, 0)
end
if not show_picklock then
frame.picklock:Hide()
if show_disenchant then
frame.keys:SetPoint("TOPRIGHT", frame.disenchant, "TOPLEFT", -default_border*3, 0)
else
frame.keys:SetPoint("TOPRIGHT", frame.open, "TOPLEFT", -default_border*3, 0)
end
else
frame.picklock:Show()
frame.keys:SetPoint("TOPRIGHT", frame.picklock, "TOPLEFT", -default_border*3, 0)
end
end
function pfUI.bag:UpdateCooldowns()
local frame
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
frame = pfUI.bags[bag] and pfUI.bags[bag].slots[slot] and pfUI.bags[bag].slots[slot].frame
if frame and frame.hasItem and _G[frame:GetName() .. "Cooldown"] then
ContainerFrame_UpdateCooldown(bag, frame)
end
end
end
end
function pfUI.bag:UpdateItemLock()
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
if pfUI.bags[bag] and pfUI.bags[bag].slots[slot] and pfUI.bags[bag].slots[slot].frame:IsShown() then
local _, _, locked, _ = GetContainerItemInfo(bag, slot)
if pfUI.bags[bag].slots[slot].locked ~= locked then
SetItemButtonDesaturated(pfUI.bags[bag].slots[slot].frame, locked, 0.5, 0.5, 0.5)
if pfUI.unusable then pfUI.unusable:UpdateSlot(bag, slot) end
pfUI.bags[bag].slots[slot].locked = locked
end
end
end
end
end
function pfUI.bag:RefreshSpells()
if not (pfUI.bag and pfUI.bag.right) then return end
for spellID, widget in pairs(extractSpells) do
if IsSpellKnown(spellID) and pfUI.bag.right[widget.frame] then
pfUI.bag.right[widget.frame]:SetID(spellID)
end
end
pfUI.bag:ReanchorAdditions()
end
function pfUI.bag:CreateAdditions(frame)
-- bag additions
if frame == pfUI.bag.right then
-- bag close button
if not frame.close then
frame.close = CreateFrame("Button", "pfBagClose", frame)
frame.close:SetPoint("TOPRIGHT", -default_border*1,-default_border )
CreateBackdrop(frame.close, default_border)
frame.close:SetSize(12, 12)
frame.close.texture = frame.close:CreateTexture("pfBagClose")
frame.close.texture:SetTexture(pfUI.media["img:close"])
frame.close.texture:ClearAllPoints()
frame.close.texture:SetPoint("TOPLEFT", frame.close, "TOPLEFT", 2, -2)
frame.close.texture:SetPoint("BOTTOMRIGHT", frame.close, "BOTTOMRIGHT", -2, 2)
frame.close.texture:SetVertexColor(1,.25,.25,1)
frame.close:SetScript("OnEnter", function ()
frame.close.backdrop:SetBackdropBorderColor(1,.25,.25,1)
end)
frame.close:SetScript("OnLeave", function ()
CreateBackdrop(frame.close, default_border)
end)
frame.close:SetScript("OnClick", function()
CloseAllBags()
end)
end
-- bags button
if not frame.bags then
frame.bags = CreateFrame("Button", "pfBagSlotShow", frame)
frame.bags:SetPoint("TOPRIGHT", frame.close, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.bags, default_border)
frame.bags:SetSize(12, 12)
frame.bags:SetTextColor(1,1,.25,1)
frame.bags:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.bags.texture = frame.bags:CreateTexture("pfBagArrowUp")
frame.bags.texture:SetTexture(pfUI.media["img:up"])
frame.bags.texture:ClearAllPoints()
frame.bags.texture:SetPoint("TOPLEFT", frame.bags, "TOPLEFT", 3, -1)
frame.bags.texture:SetPoint("BOTTOMRIGHT", frame.bags, "BOTTOMRIGHT", -3, 1)
frame.bags.texture:SetVertexColor(.25,.25,.25,1)
frame.bags:SetScript("OnEnter", function ()
frame.bags.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.bags.texture:SetVertexColor(1,1,.25,1)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(_G.TUTORIAL_TITLE10)
GameTooltip:Show()
end)
frame.bags:SetScript("OnLeave", function ()
CreateBackdrop(frame.bags, default_border)
frame.bags.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.bags:SetScript("OnClick", function()
pfUI.bag.right.bagslots:SetShown(not pfUI.bag.right.bagslots:IsShown())
end)
end
-- open button
if not frame.open then
frame.open = CreateFrame("Button", "pfBagSlotOpen", frame)
frame.open:SetPoint("TOPRIGHT", frame.bags, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.open, default_border)
frame.open:SetSize(12, 12)
frame.open:SetTextColor(1,1,.25,1)
frame.open:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.open.texture = frame.open:CreateTexture("pfBagOpenContainer")
frame.open.texture:SetTexture(pfUI.media["img:empty"])
frame.open.texture:ClearAllPoints()
frame.open.texture:SetPoint("TOPLEFT", frame.open, "TOPLEFT", 3, -1)
frame.open.texture:SetPoint("BOTTOMRIGHT", frame.open, "BOTTOMRIGHT", -3, 1)
frame.open.texture:SetVertexColor(.25,.25,.25,1)
frame.open:SetScript("OnEnter", function ()
frame.open.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.open.texture:SetVertexColor(1,1,.25,1)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
local bag, slot = GetNextOpenable()
if bag and slot then
GameTooltip:SetBagItem(bag, slot)
else
GameTooltip:SetText(_G.EMPTY)
end
GameTooltip:Show()
end)
frame.open:SetScript("OnLeave", function ()
CreateBackdrop(frame.open, default_border)
frame.open.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.open:SetScript("OnClick", function()
-- open next container item
local bag, slot = GetNextOpenable()
if bag and slot then
ClearCursor()
if MerchantFrame:IsShown() then
HideUIPanel(MerchantFrame)
end
UseContainerItem(bag, slot)
end
-- reload tootltip
local bag, slot = GetNextOpenable()
if bag and slot then
GameTooltip:SetBagItem(bag, slot)
else
GameTooltip:SetText(_G.EMPTY)
end
end)
end
-- disenchant button
if not frame.disenchant then
frame.disenchant = CreateFrame("Button", "pfBagSlotDisenchant", frame)
frame.disenchant:SetPoint("TOPRIGHT", frame.open, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.disenchant, default_border)
frame.disenchant:SetSize(12, 12)
frame.disenchant:SetTextColor(1,1,.25,1)
frame.disenchant:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.disenchant.texture = frame.disenchant:CreateTexture("pfBagDisenchant")
frame.disenchant.texture:SetTexture(pfUI.media["img:disenchant"])
frame.disenchant.texture:ClearAllPoints()
frame.disenchant.texture:SetPoint("TOPLEFT", frame.disenchant, "TOPLEFT", 3, -1)
frame.disenchant.texture:SetPoint("BOTTOMRIGHT", frame.disenchant, "BOTTOMRIGHT", -3, 1)
frame.disenchant.texture:SetVertexColor(.25,.25,.25,1)
frame.disenchant:SetScript("OnEnter", function ()
frame.disenchant.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.disenchant.texture:SetVertexColor(1,1,.25,1)
local id = this:GetID()
if id and id > 0 then
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetSpellByID(id)
GameTooltip:Show()
end
end)
frame.disenchant:SetScript("OnLeave", function ()
CreateBackdrop(frame.disenchant, default_border)
frame.disenchant.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.disenchant:SetScript("OnClick", function()
local id = this:GetID()
if id and id > 0 then
CastSpellByName(id)
end
end)
end
-- pick lock button
if not frame.picklock then
frame.picklock = CreateFrame("Button", "pfBagSlotPicklock", frame)
frame.picklock:SetPoint("TOPRIGHT", frame.disenchant, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.picklock, default_border)
frame.picklock:SetSize(12, 12)
frame.picklock:SetTextColor(1,1,.25,1)
frame.picklock:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.picklock.texture = frame.picklock:CreateTexture("pfBagPicklock")
frame.picklock.texture:SetTexture(pfUI.media["img:picklock"])
frame.picklock.texture:ClearAllPoints()
frame.picklock.texture:SetPoint("TOPLEFT", frame.picklock, "TOPLEFT", 3, -1)
frame.picklock.texture:SetPoint("BOTTOMRIGHT", frame.picklock, "BOTTOMRIGHT", -3, 1)
frame.picklock.texture:SetVertexColor(.25,.25,.25,1)
frame.picklock:SetScript("OnEnter", function ()
frame.picklock.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.picklock.texture:SetVertexColor(1,1,.25,1)
local id = this:GetID()
if id and id > 0 then
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetSpellByID(id)
GameTooltip:Show()
end
end)
frame.picklock:SetScript("OnLeave", function ()
CreateBackdrop(frame.picklock, default_border)
frame.picklock.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.picklock:SetScript("OnClick", function()
local id = this:GetID()
if id and id > 0 then
CastSpellByName(id)
end
end)
end
-- key button
if not frame.keys then
frame.keys = CreateFrame("Button", "pfBagSlotShow", frame)
frame.keys:SetPoint("TOPRIGHT", frame.picklock, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.keys, default_border)
frame.keys:SetSize(12, 12)
frame.keys:SetTextColor(1,1,.25,1)
frame.keys:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.keys.texture = frame.keys:CreateTexture("pfBagArrowUp")
frame.keys.texture:SetTexture(pfUI.media["img:key"])
frame.keys.texture:ClearAllPoints()
frame.keys.texture:SetPoint("TOPLEFT", frame.keys, "TOPLEFT", 3, -1)
frame.keys.texture:SetPoint("BOTTOMRIGHT", frame.keys, "BOTTOMRIGHT", -3, 1)
frame.keys.texture:SetVertexColor(.25,.25,.25,1)
frame.keys:SetScript("OnEnter", function ()
frame.keys.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.keys.texture:SetVertexColor(1,1,.25,1)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(_G.KEYRING)
GameTooltip:Show()
end)
frame.keys:SetScript("OnLeave", function ()
CreateBackdrop(frame.keys, default_border)
frame.keys.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.keys:SetScript("OnClick", function()
if not pfUI.bag.showKeyring then
pfUI.bag.showKeyring = true
else
pfUI.bag.showKeyring = nil
end
pfUI.bag:CheckFullUpdate()
end)
end
-- sort button (anchors to keys, which is the always-present leftmost
-- button in the dynamic chain — picklock and disenchant are class-gated)
if not frame.sort then
frame.sort = CreateFrame("Button", "pfBagSort", frame)
frame.sort:SetPoint("TOPRIGHT", frame.keys, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.sort, default_border)
frame.sort:SetSize(12, 12)
frame.sort.texture = frame.sort:CreateTexture("pfBagSortIcon")
frame.sort.texture:SetTexture(pfUI.media["img:sort"])
frame.sort.texture:ClearAllPoints()
frame.sort.texture:SetPoint("TOPLEFT", frame.sort, "TOPLEFT", 2, -2)
frame.sort.texture:SetPoint("BOTTOMRIGHT", frame.sort, "BOTTOMRIGHT", -2, 2)
frame.sort.texture:SetVertexColor(.25,.25,.25,1)
frame.sort:SetScript("OnEnter", function ()
frame.sort.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.sort.texture:SetVertexColor(1,1,.25,1)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(T["Sort Bags"])
GameTooltip:Show()
end)
frame.sort:SetScript("OnLeave", function ()
CreateBackdrop(frame.sort, default_border)
frame.sort.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.sort:SetScript("OnClick", function()
libbagsort:Sort({0, 1, 2, 3, 4}, BagSortOpts())
end)
end
-- gold string
if not frame.gold and (C.appearance.bags.movable == "1" or not pfUI.panel) then
frame.gold = CreateFrame("Frame", "pfBagGoldString", frame)
frame.gold:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -4, 1)
frame.gold:SetSize(200, 18)
frame.gold:RegisterEvent("PLAYER_ENTERING_WORLD")
frame.gold:RegisterEvent("PLAYER_MONEY")
frame.gold:SetScript("OnEvent", function()
frame.gold.text:SetText(CreateGoldString(GetMoney()))
end)
frame.gold.text = frame.gold.text or frame.gold:CreateFontString(nil, "OVERLAY", "GameFontNormal")
frame.gold.text:SetFontObject(GameFontWhite)
frame.gold.text:SetJustifyH("RIGHT")
frame.gold.text:SetAllPoints()
end
-- 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)
CreateBackdrop(frame.search, default_border)
frame.search.edit = CreateFrame("EditBox", "pfUIBagSearch", frame.search, "InputBoxTemplate")
pfUIBagSearchLeft:SetTexture(nil)
pfUIBagSearchMiddle:SetTexture(nil)
pfUIBagSearchRight:SetTexture(nil)
frame.search.edit:ClearAllPoints()
frame.search.edit:SetPoint("TOPLEFT", frame.search, "TOPLEFT", default_border*2, 0)
frame.search.edit:SetPoint("BOTTOMRIGHT", frame.search, "BOTTOMRIGHT", -default_border*2, 0)
frame.search.edit:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.search.edit:SetAutoFocus(false)
frame.search.edit:SetText(T["Search"])
frame.search.edit:SetTextColor(.5,.5,.5,1)
frame.search.edit:SetScript("OnEditFocusGained", function()
this:SetText("")
end)
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
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
end)
frame.search:SetScript("OnLeave", function()
frame.search.edit:ClearFocus()
end)
frame.search.edit:SetScript("OnMouseUp", function()
if arg1 == "RightButton" then
this:ClearFocus()
end
end)
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
end)
end
else
-- bankframe
-- bag close button
if not frame.close then
frame.close = CreateFrame("Button", "pfBagClose", frame)
frame.close:SetPoint("TOPRIGHT", -default_border*1,-default_border )
CreateBackdrop(frame.close, default_border)
frame.close:SetSize(12, 12)
frame.close.texture = frame.close:CreateTexture("pfBagClose")
frame.close.texture:SetTexture(pfUI.media["img:close"])
frame.close.texture:ClearAllPoints()
frame.close.texture:SetPoint("TOPLEFT", frame.close, "TOPLEFT", 2, -2)
frame.close.texture:SetPoint("BOTTOMRIGHT", frame.close, "BOTTOMRIGHT", -2, 2)
frame.close.texture:SetVertexColor(1,.25,.25,1)
frame.close:SetScript("OnEnter", function ()
frame.close.backdrop:SetBackdropBorderColor(1,.25,.25,1)
end)
frame.close:SetScript("OnLeave", function ()
CreateBackdrop(frame.close, default_border)
end)
frame.close:SetScript("OnClick", function()
CloseBankFrame()
end)
end
-- bags button
if not frame.bags then
frame.bags = CreateFrame("Button", "pfBagSlotShow", frame)
frame.bags:SetPoint("TOPRIGHT", frame.close, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.bags, default_border)
frame.bags:SetSize(12, 12)
frame.bags:SetTextColor(1,1,.25,1)
frame.bags:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
frame.bags.texture = frame.bags:CreateTexture("pfBagArrowUp")
frame.bags.texture:SetTexture(pfUI.media["img:up"])
frame.bags.texture:ClearAllPoints()
frame.bags.texture:SetPoint("TOPLEFT", frame.bags, "TOPLEFT", 3, -1)
frame.bags.texture:SetPoint("BOTTOMRIGHT", frame.bags, "BOTTOMRIGHT", -3, 1)
frame.bags.texture:SetVertexColor(.25,.25,.25,1)
frame.bags:SetScript("OnEnter", function ()
frame.bags.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.bags.texture:SetVertexColor(1,1,.25,1)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(_G.TUTORIAL_TITLE10)
GameTooltip:Show()
end)
frame.bags:SetScript("OnLeave", function ()
CreateBackdrop(frame.bags, default_border)
frame.bags.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.bags:SetScript("OnClick", function()
if pfUI.bag.left.bagslots:IsShown() then
pfUI.bag.left.bagslots:Hide()
else
pfUI.bag.left.bagslots:Show()
end
end)
end
-- sort button (bank)
if not frame.sort then
frame.sort = CreateFrame("Button", "pfBankSort", frame)
frame.sort:SetPoint("TOPRIGHT", frame.bags, "TOPLEFT", -default_border*3, 0)
CreateBackdrop(frame.sort, default_border)
frame.sort:SetHeight(12)
frame.sort:SetWidth(12)
frame.sort.texture = frame.sort:CreateTexture("pfBankSortIcon")
frame.sort.texture:SetTexture(pfUI.media["img:sort"])
frame.sort.texture:ClearAllPoints()
frame.sort.texture:SetPoint("TOPLEFT", frame.sort, "TOPLEFT", 2, -2)
frame.sort.texture:SetPoint("BOTTOMRIGHT", frame.sort, "BOTTOMRIGHT", -2, 2)
frame.sort.texture:SetVertexColor(.25,.25,.25,1)
frame.sort:SetScript("OnEnter", function ()
frame.sort.backdrop:SetBackdropBorderColor(1,1,.25,1)
frame.sort.texture:SetVertexColor(1,1,.25,1)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(T["Sort Bank"])
GameTooltip:Show()
end)
frame.sort:SetScript("OnLeave", function ()
CreateBackdrop(frame.sort, default_border)
frame.sort.texture:SetVertexColor(.25,.25,.25,1)
if GameTooltip:IsOwned(this) then
GameTooltip:Hide()
end
end)
frame.sort:SetScript("OnClick", function()
libbagsort:Sort({-1, 5, 6, 7, 8, 9, 10}, BagSortOpts())
end)
end
end
end
end)