PK 0>*T$ Bagnon/Bagnon.toc## Interface: 40200
## Title: Bagnon
## Author: Tuller & Jaliborc (João Libório)
## Notes: Single window displays for your inventory and bank
## SavedVariables: BagnonGlobalSettings
## SavedVariablesPerCharacter: BagnonFrameSettings
## Version: 4.2.4
## OptionalDeps: LibStub, Ace3, Bagnon_Forever, Bagnon_Armory, LibItemSearch, ButtonFacade, LibButtonFacade
embeds.xml
localization.xml
main.lua
utility.xml
components.xmlPK d>K Bagnon/Bindings.xml
Bagnon:ToggleFrame('inventory')
Bagnon:ToggleFrame('bank')
PK d>#*$ $ Bagnon/components.xml
PK d>S Bagnon/embeds.xml
PK d>kbrV Bagnon/LICENSECopyright (c) 2011 Jason Greer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.PK d>(5 Bagnon/localization.xml
PK yu>g}z- - Bagnon/main.lua--[[
main.lua
The bagnon driver thingy
--]]
Bagnon = LibStub('AceAddon-3.0'):NewAddon('Bagnon', 'AceEvent-3.0', 'AceConsole-3.0')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local Facade = LibStub('LibButtonFacade', true)
--[[
Binding Setup
--]]
BINDING_HEADER_BAGNON = 'Bagnon'
BINDING_NAME_BAGNON_TOGGLE = L.ToggleBags
BINDING_NAME_BANKNON_TOGGLE = L.ToggleBank
--[[
Startup
--]]
function Bagnon:OnInitialize()
self.frames = {}
self:HookBagClickEvents()
self:RegisterAutoDisplayEvents()
self:AddSlashCommands()
self:CreateOptionsLoader()
self:CreateLDBLauncher()
self:CreateGuildBankLoader()
if Facade then
self:StartupFacade()
end
end
--create a loader for the options menu
function Bagnon:CreateOptionsLoader()
local f = CreateFrame('Frame', nil, InterfaceOptionsFrame)
f:SetScript('OnShow', function(self)
self:SetScript('OnShow', nil)
LoadAddOn('Bagnon_Config')
end)
end
function Bagnon:CreateGuildBankLoader()
local name, title, notes, enabled, loadable = GetAddOnInfo('Bagnon_GuildBank')
if enabled and loadable then
GuildBankFrame_LoadUI = function()
LoadAddOn('Bagnon_GuildBank')
end
end
end
function Bagnon:CreateLDBLauncher()
local LDB = LibStub:GetLibrary('LibDataBroker-1.1', true)
if not LDB then return end
LDB:NewDataObject('BagnonLauncher', {
type = 'launcher',
icon = [[Interface\Icons\INV_Misc_Bag_07]],
OnClick = function(_, button)
if button == 'LeftButton' then
if IsShiftKeyDown() then
Bagnon:ToggleFrame('bank')
else
Bagnon:ToggleFrame('inventory')
end
elseif button == 'RightButton' then
Bagnon:ShowOptions()
end
end,
OnTooltipShow = function(tooltip)
if not tooltip or not tooltip.AddLine then return end
tooltip:AddLine('Bagnon')
tooltip:AddLine(L.TipShowInventory, 1, 1, 1)
tooltip:AddLine(L.TipShowBank, 1, 1, 1)
tooltip:AddLine(L.TipShowOptions, 1, 1, 1)
end,
})
end
--[[
Frame Display
--]]
function Bagnon:GetFrame(frameID)
for i, frame in pairs(self.frames) do
if frame:GetFrameID() == frameID then
return frame
end
end
end
function Bagnon:CreateFrame(frameID)
table.insert(self.frames, self.Frame:New(frameID))
end
function Bagnon:ShowFrame(frameID)
if self:IsFrameEnabled(frameID) then
if not self:GetFrame(frameID) then
self:CreateFrame(frameID)
end
self.FrameSettings:Get(frameID):Show()
return true
end
return false
end
function Bagnon:HideFrame(frameID)
if self:IsFrameEnabled(frameID) then
self.FrameSettings:Get(frameID):Hide()
return true
end
return false
end
function Bagnon:ToggleFrame(frameID)
if self:IsFrameEnabled(frameID) then
if not self:GetFrame(frameID) then
self:CreateFrame(frameID)
end
self.FrameSettings:Get(frameID):Toggle()
return true
end
return false
end
function Bagnon:IsFrameEnabled(frameID)
return self.Settings:IsFrameEnabled(frameID)
end
function Bagnon:FrameControlsBag(frameID, bagSlot)
return self.FrameSettings:Get(frameID):IsBagSlotShown(bagSlot) or (not self:IsBlizzardBagPassThroughEnabled())
end
function Bagnon:IsBlizzardBagPassThroughEnabled()
return self.Settings:IsBlizzardBagPassThroughEnabled()
end
--[[
Bag Click Events
--]]
function Bagnon:HookBagClickEvents()
--backpack
hooksecurefunc('CloseBackpack', function()
self:HideFrame('inventory')
end)
local oOpenBackpack = OpenBackpack
OpenBackpack = function()
local shown = self:FrameControlsBag('inventory', BACKPACK_CONTAINER) and self:ShowFrame('inventory')
if not shown then
oOpenBackpack()
end
end
local oToggleBackpack = ToggleBackpack
ToggleBackpack = function()
local toggled = self:FrameControlsBag('inventory', BACKPACK_CONTAINER) and self:ToggleFrame('inventory')
if not toggled then
oToggleBackpack()
end
end
--single bag
local oToggleBag = ToggleBag
ToggleBag = function(bagSlot)
local frameID = self.BagSlotInfo:IsBankBag(bagSlot) and 'bank' or 'inventory'
local toggled = self:FrameControlsBag(frameID, bagSlot) and self:ToggleFrame(frameID)
if not toggled then
oToggleBag(bagSlot)
end
end
--all bags
--closing the game menu triggers this function, and can be done in combat
hooksecurefunc('CloseAllBags', function()
self:HideFrame('inventory')
end)
local oOpenAllBags = OpenAllBags
OpenAllBags = function(force)
local opened = false
if force then
opened = self:FrameControlsBag('inventory', BACKPACK_CONTAINER) and self:ShowFrame('inventory')
else
opened = self:FrameControlsBag('inventory', BACKPACK_CONTAINER) and self:ToggleFrame('inventory')
end
if not opened then
oOpenAllBags(force)
end
end
if ToggleAllBags then
local oToggleAllBags = ToggleAllBags
ToggleAllBags = function()
local toggled = self:FrameControlsBag('inventory', BACKPACK_CONTAINER) and self:ToggleFrame('inventory')
if not toggled then
oToggleAllBags()
end
end
end
local function bag_checkIfInventoryShown(self)
if Bagnon:IsFrameEnabled('inventory') then
self:SetChecked(Bagnon.FrameSettings:Get('inventory'):IsShown())
end
end
--handle checking/unchecking of the backpack buttons based on frame display
hooksecurefunc('BagSlotButton_UpdateChecked', bag_checkIfInventoryShown)
hooksecurefunc('BackpackButton_UpdateChecked', bag_checkIfInventoryShown)
self.Callbacks:Listen(self, 'FRAME_SHOW')
self.Callbacks:Listen(self, 'FRAME_HIDE')
end
--[[
Click Events
--]]
function Bagnon:FRAME_SHOW(msg, frameID)
if frameID == 'inventory' then
if self:IsFrameEnabled('inventory') then
self:CheckBagFrameBags(true)
end
end
end
function Bagnon:FRAME_HIDE(msg, frameID)
if frameID == 'inventory' then
if self:IsFrameEnabled('inventory') then
self:CheckBagFrameBags(false)
end
end
end
--check/uncheck the bag frames
function Bagnon:CheckBagFrameBags(checked)
_G['MainMenuBarBackpackButton']:SetChecked(checked)
_G["CharacterBag0Slot"]:SetChecked(checked)
_G["CharacterBag1Slot"]:SetChecked(checked)
_G["CharacterBag2Slot"]:SetChecked(checked)
_G["CharacterBag3Slot"]:SetChecked(checked)
end
--[[
Automatic Display
--]]
function Bagnon:RegisterAutoDisplayEvents()
self.BagEvents:Listen(self, 'BANK_OPENED')
self.BagEvents:Listen(self, 'BANK_CLOSED')
self:RegisterEvent('MAIL_CLOSED')
self:RegisterEvent('AUCTION_HOUSE_SHOW')
self:RegisterEvent('AUCTION_HOUSE_CLOSED')
self:RegisterEvent('MERCHANT_SHOW')
self:RegisterEvent('MERCHANT_CLOSED')
self:RegisterEvent('TRADE_SHOW')
self:RegisterEvent('TRADE_CLOSED')
self:RegisterEvent('TRADE_SKILL_SHOW')
self:RegisterEvent('TRADE_SKILL_CLOSE')
self:RegisterEvent('GUILDBANKFRAME_OPENED')
self:RegisterEvent('GUILDBANKFRAME_CLOSED')
self:RegisterEvent('PLAYER_REGEN_DISABLED')
self:RegisterEvent('UNIT_ENTERED_VEHICLE')
--override normal bank display
BankFrame:UnregisterEvent('BANKFRAME_OPENED')
BankFrame:UnregisterEvent('BANKFRAME_CLOSED')
local f = CreateFrame('Frame', nil, CharacterFrame)
f:SetScript('OnShow', function() Bagnon:PLAYER_FRAME_SHOW() end)
f:SetScript('OnHide', function() Bagnon:PLAYER_FRAME_HIDE() end)
end
function Bagnon:ShowFrameAtEvent(frameID, event)
if self:AutoDisplayingFrameOnEvent(frameID, event) then
self:ShowFrame(frameID)
end
end
function Bagnon:HideFrameAtEvent(frameID, event)
if self:AutoDisplayingFrameOnEvent(frameID, event) then
self:HideFrame(frameID)
end
end
function Bagnon:AutoDisplayingFrameOnEvent(frameID, event)
return self.Settings:IsFrameShownAtEvent(frameID, event)
end
function Bagnon:ShowBlizzardBankFrame()
BankFrame_OnEvent(_G['BankFrame'], 'BANKFRAME_OPENED')
end
function Bagnon:HideBlizzardBankFrame()
BankFrame_OnEvent(_G['BankFrame'], 'BANKFRAME_CLOSED')
end
--[[ Display Events ]]--
-- combat
function Bagnon:PLAYER_REGEN_DISABLED()
self:HideFrameAtEvent('inventory', 'combat')
end
function Bagnon:UNIT_ENTERED_VEHICLE(unit)
if unit == 'player' then
self:HideFrameAtEvent('inventory', 'vehicle')
end
end
--visiting the bank
function Bagnon:BANK_OPENED()
if not self:ShowFrame('bank') then
self:ShowBlizzardBankFrame()
end
self:ShowFrameAtEvent('inventory', 'bank')
end
function Bagnon:BANK_CLOSED()
if not self:HideFrame('bank') then
self:HideBlizzardBankFrame()
end
self:HideFrameAtEvent('inventory', 'bank')
end
--visiting the mailbox
--mail frame is a special case, since its automatically handled by the stock interface
function Bagnon:MAIL_CLOSED()
self:HideFrame('inventory')
end
--visiting the auction house
function Bagnon:AUCTION_HOUSE_SHOW()
self:ShowFrameAtEvent('inventory', 'ah')
end
function Bagnon:AUCTION_HOUSE_CLOSED()
self:HideFrameAtEvent('inventory', 'ah')
end
--visitng a vendor
function Bagnon:MERCHANT_SHOW()
self:ShowFrameAtEvent('inventory', 'vendor')
end
function Bagnon:MERCHANT_CLOSED()
self:HideFrameAtEvent('inventory', 'vendor')
end
--trading
function Bagnon:TRADE_SHOW()
self:ShowFrameAtEvent('inventory', 'trade')
end
function Bagnon:TRADE_CLOSED()
self:HideFrameAtEvent('inventory', 'trade')
end
--visiting the guild bank
function Bagnon:GUILDBANKFRAME_OPENED()
self:ShowFrameAtEvent('inventory', 'guildbank')
end
function Bagnon:GUILDBANKFRAME_CLOSED()
self:HideFrameAtEvent('inventory', 'guildbank')
end
--crafting
function Bagnon:TRADE_SKILL_SHOW()
self:ShowFrameAtEvent('inventory', 'craft')
end
function Bagnon:TRADE_SKILL_CLOSE()
self:HideFrameAtEvent('inventory', 'craft')
end
--player frame
function Bagnon:PLAYER_FRAME_SHOW()
self:ShowFrameAtEvent('inventory', 'player')
end
function Bagnon:PLAYER_FRAME_HIDE()
self:HideFrameAtEvent('inventory', 'player')
end
--[[
Slash Commands
--]]
function Bagnon:AddSlashCommands()
self:RegisterChatCommand('bagnon', 'HandleSlashCommand')
self:RegisterChatCommand('bgn', 'HandleSlashCommand')
end
function Bagnon:HandleSlashCommand(cmd)
cmd = cmd and cmd:lower() or ''
if cmd == 'bank' then
self:ToggleFrame('bank')
elseif cmd == 'bags' then
self:ToggleFrame('inventory')
elseif cmd == 'version' then
self:PrintVersion()
elseif cmd == 'config' then
self:ShowOptions()
elseif cmd == '?' or cmd == 'help' then
self:PrintHelp()
else
if not self:ShowOptions() then
self:PrintHelp()
end
end
end
function Bagnon:PrintVersion()
self:Print(self.SavedSettings:GetDBVersion())
end
function Bagnon:PrintHelp()
local function PrintCmd(cmd, desc)
print(string.format(' - |cFF33FF99%s|r: %s', cmd, desc))
end
self:Print(L.Commands)
PrintCmd('bags', L.CmdShowInventory)
PrintCmd('bank', L.CmdShowBank)
PrintCmd('version', L.CmdShowVersion)
end
function Bagnon:ShowOptions()
if LoadAddOn('Bagnon_Config') then
InterfaceOptionsFrame_OpenToCategory(self.GeneralOptions)
return true
end
return false
end
--[[
ButtonFacade Support
--]]
if Facade then
function Bagnon:StartupFacade()
Facade:RegisterSkinCallback('Bagnon', self.OnFacadeChanged, self)
self:FacadeGroup('inventory')
self:FacadeGroup('bank')
local enabled, loadable = select(4, GetAddOnInfo('Bagnon_GuildBank'))
if enabled and loadable then
self:FacadeGroup('guildbank')
end
end
function Bagnon:FacadeGroup(frameID)
-- It's hacky, but the simplest way to do it
local frameSets = BagnonFrameSettings.frames[frameID]
local sets = frameSets and frameSets[frameID] or BagnonFrameSettings.facade
Facade:Group('Bagnon', frameID):Skin(sets and unpack(sets))
end
function Bagnon:OnFacadeChanged(skin, glossAlpha, gloss, frameID, _, colors)
-- It's hacky, but the simplest way to do it
local target
if not frameID then
target = BagnonFrameSettings
else
BagnonFrameSettings.frames[frameID] = BagnonFrameSettings.frames[frameID] or {}
target = BagnonFrameSettings.frames[frameID]
end
target.facade = {skin, glossAlpha, gloss, colors}
end
endPK d>Yȏ
Bagnon/README.textileh3. Have a question? Check the "wiki!":http://code.google.com/p/tullamods/wiki/Bagnon
Bagnon is an addon that merges all of your bags into three frames: One for your inventory, one for your bank and one for your guild bank. Beyond the basic all-in-one inventory functionality, Bagnon also provides the following features:
* Items can be colored based on quality
* Quest items can be highlighted
* Text searching (see syntax below)
* Offline viewing of inventory information from your other characters (via Bagnon_Forever)
* Databroker plugin support. Both the inventory and bank frames allow you to display a databroker plugin in the bottom left corner. I find this works well with things like Currency Tracker
h5. Included Addons
* Bagnon - Provides single window displays for your inventory and bank
* Bagnon_Config - Provides a means of configuring said frames :P
* Bagnon_Forever - Enables the ability to view your character's bank, or items from any other character on the same server, from anywhere. (You need to log onto each character at least once for this to work).
* Bagnon_Tooltips - When hovering over an item, this tells you who has an item, and where.
h5. Slash Commands
* All commands can start with either /bagnon or /bgn
* /bagnon bags - Toggles the inventory frame
* /bagnon bank - Toggles the bank frame
* /bagnon config - Displays the main options menu
h5. Search Syntax
* Bagnon 2.0 uses the same search syntax as Combuctor.
* To find an item by name, simply type the items name. Typing "silk" will find all items that have "silk" in their name.
* To find an item by type, subtype, or equip location, type t:search. "t:weapon" will find all weapons. "t:main" will find all main hand items.
* To find an item by quality, type q:quality."q:epic" will find all epic items. You can also use a quality number. "q:0" will find all grey items.
* To find an item by name, type n:name. "n:muffins" will find all items with names containing "muffins".
* To find items in an equipment set, type s:equipmentSet. "s:fire" will find all items in equipment sets you have with names that start with "fire".
* Searches can be negated using "!". "!q:epic" will find all items that are NOT epic.
* A union of two searches can be performed using the | operator. Typing "q:epic|t:weapon" will find all items that are either epic OR weapons.
* An intersection of two searches can be performed using the & operator. Typing "q:epic&t:weapon" will find all items that are epic AND weapons
* The following search keywords are also supported:
** _boe_ - Bind on equip items.
** _quest_ - Items with "quest item" in their tooltips.
** _bop_ - Bind on pickup items.
** _boa_ - Bind on account items.PK d>dJ J Bagnon/utility.xml
PK d>NL, , Bagnon/components/bag.lua--[[
bag.lua
A bag button object for Bagnon
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local Bag = Bagnon.Classy:New('CheckButton')
Bagnon.Bag = Bag
--constants
local SIZE = 32
local NORMAL_TEXTURE_SIZE = 64 * (SIZE/36)
--[[ Constructor ]]--
function Bag:New(slotID, frameID, parent)
local bag = Bag:CreateBag(slotID, parent)
bag:SetFrameID(frameID)
bag:SetScript('OnEnter', bag.OnEnter)
bag:SetScript('OnLeave', bag.OnLeave)
bag:SetScript('OnClick', bag.OnClick)
bag:SetScript('OnDragStart', bag.OnDrag)
bag:SetScript('OnReceiveDrag', bag.OnClick)
bag:SetScript('OnEvent', bag.OnEvent)
bag:SetScript('OnShow', bag.OnShow)
bag:SetScript('OnHide', bag.OnHide)
return bag
end
function Bag:CreateBag(slotID, parent)
local bag = self:Bind(CreateFrame('CheckButton', 'BagnonBag' .. self:GetNextBagSlotID(), parent))
bag:SetWidth(SIZE)
bag:SetHeight(SIZE)
bag:SetID(slotID)
local name = bag:GetName()
local icon = bag:CreateTexture(name .. 'IconTexture', 'BORDER')
icon:SetAllPoints(bag)
local count = bag:CreateFontString(name .. 'Count', 'OVERLAY')
count:SetFontObject('NumberFontNormalSmall')
count:SetJustifyH('RIGHT')
count:SetPoint('BOTTOMRIGHT', -2, 2)
local nt = bag:CreateTexture(name .. 'NormalTexture')
nt:SetTexture([[Interface\Buttons\UI-Quickslot2]])
nt:SetWidth(NORMAL_TEXTURE_SIZE)
nt:SetHeight(NORMAL_TEXTURE_SIZE)
nt:SetPoint('CENTER', 0, -1)
bag:SetNormalTexture(nt)
local pt = bag:CreateTexture()
pt:SetTexture([[Interface\Buttons\UI-Quickslot-Depress]])
pt:SetAllPoints(bag)
bag:SetPushedTexture(pt)
local ht = bag:CreateTexture()
ht:SetTexture([[Interface\Buttons\ButtonHilight-Square]])
ht:SetAllPoints(bag)
bag:SetHighlightTexture(ht)
local ct = bag:CreateTexture()
ct:SetTexture([[Interface\Buttons\CheckButtonHilight]])
ct:SetAllPoints(bag)
ct:SetBlendMode('ADD')
bag:SetCheckedTexture(ct)
if bag:IsBackpack() or bag:IsBank() then
SetItemButtonTexture(bag, [[Interface\Buttons\Button-Backpack-Up]])
SetItemButtonTextureVertexColor(bag, 1, 1, 1)
end
bag:RegisterForClicks('anyUp')
bag:RegisterForDrag('LeftButton')
return bag
end
do
local id = 0
function Bag:GetNextBagSlotID()
local nextID = id + 1
id = nextID
return nextID
end
end
--[[ Events ]]--
function Bag:OnEvent(event, ...)
local action = self[event]
if action then
action(self, event, ...)
end
end
function Bag:UpdateEvents()
self:UnregisterAllMessages()
self:UnregisterAllEvents()
self:UnregisterAllItemSlotEvents()
if self:IsVisible() then
self:RegisterMessage('BAG_SLOT_SHOW')
self:RegisterMessage('BAG_SLOT_HIDE')
if self:IsBagSlot() then
self:RegisterMessage('PLAYER_UPDATE')
if not self:IsCached() then
self:RegisterEvent('ITEM_LOCK_CHANGED')
self:RegisterEvent('CURSOR_UPDATE')
self:RegisterEvent('BAG_UPDATE')
self:RegisterEvent('PLAYERBANKSLOTS_UPDATED')
self:RegisterEvent('PLAYERBANKBAGSLOTS_UPDATED')
end
end
if self:IsBankBagSlot() then
self:RegisterItemSlotEvent('BANK_OPENED')
self:RegisterItemSlotEvent('BANK_CLOSED')
end
end
end
--event registration
function Bag:RegisterItemSlotEvent(...)
Bagnon.BagEvents:Listen(self, ...)
end
function Bag:UnregisterAllItemSlotEvents(...)
Bagnon.BagEvents:IgnoreAll(self, ...)
end
--[[ Messages ]]--
function Bag:ITEM_LOCK_CHANGED(event, inventorySlot)
if self:GetInventorySlot() == inventorySlot then
self:UpdateLock()
end
end
function Bag:CURSOR_UPDATE()
self:UpdateCursor()
end
function Bag:BAG_UPDATE(event, bag)
self:UpdateLock()
self:UpdateSlotInfo()
end
function Bag:PLAYERBANKSLOTS_UPDATED(event)
self:UpdateLock()
self:UpdateSlotInfo()
end
function Bag:PLAYERBANKBAGSLOTS_UPDATED(event)
self:UpdateLock()
self:UpdateSlotInfo()
end
function Bag:BANK_OPENED(msg)
self:UpdateLock()
self:UpdateSlotInfo()
end
function Bag:BANK_CLOSED(msg)
self:UpdateLock()
self:UpdateSlotInfo()
end
function Bag:BAG_SLOT_SHOW(msg, frameID, slotID)
if frameID == self:GetFrameID() and slotID == self:GetID() then
self:UpdateShown()
end
end
function Bag:BAG_SLOT_HIDE(msg, frameID, slotID)
if frameID == self:GetFrameID() and slotID == self:GetID() then
self:UpdateShown()
end
end
function Bag:PLAYER_UPDATE(msg, frameID, player)
if frameID == self:GetFrameID() then
self:Update()
end
end
--[[ Frame Events ]]--
function Bag:OnShow()
self:UpdateEverything()
end
function Bag:OnHide()
self:UpdateEvents()
end
function Bag:OnClick()
if self:IsPurchasable() and not self:IsCached() then
self:PurchaseSlot()
elseif CursorHasItem() and not self:IsCached() then
if self:IsBackpack() then
PutItemInBackpack()
else
PutItemInBag(self:GetInventorySlot())
end
elseif self:CanToggleSlot() then
self:ToggleSlot()
end
self:UpdateShown()
end
function Bag:OnDrag()
if self:IsBagSlot() and not self:IsCached() then
PlaySound('BAGMENUBUTTONPRESS')
PickupBagFromSlot(self:GetInventorySlot())
end
end
function Bag:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
self:SetSearch()
end
function Bag:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
self:ClearSearch()
end
--[[ Tooltip Methods ]]--
function Bag:UpdateTooltip()
GameTooltip:ClearLines()
if self:IsBackpack() then
GameTooltip:SetText(BACKPACK_TOOLTIP, 1, 1, 1)
elseif self:IsBank() then
GameTooltip:SetText(L.TipBank, 1, 1, 1)
elseif self:IsCached() then
self:UpdateCachedBagTooltip()
else
self:UpdateBagTooltip()
end
if self:CanToggleSlot() then
GameTooltip:AddLine(self:IsSlotShown() and L.TipHideBag or L.TipShowBag)
end
GameTooltip:Show()
end
function Bag:UpdateCachedBagTooltip()
local link = (self:GetItemInfo())
if link then
GameTooltip:SetHyperlink(link)
elseif self:IsPurchasable() then
GameTooltip:SetText(BANK_BAG_PURCHASE, 1, 1, 1)
elseif self:IsBankBagSlot() then
GameTooltip:SetText(BANK_BAG, 1, 1, 1)
else
GameTooltip:SetText(EQUIP_CONTAINER, 1, 1, 1)
end
end
function Bag:UpdateBagTooltip()
if not GameTooltip:SetInventoryItem('player', self:GetInventorySlot()) then
if self:IsPurchasable() then
GameTooltip:SetText(BANK_BAG_PURCHASE, 1, 1, 1)
GameTooltip:AddLine(L.TipPurchaseBag)
SetTooltipMoney(GameTooltip, GetBankSlotCost(GetNumBankSlots()))
else
GameTooltip:SetText(EQUIP_CONTAINER, 1, 1, 1)
end
end
end
--[[ Display Updating ]]--
function Bag:UpdateEverything()
self:UpdateEvents()
self:Update()
end
function Bag:Update()
if not self:IsVisible() then return end
self:UpdateLock()
self:UpdateSlotInfo()
self:UpdateCursor()
self:UpdateShown()
end
function Bag:UpdateLock()
if not self:IsBagSlot() then return end
SetItemButtonDesaturated(self, self:IsLocked())
end
function Bag:UpdateCursor()
if not self:IsBagSlot() then return end
if CursorCanGoInSlot(self:GetInventorySlot()) then
self:LockHighlight()
else
self:UnlockHighlight()
end
end
function Bag:UpdateSlotInfo()
if not self:IsBagSlot() then return end
local link, count, texture = self:GetItemInfo()
if link then
self.hasItem = link
SetItemButtonTexture(self, texture or GetItemIcon(link))
SetItemButtonTextureVertexColor(self, 1, 1, 1)
else
self.hasItem = nil
SetItemButtonTexture(self, [[Interface\PaperDoll\UI-PaperDoll-Slot-Bag]])
--color red if the bag can be purchased
if self:IsPurchasable() then
SetItemButtonTextureVertexColor(self, 1, 0.1, 0.1)
else
SetItemButtonTextureVertexColor(self, 1, 1, 1)
end
end
self:SetCount(count)
end
function Bag:SetCount(count)
local text = _G[self:GetName() .. 'Count']
local count = count or 0
if count > 1 then
if count > 999 then
text:SetFormattedText('%.1fk', count/1000)
else
text:SetText(count)
end
text:Show()
else
text:Hide()
end
end
--[[ Bag Slot Actions ]]--
--show the purchase slot dialog
function Bag:PurchaseSlot()
if not StaticPopupDialogs['CONFIRM_BUY_BANK_SLOT_BAGNON'] then
StaticPopupDialogs['CONFIRM_BUY_BANK_SLOT_BAGNON'] = {
text = CONFIRM_BUY_BANK_SLOT,
button1 = YES,
button2 = NO,
OnAccept = function()
PurchaseSlot()
end,
OnShow = function(self)
MoneyFrame_Update(self:GetName() .. 'MoneyFrame', GetBankSlotCost(GetNumBankSlots()))
end,
hasMoneyFrame = 1,
timeout = 0,
hideOnEscape = 1,
}
end
-- PlaySound('igMainMenuOption')
StaticPopup_Show('CONFIRM_BUY_BANK_SLOT_BAGNON')
end
--item viewing
function Bag:ToggleSlot()
self:GetSettings():ToggleBagSlot(self:GetID())
end
function Bag:UpdateShown()
self:SetChecked(self:IsSlotShown())
end
function Bag:IsSlotShown()
return self:CanToggleSlot() and self:GetSettings():IsBagSlotShown(self:GetID())
end
function Bag:CanToggleSlot()
return self:IsBank() or self:IsBackpack() or (self:IsBagSlot() and self.hasItem)
end
--searching
function Bag:SetSearch()
self:GetSettings():SetBagSearch(self:GetID())
end
function Bag:ClearSearch()
if self:GetSearch() == self:GetID() then
self:GetSettings():SetBagSearch(false)
end
end
function Bag:GetSearch()
return self:GetSettings():GetBagSearch()
end
--[[ Accessor Functions ]]--
--returns true if the bag is loaded from offline data, and false otehrwise
function Bag:IsCached()
return Bagnon.BagSlotInfo:IsCached(self:GetPlayer(), self:GetID())
end
--returns true if the given bag represents the backpack container
function Bag:IsBackpack()
return Bagnon.BagSlotInfo:IsBackpack(self:GetID())
end
--returns true if the given bag represetns the main bank container
function Bag:IsBank()
return Bagnon.BagSlotInfo:IsBank(self:GetID())
end
--returns true if the given bag slot is an inventory bag slot
function Bag:IsInventoryBagSlot()
return Bagnon.BagSlotInfo:IsBackpackBag(self:GetID())
end
--returns true if the given bag slot is a purchasable bank bag slot
function Bag:IsBankBagSlot()
return Bagnon.BagSlotInfo:IsBankBag(self:GetID())
end
--returns true if the given bagSlot is one the player can place a bag in, and false otherwise
function Bag:IsBagSlot()
return self:IsInventoryBagSlot() or self:IsBankBagSlot()
end
--returns true if the bag is a purchasable bank slot, and false otherwise
function Bag:IsPurchasable()
return Bagnon.BagSlotInfo:IsPurchasable(self:GetPlayer(), self:GetID())
end
--returns the inventory slot id representation of the given bag
function Bag:GetInventorySlot()
return Bagnon.BagSlotInfo:ToInventorySlot(self:GetID())
end
function Bag:GetItemInfo()
local link, count, texture = Bagnon.BagSlotInfo:GetItemInfo(self:GetPlayer(), self:GetID())
return link, count, texture
end
function Bag:IsLocked()
return Bagnon.BagSlotInfo:IsLocked(self:GetPlayer(), self:GetID())
end
--returns the currently selected player for this frame
function Bag:GetPlayer()
return self:GetSettings():GetPlayerFilter()
end
--returns the bagnon frame we're attached to
function Bag:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateEverything()
end
end
function Bag:GetFrameID()
return self.frameID
end
--return the settings object associated with this frame
function Bag:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
endPK d>ۏ~
Bagnon/components/bagFrame.lua--[[
bagFrame.lua
A container object for bags
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local BagFrame = Bagnon.Classy:New('Frame')
Bagnon.BagFrame = BagFrame
--[[ Constructor ]]--
function BagFrame:New(frameID, parent)
local f = self:Bind(CreateFrame('Frame', nil, parent))
f:Hide()
f:SetScript('OnShow', f.OnShow)
f:SetScript('OnHide', f.OnHide)
f:SetFrameID(frameID)
f:CreateBagSlots()
f:UpdateEvents()
return f
end
function BagFrame:CreateBagSlots()
local bags = {}
for i, slotID in self:GetBagSlots() do
bags[i] = Bagnon.Bag:New(slotID, self:GetFrameID(), self)
end
self.bags = bags
end
--[[ Messages ]]--
function BagFrame:BAG_FRAME_SHOW(msg, frameID)
if frameID == self:GetFrameID() then
self:UpdateShown()
end
end
function BagFrame:BAG_FRAME_HIDE(msg, frameID)
if frameID == self:GetFrameID() then
self:UpdateShown()
end
end
--[[ Frame Events ]]--
function BagFrame:OnShow()
self:Layout()
self:SendMessage('BAG_FRAME_UPDATE_SHOWN', self:GetFrameID())
end
function BagFrame:OnHide()
self:SendMessage('BAG_FRAME_UPDATE_SHOWN', self:GetFrameID())
end
--[[ Update Methods ]]--
function BagFrame:UpdateShown()
if self:IsBagFrameShown() then
if not self:IsShown() then
UIFrameFadeIn(self, 0.1)
end
else
self:Hide()
end
end
function BagFrame:UpdateEvents()
self:UnregisterAllMessages()
self:RegisterMessage('BAG_FRAME_SHOW')
self:RegisterMessage('BAG_FRAME_HIDE')
end
function BagFrame:Layout()
if not self:IsVisible() then return end
local width = 0
local height = 0
local spacing = self:GetSpacing()
local padding = self:GetPadding()
width = self.bags[1]:GetWidth() * #self.bags + spacing * (#self.bags - 1) + padding * 2
height = self.bags[1]:GetHeight() + padding * 2
local prev
for i, bag in self:GetBags() do
if prev then
bag:SetPoint('LEFT', prev, 'RIGHT', spacing, 0)
else
bag:SetPoint('LEFT', padding, 0)
end
bag:Show()
prev = bag
end
self:SetWidth(width)
self:SetHeight(height)
end
--[[ Properties ]]--
function BagFrame:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateShown()
end
end
function BagFrame:GetFrameID()
return self.frameID
end
function BagFrame:GetBags()
return ipairs(self.bags)
end
--[[ Frame Settings ]]--
function BagFrame:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function BagFrame:IsBagFrameShown()
return self:GetSettings():IsBagFrameShown()
end
function BagFrame:GetSpacing()
return 4
end
function BagFrame:GetPadding()
return 0
end
function BagFrame:GetBagSlots()
return self:GetSettings():GetBagSlots()
endPK 6[>|
Bagnon/components/bagToggle.lua--[[
bagToggle.lua
A bag toggle widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local BagToggle = Bagnon.Classy:New('CheckButton')
Bagnon.BagToggle = BagToggle
local SIZE = 20
local NORMAL_TEXTURE_SIZE = 64 * (SIZE/36)
--[[ Constructor ]]--
function BagToggle:New(frameID, parent)
local b = self:Bind(CreateFrame('CheckButton', nil, parent))
b:SetWidth(SIZE)
b:SetHeight(SIZE)
b:RegisterForClicks('anyUp')
local nt = b:CreateTexture()
nt:SetTexture([[Interface\Buttons\UI-Quickslot2]])
nt:SetWidth(NORMAL_TEXTURE_SIZE)
nt:SetHeight(NORMAL_TEXTURE_SIZE)
nt:SetPoint('CENTER', 0, -1)
b:SetNormalTexture(nt)
local pt = b:CreateTexture()
pt:SetTexture([[Interface\Buttons\UI-Quickslot-Depress]])
pt:SetAllPoints(b)
b:SetPushedTexture(pt)
local ht = b:CreateTexture()
ht:SetTexture([[Interface\Buttons\ButtonHilight-Square]])
ht:SetAllPoints(b)
b:SetHighlightTexture(ht)
local ct = b:CreateTexture()
ct:SetTexture([[Interface\Buttons\CheckButtonHilight]])
ct:SetAllPoints(b)
ct:SetBlendMode('ADD')
b:SetCheckedTexture(ct)
local icon = b:CreateTexture()
icon:SetAllPoints(b)
icon:SetTexture([[Interface\Buttons\Button-Backpack-Up]])
b:SetScript('OnClick', b.OnClick)
b:SetScript('OnEnter', b.OnEnter)
b:SetScript('OnLeave', b.OnLeave)
b:SetScript('OnShow', b.OnShow)
b:SetScript('OnHide', b.OnHide)
b:SetFrameID(frameID)
return b
end
--[[ Messages ]]--
function BagToggle:FRAME_BAGS_SHOW(msg, frameID)
if frameID == self:GetFrameID() then
self:Update()
end
end
function BagToggle:FRAME_BAGS_HIDE(msg, frameID)
if frameID == self:GetFrameID() then
self:Update()
end
end
--[[ Frame Events ]]--
function BagToggle:OnClick(button)
if button == 'LeftButton' then
self:GetSettings():ToggleBagFrame()
else
if self:GetFrameID() == 'inventory' then
Bagnon:ToggleFrame('bank')
else
Bagnon:ToggleFrame('inventory')
end
end
end
function BagToggle:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
end
function BagToggle:OnLeave()
GameTooltip:Hide()
end
function BagToggle:OnShow()
self:UpdateEvents()
self:Update()
end
function BagToggle:OnHide()
self:UpdateEvents()
self:Update()
end
--[[ Update Methods ]]--
function BagToggle:Update()
self:SetChecked(self:IsBagFrameShown())
end
function BagToggle:UpdateEvents()
if self:IsVisible() then
self:RegisterMessage('FRAME_BAGS_SHOW')
self:RegisterMessage('FRAME_BAGS_HIDE')
end
end
function BagToggle:UpdateTooltip()
if not GameTooltip:IsOwned(self) then
return
end
GameTooltip:SetText(L.TipBags)
if self:IsBagFrameShown() then
GameTooltip:AddLine(L.TipHideBags, 1,1,1)
else
GameTooltip:AddLine(L.TipShowBags, 1,1,1)
end
if self:GetFrameID() == 'inventory' then
GameTooltip:AddLine(L.TipBankToggle, 1,1,1)
else
GameTooltip:AddLine(L.TipInventoryToggle, 1,1,1)
end
GameTooltip:Show()
end
--[[ Properties ]]--
function BagToggle:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:Update()
end
end
function BagToggle:GetFrameID()
return self.frameID
end
--[[ Frame Settings ]]--
function BagToggle:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function BagToggle:IsBagFrameShown()
return self:GetSettings():IsBagFrameShown()
endPK d>:D # Bagnon/components/brokerDisplay.lua--[[
brokerDisplay.lua
A databroker display object
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local BrokerDisplay = Bagnon.Classy:New('Button')
BrokerDisplay:Hide()
Bagnon.BrokerDisplay = BrokerDisplay
local ICON_SIZE = 18
--[[ Constructor ]]--
function BrokerDisplay:New(id, frameID, parent)
local obj = self:Bind(CreateFrame('Button', nil, parent))
obj:RegisterForClicks('anyUp')
obj:SetID(id)
obj.left = obj:CreateLeftButton()
obj.left:SetPoint('LEFT')
obj.right = obj:CreateRightButton()
obj.right:SetPoint('RIGHT')
obj.icon = obj:AddIcon()
obj.icon:SetPoint('LEFT', obj.left, 'RIGHT')
obj.text = obj:AddText()
obj:SetScript('OnShow', obj.OnShow)
obj:SetScript('OnHide', obj.OnHide)
obj:SetScript('OnEnter', obj.OnEnter)
obj:SetScript('OnLeave', obj.OnLeave)
obj:SetScript('OnClick', obj.OnClick)
obj:SetScript('OnMouseWheel', obj.OnMouseWheel)
obj:SetFrameID(frameID)
obj:SetHeight(13)
obj:EnableMouseWheel(true)
obj:UpdateInsets()
return obj
end
function BrokerDisplay:AddIcon()
local texture = self:CreateTexture(nil, 'OVERLAY')
texture:SetWidth(ICON_SIZE)
texture:SetHeight(ICON_SIZE)
return texture
end
function BrokerDisplay:AddText()
local text = self:CreateFontString()
text:SetFontObject('NumberFontNormalRight')
text:SetJustifyH('LEFT')
return text
end
--[[
Broker Selection Buttons
--]]
function BrokerDisplay:CreateLeftButton()
local b = CreateFrame('Button', nil, self)
b:SetNormalFontObject('GameFontNormal')
b:SetHighlightFontObject('GameFontHighlight')
b:SetText('<')
b:SetWidth(b:GetTextWidth() + 4)
b:SetHeight(b:GetTextHeight())
b:SetScript('OnClick', function(self) self:GetParent():SetPreviousObject() end)
b:SetToplevel(true)
return b
end
function BrokerDisplay:CreateRightButton()
local b = CreateFrame('Button', nil, self)
b:SetWidth(ICON_SIZE)
b:SetHeight(ICON_SIZE)
b:SetNormalFontObject('GameFontNormal')
b:SetHighlightFontObject('GameFontHighlight')
b:SetText('>')
b:SetWidth(b:GetTextWidth() + 2)
b:SetHeight(b:GetTextHeight())
b:SetScript('OnClick', function(self) self:GetParent():SetNextObject() end)
b:SetToplevel(true)
return b
end
--[[ Messages ]]--
function BrokerDisplay:LibDataBroker_DataObjectCreated(msg, name, dataobj)
if self:GetObjectName() == name then
self:UpdateDisplay()
end
end
function BrokerDisplay:LibDataBroker_AttributeChanged(msg, name, attr, value, dataobj)
if self:GetObjectName() == name then
if attr == 'icon' then
self:UpdateIcon()
elseif attr == 'text' then
self:UpdateText()
end
end
end
function BrokerDisplay:DATABROKER_OBJECT_UPDATE(msg, frameID, objectName)
if self:GetFrameID() == frameID then
self:UpdateDisplay()
if GameTooltip:IsOwned(self) then
self:OnEnter()
end
end
end
--[[ Frame Events ]]--
function BrokerDisplay:OnEnter()
local dbo = self:GetObject()
if not dbo then return end
if dbo.OnEnter then
dbo.OnEnter(self)
elseif dbo.OnTooltipShow then
GameTooltip:SetOwner(self, 'ANCHOR_TOPRIGHT')
GameTooltip:ClearLines()
dbo.OnTooltipShow(GameTooltip)
GameTooltip:Show()
else
GameTooltip:SetOwner(self, 'ANCHOR_TOPRIGHT')
GameTooltip:ClearLines()
GameTooltip:SetText(self:GetObjectName())
GameTooltip:Show()
end
end
function BrokerDisplay:OnLeave()
local dbo = self:GetObject()
if not dbo then return end
if dbo.OnLeave then
dbo.OnLeave(self)
else
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
end
function BrokerDisplay:OnClick(...)
local dbo = self:GetObject()
if dbo and dbo.OnClick then
dbo.OnClick(self, ...)
end
end
function BrokerDisplay:OnShow()
self:UpdateEverything()
end
function BrokerDisplay:OnHide()
self:UpdateEvents()
end
function BrokerDisplay:OnMouseWheel(direction)
if direction > 0 then
self:SetNextObject()
else
self:SetPreviousObject()
end
end
--[[ Update Methods ]]--
function BrokerDisplay:UpdateEverything()
self:UpdateEvents()
self:UpdateDisplay()
end
function BrokerDisplay:UpdateEvents()
local LDB = LibStub:GetLibrary('LibDataBroker-1.1', true)
if LDB then
LDB.UnregisterAllCallbacks(self)
if self:IsVisible() then
LDB.RegisterCallback(self, 'LibDataBroker_DataObjectCreated')
LDB.RegisterCallback(self, 'LibDataBroker_AttributeChanged')
end
end
self:UnregisterAllMessages()
if self:IsVisible() then
self:RegisterMessage('DATABROKER_OBJECT_UPDATE')
end
end
function BrokerDisplay:UpdateDisplay()
self:UpdateIcon()
self:UpdateText()
end
function BrokerDisplay:UpdateText()
local obj = self:GetObject()
local text
if obj then
text = obj.text or ''
else
text = 'Select Databroker Plugin'
end
self.text:SetText(text)
self:Layout()
end
function BrokerDisplay:UpdateIcon()
local obj = self:GetObject()
local icon = obj and obj.icon
if icon then
self.icon:SetTexture(icon)
self.icon:Show()
else
self.icon:Hide()
end
self:Layout()
end
function BrokerDisplay:Layout()
if self.icon:IsShown() then
self.text:SetPoint('LEFT', self.icon, 'RIGHT', 2, 0)
self.text:SetPoint('RIGHT', self.right, 'LEFT', -2, 0)
else
self.text:SetPoint('LEFT', self.left, 'RIGHT', 2, 0)
self.text:SetPoint('RIGHT', self.right, 'LEFT', -2, 0)
end
self:UpdateInsets()
end
--calculate the clickable portion of the frame
function BrokerDisplay:UpdateInsets()
local realWidth = self.left:GetWidth()
if self.text:IsShown() then
realWidth = realWidth + (self.text:GetStringWidth() or 0)
end
if self.icon:IsShown() then
realWidth = realWidth + (self.icon:GetWidth() or 0)
end
self:SetHitRectInsets(0, self:GetWidth() - realWidth, 0, 0)
end
--[[ Display Object Updating ]]--
function BrokerDisplay:SetObject(objectName)
self:GetSettings():SetBrokerDisplayObject(objectName)
end
function BrokerDisplay:GetObject()
local LDB = LibStub:GetLibrary('LibDataBroker-1.1', true)
if LDB then
return LDB:GetDataObjectByName(self:GetObjectName())
end
return nil
end
function BrokerDisplay:GetObjectName()
return self:GetSettings():GetBrokerDisplayObject()
end
function BrokerDisplay:SetNextObject()
local LDB = LibStub:GetLibrary('LibDataBroker-1.1', true)
if not LDB then return end
local currObjName = self:GetObjectName()
local prevObjName = nil
for i, nextObjName in self:GetAvailableObjects() do
if currObjName == prevObjName then
self:SetObject(nextObjName)
return
end
prevObjName = nextObjName
end
for i, nextObjName in self:GetAvailableObjects() do
if currObjName == prevObjName then
self:SetObject(nextObjName)
return
end
prevObjName = nextObjName
end
self:SetObject(prevObjName)
end
function BrokerDisplay:SetPreviousObject()
local LDB = LibStub:GetLibrary('LibDataBroker-1.1', true)
if not LDB then return end
local currObjName = self:GetObjectName()
local prevObjName = nil
for i, nextObjName in self:GetAvailableObjects() do
if prevObjName and (currObjName == nextObjName) then
self:SetObject(prevObjName)
return
end
prevObjName = nextObjName
end
for i, nextObjName in self:GetAvailableObjects() do
if prevObjName and (currObjName == nextObjName) then
self:SetObject(prevObjName)
return
end
prevObjName = nextObjName
end
self:SetObject(prevObjName)
end
do
local objects = {}
function BrokerDisplay:GetAvailableObjects()
if next(objects) ~= nil then
for k, v in pairs(objects) do
objects[k] = nil
end
end
local LDB = LibStub:GetLibrary('LibDataBroker-1.1', true)
if LDB then
for name, obj in LDB:DataObjectIterator() do
table.insert(objects, name)
end
end
table.sort(objects)
return ipairs(objects)
end
end
--[[ Properties ]]--
function BrokerDisplay:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateEverything()
end
end
function BrokerDisplay:GetFrameID()
return self.frameID
end
function BrokerDisplay:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
endPK d>dbG bG Bagnon/components/frame.lua--[[
frame.lua
A Bagnon frame widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local Frame = Bagnon.Classy:New('Frame')
Frame:Hide()
Bagnon.Frame = Frame
--[[
Constructor
--]]
function Frame:New(frameID)
local f = self:Bind(CreateFrame('Frame', 'BagnonFrame' .. frameID, UIParent))
f:Hide()
f:SetClampedToScreen(true)
f:SetMovable(true)
f:EnableMouse(true)
f:SetBackdrop{
bgFile = [[Interface\ChatFrame\ChatFrameBackground]],
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
edgeSize = 16,
tile = true, tileSize = 16,
insets = {left = 4, right = 4, top = 4, bottom = 4}
}
f:SetScript('OnShow', f.OnShow)
f:SetScript('OnHide', f.OnHide)
f.frameID = frameID
f:Rescale()
f:UpdateEverything()
table.insert(UISpecialFrames, f:GetName())
return f
end
--[[
Frame Messages
--]]
function Frame:UpdateEvents()
self:UnregisterAllMessages()
self:RegisterMessage('FRAME_SHOW')
if self:IsVisible() then
self:RegisterMessage('FRAME_HIDE')
self:RegisterMessage('FRAME_LAYER_UPDATE')
self:RegisterMessage('FRAME_MOVE_START')
self:RegisterMessage('FRAME_MOVE_STOP')
self:RegisterMessage('FRAME_POSITION_UPDATE')
self:RegisterMessage('FRAME_OPACITY_UPDATE')
self:RegisterMessage('FRAME_COLOR_UPDATE')
self:RegisterMessage('FRAME_BORDER_COLOR_UPDATE')
self:RegisterMessage('FRAME_SCALE_UPDATE')
self:RegisterMessage('BAG_FRAME_UPDATE_SHOWN')
self:RegisterMessage('BAG_FRAME_UPDATE_LAYOUT')
self:RegisterMessage('ITEM_FRAME_SIZE_CHANGE')
self:RegisterMessage('BAG_FRAME_ENABLE_UPDATE')
self:RegisterMessage('MONEY_FRAME_ENABLE_UPDATE')
self:RegisterMessage('DATABROKER_FRAME_ENABLE_UPDATE')
self:RegisterMessage('SEARCH_TOGGLE_ENABLE_UPDATE')
self:RegisterMessage('OPTIONS_TOGGLE_ENABLE_UPDATE')
end
end
function Frame:FRAME_SHOW(msg, frameID)
if self:GetFrameID() == frameID then
self:Show()
end
end
function Frame:FRAME_HIDE(msg, frameID)
if self:GetFrameID() == frameID then
self:Hide()
end
end
function Frame:FRAME_MOVE_START(msg, frameID)
if self:GetFrameID() == frameID then
self:StartMoving()
end
end
function Frame:FRAME_MOVE_STOP(msg, frameID)
if self:GetFrameID() == frameID then
self:StopMovingOrSizing()
self:SavePosition()
end
end
function Frame:FRAME_POSITION_UPDATE(msg, frameID)
if self:GetFrameID() == frameID then
self:UpdatePosition()
end
end
function Frame:FRAME_SCALE_UPDATE(msg, frameID, scale)
if self:GetFrameID() == frameID then
self:UpdateScale()
end
end
function Frame:FRAME_OPACITY_UPDATE(msg, frameID, opacity)
if self:GetFrameID() == frameID then
self:UpdateOpacity()
end
end
function Frame:FRAME_COLOR_UPDATE(msg, frameID, r, g, b, a)
if self:GetFrameID() == frameID then
self:UpdateBackdrop()
end
end
function Frame:FRAME_BORDER_COLOR_UPDATE(msg, frameID, r, g, b, a)
if self:GetFrameID() == frameID then
self:UpdateBackdropBorder()
end
end
function Frame:BAG_FRAME_UPDATE_SHOWN(msg, frameID)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:BAG_FRAME_UPDATE_LAYOUT(msg, frameID)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:ITEM_FRAME_SIZE_CHANGE(msg, frameID)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:FRAME_LAYER_UPDATE(msg, frameID, layer)
if self:GetFrameID() == frameID then
self:SetFrameLayer(layer)
end
end
function Frame:BAG_FRAME_ENABLE_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:MONEY_FRAME_ENABLE_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:DATABROKER_FRAME_ENABLE_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:SEARCH_TOGGLE_ENABLE_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:Layout()
end
end
function Frame:OPTIONS_TOGGLE_ENABLE_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:Layout()
end
end
--[[
Frame Events
--]]
function Frame:OnShow()
PlaySound('igBackPackOpen')
self:UpdateEvents()
self:UpdateLook()
end
function Frame:OnHide()
PlaySound('igBackPackClose')
if self:IsBankFrame() then
self:CloseBankFrame()
end
self:UpdateEvents()
--fix issue where a frame is hidden, but not via bagnon controlled methods (ie, close on escape)
if self:IsFrameShown() then
self:HideFrame()
end
end
function Frame:CloseBankFrame()
if Bagnon.PlayerInfo:AtBank() then
CloseBankFrame()
end
end
function Frame:IsBankFrame()
return self:GetFrameID() == 'bank'
end
--[[
Update Methods
--]]
function Frame:UpdateEverything()
self:UpdateEvents()
self:UpdateLook()
end
function Frame:UpdateLook()
if not self:IsVisible() then
return
end
self:UpdatePosition()
self:UpdateScale()
self:UpdateOpacity()
self:UpdateBackdrop()
self:UpdateBackdropBorder()
self:UpdateShown()
self:UpdateFrameLayer()
self:Layout()
end
--[[
Frame Scale
--]]
--alter the frame's cale, but maintain the same relative position of the frame
function Frame:UpdateScale()
local oldScale = self:GetScale()
local newScale = self:GetFrameScale()
if oldScale ~= newScale then
local point, x, y = self:GetFramePosition()
local ratio = newScale / oldScale
self:SetScale(newScale)
self:GetSettings():SetPosition(point, x/ratio, y/ratio)
end
end
function Frame:GetFrameScale()
return self:GetSettings():GetScale()
end
--rescale frame without altering position, needed when loading settins
function Frame:Rescale()
self:SetScale(self:GetFrameScale())
end
--[[
Frame Opacity
--]]
function Frame:UpdateOpacity()
self:SetAlpha(self:GetFrameOpacity())
end
function Frame:GetFrameOpacity()
return self:GetSettings():GetOpacity()
end
--[[
Frame Position
--]]
--position
function Frame:SavePosition()
local point, x, y = self:GetRelativePosition()
if point then
self:GetSettings():SetPosition(point, x, y)
end
end
--get a frame's position relative to its parent
function Frame:GetRelativePosition()
local parent = self:GetParent()
local w, h = parent:GetWidth(), parent:GetHeight()
local x, y = self:GetCenter()
local s = self:GetScale()
if not (x and y) then return end
w = w/s h = h/s
local dx, dy
local hHalf = (x > w/2) and 'RIGHT' or 'LEFT'
if hHalf == 'RIGHT' then
dx = self:GetRight() - w
else
dx = self:GetLeft()
end
local vHalf = (y > h/2) and 'TOP' or 'BOTTOM'
if vHalf == 'TOP' then
dy = self:GetTop() - h
else
dy = self:GetBottom()
end
return vHalf..hHalf, dx, dy
end
function Frame:UpdatePosition()
self:ClearAllPoints()
self:SetPoint(self:GetFramePosition())
end
function Frame:GetFramePosition()
return self:GetSettings():GetPosition()
end
--[[
Frame Color
--]]
--background
function Frame:UpdateBackdrop()
self:SetBackdropColor(self:GetFrameBackdropColor())
end
function Frame:GetFrameBackdropColor()
return self:GetSettings():GetColor()
end
--border
function Frame:UpdateBackdropBorder()
self:SetBackdropBorderColor(self:GetFrameBackdropBorderColor())
end
function Frame:GetFrameBackdropBorderColor()
return self:GetSettings():GetBorderColor()
end
--[[
Frame Visibility
--]]
function Frame:UpdateShown()
if self:IsFrameShown() then
self:Show()
else
self:Hide()
end
end
function Frame:IsFrameShown()
return self:GetSettings():IsShown()
end
function Frame:HideFrame()
self:GetSettings():Hide()
end
--[[
Frame Layer/Strata
--]]
function Frame:UpdateFrameLayer()
self:SetFrameLayer(self:GetFrameLayer())
end
function Frame:SetFrameLayer(layer)
local strata, topLevel = nil, false
if layer == 'TOPLEVEL' then
strata = 'HIGH'
topLevel = true
elseif layer == 'MEDIUMLOW' then
strata = 'LOW'
topLevel = true
elseif layer == 'MEDIUMHIGH' then
strata = 'MEDIUM'
topLevel = true
else
strata = layer
topLevel = false
end
self:SetFrameStrata(strata)
self:SetToplevel(topLevel)
end
function Frame:GetFrameLayer()
return self:GetSettings():GetLayer()
end
--[[
Layout Methods
--]]
--place components & update size
function Frame:Layout()
if not self:IsVisible() then
return
end
local padW = 16
local padH = 16
local width, height = 0, 0
--place menu butons, this determines our base width
local w, h = self:PlaceMenuButtons()
width = width + w
local w, h = self:PlaceCloseButton()
width = width + w
local w, h = self:PlaceOptionsToggle()
width = width + w + 24 --append spacing between close button and this
height = height + 20
local w, h = self:PlaceTitleFrame()
width = width + w
local w, h = self:PlaceSearchFrame()
--place the middle frames
local w, h = self:PlaceBagFrame()
width = math.max(w, width)
height = height + h
local w, h = self:PlaceItemFrame()
width = math.max(w, width)
height = height + h
--place the bottom menu frames
local w, h = self:PlaceMoneyFrame()
width = math.max(w, width)
height = height + h
local w, h = self:PlaceBrokerDisplayFrame()
if not self:HasMoneyFrame() then
height = height + h
end
--adjust size
self:SetWidth(math.max(width, 156) + padW)
self:SetHeight(height + padH)
self:SavePosition()
end
--[[ Menu Button Placement ]]--
function Frame:PlaceMenuButtons()
local menuButtons = self.menuButtons or {}
self.menuButtons = menuButtons
--hide the old buttons
for i, button in pairs(menuButtons) do
button:Hide()
menuButtons[i] = nil
end
if self:HasPlayerSelector() then
local selector = self:GetPlayerSelector() or self:CreatePlayerSelector()
table.insert(menuButtons, selector)
end
if self:HasBagFrame() and self:HasBagToggle() then
local toggle = self:GetBagToggle() or self:CreateBagToggle()
table.insert(menuButtons, toggle)
end
-- guild bank support
if self:HasLogs() then
local log, moneyLog = self:GetLogToggles()
table.insert(menuButtons, log)
table.insert(menuButtons, moneyLog)
end
if self:HasSearchToggle() then
local toggle = self:GetSearchToggle() or self:CreateSearchToggle()
table.insert(menuButtons, toggle)
end
for i, button in ipairs(menuButtons) do
button:ClearAllPoints()
if i == 1 then
button:SetPoint('TOPLEFT', self, 'TOPLEFT', 8, -8)
else
button:SetPoint('TOPLEFT', menuButtons[i-1], 'TOPRIGHT', 4, 0)
end
button:Show()
end
local numButtons = #menuButtons
if numButtons > 0 then
return (menuButtons[1]:GetWidth() + 4 * numButtons - 4), menuButtons[1]:GetHeight()
end
return 0, 0
end
function Frame:GetMenuButtons()
if not self.menuButtons then
self:PlaceMenuButtons()
end
return self.menuButtons
end
--[[
Frame Components
--]]
function Frame:ShowFrame(frame)
frame:Show()
UIFrameFadeIn(frame, 0.3, 0, 1)
end
--[[ close button ]]--
local function CloseButton_OnClick(self)
self:GetParent():GetSettings():Hide(true) --force hide the frame
end
function Frame:CreateCloseButton()
local b = CreateFrame('Button', self:GetName() .. 'CloseButton', self, 'UIPanelCloseButton')
b:SetScript('OnClick', CloseButton_OnClick)
self.closeButton = b
return b
end
function Frame:GetCloseButton()
return self.closeButton
end
function Frame:PlaceCloseButton()
local b = self:GetCloseButton() or self:CreateCloseButton()
b:ClearAllPoints()
b:SetPoint('TOPRIGHT', -2, -2)
b:Show()
return 20, 20 --make the same size as the other menu buttons
end
--[[ search frame ]]--
function Frame:CreateSearchFrame()
local f = Bagnon.SearchFrame:New(self:GetFrameID(), self)
self.searchFrame = f
return f
end
function Frame:GetSearchFrame()
return self.searchFrame
end
function Frame:PlaceSearchFrame()
local menuButtons = self:GetMenuButtons()
local frame = self:GetSearchFrame() or self:CreateSearchFrame()
frame:ClearAllPoints()
if #menuButtons > 0 then
frame:SetPoint('LEFT', menuButtons[#menuButtons], 'RIGHT', 2, 0)
else
frame:SetPoint('TOPLEFT', self, 'TOPLEFT', 8, -8)
end
if self:HasOptionsToggle() then
frame:SetPoint('RIGHT', self:GetOptionsToggle(), 'LEFT', -2, 0)
else
frame:SetPoint('RIGHT', self:GetCloseButton(), 'LEFT', -2, 0)
end
frame:SetHeight(28)
return frame:GetWidth(), frame:GetHeight()
end
--[[ search toggle ]]--
function Frame:CreateSearchToggle()
local toggle = Bagnon.SearchToggle:New(self:GetFrameID(), self)
self.searchToggle = toggle
return toggle
end
function Frame:GetSearchToggle()
return self.searchToggle
end
function Frame:HasSearchToggle()
return self:GetSettings():HasSearchToggle()
end
--[[ bag frame ]]--
function Frame:CreateBagFrame()
local f = Bagnon.BagFrame:New(self:GetFrameID(), self)
self.bagFrame = f
return f
end
function Frame:GetBagFrame()
return self.bagFrame
end
function Frame:HasBagFrame()
return self:GetSettings():HasBagFrame()
end
function Frame:IsBagFrameShown()
return self:GetSettings():IsBagFrameShown()
end
function Frame:PlaceBagFrame()
if self:HasBagFrame() then
--the bag frame has to be created here to respond to events
local frame = self:GetBagFrame() or self:CreateBagFrame()
if self:IsBagFrameShown() then
frame:ClearAllPoints()
local menuButtons = self:GetMenuButtons()
if #menuButtons > 0 then
frame:SetPoint('TOPLEFT', menuButtons[1], 'BOTTOMLEFT', 0, -4)
else
frame:SetPoint('TOPLEFT', self:GetTitleFrame(), 'BOTTOMLEFT', 0, -4)
end
frame:Show()
return frame:GetWidth(), frame:GetHeight() + 4
else
frame:Hide()
return 0, 0
end
end
local frame = self:GetBagFrame()
if frame then
frame:Hide()
end
return 0, 0
end
--[[ bag toggle ]]--
function Frame:CreateBagToggle()
local toggle = Bagnon.BagToggle:New(self:GetFrameID(), self)
self.bagToggle = toggle
return toggle
end
function Frame:GetBagToggle()
return self.bagToggle
end
--this exists purely so that it can be overridden by guildBank
function Frame:HasBagToggle()
return true
end
--[[ title frame ]]--
function Frame:CreateTitleFrame()
local f = Bagnon.TitleFrame:New(self:GetFrameID(), self)
self.titleFrame = f
return f
end
function Frame:GetTitleFrame()
return self.titleFrame
end
function Frame:PlaceTitleFrame()
local menuButtons = self:GetMenuButtons()
local frame = self:GetTitleFrame() or self:CreateTitleFrame()
local w, h = 0, 0
frame:ClearAllPoints()
if #menuButtons > 0 then
frame:SetPoint('LEFT', menuButtons[#menuButtons], 'RIGHT', 4, 0)
w = frame:GetTextWidth() / 2 + 4
h = 20
else
frame:SetPoint('TOPLEFT', self, 'TOPLEFT', 8, -8)
w = frame:GetTextWidth() + 8
h = 20
end
if self:HasOptionsToggle() then
frame:SetPoint('RIGHT', self:GetOptionsToggle(), 'LEFT', -4, 0)
else
frame:SetPoint('RIGHT', self:GetCloseButton(), 'LEFT', -4, 0)
end
frame:SetHeight(20)
return w, h
end
--[[ item frame ]]--
function Frame:CreateItemFrame()
local f = Bagnon.ItemFrame:New(self:GetFrameID(), self)
self.itemFrame = f
return f
end
function Frame:GetItemFrame()
return self.itemFrame
end
function Frame:PlaceItemFrame()
local frame = self:GetItemFrame() or self:CreateItemFrame()
frame:ClearAllPoints()
if self:HasBagFrame() and self:IsBagFrameShown() then
frame:SetPoint('TOPLEFT', self:GetBagFrame(), 'BOTTOMLEFT', 0, -4)
else
local menuButtons = self:GetMenuButtons()
if #menuButtons > 0 then
frame:SetPoint('TOPLEFT', menuButtons[1], 'BOTTOMLEFT', 0, -4)
else
frame:SetPoint('TOPLEFT', self:GetTitleFrame(), 'BOTTOMLEFT', 0, -4)
end
end
frame:Show()
return frame:GetWidth() - 2, frame:GetHeight()
end
--[[ player selector ]]--
function Frame:GetPlayerSelector()
return self.playerSelector
end
function Frame:CreatePlayerSelector()
local f = Bagnon.PlayerSelector:New(self:GetFrameID(), self)
self.playerSelector = f
return f
end
function Frame:HasPlayerSelector()
return BagnonDB and true or false
end
--[[ money frame ]]--
function Frame:GetMoneyFrame()
return self.moneyFrame
end
function Frame:CreateMoneyFrame()
local f = Bagnon.MoneyFrame:New(self:GetFrameID(), self)
self.moneyFrame = f
return f
end
function Frame:HasMoneyFrame()
return self:GetSettings():HasMoneyFrame()
end
function Frame:PlaceMoneyFrame()
if self:HasMoneyFrame() then
local frame = self:GetMoneyFrame() or self:CreateMoneyFrame()
frame:ClearAllPoints()
frame:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, 10)
frame:Show()
return frame:GetWidth(), 24
end
local frame = self:GetMoneyFrame()
if frame then
frame:Hide()
end
return 0, 0
end
--[[ libdatabroker display ]]--
function Frame:GetBrokerDisplay()
return self.brokerDisplay
end
function Frame:CreateBrokerDisplay()
local f = Bagnon.BrokerDisplay:New(1, self:GetFrameID(), self)
self.brokerDisplay = f
return f
end
function Frame:HasBrokerDisplay()
return self:GetSettings():HasDBOFrame()
end
function Frame:PlaceBrokerDisplayFrame()
if self:HasBrokerDisplay() then
local frame = self:GetBrokerDisplay() or self:CreateBrokerDisplay()
frame:ClearAllPoints()
frame:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 8, 10)
if self:HasMoneyFrame() then
frame:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', -(self:GetMoneyFrame():GetWidth() + 4), 10)
else
frame:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', -8, 10)
end
frame:Show()
return frame:GetWidth(), 24
end
local frame = self:GetBrokerDisplay()
if frame then
frame:Hide()
end
return 0, 0
end
--[[ options toggle ]]--
function Frame:GetOptionsToggle()
return self.optionsToggle
end
function Frame:CreateOptionsToggle()
local f = Bagnon.OptionsToggle:New(self:GetFrameID(), self)
self.optionsToggle = f
return f
end
function Frame:PlaceOptionsToggle()
if self:HasOptionsToggle() then
local toggle = self:GetOptionsToggle() or self:CreateOptionsToggle()
toggle:ClearAllPoints()
toggle:SetPoint('TOPRIGHT', self, 'TOPRIGHT', -32, -8)
toggle:Show()
return toggle:GetWidth(), toggle:GetHeight()
end
local toggle = self:GetOptionsToggle()
if toggle then
toggle:Hide()
end
return 0, 0
end
function Frame:HasOptionsToggle()
local name, title, notes, enabled = GetAddOnInfo('Bagnon_Config')
return enabled and self:GetSettings():HasOptionsToggle()
end
function Frame:HasLogs()
return nil
end
--[[
Frame Settings Access
--]]
function Frame:GetFrameID()
return self.frameID
end
function Frame:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
endPK d>8zŝ%0 %0 # Bagnon/components/frameSettings.lua--[[
frameSettings.lua
A bagnon frame settings object
--]]
local FrameSettings = {}
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local Facade = LibStub('LibButtonFacade', true)
Bagnon.FrameSettings = FrameSettings
--[[---------------------------------------------------------------------------
Constructorish
--]]---------------------------------------------------------------------------
FrameSettings.mt = {
__index = FrameSettings
}
FrameSettings.objects = setmetatable({}, {__index = function(tbl, id)
local obj = setmetatable({frameID = id, shown = 0}, FrameSettings.mt)
tbl[id] = obj
return obj
end})
function FrameSettings:Get(id)
return self.objects[id]
end
--[[---------------------------------------------------------------------------
Accessor Methods
--]]---------------------------------------------------------------------------
function FrameSettings:GetID()
return self.frameID
end
function FrameSettings:GetDB()
local db = self.db or Bagnon.SavedFrameSettings:Get(self:GetID())
self.db = db
return db
end
--[[---------------------------------------------------------------------------
Message Passing
--]]---------------------------------------------------------------------------
function FrameSettings:SendMessage(msg, ...)
Bagnon.Callbacks:SendMessage(msg, self:GetID(), ...)
end
--[[---------------------------------------------------------------------------
Update Methods
--]]---------------------------------------------------------------------------
--[[ Frame Visibility ]]--
--the logic here is a little wacky, since we deal with auto open/close events
--if a frame was manually opened, then it should only be closable manually
function FrameSettings:Show()
local wasShown = self:IsShown()
self.shown = (self.shown or 0) + 1
if not wasShown then
self:SendMessage('FRAME_SHOW')
end
end
function FrameSettings:Hide(forceHide)
self.shown = (self.shown or 1) - 1
if forceHide or self.shown <= 0 then
self.shown = 0
--reset player filter on hide
self:SetPlayerFilter(UnitName('player'))
self:SendMessage('FRAME_HIDE')
end
end
function FrameSettings:Toggle()
if self:IsShown() then
self:Hide(true)
else
self:Show()
end
end
function FrameSettings:IsShown()
return (self.shown or 0) > 0
end
--[[ Frame Position ]]--
--position
function FrameSettings:SetPosition(point, x, y)
local oPoint, oX, oY = self:GetPosition()
if not(point == oPoint and x == oX and y == oY) then
self:GetDB():SetPosition(point, x, y)
self:SendMessage('FRAME_POSITION_UPDATE', self:GetPosition())
end
end
function FrameSettings:GetPosition()
local point, x, y = self:GetDB():GetPosition()
return point, x, y
end
function FrameSettings:IsMovable()
return not Bagnon.Settings:AreFramePositionsLocked()
end
--[[ Frame Layout ]]--
--scale
function FrameSettings:SetScale(scale)
if self:GetScale() ~= scale then
self:GetDB():SetScale(scale)
self:SendMessage('FRAME_SCALE_UPDATE', self:GetScale())
end
end
function FrameSettings:GetScale()
return self:GetDB():GetScale()
end
--opacity
function FrameSettings:SetOpacity(opacity)
if self:GetOpacity() ~= opacity then
self:GetDB():SetOpacity(opacity)
self:SendMessage('FRAME_OPACITY_UPDATE', self:GetOpacity())
end
end
function FrameSettings:GetOpacity()
return self:GetDB():GetOpacity()
end
--frame color
function FrameSettings:SetColor(r, g, b, a)
local pR, pG, pB, pA = self:GetColor()
if not(pR == r and pG == g and pB == b and pA == a) then
self:GetDB():SetColor(r, g, b, a)
self:SendMessage('FRAME_COLOR_UPDATE', self:GetColor())
end
end
function FrameSettings:GetColor()
return self:GetDB():GetColor()
end
--border color
function FrameSettings:SetBorderColor(r, g, b, a)
local pR, pG, pB, pA = self:GetBorderColor()
if not(pR == r and pG == g and pB == b and pA == a) then
self:GetDB():SetBorderColor(r, g, b, a)
self:SendMessage('FRAME_BORDER_COLOR_UPDATE', self:GetBorderColor())
end
end
function FrameSettings:GetBorderColor()
return self:GetDB():GetBorderColor()
end
--frame layer
function FrameSettings:SetLayer(layer)
if self:GetLayer() ~= layer then
self:GetDB():SetLayer(layer)
self:SendMessage('FRAME_LAYER_UPDATE', self:GetLayer())
end
end
function FrameSettings:GetLayer()
return self:GetDB():GetLayer()
end
--returns a list of all possible frame layers
function FrameSettings:GetAvailableLayers()
if not FrameSettings.availableFrameLayers then
FrameSettings.availableFrameLayers = {'LOW', 'MEDIUMLOW', 'MEDIUM', 'MEDIUMHIGH', 'HIGH', 'TOPLEVEL'}
end
return FrameSettings.availableFrameLayers
end
--[[ Frame Components ]]--
--returns true if the frame has a bag frame, and false otherwise
function FrameSettings:SetHasBagFrame(enable)
local enable = enable and true or false --done to handle 1/nil cases
if self:HasBagFrame() ~= enable then
self:GetDB():SetHasBagFrame(enable)
self:SendMessage('BAG_FRAME_ENABLE_UPDATE', self:HasBagFrame())
end
end
function FrameSettings:HasBagFrame()
return self:GetDB():HasBagFrame()
end
--returns true if the frame has a money frame, and false otherwise
function FrameSettings:SetHasMoneyFrame(enable)
local enable = enable and true or false
if self:HasMoneyFrame() ~= enable then
self:GetDB():SetHasMoneyFrame(enable)
self:SendMessage('MONEY_FRAME_ENABLE_UPDATE', self:HasMoneyFrame())
end
end
function FrameSettings:HasMoneyFrame()
return self:GetDB():HasMoneyFrame()
end
--returns true if the frame has a databroker object frame, and false otherwise
function FrameSettings:SetHasDBOFrame(enable)
local enable = enable and true or false
if self:HasDBOFrame() ~= enable then
self:GetDB():SetHasDBOFrame(enable)
self:SendMessage('DATABROKER_FRAME_ENABLE_UPDATE', self:HasDBOFrame())
end
end
function FrameSettings:HasDBOFrame()
return self:GetDB():HasDBOFrame()
end
--returns true if the search frame TOGGLE is shown, and false otherwise
function FrameSettings:SetHasSearchToggle(enable)
local enable = enable and true or false
if self:HasSearchToggle() ~= enable then
self:GetDB():SetHasSearchToggle(enable)
self:SendMessage('SEARCH_TOGGLE_ENABLE_UPDATE', self:HasSearchToggle())
end
end
function FrameSettings:HasSearchToggle()
return self:GetDB():HasSearchToggle()
end
--options toggle
function FrameSettings:SetHasOptionsToggle(enable)
local enable = enable and true or false
if self:HasOptionsToggle() ~= enable then
self:GetDB():SetHasOptionsToggle(enable)
self:SendMessage('OPTIONS_TOGGLE_ENABLE_UPDATE', self:HasOptionsToggle())
end
end
function FrameSettings:HasOptionsToggle()
return self:GetDB():HasOptionsToggle()
end
--[[ Broker Display Object ]]--
function FrameSettings:SetBrokerDisplayObject(objectName)
if self:GetBrokerDisplayObject() ~= objectName then
self:GetDB():SetBrokerDisplayObject(objectName)
self:SendMessage('DATABROKER_OBJECT_UPDATE', self:GetBrokerDisplayObject())
end
end
function FrameSettings:GetBrokerDisplayObject()
return self:GetDB():GetBrokerDisplayObject()
end
--[[ Bag Frame Visibility ]]--
function FrameSettings:ShowBagFrame()
if not self:IsBagFrameShown() then
self.showBagFrame = true
self:SendMessage('BAG_FRAME_SHOW')
end
end
function FrameSettings:HideBagFrame()
if self:IsBagFrameShown() then
self.showBagFrame = false
self:SendMessage('BAG_FRAME_HIDE')
end
end
function FrameSettings:ToggleBagFrame()
if self:IsBagFrameShown() then
self:HideBagFrame()
else
self:ShowBagFrame()
end
end
function FrameSettings:IsBagFrameShown()
return self.showBagFrame
end
--[[ Item Frame Layout ]]--
--spacing
function FrameSettings:SetItemFrameSpacing(spacing)
if self:GetItemFrameSpacing() ~= spacing then
self:GetDB():SetItemFrameSpacing(spacing)
self:SendMessage('ITEM_FRAME_SPACING_UPDATE', self:GetItemFrameSpacing())
end
end
function FrameSettings:GetItemFrameSpacing()
return self:GetDB():GetItemFrameSpacing()
end
--columns
function FrameSettings:SetItemFrameColumns(columns)
if self:GetItemFrameColumns() ~= columns then
self:GetDB():SetItemFrameColumns(columns)
self:SendMessage('ITEM_FRAME_COLUMNS_UPDATE', self:GetItemFrameColumns())
end
end
function FrameSettings:GetItemFrameColumns()
return self:GetDB():GetItemFrameColumns()
end
--bag break layout
function FrameSettings:SetBagBreak(enable)
local enable = enable and true or false
if self:IsBagBreakEnabled() ~= enable then
self:GetDB():SetBagBreak(enable)
self:SendMessage('ITEM_FRAME_BAG_BREAK_UPDATE', self:IsBagBreakEnabled())
end
end
function FrameSettings:IsBagBreakEnabled()
return self:GetDB():IsBagBreakEnabled()
end
--[[ Bag Slot Availability ]]--
--returns true if the slot is available to this frame, and false otherwise
function FrameSettings:HasBagSlot(slot)
for i, bagSlot in self:GetBagSlots() do
if bagSlot == slot then
return true
end
end
return false
end
--returns an iterator for all bag slots available to this frame
function FrameSettings:GetBagSlots()
return ipairs(self:GetDB():GetBags())
end
--[[ Bag Slot Visibility ]]--
function FrameSettings:ShowBagSlot(slotToShow)
if not self:IsBagSlotShown(slotToShow) then
self:GetDB():ShowBag(slotToShow)
self:SendMessage('BAG_SLOT_SHOW', slotToShow)
end
end
function FrameSettings:HideBagSlot(slotToHide)
if self:IsBagSlotShown(slotToHide) then
self:GetDB():HideBag(slotToHide)
self:SendMessage('BAG_SLOT_HIDE', slotToHide)
end
end
function FrameSettings:ToggleBagSlot(slot)
if self:IsBagSlotShown(slot) then
self:HideBagSlot(slot)
else
self:ShowBagSlot(slot)
end
end
function FrameSettings:IsBagSlotShown(slot)
for i, bagSlot in self:GetVisibleBagSlots() do
if bagSlot == slot then
return true
end
end
return false
end
function FrameSettings:IsBagSlotHidden(slot)
return not self:GetDB():IsBagShown(slot)
end
--[[ Bag Slot Iterators ]]--
--returns an iterator for all bag slots that are available to this frame and marked as visible
local function reverseVisibleSlotIterator(obj, i)
local bagSlots = obj:GetDB():GetBags()
local nextSlot = i - 1
for j = nextSlot, 1, -1 do
local slot = bagSlots[j]
if not obj:IsBagSlotHidden(slot) then
return j, slot
end
end
end
local function visibleSlotIterator(obj, i)
local bagSlots = obj:GetDB():GetBags()
local nextSlot = i + 1
for j = nextSlot, #bagSlots do
local slot = bagSlots[j]
if not obj:IsBagSlotHidden(slot) then
return j, slot
end
end
end
function FrameSettings:GetVisibleBagSlots()
if self:IsSlotOrderReversed() then
local bagSlots = self:GetDB():GetBags()
return reverseVisibleSlotIterator, self, #bagSlots + 1
end
return visibleSlotIterator, self, 0
end
function FrameSettings:SetReverseSlotOrder(enable)
local enable = enable and true or false
if self:IsSlotOrderReversed() ~= enable then
self:GetDB():SetReverseSlotOrder(enable)
self:SendMessage('SLOT_ORDER_UPDATE', self:IsSlotOrderReversed())
end
end
function FrameSettings:IsSlotOrderReversed()
return self:GetDB():IsSlotOrderReversed()
end
--[[ Text Filtering ]]--
function FrameSettings:EnableTextSearch()
if not self:IsTextSearchEnabled() then
self.enableTextSearch = true
self:SendMessage('TEXT_SEARCH_ENABLE')
end
end
function FrameSettings:DisableTextSearch()
if self:IsTextSearchEnabled() then
self.enableTextSearch = false
self:SendMessage('TEXT_SEARCH_DISABLE')
end
end
function FrameSettings:ToggleTextSearch()
if self:IsTextSearchEnabled() then
self:DisableTextSearch()
else
self:EnableTextSearch()
end
end
function FrameSettings:IsTextSearchEnabled()
return self.enableTextSearch
end
--[[ Bag Filtering ]]--
function FrameSettings:SetBagSearch(bagSlotID)
if self:GetBagSearch() ~= bagSlotID then
self.bagSearch = bagSlotID
self:SendMessage('BAG_SEARCH_UPDATE', self:GetBagSearch())
end
end
function FrameSettings:GetBagSearch()
return self.bagSearch or false
end
--[[ Player Filtering ]]--
function FrameSettings:SetPlayerFilter(player)
local currentFilter = self:GetPlayerFilter()
if currentFilter ~= player then
self.playerFilter = player
self:SendMessage('PLAYER_UPDATE', self:GetPlayerFilter())
end
end
function FrameSettings:GetPlayerFilter()
return self.playerFilter or UnitName('player')
end
--[[ ButtonFacade Settings ]]--
if Facade then
function FrameSettings:GetFacade()
self:GetDB():GetFacade()
end
endPK v>Q= = Bagnon/components/item.lua--[[
item.lua
An item slot button
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local ItemSlot = Bagnon.Classy:New('Button')
ItemSlot:Hide()
Bagnon.ItemSlot = ItemSlot
local Facade = LibStub('LibButtonFacade', true)
local ItemSearch = LibStub('LibItemSearch-1.0')
local Unfit = LibStub('Unfit-1.0')
local function hasBlizzQuestHighlight()
return GetContainerItemQuestInfo and true or false
end
--[[
The item widget
--]]
--[[ ItemSlot Constructor ]]--
function ItemSlot:New(bag, slot, frameID, parent)
local item = self:Restore() or self:Create()
item:SetParent(item:GetDummyBag(parent, bag))
item:SetID(slot)
item:SetFrameID(frameID)
if item:IsVisible() then
item:Update()
else
item:Show()
end
if Facade then
local name = item:GetName()
Facade:Group('Bagnon', frameID):AddButton(item, {
Count = _G[name .. 'Count'],
Icon = _G[name .. 'IconTexture'],
Normal = _G[name .. 'NormalTexture'],
Highlight = item:GetHighlightTexture(),
Pushed = item:GetPushedTexture(),
Cooldown = item.cooldown,
Border = item.border,
AutoCastable = false, AutoCast = false,
HotKey = false, Name = false, Duration = false,
Disabled = false, Checked = false,
Flash = false,
})
end
return item
end
--constructs a brand new item slot
function ItemSlot:Create()
local id = self:GetNextItemSlotID()
local item = self:Bind(self:GetBlizzardItemSlot(id) or self:ConstructNewItemSlot(id))
local name = item:GetName()
--add a quality border texture
local border = item:CreateTexture(nil, 'OVERLAY')
border:SetWidth(67)
border:SetHeight(67)
border:SetPoint('CENTER', item)
border:SetTexture([[Interface\Buttons\UI-ActionButton-Border]])
border:SetBlendMode('ADD')
border:Hide()
--hack, make sure the cooldown model stays visible
item.questBorder = _G[name .. 'IconQuestTexture']
item.cooldown = _G[name .. 'Cooldown']
item.UpdateTooltip = nil
item.border = border
--get rid of any registered frame events, and use my own
item:SetScript('OnEvent', nil)
item:SetScript('OnEnter', item.OnEnter)
item:SetScript('OnLeave', item.OnLeave)
item:SetScript('OnShow', item.OnShow)
item:SetScript('OnHide', item.OnHide)
item:SetScript('PostClick', item.PostClick)
item:HookScript("OnClick", item.ItemClicked)
item:Hide()
return item
end
--creates a new item slot for
function ItemSlot:ConstructNewItemSlot(id)
return CreateFrame('Button', 'BagnonItemSlot' .. id, nil, 'ContainerFrameItemButtonTemplate')
end
--returns an available blizzard item slot for
function ItemSlot:GetBlizzardItemSlot(id)
--only allow reuse of blizzard frames if all frames are enabled
if not self:CanReuseBlizzardBagSlots() then
return nil
end
local bag = math.ceil(id / MAX_CONTAINER_ITEMS)
local slot = (id-1) % MAX_CONTAINER_ITEMS + 1
local item = _G[format('ContainerFrame%dItem%d', bag, slot)]
if item then
item:SetID(0)
item:ClearAllPoints()
return item
end
end
function ItemSlot:CanReuseBlizzardBagSlots()
return Bagnon.Settings:AreAllFramesEnabled() and (not Bagnon.Settings:IsBlizzardBagPassThroughEnabled())
end
--returns the next available item slot
function ItemSlot:Restore()
local item = ItemSlot.unused and next(ItemSlot.unused)
if item then
ItemSlot.unused[item] = nil
return item
end
end
--gets the next unique item slot id
do
local id = 1
function ItemSlot:GetNextItemSlotID()
local nextID = id
id = id + 1
return nextID
end
end
--[[ ItemSlot Destructor ]]--
function ItemSlot:Free()
self:Hide()
self:SetParent(nil)
self:UnregisterAllEvents()
self:UnregisterAllMessages()
ItemSlot.unused = ItemSlot.unused or {}
ItemSlot.unused[self] = true
if Facade then
Facade:Group('Bagnon', frameID):RemoveButton(item, true)
end
end
--[[ Events ]]--
function ItemSlot:ITEM_SLOT_UPDATE(msg, bag, slot)
self:Update()
end
function ItemSlot:ITEM_LOCK_CHANGED(event, bag, slot)
self:UpdateLocked()
end
function ItemSlot:ITEM_SLOT_UPDATE_COOLDOWN(msg, bag, slot)
self:UpdateCooldown()
end
function ItemSlot:TEXT_SEARCH_UPDATE(msg, frameID, search)
self:UpdateSearch()
end
function ItemSlot:BAG_SEARCH_UPDATE(msg, frameID, search)
if self:GetFrameID() == frameID then
self:UpdateBagSearch()
end
end
function ItemSlot:ITEM_HIGHLIGHT_QUALITY_UPDATE(msg, enable)
self:UpdateBorder()
end
function ItemSlot:ITEM_HIGHLIGHT_UNUSABLE_UPDATE(msg, enable)
self:UpdateBorder()
end
function ItemSlot:ITEM_HIGHLIGHT_QUEST_UPDATE(msg, enable)
self:UpdateBorder()
end
function ItemSlot:ITEM_HIGHLIGHT_OPACITY_UPDATE(msg, opacity)
self:UpdateBorder()
end
function ItemSlot:SHOW_EMPTY_ITEM_SLOT_TEXTURE_UPDATE(msg, enable)
self:Update()
end
function ItemSlot:ITEM_SLOT_COLOR_ENABLED_UPDATE(msg, type, r, g, b)
self:Update()
end
function ItemSlot:ITEM_SLOT_COLOR_UPDATE(msg, type, r, g, b)
self:Update()
end
function ItemSlot:QUEST_ACCEPTED()
self:UpdateBorder()
end
function ItemSlot:UNIT_QUEST_LOG_CHANGED()
self:UpdateBorder()
end
-- Flash search broadcast hook
function ItemSlot:FLASH_SEARCH_UPDATE(msg, search)
self:FlashSearch(search)
end
function ItemSlot:HandleEvent(msg, ...)
local action = self[msg]
if action then
action(self, msg, ...)
end
end
--[[ Frame Events ]]--
function ItemSlot:OnShow()
self:Update()
end
function ItemSlot:OnHide()
self:HideStackSplitFrame()
end
function ItemSlot:OnDragStart()
if self:IsCached() and CursorHasItemSlot() then
ClearCursor()
end
end
function ItemSlot:OnModifiedClick(button)
local link = self:IsCached() and self:GetItem()
if link then
HandleModifiedItemClick(link)
end
end
function ItemSlot:OnEnter()
local dummySlot = self:GetDummyItemSlot()
if self:IsCached() then
dummySlot:SetParent(self)
dummySlot:SetAllPoints(self)
dummySlot:Show()
else
dummySlot:Hide()
if self:IsBank() then
if self:GetItem() then
self:AnchorTooltip()
GameTooltip:SetInventoryItem('player', BankButtonIDToInvSlotID(self:GetID()))
GameTooltip:Show()
CursorUpdate(self)
end
else
ContainerFrameItemButton_OnEnter(self)
end
end
end
function ItemSlot:OnLeave()
GameTooltip:Hide()
ResetCursor()
end
--[[ Update Methods ]]--
-- Update the texture, lock status, and other information about an item
function ItemSlot:Update()
if not self:IsVisible() then return end
local texture, count, locked, quality, readable, lootable, link = self:GetItemSlotInfo()
self:SetItem(link)
self:SetTexture(texture)
self:SetCount(count)
self:SetLocked(locked)
self:SetReadable(readable)
self:SetBorderQuality(quality)
self:UpdateCooldown()
self:UpdateSlotColor()
self:UpdateSearch()
self:UpdateBagSearch()
if GameTooltip:IsOwned(self) then
self:UpdateTooltip()
end
end
--item link
function ItemSlot:SetItem(itemLink)
self.hasItem = itemLink or nil
end
function ItemSlot:GetItem()
return self.hasItem
end
--item texture
function ItemSlot:SetTexture(texture)
SetItemButtonTexture(self, texture or self:GetEmptyItemTexture())
end
function ItemSlot:GetEmptyItemTexture()
if self:ShowingEmptyItemSlotTexture() then
return [[Interface\PaperDoll\UI-Backpack-EmptySlot]]
end
return nil
end
--item slot color
function ItemSlot:UpdateSlotColor()
if (not self:GetItem()) and self:ColoringBagSlots() then
if self:IsTradeBagSlot() then
self:SetSlotColor(self:GetTradeSlotColor())
else
self:SetSlotColor(self:GetNormalSlotColor())
end
else
self:SetSlotColor(1, 1, 1)
end
end
function ItemSlot:SetSlotColor(...)
SetItemButtonTextureVertexColor(self, ...)
self:GetNormalTexture():SetVertexColor(...)
end
--item count
function ItemSlot:SetCount(count)
SetItemButtonCount(self, count)
end
--readable status
function ItemSlot:SetReadable(readable)
self.readable = readable
end
--locked status
function ItemSlot:SetLocked(locked)
SetItemButtonDesaturated(self, locked)
end
function ItemSlot:UpdateLocked()
self:SetLocked(self:IsLocked())
end
--returns true if the slot is locked, and false otherwise
function ItemSlot:IsLocked()
return Bagnon.ItemSlotInfo:IsLocked(self:GetPlayer(), self:GetBag(), self:GetID())
end
--colors the item border based on the quality of the item. hides it for common/poor items
function ItemSlot:SetBorderQuality(quality)
local border = self.border
local qBorder = self.questBorder
qBorder:Hide()
border:Hide()
if self:HighlightingQuestItems() then
local isQuestItem, isQuestStarter = self:IsQuestItem()
if isQuestItem then
border:SetVertexColor(1, .82, .2, self:GetHighlightAlpha())
border:Show()
return
end
if isQuestStarter then
qBorder:SetTexture(TEXTURE_ITEM_QUEST_BANG)
qBorder:Show()
return
end
end
if self:HighlightUnusableItems() then
local link = select(7, self:GetItemSlotInfo())
if Unfit:IsItemUnusable(link) then
local r, g, b = RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b
border:SetVertexColor(r, g, b, self:GetHighlightAlpha())
border:Show()
return
end
end
if self:HighlightingItemsByQuality() then
if self:GetItem() and quality and quality > 1 then
local r, g, b = GetItemQualityColor(quality)
border:SetVertexColor(r, g, b, self:GetHighlightAlpha())
border:Show()
return
end
end
end
function ItemSlot:UpdateBorder()
local texture, count, locked, quality = self:GetItemSlotInfo()
self:SetBorderQuality(quality)
end
--cooldown
function ItemSlot:UpdateCooldown()
if self:GetItem() and (not self:IsCached()) then
ContainerFrame_UpdateCooldown(self:GetBag(), self)
else
CooldownFrame_SetTimer(self.cooldown, 0, 0, 0)
SetItemButtonTextureVertexColor(self, 1, 1, 1)
end
end
--stack split frame
function ItemSlot:HideStackSplitFrame()
if self.hasStackSplit and self.hasStackSplit == 1 then
StackSplitFrame:Hide()
end
end
--tooltip methods
ItemSlot.UpdateTooltip = ItemSlot.OnEnter
function ItemSlot:AnchorTooltip()
if self:GetRight() >= (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
end
--search
function ItemSlot:UpdateSearch()
local shouldFade = false
local search = self:GetItemSearch()
if search and search ~= '' then
local itemLink = self:GetItem()
shouldFade = not(itemLink and ItemSearch:Find(itemLink, search))
end
if shouldFade then
self:SetAlpha(0.4)
SetItemButtonDesaturated(self, true)
self.border:Hide()
else
self:SetAlpha(1)
self:UpdateLocked()
self:UpdateBorder()
self:UpdateSlotColor()
end
end
function ItemSlot:GetItemSearch()
return Bagnon.Settings:GetTextSearch()
end
--bag search
function ItemSlot:UpdateBagSearch()
local search = self:GetBagSearch()
if self:GetBag() == search then
self:LockHighlight()
else
self:UnlockHighlight()
end
end
function ItemSlot:GetBagSearch()
return self:GetSettings():GetBagSearch()
end
--flash search
-- If the current item does match the sought name, flash it
function ItemSlot:FlashSearch(search)
if search and search ~= '' then
local itemLink = self:GetItem()
if ItemSearch:Find(itemLink, search) then
UIFrameFlash(self, 0.2, 0.3, 1.5, true, 0.0, 0.0 )
end
end
end
-- Callback function for item slot clicked
function ItemSlot:ItemClicked(button)
if IsAltKeyDown() and button == 'LeftButton' then
local link = self:GetItem()
if link then
Bagnon.Settings:FlashFind(link:match('^|c%x+|Hitem.+|h%[(.*)%]'))
end
end
end
--[[ Accessor Methods ]]--
function ItemSlot:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:Update()
end
end
function ItemSlot:GetFrameID()
return self.frameID
end
function ItemSlot:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function ItemSlot:GetPlayer()
return self:GetSettings():GetPlayerFilter()
end
function ItemSlot:GetBag()
return self:GetParent() and self:GetParent():GetID() or 1
end
function ItemSlot:IsSlot(bag, slot)
return self:GetBag() == bag and self:GetID() == slot
end
function ItemSlot:IsCached()
return Bagnon.BagSlotInfo:IsCached(self:GetPlayer(), self:GetBag())
end
function ItemSlot:IsBank()
return Bagnon.BagSlotInfo:IsBank(self:GetBag())
end
function ItemSlot:IsBankSlot()
local bag = self:GetBag()
return Bagnon.BagSlotInfo:IsBank(bag) or Bagnon.BagSlotInfo:IsBankBag(bag)
end
function ItemSlot:AtBank()
return Bagnon.PlayerInfo:AtBank()
end
function ItemSlot:GetItemSlotInfo()
local texture, count, locked, quality, readable, lootable, link = Bagnon.ItemSlotInfo:GetItemInfo(self:GetPlayer(), self:GetBag(), self:GetID())
return texture, count, locked, quality, readable, lootable, link
end
--[[ Item Type Highlighting ]]--
function ItemSlot:HighlightingItemsByQuality()
return Bagnon.Settings:HighlightingItemsByQuality()
end
function ItemSlot:HighlightUnusableItems()
return Bagnon.Settings:HighlightUnusableItems()
end
function ItemSlot:HighlightingQuestItems()
return Bagnon.Settings:HighlightingQuestItems()
end
function ItemSlot:GetHighlightAlpha()
return Bagnon.Settings:GetHighlightOpacity()
end
--returns true if the item is a quest item or not
--in 3.3, includes a second return to determine if the item is a quest starter for a quest the player lacks
local QUEST_ITEM_SEARCH = string.format('t:%s|%s', select(10, GetAuctionItemClasses()), 'quest')
function ItemSlot:IsQuestItem()
local itemLink = self:GetItem()
if not itemLink then
return false, false
end
if self:IsCached() then
return ItemSearch:Find(itemLink, QUEST_ITEM_SEARCH), false
else
local isQuestItem, questID, isActive = GetContainerItemQuestInfo(self:GetBag(), self:GetID())
return isQuestItem, (questID and not isActive)
end
end
--[[ Item Slot Coloring ]]--
function ItemSlot:IsTradeBagSlot()
return Bagnon.BagSlotInfo:IsTradeBag(self:GetPlayer(), self:GetBag())
end
function ItemSlot:GetNormalSlotColor()
return Bagnon.Settings:GetItemSlotColor('normal')
end
function ItemSlot:GetTradeSlotColor()
return Bagnon.Settings:GetItemSlotColor('trade')
end
function ItemSlot:ColoringBagSlots()
return Bagnon.Settings:ColoringBagSlots()
end
--[[ Empty Slot Visibility ]]--
function ItemSlot:ShowingEmptyItemSlotTexture()
return Bagnon.Settings:ShowingEmptyItemSlotTextures()
end
--[[ Delicious Hacks ]]--
-- dummy slot - A hack, used to provide a tooltip for cached items without tainting other item code
function ItemSlot:GetDummyItemSlot()
ItemSlot.dummySlot = ItemSlot.dummySlot or ItemSlot:CreateDummyItemSlot()
return ItemSlot.dummySlot
end
function ItemSlot:CreateDummyItemSlot()
local slot = CreateFrame('Button')
slot:RegisterForClicks('anyUp')
slot:SetToplevel(true)
slot:Hide()
local function Slot_OnEnter(self)
local parent = self:GetParent()
parent:LockHighlight()
if parent:IsCached() and parent:GetItem() then
ItemSlot.AnchorTooltip(self)
GameTooltip:SetHyperlink(parent:GetItem())
GameTooltip:Show()
end
end
local function Slot_OnLeave(self)
GameTooltip:Hide()
self:Hide()
end
local function Slot_OnHide(self)
local parent = self:GetParent()
if parent then
parent:UnlockHighlight()
end
end
local function Slot_OnClick(self, button)
self:GetParent():OnModifiedClick(button)
end
slot.UpdateTooltip = Slot_OnEnter
slot:SetScript('OnClick', Slot_OnClick)
slot:SetScript('OnEnter', Slot_OnEnter)
slot:SetScript('OnLeave', Slot_OnLeave)
slot:SetScript('OnShow', Slot_OnEnter)
slot:SetScript('OnHide', Slot_OnHide)
return slot
end
--dummy bag, a hack to enforce the internal blizzard rule that item:GetParent():GetID() == bagID
function ItemSlot:GetDummyBag(parent, bag)
local dummyBags = parent.dummyBags
--metatable magic to create a new frame on demand
if not dummyBags then
dummyBags = setmetatable({}, {
__index = function(t, k)
local f = CreateFrame('Frame', nil, parent)
f:SetID(k)
t[k] = f
return f
end
})
parent.dummyBags = dummyBags
end
return dummyBags[bag]
endPK qx>L/ / Bagnon/components/itemFrame.lua--[[
itemFrame.lua
An item slot container
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local ItemFrame = Bagnon.Classy:New('Frame')
local Facade = LibStub('LibButtonFacade', true)
ItemFrame:Hide()
Bagnon.ItemFrame = ItemFrame
local function hasBlizzQuestHighlight()
return GetContainerItemQuestInfo and true or false
end
--[[ Extreme Constants! ]]--
ItemFrame.ITEM_SIZE = 39
--[[ Constructor ]]--
local function throttledUpdater_OnUpdate(self, elapsed)
local p = self:GetParent()
if p:NeedsLayout() then
p:Layout()
end
self:Hide()
end
function ItemFrame:New(frameID, parent)
local f = self:Bind(CreateFrame('Frame', nil, parent))
f.itemSlots = {}
f.throttledUpdater = CreateFrame('Frame', nil, f)
f.throttledUpdater:SetScript('OnUpdate', throttledUpdater_OnUpdate)
f:SetFrameID(frameID)
f:SetScript('OnSizeChanged', f.OnSizeChanged)
f:SetScript('OnEvent', f.OnEvent)
f:SetScript('OnShow', f.OnShow)
f:SetScript('OnHide', f.OnHide)
return f
end
--[[ Messages ]]--
function ItemFrame:OnEvent(event, ...)
local action = self[event]
if action then
action(self, event, ...)
end
end
function ItemFrame:ITEM_SLOT_ADD(msg, bag, slot)
if self:IsBagShown(bag) and (not self:IsBagSlotCached(bag)) then
self:AddItemSlot(bag, slot)
end
end
function ItemFrame:ITEM_SLOT_REMOVE(msg, bag, slot)
if self:IsBagShown(bag) and (not self:IsBagSlotCached(bag)) then
self:RemoveItemSlot(bag, slot)
end
end
function ItemFrame:ITEM_LOCK_CHANGED(msg, bag, slot, ...)
if slot and self:IsBagShown(bag) and (not self:IsBagSlotCached(bag)) then
self:HandleSpecificItemEvent(msg, bag, slot, ...)
end
end
function ItemFrame:BANK_OPENED(msg)
self:UpdateEverything()
end
function ItemFrame:BANK_CLOSED(msg)
self:UpdateEverything()
end
function ItemFrame:PLAYER_UPDATE(msg, frameID, player)
if self:GetFrameID() == frameID then
self:UpdateEverything()
end
end
function ItemFrame:BAG_UPDATE_TYPE(msg, bag, type)
if self:IsBagShown(bag) and not self:IsBagSlotCached(bag) then
self:UpdateAllItemSlotsForBag(bag)
end
end
function ItemFrame:BAG_SLOT_SHOW(msg, frameID, bagSlot)
if self:GetFrameID() == frameID then
self:AddAllItemSlotsForBag(bagSlot)
end
end
function ItemFrame:BAG_SLOT_HIDE(msg, frameID, bagSlot)
if self:GetFrameID() == frameID then
self:RemoveAllItemSlotsForBag(bagSlot)
end
end
function ItemFrame:ITEM_FRAME_SPACING_UPDATE(msg, frameID, spacing)
if self:GetFrameID() == frameID then
self:RequestLayout()
end
end
function ItemFrame:ITEM_FRAME_COLUMNS_UPDATE(msg, frameID, columns)
if self:GetFrameID() == frameID then
self:RequestLayout()
end
end
function ItemFrame:SLOT_ORDER_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:RequestLayout()
end
end
function ItemFrame:ITEM_FRAME_BAG_BREAK_UPDATE(msg, frameID, enable)
if self:GetFrameID() == frameID then
self:RequestLayout()
end
end
function ItemFrame:UNIT_QUEST_LOG_CHANGED(event, unit)
if unit == 'player' then
self:HandleGlobalItemEvent(event)
end
end
function ItemFrame:QUEST_ACCEPTED(event)
self:HandleGlobalItemEvent(event)
end
function ItemFrame:HandleGlobalItemEvent(msg, ...)
for i, item in self:GetAllItemSlots() do
item:HandleEvent(msg, ...)
end
end
function ItemFrame:HandleSpecificItemEvent(msg, bag, slot, ...)
if self:IsBagShown(bag) and (not self:IsBagSlotCached(bag)) then
local item = self:GetItemSlot(bag, slot)
if item then
item:HandleEvent(msg, bag, slot, ...)
end
end
end
function ItemFrame:RegisterItemEvent(...)
Bagnon.BagEvents:Listen(self, ...)
end
function ItemFrame:UnregisterItemEvent(...)
Bagnon.BagEvents:Ignore(self, ...)
end
function ItemFrame:UnregisterAllItemEvents(...)
Bagnon.BagEvents:IgnoreAll(self, ...)
end
--[[ Frame Events ]]--
function ItemFrame:OnShow()
self:UpdateEverything()
end
function ItemFrame:OnHide()
self:UpdateEvents()
end
function ItemFrame:OnSizeChanged()
self:SendMessage('ITEM_FRAME_SIZE_CHANGE', self:GetFrameID())
end
--[[ Update Methods ]]--
function ItemFrame:UpdateEverything()
self:UpdateEvents()
if self:IsVisible() then
self:ReloadAllItemSlots()
self:RequestLayout()
end
end
function ItemFrame:UpdateEvents()
self:UnregisterAllEvents()
self:UnregisterAllItemEvents()
self:UnregisterAllMessages()
if self:IsVisible() then
--live item events
if not self:IsCached() then
self:RegisterEvent('ITEM_LOCK_CHANGED')
if hasBlizzQuestHighlight() then
self:RegisterEvent('QUEST_ACCEPTED')
self:RegisterEvent('UNIT_QUEST_LOG_CHANGED')
end
self:RegisterItemEvent('ITEM_SLOT_ADD')
self:RegisterItemEvent('ITEM_SLOT_REMOVE')
self:RegisterItemEvent('ITEM_SLOT_UPDATE', 'HandleSpecificItemEvent')
self:RegisterItemEvent('ITEM_SLOT_UPDATE_COOLDOWN', 'HandleSpecificItemEvent')
self:RegisterItemEvent('BAG_UPDATE_TYPE')
if self:HasBankBags() then
self:RegisterItemEvent('BANK_OPENED')
self:RegisterItemEvent('BANK_CLOSED')
end
end
self:RegisterMessage('BAG_SLOT_SHOW')
self:RegisterMessage('BAG_SLOT_HIDE')
self:RegisterMessage('PLAYER_UPDATE')
self:RegisterMessage('ITEM_FRAME_SPACING_UPDATE')
self:RegisterMessage('ITEM_FRAME_COLUMNS_UPDATE')
self:RegisterMessage('SLOT_ORDER_UPDATE')
self:RegisterMessage('ITEM_FRAME_BAG_BREAK_UPDATE')
self:RegisterMessage('TEXT_SEARCH_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('BAG_SEARCH_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('ITEM_HIGHLIGHT_QUEST_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('ITEM_HIGHLIGHT_QUALITY_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('ITEM_HIGHLIGHT_UNUSABLE_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('ITEM_HIGHLIGHT_OPACITY_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('SHOW_EMPTY_ITEM_SLOT_TEXTURE_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('ITEM_SLOT_COLOR_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('ITEM_SLOT_COLOR_ENABLED_UPDATE', 'HandleGlobalItemEvent')
self:RegisterMessage('FLASH_SEARCH_UPDATE', 'HandleGlobalItemEvent')
end
end
--[[ Item Slot Management ]]--
--if an item is not assigned to the given slotIndex, then add an item
function ItemFrame:AddItemSlot(bag, slot)
if self:IsBagShown(bag) and not self:GetItemSlot(bag, slot) then
local itemSlot = self:NewItemSlot(bag, slot)
self.itemSlots[self:GetSlotIndex(bag, slot)] = itemSlot
self:RequestLayout()
end
end
function ItemFrame:NewItemSlot(bag, slot)
return Bagnon.ItemSlot:New(bag, slot, self:GetFrameID(), self)
end
--removes any item slot associated with the given slotIndex
function ItemFrame:RemoveItemSlot(bag, slot)
local itemSlot = self:GetItemSlot(bag, slot)
if itemSlot then
itemSlot:Free()
self.itemSlots[self:GetSlotIndex(bag, slot)] = nil
self:RequestLayout()
end
end
function ItemFrame:UpdateItemSlot(bag, slot)
local itemSlot = self:GetItemSlot(bag, slot)
if itemSlot then
itemSlot:Update()
end
end
--returns the item slot assigned to the given slotIndex
function ItemFrame:GetItemSlot(bag, slot)
return self.itemSlots[self:GetSlotIndex(bag, slot)]
end
function ItemFrame:GetAllItemSlots()
return pairs(self.itemSlots)
end
--takes a bag and a slot, and returns an array index
function ItemFrame:GetSlotIndex(bag, slot)
if bag < 0 then
return bag*100 - slot
end
return bag * 100 + slot
end
--remove all item slots from the frame
function ItemFrame:AddAllItemSlotsForBag(bag)
for slot = 1, self:GetBagSize(bag) do
self:AddItemSlot(bag, slot)
end
end
function ItemFrame:RemoveAllItemSlotsForBag(bag)
for slot = 1, self:GetBagSize(bag) do
self:RemoveItemSlot(bag, slot)
end
end
function ItemFrame:UpdateAllItemSlotsForBag(bag)
for slot = 1, self:GetBagSize(bag) do
self:UpdateItemSlot(bag, slot)
end
end
--remove all unused item slots from the frame
--add all missing slots to the frame
--update all existing slots on the frame
--if slots have been added or removed, then request a layout update
function ItemFrame:ReloadAllItemSlots()
local changed = false
local itemSlots = self.itemSlots
for i, itemSlot in pairs(itemSlots) do
local used = self:IsBagShown(itemSlot:GetBag()) and (itemSlot:GetID() <= self:GetBagSize(itemSlot:GetBag()))
if not used then
itemSlot:Free()
itemSlots[i] = nil
changed = true
end
end
for _, bag in self:GetVisibleBags() do
for slot = 1, self:GetBagSize(bag) do
local itemSlot = self:GetItemSlot(bag, slot)
if not itemSlot then
self:AddItemSlot(bag, slot)
changed = true
else
itemSlot:Update()
end
end
end
if changed then
self:RequestLayout()
end
end
--[[ Layout Methods ]]--
function ItemFrame:Layout()
if self:IsBagBreakEnabled() then
self:Layout_BagBreak()
else
self:Layout_Default()
end
if Facade then
Facade:Group('Bagnon', self:GetFrameID()):ReSkin()
end
end
--arranges itemSlots on the itemFrame, and adjusts size to fit
function ItemFrame:Layout_Default()
self.needsLayout = nil
local columns = self:NumColumns()
local spacing = self:GetSpacing()
local effItemSize = self.ITEM_SIZE + spacing
local i = 0
for _, bag in self:GetVisibleBags() do
for slot = 1, self:GetBagSize(bag) do
local itemSlot = self:GetItemSlot(bag, slot)
if itemSlot then
i = i + 1
local row = (i - 1) % columns
local col = math.ceil(i / columns) - 1
itemSlot:ClearAllPoints()
itemSlot:SetPoint('TOPLEFT', self, 'TOPLEFT', effItemSize * row, -effItemSize * col)
end
end
end
local width = effItemSize * math.min(columns, i) - spacing
local height = effItemSize * ceil(i / columns) - spacing
self:SetWidth(width)
self:SetHeight(height)
end
function ItemFrame:Layout_BagBreak()
self.needsLayout = nil
local columns = self:NumColumns()
local spacing = self:GetSpacing()
local effItemSize = self.ITEM_SIZE + spacing
local rows = 1
local col = 1
local maxCols = 0
for _, bag in self:GetVisibleBags() do
local bagSize = self:GetBagSize(bag)
for slot = 1, bagSize do
local itemSlot = self:GetItemSlot(bag, slot)
itemSlot:ClearAllPoints()
itemSlot:SetPoint('TOPLEFT', self, 'TOPLEFT', effItemSize * (col - 1), -effItemSize * (rows - 1))
if col == columns then
col = 1
if slot < bagSize then
rows = rows + 1
end
else
col = col + 1
maxCols = math.max(maxCols, col)
end
end
rows = rows + 1
col = 1
end
local width = effItemSize * maxCols - spacing*2
local height = effItemSize * (rows - 1) - spacing*2
self:SetWidth(width)
self:SetHeight(height)
end
--request a layout update on this frame
function ItemFrame:RequestLayout()
self.needsLayout = true
self.throttledUpdater:Show()
end
--returns true if the frame should have its layout updated, and false otherwise
function ItemFrame:NeedsLayout()
return self.needsLayout
end
--[[ Frame Properties ]]--
--frameID
function ItemFrame:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateEverything()
end
end
function ItemFrame:GetFrameID()
return self.frameID
end
--frame settings
function ItemFrame:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
--player info
function ItemFrame:GetPlayer()
return self:GetSettings():GetPlayerFilter()
end
function ItemFrame:IsCached()
return Bagnon.PlayerInfo:IsCached(self:GetPlayer())
end
--bag info
function ItemFrame:HasBag(bag)
return self:GetSettings():HasBagSlot(slot)
end
function ItemFrame:GetBagSize(bag)
return Bagnon.BagSlotInfo:GetSize(self:GetPlayer(), bag)
end
function ItemFrame:IsBagShown(bag)
return self:GetSettings():IsBagSlotShown(bag)
end
function ItemFrame:IsBagSlotCached(bag)
return Bagnon.BagSlotInfo:IsCached(self:GetPlayer(), bag)
end
function ItemFrame:GetVisibleBags()
return self:GetSettings():GetVisibleBagSlots()
end
function ItemFrame:HasBankBags()
for _, bag in self:GetVisibleBags() do
if Bagnon.BagSlotInfo:IsBank(bag) or Bagnon.BagSlotInfo:IsBankBag(bag) then
return true
end
end
return false
end
--layout info
function ItemFrame:NumColumns()
return self:GetSettings():GetItemFrameColumns()
end
function ItemFrame:GetSpacing()
return self:GetSettings():GetItemFrameSpacing()
end
function ItemFrame:IsBagBreakEnabled()
return self:GetSettings():IsBagBreakEnabled()
endPK d>W Bagnon/components/moneyFrame.lua--[[
moneyFrame.lua
A money frame object
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local MoneyFrame = Bagnon.Classy:New('Frame')
MoneyFrame:Hide()
Bagnon.MoneyFrame = MoneyFrame
--[[ Things! ]]--
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local GOLD_TEXT = string.format('|cffffd700%s|r', 'g')
local SILVER_TEXT = string.format('|cffc7c7cf%s|r', 's')
local COPPER_TEXT = string.format('|cffeda55f%s|r', 'c')
--[[ Constructor ]]--
function MoneyFrame:New(frameID, parent)
local f = self:Bind(CreateFrame('Frame', 'BagnonMoneyFrame' .. self:GetNextID(), parent, 'SmallMoneyFrameTemplate'))
f:SetFrameID(frameID)
f:AddClickFrame()
f:SetScript('OnShow', f.OnShow)
f:SetScript('OnHide', f.OnHide)
f:RegisterMessage('PLAYER_UPDATE')
return f
end
--creates a clickable frame for tooltips/etc
local function ClickFrame_OnClick(self, button)
self:GetParent():OnClick(button)
end
local function ClickFrame_OnEnter(self)
self:GetParent():OnEnter()
end
local function ClickFrame_OnLeave(self)
self:GetParent():OnLeave()
end
function MoneyFrame:AddClickFrame()
local f = CreateFrame('Button', self:GetName() .. 'Click', self)
f:SetFrameLevel(self:GetFrameLevel() + 3)
f:SetAllPoints(self)
f:SetScript('OnClick', ClickFrame_OnClick)
f:SetScript('OnEnter', ClickFrame_OnEnter)
f:SetScript('OnLeave', ClickFrame_OnLeave)
return f
end
do
local id = 0
function MoneyFrame:GetNextID()
local nextID = id + 1
id = nextID
return nextID
end
end
--[[ Events ]]--
function MoneyFrame:PLAYER_UPDATE(msg, frameID, player)
if self:GetFrameID() == frameID then
self:UpdateValue()
end
end
--[[ Frame Events ]]--
function MoneyFrame:OnShow()
self:UpdateEverything()
end
function MoneyFrame:OnHide()
self:UpdateEvents()
end
function MoneyFrame:OnClick()
local name = self:GetName()
if MouseIsOver(_G[name .. 'GoldButton']) then
OpenCoinPickupFrame(COPPER_PER_GOLD, MoneyTypeInfo[self.moneyType].UpdateFunc(), self)
self.hasPickup = 1
elseif MouseIsOver(_G[name .. 'SilverButton']) then
OpenCoinPickupFrame(COPPER_PER_SILVER, MoneyTypeInfo[self.moneyType].UpdateFunc(), self)
self.hasPickup = 1
elseif MouseIsOver(_G[name .. 'CopperButton']) then
OpenCoinPickupFrame(1, MoneyTypeInfo[self.moneyType].UpdateFunc(), self)
self.hasPickup = 1
end
self:OnLeave()
end
function MoneyFrame:OnEnter()
if not BagnonDB then return end
GameTooltip:SetOwner(self, 'ANCHOR_TOPRIGHT')
GameTooltip:SetText(string.format(L.TipGoldOnRealm, GetRealmName()))
local totalMoney = 0
for i, player in pairs(BagnonDB:GetPlayerList()) do
local money = Bagnon.PlayerInfo:GetMoney(player)
if money > 0 then
totalMoney = totalMoney + money
self:AddPlayerTotalToTooltip(player, money, GameTooltip)
end
end
GameTooltip:AddLine('----------------------------------------')
self:AddPlayerTotalToTooltip(L.Total, totalMoney, GameTooltip)
GameTooltip:Show()
end
function MoneyFrame:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
--[[ Update Methods ]]--
function MoneyFrame:UpdateEverything()
self:UpdateEvents()
self:UpdateValue()
end
function MoneyFrame:UpdateValue()
if self:IsVisible() then
MoneyFrame_Update(self:GetName(), self:GetMoney())
end
end
function MoneyFrame:UpdateEvents()
self:UnregisterAllMessages()
if self:IsVisible() then
self:RegisterMessage('PLAYER_UPDATE')
end
end
--[[ Frame Properties ]]--
function MoneyFrame:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function MoneyFrame:GetPlayer()
return self:GetSettings():GetPlayerFilter()
end
function MoneyFrame:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateEverything()
end
end
function MoneyFrame:GetFrameID()
return self.frameID
end
function MoneyFrame:GetMoney()
return Bagnon.PlayerInfo:GetMoney(self:GetPlayer())
end
function MoneyFrame:GetGoldSilverCopper(money)
local gold = math.floor(money / (COPPER_PER_SILVER * SILVER_PER_GOLD))
local silver = math.floor((money - (gold * COPPER_PER_SILVER * SILVER_PER_GOLD)) / COPPER_PER_SILVER)
local copper = money % COPPER_PER_SILVER
return gold, silver, copper
end
function MoneyFrame:AddPlayerTotalToTooltip(player, money, tooltip)
local gold, silver, copper = self:GetGoldSilverCopper(money)
local text
if gold > 0 then
text = string.format('|cffffffff%d|r%s', gold, GOLD_TEXT)
end
if silver > 0 then
if text then
text = text .. string.format(' |cffffffff%d|r%s', silver, SILVER_TEXT)
else
text = string.format('|cffffffff%d|r%s', silver, SILVER_TEXT)
end
end
if copper > 0 then
if text then
text = text .. string.format(' |cffffffff%d|r%s', copper, COPPER_TEXT)
else
text = string.format('|cffffffff%d|r%s', copper, COPPER_TEXT)
end
end
tooltip:AddDoubleLine(player, text, 1, 1, 1, 1, 1, 1, 0)
endPK d>. # Bagnon/components/optionsToggle.lua--[[
optionsToggle.lua
A options frame toggle widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local OptionsToggle = Bagnon.Classy:New('Button')
Bagnon.OptionsToggle = OptionsToggle
local SIZE = 20
local NORMAL_TEXTURE_SIZE = 64 * (SIZE/36)
--[[ Constructor ]]--
function OptionsToggle:New(frameID, parent)
local b = self:Bind(CreateFrame('Button', nil, parent))
b:SetWidth(SIZE)
b:SetHeight(SIZE)
b:RegisterForClicks('anyUp')
local nt = b:CreateTexture()
nt:SetTexture([[Interface\Buttons\UI-Quickslot2]])
nt:SetWidth(NORMAL_TEXTURE_SIZE)
nt:SetHeight(NORMAL_TEXTURE_SIZE)
nt:SetPoint('CENTER', 0, -1)
b:SetNormalTexture(nt)
local pt = b:CreateTexture()
pt:SetTexture([[Interface\Buttons\UI-Quickslot-Depress]])
pt:SetAllPoints(b)
b:SetPushedTexture(pt)
local ht = b:CreateTexture()
ht:SetTexture([[Interface\Buttons\ButtonHilight-Square]])
ht:SetAllPoints(b)
b:SetHighlightTexture(ht)
local icon = b:CreateTexture()
icon:SetAllPoints(b)
icon:SetTexture([[Interface\Icons\Trade_Engineering]])
b:SetScript('OnClick', b.OnClick)
b:SetScript('OnEnter', b.OnEnter)
b:SetScript('OnLeave', b.OnLeave)
b:SetFrameID(frameID)
return b
end
--[[ Frame Events ]]--
function OptionsToggle:OnClick()
if LoadAddOn('Bagnon_Config') then
Bagnon.FrameOptions:ShowFrame(self:GetFrameID())
end
end
function OptionsToggle:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
end
function OptionsToggle:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
--[[ Update Methods ]]--
function OptionsToggle:UpdateTooltip()
if GameTooltip:IsOwned(self) then
GameTooltip:SetText(L.TipShowFrameConfig)
end
end
--[[ Properties ]]--
function OptionsToggle:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
end
end
function OptionsToggle:GetFrameID()
return self.frameID
endPK d>, $ Bagnon/components/playerSelector.lua--[[
playerSelector.lua
A player selector widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local PlayerSelector = Bagnon.Classy:New('Button')
Bagnon.PlayerSelector = PlayerSelector
local SIZE = 20
local NORMAL_TEXTURE_SIZE = 64 * (SIZE/36)
--[[ Constructor ]]--
function PlayerSelector:New(frameID, parent)
local b = self:Bind(CreateFrame('Button', nil, parent))
b:SetWidth(SIZE)
b:SetHeight(SIZE)
b:RegisterForClicks('anyUp')
local nt = b:CreateTexture()
nt:SetTexture([[Interface\Buttons\UI-Quickslot2]])
nt:SetWidth(NORMAL_TEXTURE_SIZE)
nt:SetHeight(NORMAL_TEXTURE_SIZE)
nt:SetPoint('CENTER', 0, -1)
b:SetNormalTexture(nt)
local pt = b:CreateTexture()
pt:SetTexture([[Interface\Buttons\UI-Quickslot-Depress]])
pt:SetAllPoints(b)
b:SetPushedTexture(pt)
local ht = b:CreateTexture()
ht:SetTexture([[Interface\Buttons\ButtonHilight-Square]])
ht:SetAllPoints(b)
b:SetHighlightTexture(ht)
local icon = b:CreateTexture()
icon:SetAllPoints(b)
icon:SetTexture(self:GetPlayerIcon())
b.icon = icon
b:SetScript('OnClick', b.OnClick)
b:SetScript('OnEnter', b.OnEnter)
b:SetScript('OnLeave', b.OnLeave)
b:SetScript('OnShow', b.OnShow)
b:SetFrameID(frameID)
return b
end
--[[ Frame Events ]]--
function PlayerSelector:OnShow()
self.icon:SetTexture(self:GetPlayerIcon())
end
function PlayerSelector:OnClick()
self:ShowPlayerSelector()
end
function PlayerSelector:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
end
function PlayerSelector:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
--[[ Update Methods ]]--
function PlayerSelector:ShowPlayerSelector()
if BagnonDB then
BagnonDB:SetDropdownFrame(self)
BagnonDB:ToggleDropdown(self, -4, -2)
end
end
function PlayerSelector:UpdateTooltip()
GameTooltip:SetText(L.TipChangePlayer)
end
--[[ Properties ]]--
function PlayerSelector:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
end
end
function PlayerSelector:GetFrameID()
return self.frameID
end
function PlayerSelector:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function PlayerSelector:SetPlayer(player)
self:GetSettings():SetPlayerFilter(player)
end
function PlayerSelector:GetPlayer()
return self:GetSettings():GetPlayerFilter()
end
function PlayerSelector:GetPlayerIcon()
local race, enRace = UnitRace('player')
--forsaken hack
if enRace == 'Scourge' then
enRace = 'Undead'
end
local sex = UnitSex('player') == 3 and 'Female' or 'Male'
return string.format([[Interface\CharacterFrame\TEMPORARYPORTRAIT-%s-%s]], sex, enRace)
-- switching to temporary portraits until the next holiday achievements that bring worgen ones in
-- return string.format([[Interface\Icons\Achievement_Character_%s_%s]], enRace, sex)
endPK d>Q?L+ L+ ( Bagnon/components/savedFrameSettings.lua--[[
savedFrameSettings.lua
Persistent frame settings
--]]
local SavedFrameSettings = {}
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local Facade = LibStub('LibButtonFacade', true)
Bagnon.SavedFrameSettings = SavedFrameSettings
--[[---------------------------------------------------------------------------
Local Functions of Justice
--]]---------------------------------------------------------------------------
local function removeDefaults(tbl, defaults)
for k, v in pairs(defaults) do
if type(tbl[k]) == 'table' and type(v) == 'table' then
removeDefaults(tbl[k], v)
if next(tbl[k]) == nil then
tbl[k] = nil
end
elseif tbl[k] == v then
tbl[k] = nil
end
end
end
local function copyDefaults(tbl, defaults)
for k, v in pairs(defaults) do
if type(v) == 'table' then
tbl[k] = copyDefaults(tbl[k] or {}, v)
elseif tbl[k] == nil then
tbl[k] = v
end
end
return tbl
end
--[[---------------------------------------------------------------------------
Constructorish
--]]---------------------------------------------------------------------------
SavedFrameSettings.mt = {
__index = SavedFrameSettings
}
SavedFrameSettings.objects = setmetatable({}, {__index = function(tbl, id)
local obj = setmetatable({frameID = id}, SavedFrameSettings.mt)
tbl[id] = obj
return obj
end})
function SavedFrameSettings:Get(id)
return self.objects[id]
end
--[[---------------------------------------------------------------------------
Events
--]]---------------------------------------------------------------------------
--create an event handler
do
local f = CreateFrame('Frame')
f:SetScript('OnEvent', function(self, event, ...)
local action = SavedFrameSettings[event]
if action then
action(SavedFrameSettings, event, ...)
end
end)
f:RegisterEvent('PLAYER_LOGOUT')
end
--remove any settings that are set to defaults upon logout
function SavedFrameSettings:PLAYER_LOGOUT()
self:ClearDefaults()
end
--[[---------------------------------------------------------------------------
Accessor Methods
--]]---------------------------------------------------------------------------
--get settings for all frames
--only one instance of this for everything (hence the lack of self use)
function SavedFrameSettings:GetGlobalDB()
if not SavedFrameSettings.db then
SavedFrameSettings.db = _G['BagnonFrameSettings']
if SavedFrameSettings.db then
if self:IsDBOutOfDate() then
self:UpgradeDB()
end
else
SavedFrameSettings.db = {
frames = {},
version = self:GetAddOnVersion()
}
_G['BagnonFrameSettings'] = SavedFrameSettings.db
end
end
return SavedFrameSettings.db
end
--get frame specific settings
function SavedFrameSettings:GetDB()
if not self.frameDB then
self.frameDB = self:GetGlobalDB().frames[self:GetFrameID()]
if not self.frameDB then
self.frameDB = {}
self:GetGlobalDB().frames[self:GetFrameID()] = self.frameDB
end
copyDefaults(self.frameDB, self:GetDefaultSettings())
end
return self.frameDB
end
function SavedFrameSettings:GetFrameID()
return self.frameID
end
--[[---------------------------------------------------------------------------
Upgrade Methods
--]]---------------------------------------------------------------------------
function SavedFrameSettings:UpgradeDB()
local major, minor, bugfix = self:GetDBVersion():match('(%w+)%.(%w+)%.(%w+)')
local db = self:GetGlobalDB()
--hidden bags upgrade
for frameID, settings in pairs(db.frames) do
local hiddenBags = settings.hiddenBags
if hiddenBags then
for k, v in pairs(hiddenBags) do
if tonumber(k) and tonumber(v) then
hiddenBags[v] = true
hiddenBags[k] = nil
end
end
end
end
db.version = self:GetAddOnVersion()
end
function SavedFrameSettings:IsDBOutOfDate()
return self:GetDBVersion() ~= self:GetAddOnVersion()
end
function SavedFrameSettings:GetDBVersion()
return self:GetGlobalDB().version
end
function SavedFrameSettings:GetAddOnVersion()
return GetAddOnMetadata('Bagnon', 'Version')
end
function SavedFrameSettings:ClearDefaults()
local db = self:GetGlobalDB()
for frameID, settings in pairs(db.frames) do
removeDefaults(settings, self:GetDefaultSettings(frameID))
if next(settings) == nil then
db[frameID] = nil
end
end
end
--[[---------------------------------------------------------------------------
Update Methods
--]]---------------------------------------------------------------------------
--[[ Frame Color ]]--
--background
function SavedFrameSettings:SetColor(r, g, b, a)
local color = self:GetDB().frameColor
color[1] = r
color[2] = g
color[3] = b
color[4] = a
end
function SavedFrameSettings:GetColor()
local r, g, b, a = unpack(self:GetDB().frameColor)
return r, g, b, a
end
--border
function SavedFrameSettings:SetBorderColor(r, g, b, a)
local color = self:GetDB().frameBorderColor
color[1] = r
color[2] = g
color[3] = b
color[4] = a
end
function SavedFrameSettings:GetBorderColor()
local r, g, b, a = unpack(self:GetDB().frameBorderColor)
return r, g, b, a
end
--[[ Frame Position ]]--
function SavedFrameSettings:SetPosition(point, x, y)
local db = self:GetDB()
db.point = point
db.x = x
db.y = y
end
function SavedFrameSettings:GetPosition()
local db = self:GetDB()
return db.point, db.x, db.y
end
--[[ Frame Scale ]]--
function SavedFrameSettings:SetScale(scale)
self:GetDB().scale = scale
end
function SavedFrameSettings:GetScale()
return self:GetDB().scale
end
--[[ Frame Opacity ]]--
function SavedFrameSettings:SetOpacity(opacity)
self:GetDB().opacity = opacity
end
function SavedFrameSettings:GetOpacity()
return self:GetDB().opacity
end
--[[ Frame Layer]]--
function SavedFrameSettings:SetLayer(layer)
self:GetDB().frameLayer = layer
end
function SavedFrameSettings:GetLayer()
return self:GetDB().frameLayer
end
--[[ Frame Components ]]--
function SavedFrameSettings:SetHasBagFrame(enable)
self:GetDB().hasBagFrame = enable or false
end
function SavedFrameSettings:HasBagFrame()
return self:GetDB().hasBagFrame
end
function SavedFrameSettings:SetHasMoneyFrame(enable)
self:GetDB().hasMoneyFrame = enable or false
end
function SavedFrameSettings:HasMoneyFrame()
return self:GetDB().hasMoneyFrame
end
function SavedFrameSettings:SetHasDBOFrame(enable)
self:GetDB().hasDBOFrame = enable or false
end
function SavedFrameSettings:HasDBOFrame()
return self:GetDB().hasDBOFrame
end
function SavedFrameSettings:SetHasSearchToggle(enable)
self:GetDB().hasSearchToggle = enable or false
end
function SavedFrameSettings:HasSearchToggle()
return self:GetDB().hasSearchToggle
end
function SavedFrameSettings:SetHasOptionsToggle(enable)
self:GetDB().hasOptionsToggle = enable or false
end
function SavedFrameSettings:HasOptionsToggle()
return self:GetDB().hasOptionsToggle
end
--[[ Frame Bags ]]--
--show a bag
function SavedFrameSettings:ShowBag(bag)
self:GetDB().hiddenBags[bag] = false
end
--hide a bag
function SavedFrameSettings:HideBag(bag)
self:GetDB().hiddenBags[bag] = true
end
function SavedFrameSettings:IsBagShown(bag)
return not self:GetDB().hiddenBags[bag]
end
--get all available bags
function SavedFrameSettings:GetBags()
return self:GetDB().availableBags
end
--get all hidden bags
function SavedFrameSettings:GetHiddenBags()
return self:GetDB().hiddenBags
end
--[[ Item Frame Layout ]]--
--columns
function SavedFrameSettings:SetItemFrameColumns(columns)
self:GetDB().itemFrameColumns = columns
end
function SavedFrameSettings:GetItemFrameColumns()
return self:GetDB().itemFrameColumns
end
--spacing
function SavedFrameSettings:SetItemFrameSpacing(spacing)
self:GetDB().itemFrameSpacing = spacing
end
function SavedFrameSettings:GetItemFrameSpacing()
return self:GetDB().itemFrameSpacing
end
--bag break layout
function SavedFrameSettings:SetBagBreak(enable)
self:GetDB().bagBreak = enable
end
function SavedFrameSettings:IsBagBreakEnabled()
return self:GetDB().bagBreak
end
--[[ Item Frame Slot Ordering ]]--
function SavedFrameSettings:SetReverseSlotOrder(enable)
self:GetDB().reverseSlotOrder = enable
end
function SavedFrameSettings:IsSlotOrderReversed()
return self:GetDB().reverseSlotOrder
end
--[[ Databroker Display Object ]]--
function SavedFrameSettings:SetBrokerDisplayObject(objectName)
self:GetDB().dataBrokerObject = objectName
end
function SavedFrameSettings:GetBrokerDisplayObject()
return self:GetDB().dataBrokerObject
end
--[[ ButtonFacade Settings ]]--
if Facade then
function SavedFrameSettings:GetFacade()
local facade = self:GetDB().facade
return facade and unpack(facade)
end
end
--[[---------------------------------------------------------------------------
Frame Defaults
--]]---------------------------------------------------------------------------
--generic
function SavedFrameSettings:GetDefaultSettings(frameID)
local frameID = frameID or self:GetFrameID()
if frameID == 'bank' then
return self:GetDefaultBankSettings()
elseif frameID == 'guildbank' then
return self:GetDefaultGuildBankSettings()
end
return self:GetDefaultInventorySettings()
end
--inventory
function SavedFrameSettings:GetDefaultInventorySettings()
local defaults = SavedFrameSettings.invDefaults or {
--bag settings
availableBags = {BACKPACK_CONTAINER, 1, 2, 3, 4},
hiddenBags = {
[BACKPACK_CONTAINER] = false,
[1] = false,
[2] = false,
[3] = false,
[4] = false,
[KEYRING_CONTAINER] = true,
},
--frame
frameColor = {0, 0, 0, 0.5},
frameBorderColor = {1, 1, 1, 1},
scale = 1,
opacity = 1,
point = 'BOTTOMRIGHT',
x = 0,
y = 150,
frameLayer = 'HIGH',
--itemFrame
itemFrameColumns = 8,
itemFrameSpacing = 2,
bagBreak = false,
--optional components
hasMoneyFrame = true,
hasBagFrame = true,
hasDBOFrame = true,
hasSearchToggle = true,
hasOptionsToggle = true,
--dbo display object
dataBrokerObject = 'BagnonLauncher',
--slot ordering
reverseSlotOrder = false,
}
SavedFrameSettings.invDefaults = defaults
return defaults
end
--bank
function SavedFrameSettings:GetDefaultBankSettings()
local defaults = SavedFrameSettings.bankDefaults or {
--bag settings
availableBags = {BANK_CONTAINER, 5, 6, 7, 8, 9, 10, 11},
hiddenBags = {
[BANK_CONTAINER] = false,
[5] = false,
[6] = false,
[7] = false,
[8] = false,
[9] = false,
[10] = false,
[11] = false
},
--frame
frameColor = {0, 0, 0, 0.5},
frameBorderColor = {1, 1, 0, 1},
scale = 1,
opacity = 1,
point = 'BOTTOMLEFT',
x = 0,
y = 150,
frameLayer = 'HIGH',
--itemFrame
itemFrameColumns = 10,
itemFrameSpacing = 2,
bagBreak = false,
--optional components
hasMoneyFrame = true,
hasBagFrame = true,
hasDBOFrame = true,
hasSearchToggle = true,
hasOptionsToggle = true,
--dbo display object
dataBrokerObject = 'BagnonLauncher',
--slot ordering
reverseSlotOrder = false,
}
SavedFrameSettings.bankDefaults = defaults
return defaults
end
function SavedFrameSettings:GetDefaultGuildBankSettings()
return self:GetDefaultInventorySettings()
endPK d>
# Bagnon/components/savedSettings.lua--[[
dbSettings.lua
Database access for Bagnon
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local SavedSettings = {}
Bagnon.SavedSettings = SavedSettings
--[[---------------------------------------------------------------------------
Local Functions of Justice
--]]---------------------------------------------------------------------------
local function removeDefaults(tbl, defaults)
for k, v in pairs(defaults) do
if type(tbl[k]) == 'table' and type(v) == 'table' then
removeDefaults(tbl[k], v)
if next(tbl[k]) == nil then
tbl[k] = nil
end
elseif tbl[k] == v then
tbl[k] = nil
end
end
end
local function copyDefaults(tbl, defaults)
for k, v in pairs(defaults) do
if type(v) == 'table' then
tbl[k] = copyDefaults(tbl[k] or {}, v)
elseif tbl[k] == nil then
tbl[k] = v
end
end
return tbl
end
--[[---------------------------------------------------------------------------
Constructorish
--]]---------------------------------------------------------------------------
function SavedSettings:GetDB()
if not self.db then
self.db = _G['BagnonGlobalSettings']
if self.db then
if self:IsDBOutOfDate() then
self:UpgradeDB()
end
else
self.db = self:CreateNewDB()
Bagnon:Print(L.NewUser)
end
copyDefaults(self.db, self:GetDefaultSettings())
end
return self.db
end
function SavedSettings:GetDefaultSettings()
self.defaults = self.defaults or {
highlightItemsByQuality = true,
highlightQuestItems = true,
showEmptyItemSlotTexture = true,
lockFramePositions = false,
colorBagSlots = true,
enableFlashFind = true,
enableBlizzardBagPassThrough = false,
enabledFrames = {
inventory = true,
bank = true,
},
autoDisplayEvents = {
inventory = {
ah = false,
bank = true,
vendor = true,
mail = true,
guildbank = true,
trade = false,
craft = false,
player = false
},
},
slotColors = {
trade = {0.5, 1, 0.5},
normal = {1, 1, 1},
},
highlightOpacity = 0.5,
}
return self.defaults
end
--[[---------------------------------------------------------------------------
Upgrade Methods
--]]---------------------------------------------------------------------------
function SavedSettings:CreateNewDB()
local db = {
version = self:GetAddOnVersion()
}
_G['BagnonGlobalSettings'] = db
return db
end
function SavedSettings:UpgradeDB()
local major, minor, bugfix = self:GetDBVersion():match('(%w+)%.(%w+)%.(%w+)')
--do upgrade stuff
if tonumber(minor) <= 6 and tonumber(bugfix) <= 2 then
local db = self.db
local autoDisplayEvents = self.db.autoDisplayEvents
if autoDisplayEvents then
for i = 1, #autoDisplayEvents do
autoDisplayEvents[i] = nil
end
end
end
self:GetDB().version = self:GetAddOnVersion()
Bagnon:Print(string.format(L.Updated, self:GetDBVersion()))
end
function SavedSettings:IsDBOutOfDate()
return self:GetDBVersion() ~= self:GetAddOnVersion()
end
function SavedSettings:GetDBVersion()
return self:GetDB().version
end
function SavedSettings:GetAddOnVersion()
return GetAddOnMetadata('Bagnon', 'Version')
end
--[[---------------------------------------------------------------------------
Events
--]]---------------------------------------------------------------------------
--create an event handler
do
local f = CreateFrame('Frame')
f:SetScript('OnEvent', function(self, event, ...)
local action = SavedSettings[event]
if action then
action(SavedSettings, event, ...)
end
end)
f:RegisterEvent('PLAYER_LOGOUT')
end
--remove any settings that are set to defaults upon logout
function SavedSettings:PLAYER_LOGOUT()
self:UpdateEnableFrames()
self:UpdateEnableBlizzardBagPassThrough()
self:ClearDefaults()
end
--handle enabling/disabling of frames
function SavedSettings:UpdateEnableFrames()
local framesToEnable = Bagnon.Settings.framesToEnable
if framesToEnable then
for frameID, enableStatus in pairs(framesToEnable) do
self:GetDB().enabledFrames[frameID] = enableStatus
end
end
end
function SavedSettings:UpdateEnableBlizzardBagPassThrough()
self:GetDB().enableBlizzardBagPassThrough = Bagnon.Settings:WillBlizzardBagPassThroughBeEnabled()
end
function SavedSettings:ClearDefaults()
if self.db then
removeDefaults(self.db, self:GetDefaultSettings())
end
end
--[[---------------------------------------------------------------------------
Complex Settings
--]]---------------------------------------------------------------------------
--frame auto display events
function SavedSettings:SetShowFrameAtEvent(frameID, event, enable)
self:GetDB().autoDisplayEvents[frameID][event] = enable and true or false
end
function SavedSettings:IsFrameShownAtEvent(frameID, event)
return self:GetDB().autoDisplayEvents[frameID][event]
end
PK d>̴h
! Bagnon/components/searchFrame.lua--[[
searchFrame.lua
A searcn frame widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local SearchFrame = Bagnon.Classy:New('EditBox')
SearchFrame:Hide()
Bagnon.SearchFrame = SearchFrame
SearchFrame.backdrop = {
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
bgFile = [[Interface\ChatFrame\ChatFrameBackground]],
insets = {
left = 2,
right = 2,
top = 2,
bottom = 2
},
tile = true,
tileSize = 16,
edgeSize = 16,
}
function SearchFrame:New(frameID, parent)
local f = self:Bind(CreateFrame('EditBox', nil, parent))
f:SetToplevel(true)
f:Hide()
f:SetFrameStrata('DIALOG')
f:SetTextInsets(8, 8, 0, 0)
f:SetFontObject('ChatFontNormal')
f:SetBackdrop(f.backdrop)
f:SetBackdropColor(0, 0, 0, 0.8)
f:SetBackdropBorderColor(1, 1, 1, 0.8)
f:SetScript('OnShow', f.OnShow)
f:SetScript('OnHide', f.OnHide)
f:SetScript('OnTextChanged', f.OnTextChanged)
f:SetScript('OnEscapePressed', f.OnEscapePressed)
f:SetScript('OnEnterPressed', f.OnEnterPressed)
f:SetFrameID(frameID)
f:UpdateEvents()
f:SetAutoFocus(false)
-- f:UpdateShown()
-- f:UpdateText()
return f
end
--[[ Messages ]]--
function SearchFrame:TEXT_SEARCH_ENABLE(msg, frameID)
if self:GetFrameID() == frameID then
self:UpdateShown()
end
end
function SearchFrame:TEXT_SEARCH_DISABLE(msg, frameID)
if self:GetFrameID() == frameID then
self:UpdateShown()
end
end
function SearchFrame:TEXT_SEARCH_UPDATE(msg, search)
self:UpdateText()
end
--[[ Frame Events ]]--
function SearchFrame:OnShow()
self:UpdateEvents()
self:SetSearch(self:GetLastSearch())
self:HighlightText()
self:SetFocus()
end
function SearchFrame:OnHide()
self:UpdateEvents()
self:ClearFocus()
self:SetSearch('')
end
function SearchFrame:OnTextChanged()
self:SetSearch(self:GetText())
end
function SearchFrame:OnEscapePressed()
self:DisableSearch()
end
function SearchFrame:OnEnterPressed()
self:DisableSearch()
end
--[[ Update Methods ]]--
function SearchFrame:UpdateEvents()
self:UnregisterAllMessages()
self:RegisterMessage('TEXT_SEARCH_ENABLE')
self:RegisterMessage('TEXT_SEARCH_DISABLE')
--[[
if self:IsVisible() then
self:RegisterMessage('TEXT_SEARCH_UPDATE')
end
--]]
end
function SearchFrame:UpdateShown()
if self:IsSearchEnabled() then
if not self:IsShown() then
UIFrameFadeIn(self, 0.1)
end
else
self:Hide()
end
end
function SearchFrame:UpdateText()
self:SetText(self:GetSearch())
end
--[[ Propertiesish ]]--
function SearchFrame:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateShown()
self:UpdateText()
end
end
function SearchFrame:GetFrameID()
return self.frameID
end
--[[ Frame Settings ]]--
function SearchFrame:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function SearchFrame:SetSearch(search)
Bagnon.Settings:SetTextSearch(search)
end
function SearchFrame:GetSearch()
return Bagnon.Settings:GetTextSearch()
end
function SearchFrame:GetLastSearch()
return Bagnon.Settings:GetLastTextSearch()
end
function SearchFrame:EnableSearch()
self:GetSettings():EnableTextSearch()
end
function SearchFrame:DisableSearch()
self:GetSettings():DisableTextSearch()
end
function SearchFrame:IsSearchEnabled()
return self:GetSettings():IsTextSearchEnabled()
endPK d>s " Bagnon/components/searchToggle.lua--[[
searchToggle.lua
A searcn toggle widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local SearchToggle = Bagnon.Classy:New('CheckButton')
Bagnon.SearchToggle = SearchToggle
local SIZE = 20
local NORMAL_TEXTURE_SIZE = 64 * (SIZE/36)
--[[ Constructor ]]--
function SearchToggle:New(frameID, parent)
local b = self:Bind(CreateFrame('CheckButton', nil, parent))
b:SetWidth(SIZE)
b:SetHeight(SIZE)
b:RegisterForClicks('anyUp')
local nt = b:CreateTexture()
nt:SetTexture([[Interface\Buttons\UI-Quickslot2]])
nt:SetWidth(NORMAL_TEXTURE_SIZE)
nt:SetHeight(NORMAL_TEXTURE_SIZE)
nt:SetPoint('CENTER', 0, -1)
b:SetNormalTexture(nt)
local pt = b:CreateTexture()
pt:SetTexture([[Interface\Buttons\UI-Quickslot-Depress]])
pt:SetAllPoints(b)
b:SetPushedTexture(pt)
local ht = b:CreateTexture()
ht:SetTexture([[Interface\Buttons\ButtonHilight-Square]])
ht:SetAllPoints(b)
b:SetHighlightTexture(ht)
local ct = b:CreateTexture()
ct:SetTexture([[Interface\Buttons\CheckButtonHilight]])
ct:SetAllPoints(b)
ct:SetBlendMode('ADD')
b:SetCheckedTexture(ct)
local icon = b:CreateTexture()
icon:SetAllPoints(b)
icon:SetTexture([[Interface\Icons\INV_Misc_Spyglass_03]])
b:SetScript('OnClick', b.OnClick)
b:SetScript('OnEnter', b.OnEnter)
b:SetScript('OnLeave', b.OnLeave)
b:SetScript('OnShow', b.OnShow)
b:SetScript('OnHide', b.OnHide)
b:SetFrameID(frameID)
return b
end
--[[ Messages ]]--
function SearchToggle:TEXT_SEARCH_ENABLE(msg, frameID)
if frameID == self:GetFrameID() then
self:Update()
end
end
function SearchToggle:TEXT_SEARCH_DISABLE(msg, frameID)
if frameID == self:GetFrameID() then
self:Update()
end
end
--[[ Frame Events ]]--
function SearchToggle:OnShow()
self:UpdateEvents()
self:Update()
end
function SearchToggle:OnHide()
self:UpdateEvents()
end
function SearchToggle:OnClick()
self:ToggleSearch()
end
function SearchToggle:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
end
function SearchToggle:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
--[[ Update Methods ]]--
function SearchToggle:Update()
if self:IsVisible() then
self:SetChecked(self:IsSearchEnabled())
end
end
function SearchToggle:UpdateEvents()
self:UnregisterAllMessages()
if self:IsVisible() then
self:RegisterMessage('TEXT_SEARCH_ENABLE')
self:RegisterMessage('TEXT_SEARCH_DISABLE')
end
end
function SearchToggle:UpdateTooltip()
if not GameTooltip:IsOwned(self) then return end
if self:IsSearchEnabled() then
GameTooltip:SetText(L.TipHideSearch)
else
GameTooltip:SetText(L.TipShowSearch)
end
end
--[[ Properties ]]--
function SearchToggle:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateEvents()
self:Update()
end
end
function SearchToggle:GetFrameID()
return self.frameID
end
function SearchToggle:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function SearchToggle:ToggleSearch()
self:GetSettings():ToggleTextSearch()
end
function SearchToggle:IsSearchEnabled()
return self:GetSettings():IsTextSearchEnabled()
endPK d>aSN Bagnon/components/settings.lua--[[
profileSettings.lua
Handles non specific frame settings
--]]
local Settings = {}
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
Bagnon.Settings = Settings
--[[---------------------------------------------------------------------------
Accessor Methods
--]]---------------------------------------------------------------------------
function Settings:GetDB()
return Bagnon.SavedSettings:GetDB()
end
--[[---------------------------------------------------------------------------
Message Passing
--]]---------------------------------------------------------------------------
function Settings:SendMessage(msg, ...)
Bagnon.Callbacks:SendMessage(msg, ...)
end
--[[---------------------------------------------------------------------------
Settings...Setting
--]]---------------------------------------------------------------------------
--highlight items by quality
function Settings:SetHighlightItemsByQuality(enable)
if self:HighlightingItemsByQuality() ~= enable then
self:GetDB().highlightItemsByQuality = enable
self:SendMessage('ITEM_HIGHLIGHT_QUALITY_UPDATE')
end
end
function Settings:HighlightingItemsByQuality()
return self:GetDB().highlightItemsByQuality
end
--highlight unusable items
function Settings:SetHighlightUnusableItems(enable)
if self:HighlightUnusableItems() ~= enable then
self:GetDB().highlightUnusableItems = enable
self:SendMessage('ITEM_HIGHLIGHT_UNUSABLE_UPDATE')
end
end
function Settings:HighlightUnusableItems()
return self:GetDB().highlightUnusableItems
end
--highlight quest items
function Settings:SetHighlightQuestItems(enable)
if self:HighlightingQuestItems() ~= enable then
self:GetDB().highlightQuestItems = enable
self:SendMessage('ITEM_HIGHLIGHT_QUEST_UPDATE')
end
end
function Settings:HighlightingQuestItems()
return self:GetDB().highlightQuestItems
end
--highlight opacity
function Settings:SetHighlightOpacity(value)
local value = math.max(math.min(value, 1), 0)
if self:GetHighlightOpacity() ~= value then
self:GetDB().highlightOpacity = value
self:SendMessage('ITEM_HIGHLIGHT_OPACITY_UPDATE', value)
end
end
function Settings:GetHighlightOpacity()
return self:GetDB().highlightOpacity
end
--show empty item slots
function Settings:SetShowEmptyItemSlotTexture(enable)
if self:ShowingEmptyItemSlotTextures() ~= enable then
self:GetDB().showEmptyItemSlotTexture = enable
self:SendMessage('SHOW_EMPTY_ITEM_SLOT_TEXTURE_UPDATE', enable)
end
end
function Settings:ShowingEmptyItemSlotTextures()
return self:GetDB().showEmptyItemSlotTexture
end
--lock frame positions
function Settings:SetLockFramePositions(enable)
if self:AreFramePositionsLocked() ~= enable then
self:GetDB().lockFramePositions = enable
self:SendMessage('LOCK_FRAME_POSITIONS_UPDATE', enable)
end
end
function Settings:AreFramePositionsLocked()
return self:GetDB().lockFramePositions
end
--item slot coloring
function Settings:SetColorBagSlots(enable)
if self:ColoringBagSlots() ~= enable then
self:GetDB().colorBagSlots = enable
self:SendMessage('ITEM_SLOT_COLOR_ENABLED_UPDATE', enable)
end
end
function Settings:ColoringBagSlots()
return self:GetDB().colorBagSlots
end
function Settings:SetItemSlotColor(type, r, g, b)
local oR, oG, oB = self:GetItemSlotColor(type)
if not(oR == r and oG == g and oB == b) then
local slotColor = self:GetDB().slotColors[type]
slotColor[1] = r
slotColor[2] = g
slotColor[3] = b
self:SendMessage('ITEM_SLOT_COLOR_UPDATE', type, self:GetItemSlotColor(type))
end
end
function Settings:GetItemSlotColor(type)
local slotColor = self:GetDB().slotColors[type]
return unpack(slotColor)
end
--enable frames
function Settings:SetEnableFrame(frameID, enable)
local enable = enable and true or false
if self:WillFrameBeEnabled(frameID) ~= enable then
self.framesToEnable = self.framesToEnable or setmetatable({}, {__index = self:GetDB().enabledFrames})
self.framesToEnable[frameID] = enable and true or false
self:SendMessage('ENABLE_FRAME_UPDATE', frameID, self:WillFrameBeEnabled(frameID))
end
end
function Settings:IsFrameEnabled(frameID)
return self:GetDB().enabledFrames[frameID] and true or false
end
function Settings:WillFrameBeEnabled(frameID)
self.framesToEnable = self.framesToEnable or setmetatable({}, {__index = self:GetDB().enabledFrames})
return self.framesToEnable[frameID]
end
function Settings:AreAllFramesEnabled()
for frameID, isEnabled in pairs(self:GetDB().enabledFrames) do
if not isEnabled then
return false
end
end
return true
end
--automatic frame display
function Settings:SetShowFrameAtEvent(frameID, event, enable)
local enable = enable and true or false
if self:IsFrameShownAtEvent(frameID, event) ~= enable then
Bagnon.SavedSettings:SetShowFrameAtEvent(frameID, event, enable)
self:SendMessage('FRAME_DISPLAY_EVENT_UPDATE', frameID, event, self:IsFrameShownAtEvent(frameID, event))
end
end
function Settings:IsFrameShownAtEvent(frameID, event)
return Bagnon.SavedSettings:IsFrameShownAtEvent(frameID, event)
end
--blizzard bag passthrough
function Settings:SetEnableBlizzardBagPassThrough(enable)
local enable = enable and true or false
if self:WillBlizzardBagPassThroughBeEnabled() ~= enable then
self.enableBlizzardBagPassThrough = enable
self:SendMessage('BLIZZARD_BAG_PASSTHROUGH_UPDATE', self:WillBlizzardBagPassThroughBeEnabled())
end
end
function Settings:IsBlizzardBagPassThroughEnabled()
return self:GetDB().enableBlizzardBagPassThrough
end
function Settings:WillBlizzardBagPassThroughBeEnabled()
if self.enableBlizzardBagPassThrough == nil then
self.enableBlizzardBagPassThrough = self:IsBlizzardBagPassThroughEnabled()
end
return self.enableBlizzardBagPassThrough
end
--item searching
function Settings:SetTextSearch(search)
local lastSearch = self:GetTextSearch()
if lastSearch ~= search then
self.textSearch = search
self:SetLastTextSearch(lastSearch)
self:SendMessage('TEXT_SEARCH_UPDATE', self:GetTextSearch())
end
end
function Settings:GetTextSearch()
return self.textSearch or ''
end
function Settings:SetLastTextSearch(search)
if search and search ~= '' then
self.lastTextSearch = search
end
end
function Settings:GetLastTextSearch()
return self.lastTextSearch or ''
end
--flash search
function Settings:SetEnableFlashFind(enable)
local enable = enable and true or false
if self:IsFlashFindEnabled() ~= enable then
self:GetDB().enableFlashFind = enable
self:SendMessage('FLASH_FIND_UPDATE', self:IsFlashFindEnabled())
end
end
function Settings:IsFlashFindEnabled()
return self:GetDB().enableFlashFind and true or false
end
-- Opens the inventory and broadcasts the search message to item frames
function Settings:FlashFind(name)
if self:IsFlashFindEnabled() then
Bagnon:ShowFrame('inventory')
self:SendMessage('FLASH_SEARCH_UPDATE', name)
end
end
-- Function that is invoked when a chat link is clicked
hooksecurefunc("SetItemRef", function(link, text, button)
local name = text and text:match('^|c%x+|Hitem.+|h%[(.*)%]')
-- Alt must be pressed and left mouse button must be used
if IsAltKeyDown() and button == "LeftButton" and name then
Settings:FlashFind(name)
end
end)PK d>.(
Bagnon/components/titleFrame.lua--[[
titleFrame.lua
A title frame widget
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local TitleFrame = Bagnon.Classy:New('Button')
TitleFrame:Hide()
Bagnon.TitleFrame = TitleFrame
--[[ Constructor ]]--
function TitleFrame:New(frameID, parent)
local b = self:Bind(CreateFrame('Button', nil, parent))
b:SetToplevel(true)
b:SetNormalFontObject('GameFontNormalLeft')
b:SetHighlightFontObject('GameFontHighlightLeft')
b:RegisterForClicks('anyUp')
b:SetScript('OnShow', b.OnShow)
b:SetScript('OnHide', b.OnHide)
b:SetScript('OnMouseDown', b.OnMouseDown)
b:SetScript('OnMouseUp', b.OnMouseUp)
b:SetScript('OnDoubleClick', b.OnDoubleClick)
b:SetScript('OnEnter', b.OnEnter)
b:SetScript('OnLeave', b.OnLeave)
b:SetScript('OnClick', b.OnClick)
b:SetFrameID(frameID)
b:UpdateEvents()
return b
end
--[[ Messages ]]--
function TitleFrame:PLAYER_UPDATE(msg, frameID, player)
if frameID == self:GetFrameID() then
self:UpdateText()
end
end
--[[ Frame Events ]]--
function TitleFrame:OnShow()
self:UpdateText()
self:UpdateEvents()
end
function TitleFrame:OnHide()
self:StopMovingFrame()
end
function TitleFrame:OnMouseDown()
if self:IsFrameMovable() or IsAltKeyDown() then
self:StartMovingFrame()
end
end
function TitleFrame:OnMouseUp()
self:StopMovingFrame()
end
function TitleFrame:OnDoubleClick()
self:ToggleSearchFrame()
end
function TitleFrame:OnClick(button)
if button == 'RightButton' then
if LoadAddOn('Bagnon_Config') then
Bagnon.FrameOptions:ShowFrame(self:GetFrameID())
end
end
end
function TitleFrame:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
end
function TitleFrame:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
--[[ Update Methods ]]--
function TitleFrame:UpdateText()
self:SetFormattedText(self:GetTitleText(), self:GetPlayer())
self:GetFontString():SetAllPoints(self)
end
function TitleFrame:UpdateTooltip()
GameTooltip:SetText(L.TipDoubleClickSearch)
GameTooltip:Show()
end
function TitleFrame:UpdateEvents()
self:UnregisterAllMessages()
if self:IsVisible() then
self:RegisterMessage('PLAYER_UPDATE')
end
end
function TitleFrame:StartMovingFrame()
self:SendMessage('FRAME_MOVE_START', self:GetFrameID())
end
function TitleFrame:StopMovingFrame()
self:SendMessage('FRAME_MOVE_STOP', self:GetFrameID())
end
--[[ Properties ]]--
function TitleFrame:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
self:UpdateText()
end
end
function TitleFrame:GetFrameID()
return self.frameID
end
--yeah, still hardcoded
function TitleFrame:GetTitleText()
if self:GetFrameID() == 'bank' then
return L.TitleBank
end
if self:GetFrameID() == 'guildbank' then
return [[%s's Guild Bank]]
end
return L.TitleBags
end
--[[ Frame Settings ]]--
function TitleFrame:GetSettings()
return Bagnon.FrameSettings:Get(self:GetFrameID())
end
function TitleFrame:GetPlayer()
return self:GetSettings():GetPlayerFilter()
end
function TitleFrame:IsFrameMovable()
return self:GetSettings():IsMovable()
end
function TitleFrame:ToggleSearchFrame()
self:GetSettings():ToggleTextSearch()
endPK d>ɣC C ! Bagnon/libs/LibDataBroker-1.1.lua
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
if oldminor < 2 then
lib.domt = {
__metatable = "access denied",
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
}
end
if oldminor < 3 then
lib.domt.__newindex = function(self, key, value)
if not attributestorage[self] then attributestorage[self] = {} end
if attributestorage[self][key] == value then return end
attributestorage[self][key] = value
local name = namestorage[self]
if not name then return end
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
end
end
if oldminor < 2 then
function lib:NewDataObject(name, dataobj)
if self.proxystorage[name] then return end
if dataobj then
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
self.attributestorage[dataobj] = {}
for i,v in pairs(dataobj) do
self.attributestorage[dataobj][i] = v
dataobj[i] = nil
end
end
dataobj = setmetatable(dataobj or {}, self.domt)
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
return dataobj
end
end
if oldminor < 1 then
function lib:DataObjectIterator()
return pairs(self.proxystorage)
end
function lib:GetDataObjectByName(dataobjectname)
return self.proxystorage[dataobjectname]
end
function lib:GetNameByDataObject(dataobject)
return self.namestorage[dataobject]
end
end
if oldminor < 4 then
local next = pairs(attributestorage)
function lib:pairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
return next, attributestorage[dataobj], nil
end
local ipairs_iter = ipairs(attributestorage)
function lib:ipairs(dataobject_or_name)
local t = type(dataobject_or_name)
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
assert(attributestorage[dataobj], "Data object not found")
return ipairs_iter, attributestorage[dataobj], 0
end
end
PK d> ` ` ) Bagnon/libs/AceAddon-3.0/AceAddon-3.0.lua--- **AceAddon-3.0** provides a template for creating addon objects.
-- It'll provide you with a set of callback functions that allow you to simplify the loading
-- process of your addon.\\
-- Callbacks provided are:\\
-- * **OnInitialize**, which is called directly after the addon is fully loaded.
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
-- * **OnDisable**, which is only called when your addon is manually being disabled.
-- @usage
-- -- A small (but complete) addon, that doesn't do anything,
-- -- but shows usage of the callbacks.
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
--
-- function MyAddon:OnInitialize()
-- -- do init tasks here, like loading the Saved Variables,
-- -- or setting up slash commands.
-- end
--
-- function MyAddon:OnEnable()
-- -- Do more initialization here, that really enables the use of your addon.
-- -- Register Events, Hook functions, Create Frames, Get information from
-- -- the game that wasn't available in OnInitialize
-- end
--
-- function MyAddon:OnDisable()
-- -- Unhook, Unregister Events, Hide frames that you created.
-- -- You would probably only use an OnDisable if you want to
-- -- build a "standby" mode, or be able to toggle modules on/off.
-- end
-- @class file
-- @name AceAddon-3.0.lua
-- @release $Id: AceAddon-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
local MAJOR, MINOR = "AceAddon-3.0", 5
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceAddon then return end -- No Upgrade needed.
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
AceAddon.addons = AceAddon.addons or {} -- addons in general
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
-- Lua APIs
local tinsert, tconcat, tremove = table.insert, table.concat, table.remove
local fmt, tostring = string.format, tostring
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
local loadstring, assert, error = loadstring, assert, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...)
-- we check to see if the func is passed is actually a function here and don't error when it isn't
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
-- present execution should continue without hinderance
if type(func) == "function" then
return Dispatchers[select('#', ...)](func, ...)
end
end
-- local functions that will be implemented further down
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
-- used in the addon metatable
local function addontostring( self ) return self.name end
--- Create a new AceAddon-3.0 addon.
-- Any libraries you specified will be embeded, and the addon will be scheduled for
-- its OnInitialize and OnEnable callbacks.
-- The final addon object, with all libraries embeded, will be returned.
-- @paramsig [object ,]name[, lib, ...]
-- @param object Table to use as a base for the addon (optional)
-- @param name Name of the addon object to create
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a simple addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
--
-- -- Create a Addon object based on the table of a frame
-- local MyFrame = CreateFrame("Frame")
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
function AceAddon:NewAddon(objectorname, ...)
local object,name
local i=1
if type(objectorname)=="table" then
object=objectorname
name=...
i=2
else
name=objectorname
end
if type(name)~="string" then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
end
if self.addons[name] then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
end
object = object or {}
object.name = name
local addonmeta = {}
local oldmeta = getmetatable(object)
if oldmeta then
for k, v in pairs(oldmeta) do addonmeta[k] = v end
end
addonmeta.__tostring = addontostring
setmetatable( object, addonmeta )
self.addons[name] = object
object.modules = {}
object.defaultModuleLibraries = {}
Embed( object ) -- embed NewModule, GetModule methods
self:EmbedLibraries(object, select(i,...))
-- add to queue of addons to be initialized upon ADDON_LOADED
tinsert(self.initializequeue, object)
return object
end
--- Get the addon object by its name from the internal AceAddon registry.
-- Throws an error if the addon object cannot be found (except if silent is set).
-- @param name unique name of the addon object
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
function AceAddon:GetAddon(name, silent)
if not silent and not self.addons[name] then
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
end
return self.addons[name]
end
-- - Embed a list of libraries into the specified addon.
-- This function will try to embed all of the listed libraries into the addon
-- and error if a single one fails.
--
-- **Note:** This function is for internal use by :NewAddon/:NewModule
-- @paramsig addon, [lib, ...]
-- @param addon addon object to embed the libs in
-- @param lib List of libraries to embed into the addon
function AceAddon:EmbedLibraries(addon, ...)
for i=1,select("#", ... ) do
local libname = select(i, ...)
self:EmbedLibrary(addon, libname, false, 4)
end
end
-- - Embed a library into the addon object.
-- This function will check if the specified library is registered with LibStub
-- and if it has a :Embed function to call. It'll error if any of those conditions
-- fails.
--
-- **Note:** This function is for internal use by :EmbedLibraries
-- @paramsig addon, libname[, silent[, offset]]
-- @param addon addon object to embed the library in
-- @param libname name of the library to embed
-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
local lib = LibStub:GetLibrary(libname, true)
if not lib and not silent then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
elseif lib and type(lib.Embed) == "function" then
lib:Embed(addon)
tinsert(self.embeds[addon], libname)
return true
elseif lib then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
end
end
--- Return the specified module from an addon object.
-- Throws an error if the addon object cannot be found (except if silent is set)
-- @name //addon//:GetModule
-- @paramsig name[, silent]
-- @param name unique name of the module
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- -- Get the Module
-- MyModule = MyAddon:GetModule("MyModule")
function GetModule(self, name, silent)
if not self.modules[name] and not silent then
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
end
return self.modules[name]
end
local function IsModuleTrue(self) return true end
--- Create a new module for the addon.
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
-- an addon object.
-- @name //addon//:NewModule
-- @paramsig name[, prototype|lib[, lib, ...]]
-- @param name unique name of the module
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a module with some embeded libraries
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
--
-- -- Create a module with a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
function NewModule(self, name, prototype, ...)
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
module.IsModule = IsModuleTrue
module:SetEnabledState(self.defaultModuleState)
module.moduleName = name
if type(prototype) == "string" then
AceAddon:EmbedLibraries(module, prototype, ...)
else
AceAddon:EmbedLibraries(module, ...)
end
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
if not prototype or type(prototype) == "string" then
prototype = self.defaultModulePrototype or nil
end
if type(prototype) == "table" then
local mt = getmetatable(module)
mt.__index = prototype
setmetatable(module, mt) -- More of a Base class type feel.
end
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
self.modules[name] = module
return module
end
--- Returns the real name of the addon or module, without any prefix.
-- @name //addon//:GetName
-- @paramsig
-- @usage
-- print(MyAddon:GetName())
-- -- prints "MyAddon"
function GetName(self)
return self.moduleName or self.name
end
--- Enables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
-- and enabling all modules of the addon (unless explicitly disabled).\\
-- :Enable() also sets the internal `enableState` variable to true
-- @name //addon//:Enable
-- @paramsig
-- @usage
-- -- Enable MyModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
function Enable(self)
self:SetEnabledState(true)
return AceAddon:EnableAddon(self)
end
--- Disables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
-- and disabling all modules of the addon.\\
-- :Disable() also sets the internal `enableState` variable to false
-- @name //addon//:Disable
-- @paramsig
-- @usage
-- -- Disable MyAddon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:Disable()
function Disable(self)
self:SetEnabledState(false)
return AceAddon:DisableAddon(self)
end
--- Enables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
-- @name //addon//:EnableModule
-- @paramsig name
-- @usage
-- -- Enable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
--
-- -- Enable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:EnableModule("MyModule")
function EnableModule(self, name)
local module = self:GetModule( name )
return module:Enable()
end
--- Disables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
-- @name //addon//:DisableModule
-- @paramsig name
-- @usage
-- -- Disable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Disable()
--
-- -- Disable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:DisableModule("MyModule")
function DisableModule(self, name)
local module = self:GetModule( name )
return module:Disable()
end
--- Set the default libraries to be mixed into all modules created by this object.
-- Note that you can only change the default module libraries before any module is created.
-- @name //addon//:SetDefaultModuleLibraries
-- @paramsig lib[, lib, ...]
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
-- -- Create a module
-- MyModule = MyAddon:NewModule("MyModule")
function SetDefaultModuleLibraries(self, ...)
if next(self.modules) then
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleLibraries = {...}
end
--- Set the default state in which new modules are being created.
-- Note that you can only change the default state before any module is created.
-- @name //addon//:SetDefaultModuleState
-- @paramsig state
-- @param state Default state for new modules, true for enabled, false for disabled
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Set the default state to "disabled"
-- MyAddon:SetDefaultModuleState(false)
-- -- Create a module and explicilty enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
function SetDefaultModuleState(self, state)
if next(self.modules) then
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleState = state
end
--- Set the default prototype to use for new modules on creation.
-- Note that you can only change the default prototype before any module is created.
-- @name //addon//:SetDefaultModulePrototype
-- @paramsig prototype
-- @param prototype Default prototype for the new modules (table)
-- @usage
-- -- Define a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- -- Set the default prototype
-- MyAddon:SetDefaultModulePrototype(prototype)
-- -- Create a module and explicitly Enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
-- -- should print "OnEnable called!" now
-- @see NewModule
function SetDefaultModulePrototype(self, prototype)
if next(self.modules) then
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
end
if type(prototype) ~= "table" then
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
end
self.defaultModulePrototype = prototype
end
--- Set the state of an addon or module
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
-- @name //addon//:SetEnabledState
-- @paramsig state
-- @param state the state of an addon or module (enabled=true, disabled=false)
function SetEnabledState(self, state)
self.enabledState = state
end
--- Return an iterator of all modules associated to the addon.
-- @name //addon//:IterateModules
-- @paramsig
-- @usage
-- -- Enable all modules
-- for name, module in MyAddon:IterateModules() do
-- module:Enable()
-- end
local function IterateModules(self) return pairs(self.modules) end
-- Returns an iterator of all embeds in the addon
-- @name //addon//:IterateEmbeds
-- @paramsig
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
--- Query the enabledState of an addon.
-- @name //addon//:IsEnabled
-- @paramsig
-- @usage
-- if MyAddon:IsEnabled() then
-- MyAddon:Disable()
-- end
local function IsEnabled(self) return self.enabledState end
local mixins = {
NewModule = NewModule,
GetModule = GetModule,
Enable = Enable,
Disable = Disable,
EnableModule = EnableModule,
DisableModule = DisableModule,
IsEnabled = IsEnabled,
SetDefaultModuleLibraries = SetDefaultModuleLibraries,
SetDefaultModuleState = SetDefaultModuleState,
SetDefaultModulePrototype = SetDefaultModulePrototype,
SetEnabledState = SetEnabledState,
IterateModules = IterateModules,
IterateEmbeds = IterateEmbeds,
GetName = GetName,
}
local function IsModule(self) return false end
local pmixins = {
defaultModuleState = true,
enabledState = true,
IsModule = IsModule,
}
-- Embed( target )
-- target (object) - target object to embed aceaddon in
--
-- this is a local function specifically since it's meant to be only called internally
function Embed(target)
for k, v in pairs(mixins) do
target[k] = v
end
for k, v in pairs(pmixins) do
target[k] = target[k] or v
end
end
-- - Initialize the addon after creation.
-- This function is only used internally during the ADDON_LOADED event
-- It will call the **OnInitialize** function on the addon object (if present),
-- and the **OnEmbedInitialize** function on all embeded libraries.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- @param addon addon object to intialize
function AceAddon:InitializeAddon(addon)
safecall(addon.OnInitialize, addon)
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
end
-- we don't call InitializeAddon on modules specifically, this is handled
-- from the event handler and only done _once_
end
-- - Enable the addon after creation.
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
-- It will call the **OnEnable** function on the addon object (if present),
-- and the **OnEmbedEnable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Enable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:EnableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if self.statuses[addon.name] or not addon.enabledState then return false end
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
self.statuses[addon.name] = true
safecall(addon.OnEnable, addon)
-- make sure we're still enabled before continueing
if self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
end
-- enable possible modules.
for name, module in pairs(addon.modules) do
self:EnableAddon(module)
end
end
return self.statuses[addon.name] -- return true if we're disabled
end
-- - Disable the addon
-- Note: This function is only used internally.
-- It will call the **OnDisable** function on the addon object (if present),
-- and the **OnEmbedDisable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Disable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:DisableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if not self.statuses[addon.name] then return false end
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
self.statuses[addon.name] = false
safecall( addon.OnDisable, addon )
-- make sure we're still disabling...
if not self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
end
-- disable possible modules.
for name, module in pairs(addon.modules) do
self:DisableAddon(module)
end
end
return not self.statuses[addon.name] -- return true if we're disabled
end
--- Get an iterator over all registered addons.
-- @usage
-- -- Print a list of all installed AceAddon's
-- for name, addon in AceAddon:IterateAddons() do
-- print("Addon: " .. name)
-- end
function AceAddon:IterateAddons() return pairs(self.addons) end
--- Get an iterator over the internal status registry.
-- @usage
-- -- Print a list of all enabled addons
-- for name, status in AceAddon:IterateAddonStatus() do
-- if status then
-- print("EnabledAddon: " .. name)
-- end
-- end
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
-- Following Iterators are deprecated, and their addon specific versions should be used
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
-- Event Handling
local function onEvent(this, event, arg1)
if event == "ADDON_LOADED" or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1)
-- this might be an issue with recursion - TODO: validate
if event == "ADDON_LOADED" then addon.baseName = arg1 end
AceAddon:InitializeAddon(addon)
tinsert(AceAddon.enablequeue, addon)
end
if IsLoggedIn() then
while(#AceAddon.enablequeue > 0) do
local addon = tremove(AceAddon.enablequeue, 1)
AceAddon:EnableAddon(addon)
end
end
end
end
AceAddon.frame:RegisterEvent("ADDON_LOADED")
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
AceAddon.frame:SetScript("OnEvent", onEvent)
-- upgrade embeded
for name, addon in pairs(AceAddon.addons) do
Embed(addon)
end
PK d>8 ) Bagnon/libs/AceAddon-3.0/AceAddon-3.0.xml
PK d>+
- Bagnon/libs/AceConsole-3.0/AceConsole-3.0.lua--- **AceConsole-3.0** provides registration facilities for slash commands.
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
-- to your addons individual needs.
--
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceConsole.
-- @class file
-- @name AceConsole-3.0
-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $
local MAJOR,MINOR = "AceConsole-3.0", 7
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceConsole then return end -- No upgrade needed
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
-- Lua APIs
local tconcat, tostring, select = table.concat, tostring, select
local type, pairs, error = type, pairs, error
local format, strfind, strsub = string.format, string.find, string.sub
local max = math.max
-- WoW APIs
local _G = _G
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
local tmp={}
local function Print(self,frame,...)
local n=0
if self ~= AceConsole then
n=n+1
tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
end
for i=1, select("#", ...) do
n=n+1
tmp[n] = tostring(select(i, ...))
end
frame:AddMessage( tconcat(tmp," ",1,n) )
end
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] ...
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param ... List of any values to be printed
function AceConsole:Print(...)
local frame = ...
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
return Print(self, frame, select(2,...))
else
return Print(self, DEFAULT_CHAT_FRAME, ...)
end
end
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
-- @paramsig [chatframe ,] "format"[, ...]
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
-- @param format Format string - same syntax as standard Lua format()
-- @param ... Arguments to the format string
function AceConsole:Printf(...)
local frame = ...
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
return Print(self, frame, format(select(2,...)))
else
return Print(self, DEFAULT_CHAT_FRAME, format(...))
end
end
--- Register a simple chat command
-- @param command Chat command to be registered WITHOUT leading "/"
-- @param func Function to call when the slash command is being used (funcref or methodname)
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
function AceConsole:RegisterChatCommand( command, func, persist )
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
local name = "ACECONSOLE_"..command:upper()
if type( func ) == "string" then
SlashCmdList[name] = function(input, editBox)
self[func](self, input, editBox)
end
else
SlashCmdList[name] = func
end
_G["SLASH_"..name.."1"] = "/"..command:lower()
AceConsole.commands[command] = name
-- non-persisting commands are registered for enabling disabling
if not persist then
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
AceConsole.weakcommands[self][command] = func
end
return true
end
--- Unregister a chatcommand
-- @param command Chat command to be unregistered WITHOUT leading "/"
function AceConsole:UnregisterChatCommand( command )
local name = AceConsole.commands[command]
if name then
SlashCmdList[name] = nil
_G["SLASH_" .. name .. "1"] = nil
hash_SlashCmdList["/" .. command:upper()] = nil
AceConsole.commands[command] = nil
end
end
--- Get an iterator over all Chat Commands registered with AceConsole
-- @return Iterator (pairs) over all commands
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
local function nils(n, ...)
if n>1 then
return nil, nils(n-1, ...)
elseif n==1 then
return nil, ...
else
return ...
end
end
--- Retreive one or more space-separated arguments from a string.
-- Treats quoted strings and itemlinks as non-spaced.
-- @param string The raw argument string
-- @param numargs How many arguments to get (default 1)
-- @param startpos Where in the string to start scanning (default 1)
-- @return Returns arg1, arg2, ..., nextposition\\
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
function AceConsole:GetArgs(str, numargs, startpos)
numargs = numargs or 1
startpos = max(startpos or 1, 1)
local pos=startpos
-- find start of new arg
pos = strfind(str, "[^ ]", pos)
if not pos then -- whoops, end of string
return nils(numargs, 1e9)
end
if numargs<1 then
return pos
end
-- quoted or space separated? find out which pattern to use
local delim_or_pipe
local ch = strsub(str, pos, pos)
if ch=='"' then
pos = pos + 1
delim_or_pipe='([|"])'
elseif ch=="'" then
pos = pos + 1
delim_or_pipe="([|'])"
else
delim_or_pipe="([| ])"
end
startpos = pos
while true do
-- find delimiter or hyperlink
local ch,_
pos,_,ch = strfind(str, delim_or_pipe, pos)
if not pos then break end
if ch=="|" then
-- some kind of escape
if strsub(str,pos,pos+1)=="|H" then
-- It's a |H....|hhyper link!|h
pos=strfind(str, "|h", pos+2) -- first |h
if not pos then break end
pos=strfind(str, "|h", pos+2) -- second |h
if not pos then break end
elseif strsub(str,pos, pos+1) == "|T" then
-- It's a |T....|t texture
pos=strfind(str, "|t", pos+2)
if not pos then break end
end
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
else
-- found delimiter, done with this arg
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
end
end
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
return strsub(str, startpos), nils(numargs-1, 1e9)
end
--- embedding and embed handling
local mixins = {
"Print",
"Printf",
"RegisterChatCommand",
"UnregisterChatCommand",
"GetArgs",
}
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceBucket in
function AceConsole:Embed( target )
for k, v in pairs( mixins ) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
function AceConsole:OnEmbedEnable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
end
end
end
function AceConsole:OnEmbedDisable( target )
if AceConsole.weakcommands[target] then
for command, func in pairs( AceConsole.weakcommands[target] ) do
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
end
end
end
for addon in pairs(AceConsole.embeds) do
AceConsole:Embed(addon)
end
PK d>pVV - Bagnon/libs/AceConsole-3.0/AceConsole-3.0.xml
PK d>]Z Z ) Bagnon/libs/AceEvent-3.0/AceEvent-3.0.lua--- AceEvent-3.0 provides event registration and secure dispatching.
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
-- CallbackHandler, and dispatches all game events or addon message to the registrees.
--
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceEvent.
-- @class file
-- @name AceEvent-3.0
-- @release $Id: AceEvent-3.0.lua 877 2009-11-02 15:56:50Z nevcairiel $
local MAJOR, MINOR = "AceEvent-3.0", 3
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
if not AceEvent then return end
-- Lua APIs
local pairs = pairs
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
-- APIs and registry for blizzard events, using CallbackHandler lib
if not AceEvent.events then
AceEvent.events = CallbackHandler:New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
end
function AceEvent.events:OnUsed(target, eventname)
AceEvent.frame:RegisterEvent(eventname)
end
function AceEvent.events:OnUnused(target, eventname)
AceEvent.frame:UnregisterEvent(eventname)
end
-- APIs and registry for IPC messages, using CallbackHandler lib
if not AceEvent.messages then
AceEvent.messages = CallbackHandler:New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
)
AceEvent.SendMessage = AceEvent.messages.Fire
end
--- embedding and embed handling
local mixins = {
"RegisterEvent", "UnregisterEvent",
"RegisterMessage", "UnregisterMessage",
"SendMessage",
"UnregisterAllEvents", "UnregisterAllMessages",
}
--- Register for a Blizzard Event.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterEvent
-- @class function
-- @paramsig event[, callback [, arg]]
-- @param event The event to register for
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
--- Unregister an event.
-- @name AceEvent:UnregisterEvent
-- @class function
-- @paramsig event
-- @param event The event to unregister
--- Register for a custom AceEvent-internal message.
-- The callback will always be called with the event as the first argument, and if supplied, the `arg` as second argument.
-- Any arguments to the event will be passed on after that.
-- @name AceEvent:RegisterMessage
-- @class function
-- @paramsig message[, callback [, arg]]
-- @param message The message to register for
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
-- @param arg An optional argument to pass to the callback function
--- Unregister a message
-- @name AceEvent:UnregisterMessage
-- @class function
-- @paramsig message
-- @param message The message to unregister
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
-- @name AceEvent:SendMessage
-- @class function
-- @paramsig message, ...
-- @param message The message to send
-- @param ... Any arguments to the message
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceEvent in
function AceEvent:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
-- AceEvent:OnEmbedDisable( target )
-- target (object) - target object that is being disabled
--
-- Unregister all events messages etc when the target disables.
-- this method should be called by the target manually or by an addon framework
function AceEvent:OnEmbedDisable(target)
target:UnregisterAllEvents()
target:UnregisterAllMessages()
end
-- Script to fire blizzard events into the event listeners
local events = AceEvent.events
AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
events:Fire(event, ...)
end)
--- Finally: upgrade our old embeds
for target, v in pairs(AceEvent.embeds) do
AceEvent:Embed(target)
end
PK d>ך ) Bagnon/libs/AceEvent-3.0/AceEvent-3.0.xml
PK d>ק} } + Bagnon/libs/AceLocale-3.0/AceLocale-3.0.lua--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file
-- @name AceLocale-3.0
-- @release $Id: AceLocale-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
local MAJOR,MINOR = "AceLocale-3.0", 2
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceLocale then return end -- no upgrade needed
-- Lua APIs
local assert, tostring, error = assert, tostring, error
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: GAME_LOCALE, geterrorhandler
local gameLocale = GetLocale()
if gameLocale == "enGB" then
gameLocale = "enUS"
end
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
-- This metatable is used on all tables returned from GetLocale
local readmeta = {
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
rawset(self, key, key) -- only need to see the warning once, really
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
return key
end
}
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
local readmetasilent = {
__index = function(self, key) -- requesting totally unknown entries: return key
rawset(self, key, key) -- only need to invoke this function once
return key
end
}
-- Remember the locale table being registered right now (it gets set by :NewLocale())
-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
local registering
-- local assert false function
local assertfalse = function() assert(false) end
-- This metatable proxy is used when registering nondefault locales
local writeproxy = setmetatable({}, {
__newindex = function(self, key, value)
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
end,
__index = assertfalse
})
-- This metatable proxy is used when registering the default locale.
-- It refuses to overwrite existing values
-- Reason 1: Allows loading locales in any order
-- Reason 2: If 2 modules have the same string, but only the first one to be
-- loaded has a translation for the current locale, the translation
-- doesn't get overwritten.
--
local writedefaultproxy = setmetatable({}, {
__newindex = function(self, key, value)
if not rawget(registering, key) then
rawset(registering, key, value == true and key or value)
end
end,
__index = assertfalse
})
--- Register a new locale (or extend an existing one) for the specified application.
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
-- game locale.
-- @paramsig application, locale[, isDefault[, silent]]
-- @param application Unique name of addon / module
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
-- @param silent If true, the locale will not issue warnings for missing keys. Can only be set on the default locale.
-- @usage
-- -- enUS.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
-- L["string1"] = true
--
-- -- deDE.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
-- if not L then return end
-- L["string1"] = "Zeichenkette1"
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
function AceLocale:NewLocale(application, locale, isDefault, silent)
if silent and not isDefault then
error("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' can only be specified for the default locale", 2)
end
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
-- Ammo: I still think this is a bad idea, for instance an addon that checks for some ingame string will fail, just because some other addon
-- gives the user the illusion that they can run in a different locale? Ditch this whole thing or allow a setting per 'application'. I'm of the
-- opinion to remove this.
local gameLocale = GAME_LOCALE or gameLocale
if locale ~= gameLocale and not isDefault then
return -- nop, we don't need these translations
end
local app = AceLocale.apps[application]
if not app then
app = setmetatable({}, silent and readmetasilent or readmeta)
AceLocale.apps[application] = app
AceLocale.appnames[app] = application
end
registering = app -- remember globally for writeproxy and writedefaultproxy
if isDefault then
return writedefaultproxy
end
return writeproxy
end
--- Returns localizations for the current locale (or default locale if translations are missing).
-- Errors if nothing is registered (spank developer, not just a missing translation)
-- @param application Unique name of addon / module
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
-- @return The locale table for the current language.
function AceLocale:GetLocale(application, silent)
if not silent and not AceLocale.apps[application] then
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
end
return AceLocale.apps[application]
end
PK d>{N + Bagnon/libs/AceLocale-3.0/AceLocale-3.0.xml
PK d>{# # 7 Bagnon/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua--[[ $Id: CallbackHandler-1.0.lua 895 2009-12-06 16:28:55Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 5
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
if not CallbackHandler then return end -- No upgrade needed
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
local method, ARGS
local function call() method(ARGS) end
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
return dispatch
]]
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
registry.recurse = oldrecurse
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
method = method or eventname
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
local regfunc
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId"
if type(self)~="table" and type(self)~="string" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string expected.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
return registry
end
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
PK d>=n 7 Bagnon/libs/CallbackHandler-1.0/CallbackHandler-1.0.xml
PK d>z_' _' 3 Bagnon/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua--[[
ItemSearch
An item text search engine of some sort
Grammar:
:=
:= & ;
:= | ;
:= ! ;
:= ; ; ;
:= bop ; boa ; bou ; boe ; quest
:= q ; q
:= ilvl
:= t:
:=
:= : | = | == | != | ~= | < | > | <= | >=
I kindof half want to make a full parser for this
--]]
local MAJOR, MINOR = "LibItemSearch-1.0", 2
local ItemSearch = LibStub:NewLibrary(MAJOR, MINOR)
if not ItemSearch then return end
--[[ general search ]]--
function ItemSearch:Find(itemLink, search)
if not search then
return true
end
if not itemLink then
return false
end
local search = search:lower()
if search:match('\124') then
return self:FindUnionSearch(itemLink, strsplit('\124', search))
end
return self:FindUnionSearch(itemLink, search)
end
--[[ union search: & ]]--
function ItemSearch:FindUnionSearch(itemLink, ...)
for i = 1, select('#', ...) do
local search = select(i, ...)
if search and search ~= '' then
if search:match('\038') then
if self:FindIntersectSearch(itemLink, strsplit('\038', search)) then
return true
end
else
if self:FindIntersectSearch(itemLink, search) then
return true
end
end
end
end
return false
end
--[[ intersect search: | ]]--
function ItemSearch:FindIntersectSearch(itemLink, ...)
for i = 1, select('#', ...) do
local search = select(i, ...)
if search and search ~= '' then
if not self:FindNegatableSearch(itemLink, search) then
return false
end
end
end
return true
end
--[[ negated search: ! ]]--
function ItemSearch:FindNegatableSearch(itemLink, search)
local negatedSearch = search:match('^\033(.+)$')
if negatedSearch then
return not self:FindTypedSearch(itemLink, negatedSearch)
end
return self:FindTypedSearch(itemLink, search)
end
--[[
typed search:
user defined search types
A typed search object should look like the following:
{
string id
unique identifier for the search type,
string searchCapture = function isSearch(self, search)
returns a capture if the given search matches this typed search
returns nil if the search is not a match for this type
bool isMatch = function findItem(self, itemLink, searchCapture)
returns true if is in the search defined by
}
--]]
local typedSearches = {}
function ItemSearch:RegisterTypedSearch(typedSearchObj)
typedSearches[typedSearchObj.id] = typedSearchObj
end
function ItemSearch:GetTypedSearches()
return pairs(typedSearches)
end
function ItemSearch:GetTypedSearch(id)
return typedSearches[id]
end
function ItemSearch:FindTypedSearch(itemLink, search)
if not search then
return false
end
for id, searchInfo in self:GetTypedSearches() do
local capture1, capture2, capture3 = searchInfo:isSearch(search)
if capture1 then
return searchInfo:findItem(itemLink, capture1, capture2, capture3)
end
end
return self:GetTypedSearch('itemTypeGeneric'):findItem(itemLink, search) or self:GetTypedSearch('itemName'):findItem(itemLink, search)
end
--[[
Basic typed searches
--]]
function ItemSearch:Compare(op, lhs, rhs)
--ugly, but it works
if op == ':' or op == '=' or op == '==' then
return lhs == rhs
end
if op == '!=' or op == '~=' then
return lhs ~= rhs
end
if op == '<=' then
return lhs <= rhs
end
if op == '<' then
return lhs < rhs
end
if op == '>' then
return lhs > rhs
end
if op == '>=' then
return lhs >= rhs
end
return false
end
--[[ basic text search n:(.+) ]]--
local function search_IsInText(search, ...)
for i = 1, select('#', ...) do
local text = select(i, ...)
text = text and tostring(text):lower()
if text and (text == search or text:match(search)) then
return true
end
end
return false
end
ItemSearch:RegisterTypedSearch{
id = 'itemName',
isSearch = function(self, search)
return search and search:match('^n:(.+)$')
end,
findItem = function(self, itemLink, search)
local itemName = (GetItemInfo(itemLink))
return search_IsInText(search, itemName)
end
}
--[[ item type,subtype,equip loc search t:(.+) ]]--
ItemSearch:RegisterTypedSearch{
id = 'itemTypeGeneric',
isSearch = function(self, search)
return search and search:match('^t:(.+)$')
end,
findItem = function(self, itemLink, search)
local name, link, quality, iLevel, reqLevel, type, subType, maxStack, equipSlot = GetItemInfo(itemLink)
if not name then
return false
end
return search_IsInText(search, type, subType, _G[equipSlot])
end
}
--[[ item quality search: q(sign)(%d+) | q:(qualityName) ]]--
ItemSearch:RegisterTypedSearch{
id = 'itemQuality',
isSearch = function(self, search)
if search then
return search:match('^q([%~%:%<%>%=%!]+)(%w+)$')
end
end,
descToQuality = function(self, desc)
local q = 0
local quality = _G['ITEM_QUALITY' .. q .. '_DESC']
while quality and quality:lower() ~= desc do
q = q + 1
quality = _G['ITEM_QUALITY' .. q .. '_DESC']
end
if quality then
return q
end
end,
findItem = function(self, itemLink, op, search)
local name, link, quality = GetItemInfo(itemLink)
if not name then
return false
end
local num = tonumber(search) or self:descToQuality(search)
return num and ItemSearch:Compare(op, quality, num) or false
end,
}
--[[ item level search: lvl(sign)(%d+) ]]--
ItemSearch:RegisterTypedSearch{
id = 'itemLevel',
isSearch = function(self, search)
if search then
return search:match('^ilvl([:<>=!]+)(%d+)$')
end
end,
findItem = function(self, itemLink, op, search)
local name, link, quality, iLvl = GetItemInfo(itemLink)
if not iLvl then
return false
end
local num = tonumber(search)
return num and ItemSearch:Compare(op, iLvl, num) or false
end,
}
--[[ tooltip keyword search ]]--
local tooltipCache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end})
local tooltipScanner = _G['LibItemSearchTooltipScanner'] or CreateFrame('GameTooltip', 'LibItemSearchTooltipScanner', UIParent, 'GameTooltipTemplate')
local function link_FindSearchInTooltip(itemLink, search)
--look in the cache for the result
local itemID = itemLink:match('item:(%d+)')
local cachedResult = tooltipCache[search][itemID]
if cachedResult ~= nil then
return cachedResult
end
--no match?, pull in the resut from tooltip parsing
tooltipScanner:SetOwner(UIParent, 'ANCHOR_NONE')
tooltipScanner:SetHyperlink(itemLink)
local result = false
if tooltipScanner:NumLines() > 1 and _G[tooltipScanner:GetName() .. 'TextLeft2']:GetText() == search then
result = true
elseif tooltipScanner:NumLines() > 2 and _G[tooltipScanner:GetName() .. 'TextLeft3']:GetText() == search then
result = true
end
tooltipScanner:Hide()
tooltipCache[search][itemID] = result
return result
end
ItemSearch:RegisterTypedSearch{
id = 'tooltip',
isSearch = function(self, search)
return self.keywords[search]
end,
findItem = function(self, itemLink, search)
return search and link_FindSearchInTooltip(itemLink, search)
end,
keywords = {
['boe'] = ITEM_BIND_ON_EQUIP,
['bop'] = ITEM_BIND_ON_PICKUP,
['bou'] = ITEM_BIND_ON_USE,
['quest'] = ITEM_BIND_QUEST,
['boa'] = ITEM_BIND_TO_ACCOUNT
}
}
--[[ equipment set search ]]--
local function IsWardrobeLoaded()
local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo('Wardrobe')
return enabled
end
local function findEquipmentSetByName(search)
local startsWithSearch = '^' .. search
local partialMatch = nil
for i = 1, GetNumEquipmentSets() do
local setName = (GetEquipmentSetInfo(i))
local lSetName = setName:lower()
if lSetName == search then
return setName
end
if lSetName:match(startsWithSearch) then
partialMatch = setName
end
end
-- Wardrobe Support
if Wardrobe then
for i, outfit in ipairs( Wardrobe.CurrentConfig.Outfit) do
local setName = outfit.OutfitName
local lSetName = setName:lower()
if lSetName == search then
return setName
end
if lSetName:match(startsWithSearch) then
partialMatch = setName
end
end
end
return partialMatch
end
local function isItemInEquipmentSet(itemLink, setName)
if not setName then
return false
end
local itemIDs = GetEquipmentSetItemIDs(setName)
if not itemIDs then
return false
end
local itemID = tonumber(itemLink:match('item:(%d+)'))
for inventoryID, setItemID in pairs(itemIDs) do
if itemID == setItemID then
return true
end
end
return false
end
local function isItemInWardrobeSet(itemLink, setName)
if not Wardrobe then return false end
local itemName = (GetItemInfo(itemLink))
for i, outfit in ipairs(Wardrobe.CurrentConfig.Outfit) do
if outfit.OutfitName == setName then
for j, item in pairs(outfit.Item) do
if item and (item.IsSlotUsed == 1) and (item.Name == itemName) then
return true
end
end
end
end
return false
end
ItemSearch:RegisterTypedSearch{
id = 'equipmentSet',
isSearch = function(self, search)
return search and search:match('^s:(.+)$')
end,
findItem = function(self, itemLink, search)
local setName = findEquipmentSetByName(search)
if not setName then
return false
end
return isItemInEquipmentSet(itemLink, setName)
or isItemInWardrobeSet(itemLink, setName)
end,
}PK 0>}M? / Bagnon/libs/LibItemSearch-1.0/LibItemSearch.toc## Interface: 40000
## Title: LibItemSearch
## Notes: An item search library
## Author: Tuller
## LoadOnDemand: 1
LibStub.lua
LibItemSearch-1.0.luaPK d>u u ) Bagnon/libs/LibItemSearch-1.0/LibStub.lua-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
PK d>nь $ Bagnon/libs/LibItemSearch-1.0/READMELibItemSearch
An item text search engine of some sort
Grammar:
:=
:= & ;
:= | ;
:= ! ;
:= ; ; ;
:= bop ; boa ; bou ; boe ; quest
:= q ; q
:= ilvl
:= t:
:=
:= : | = | == | != | ~= | < | > | <= | >=PK d>5v+GW W Bagnon/libs/LibStub/LibStub.lua-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
PK 0>~Q Bagnon/libs/LibStub/LibStub.toc## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
LibStub.lua
PK d>A A ! Bagnon/libs/Unfit-1.0/License.url[InternetShortcut]
URL=http://www.gnu.org/licenses/gpl-3.0.txt
PK d>a5 # Bagnon/libs/Unfit-1.0/Unfit-1.0.lua--[[
Copyright 2011 João Cardoso
Unfit is distributed under the terms of the GNU General Public License (or the Lesser GPL).
This file is part of Unfit.
Unfit is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Unfit is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Unfit. If not, see .
--]]
local Lib = LibStub:NewLibrary('Unfit-1.0', 3)
if not Lib then
return
else
Lib.unusable = Lib.unusable or {}
end
--[[ Data ]]--
local _, Class = UnitClass('player')
local Unusable = Lib.unusable
if Class == 'DEATHKNIGHT' then
Unusable = {{3, 4, 10, 11, 13, 14, 15, 16}, {6}}
elseif Class == 'DRUID' then
Unusable = {{1, 2, 3, 4, 8, 9, 14, 15, 16}, {4, 5, 6}, true}
elseif Class == 'HUNTER' then
Unusable = {{5, 6, 16}, {5, 6, 7}}
elseif Class == 'MAGE' then
Unusable = {{1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15}, {3, 4, 5, 6, 7}, true}
elseif Class == 'PALADIN' then
Unusable = {{3, 4, 10, 11, 13, 14, 15, 16}, {}, true}
elseif Class == 'PRIEST' then
Unusable = {{1, 2, 3, 4, 6, 7, 8, 9, 11, 14, 15}, {3, 4, 5, 6, 7}, true}
elseif Class == 'ROGUE' then
Unusable = {{2, 6, 7, 9, 10, 16}, {4, 5, 6, 7}}
elseif Class == 'SHAMAN' then
Unusable = {{3, 4, 7, 8, 9, 14, 15, 16}, {5}}
elseif Class == 'WARLOCK' then
Unusable = {{1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15}, {3, 4, 5, 6, 7}, true}
elseif Class == 'WARRIOR' then
Unusable = {{16}, {7}}
end
for class = 1, 2 do
local subs = {GetAuctionItemSubClasses(class)}
for i, subclass in ipairs(Unusable[class]) do
Unusable[subs[subclass]] = true
end
Unusable[class] = nil
subs = nil
end
--[[ API ]]--
function Lib:IsItemUnusable(...)
if ... then
local subclass, _, slot = select(7, GetItemInfo(...))
return Lib:IsClassUnusable(subclass, slot)
end
end
function Lib:IsClassUnusable(subclass, slot)
if subclass then
return Unusable[subclass] or slot == 'INVTYPE_WEAPONOFFHAND' and Unusable[3]
end
endPK 0>Q& # Bagnon/libs/Unfit-1.0/Unfit-1.0.toc## Interface: 40000
## Title: Unfit-1.0
## Notes: Determines which items are usable for the player's class
## Author: Jaliborc (João Cardoso)
## X-Category: Library
## X-Licence: GNU General Public License - Version 3
## OptionalDeps: LibStub
Unfit-1.0.luaPK d>0m # Bagnon/libs/Unfit-1.0/Unfit-1.0.xml
PK [> ' Bagnon/localization/localization.cn.lua--[[
THIS FILE IS ENCODED IN UTF-8
Bagnon Localization Information: Chinese Simplified
Credits: Diablohu, yleaf@cwdg(yaroot@gmail.com), 狂飙@cwdg(networm@qq.com)
Last Update: 2009/06/19 by 狂飙@cwdg(networm@qq.com)
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'zhCN')
if not L then return end
--keybinding text
L.ToggleBags = '开关 背包'
L.ToggleBank = '开关 银行'
--system messages
L.NewUser = '这是该角色第一次使用 Bagnon,已载入默认设置。'
L.Updated = '已更新到 Bagnon v%s'
L.UpdatedIncompatible = '由一个不相容版本升级,已载入默认设置。'
--slash commands
L.Commands = '命令:'
L.CmdShowInventory = '开关背包界面'
L.CmdShowBank = '开关银行界面'
L.CmdShowVersion = '显示当前版本'
--frame text
L.TitleBags = '%s的背包'
L.TitleBank = '%s的银行'
--tooltips
L.TipBags = '背包'
L.TipBank = '银行'
L.TipChangePlayer = '查看其他角色的物品'
L.TipGoldOnRealm = '%s上的总资产'
L.TipHideBag = '隐藏包裹'
L.TipHideBags = '隐藏背包'
L.TipHideSearch = '隐藏搜索界面'
L.TipPurchaseBag = '购买银行空位'
L.TipShowBag = '显示包裹'
L.TipShowBags = '显示背包'
L.TipShowMenu = '右击打开设置菜单'
L.TipShowSearch = '显示搜索界面'
L.TipShowSearch = '搜索'
L.TipShowFrameConfig = '打开设置菜单'
L.TipDoubleClickSearch = '双击打开搜索框'
L.TipBagToggle = '<左键点击> 切换是否显示背包'
L.TipInventoryToggle = '<右键点击> 显示整合背包'
L.Total = '总共'
--databroker plugin tooltips
L.TipShowBank = 'Shift-点击 开关银行'
L.TipShowInventory = '点击 开关背包'
L.TipShowOptions = '右击 打开设置菜单'PK [>h{} } ' Bagnon/localization/localization.de.lua--[[
Bagnon Localization Information: German
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'deDE')
if not L then return end
--keybinding text
L.ToggleBags = 'Inventar umschalten'
L.ToggleBank = 'Bank umschalten'
L.ToggleKeys = 'Schl\195\188sselbund umschalten'
--system messages
L.NewUser = 'Neuen Benutzer erkannt. Standardeinstellungen wurden geladen'
L.Updated = 'Aktualisiert auf v%s'
L.UpdatedIncompatible = 'Aktualisierung von einer inkompatiblen Version. Standardeinstellungen wurden geladen'
--slash commands
L.Commands = 'Befehle:'
L.CmdShowInventory = 'Schaltet die Inventaranzeige um'
L.CmdShowBank = 'Schaltet die Bankanzeige um'
L.CmdShowVersion = 'Zeigt die aktuelle Version an'
--frame text
L.TitleBags = '%s\'s Inventar'
L.TitleBank = '%s\'s Bank'
--tooltips
L.TipBank = 'Bank'
L.TipChangePlayer = ' um die Gegenst\195\164nde anderer Charaktere anzuzeigen.'
L.TipGoldOnRealm = 'Auf %s gesamt'
L.TipHideBag = ' um diese Tasche zu verstecken.'
L.TipHideBags = ' um die Taschenanzeige zu verstecken.'
L.TipHideSearch = ' um das Suchfenster zu verstecken.'
L.TipPurchaseBag = ' um das Bankfach zu kaufen.'
L.TipShowBag = ' um diese Tasche anzuzeigen.'
L.TipShowBags = ' um das Taschenfenster anzuzeigen.'
L.TipShowMenu = ' um das Fenster zu konfigurieren.'
L.TipShowSearch = ' um das Suchfenster anzuzeigen.'
L.TipShowSearch = ' zum Suchen.'
L.TipShowFrameConfig = ' um dieses Fenster zu konfigurieren.'
L.TipDoubleClickSearch = ' zum Verschieben.\n zum Konfigurieren.\n zum Suchen.'
L.Total = 'Gesamt'
--databroker plugin tooltips
L.TipShowBank = ' um die Bank umzuschalten'
L.TipShowInventory = ' um das Inventar umzuschalten'
L.TipShowOptions = ' um das Konfigurationsmen\195\188 anzuzeigen'PK d>:;c ' Bagnon/localization/localization.es.lua--[[
Bagnon Localization file: Spanish
Credit goes to Ferroginus
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'esES')
if not L then return endPK d>R6m ' Bagnon/localization/localization.fr.lua--[[
Bagnon Localization file: French Language
Credit goes to namAtsar
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'frFR')
if not L then return endPK N[>G $ Bagnon/localization/localization.lua--[[
Bagnon Localization Information: English Language
This file must be present to have partial translations
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'enUS', true)
--keybinding text
L.ToggleBags = 'Toggle Inventory'
L.ToggleBank = 'Toggle Bank'
--system messages
L.NewUser = 'New user detected, default settings loaded'
L.Updated = 'Updated to v%s'
L.UpdatedIncompatible = 'Updating from an incompatible version, defaults loaded'
--slash commands
L.Commands = 'Commands:'
L.CmdShowInventory = 'Toggles your inventory'
L.CmdShowBank = 'Toggles your bank'
L.CmdShowVersion = 'Prints the current verison'
--frame text
L.TitleBags = '%s\'s Inventory'
L.TitleBank = '%s\'s Bank'
--tooltips
L.TipBags = 'Bags'
L.TipBank = 'Bank'
L.TipBankToggle = ' to toggle your bank.'
L.TipChangePlayer = 'Click to view another character\'s items.'
L.TipGoldOnRealm = '%s Totals'
L.TipHideBag = 'Click to hide this bag.'
L.TipHideBags = ' to hide the bags display.'
L.TipHideSearch = 'Click to hide the search box.'
L.TipInventoryToggle = ' to toggle your inventory.'
L.TipPurchaseBag = 'Click to purchase this bank slot.'
L.TipShowBag = 'Click to show this bag.'
L.TipShowBags = ' to show the bags display.'
L.TipShowMenu = ' to configure this window.'
L.TipShowSearch = 'Click to search.'
L.TipShowFrameConfig = 'Click to configure this window.'
L.TipDoubleClickSearch = ' to move.\n to configure.\n to search.'
L.Total = 'Total'
--databroker plugin tooltips
L.TipShowBank = ' to toggle your bank.'
L.TipShowInventory = ' to toggle your inventory.'
L.TipShowOptions = ' to open the options menu.'PK [>7
' Bagnon/localization/localization.ru.lua--[[
Bagnon Localization Information: Russian Localization by kutensky
Updated by StingerSoft
This file must be present to have partial translations
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'ruRU')
if not L then return end
--keybinding text
L.ToggleBags = 'Открыть/закрыть инвентарь'
L.ToggleBank = 'Открыть/закрыть банк'
L.ToggleKeys = 'Открыть/закрыть связку ключей'
--system messages
L.NewUser = 'Обнаружен новый пользователь, загружены стандартные настройки'
L.Updated = 'Обновлено до v%s'
L.UpdatedIncompatible = 'Обновление от несовместимой версии, загружены стандартные настройки'
--slash commands
L.Commands = 'Команды:'
L.CmdShowInventory = 'Открыть/закрыть инвентарь'
L.CmdShowBank = 'Открыть/закрыть банк'
L.CmdShowVersion = 'Сообщить текущую версию модификации'
--frame text
L.TitleBags = 'Инвентарь |3-1(%s)'
L.TitleBank = 'Банк |3-1(%s)'
--tooltips
L.TipBank = 'Банк'
L.TipChangePlayer = '<Клик> - просмотр предметов другого персонажа.'
L.TipGoldOnRealm = 'Всего денег на %s'
L.TipHideBag = '<Клик> - скрыть сумку.'
L.TipHideBags = '<Клик> - скрыть область сумок.'
L.TipHideSearch = '<Клик> скрыть область поиска.'
L.TipPurchaseBag = '<Клик> - купить ячейку в банке.'
L.TipShowBag = '<Клик> - показать сумку.'
L.TipShowBags = '<Клик> - показать область сумки.'
L.TipShowMenu = '<Правый-клик> - настройки.'
L.TipShowSearch = '<Клик> - показать область поиска.'
L.TipShowSearch = '<Клик> - поиск.'
L.TipShowFrameConfig = '<Правый-клик> - настройки.'
L.TipDoubleClickSearch = ' - переместить.\n<Правый-клик> - настройка.\n<Двойной-клик> - поиск.'
L.Total = 'Всего'
--databroker plugin tooltips
L.TipShowBank = ' - открыть/закрыть банк.'
L.TipShowInventory = '<Левый клик> - открыть/закрыть инвентарь.'
L.TipShowOptions = '<Правый-клик> - настройки.'PK [>FU U ' Bagnon/localization/localization.tw.lua--[[
THIS FILE IS ENCODED IN UTF-8
Bagnon Localization Information: Chinese Traditional
2007/11/17 by matini< yiting.jheng gmail com
2008/12/01 by yleaf@cwdg(yaroot@gmail.com)
2009/04/23 by youngway@水晶之刺
2009/06/19 by 狂飆@cwdg(networm@qq.com)
Last Update: 2009/06/19 by 狂飆@cwdg(networm@qq.com)
--]]
local L = LibStub('AceLocale-3.0'):NewLocale('Bagnon', 'zhTW')
if not L then return end
--keybinding text
L.ToggleBags = '開關 背包'
L.ToggleBank = '開關 銀行'
L.ToggleKeys = '開關 鑰匙鏈'
--system messages
L.NewUser = '這是該角色第一次使用 Bagnon,已載入默認設置。'
L.Updated = '已更新到 Bagnon v%s'
L.UpdatedIncompatible = '由一個不相容版本升級,已載入默認設置。'
--slash commands
L.Commands = '命令:'
L.CmdShowInventory = '開關背包介面'
L.CmdShowBank = '開關銀行介面'
L.CmdShowVersion = '顯示當前版本'
--frame text
L.TitleBags = '%s的背包'
L.TitleBank = '%s的銀行'
--tooltips
L.Bags = '容器'
L.TipBank = '銀行'
L.TipChangePlayer = '查看其他角色的物品'
L.TipGoldOnRealm = '%s上的總資產'
L.TipHideBag = '隱藏包裹'
L.TipHideBags = '隱藏背包'
L.TipHideSearch = '隱藏搜索介面'
L.TipPurchaseBag = '購買銀行空位'
L.TipShowBag = '顯示包裹'
L.TipShowBags = '顯示背包'
L.TipShowMenu = '右擊打開設置菜單'
L.TipShowSearch = '顯示搜索介面'
L.TipShowSearch = '搜索'
L.TipShowFrameConfig = '打開設置菜單'
L.TipDoubleClickSearch = '按兩下打開搜索框'
L.TipInventoryToggle = '<右鍵點選>打開或關閉背包視窗'
L.TipBankToggle = '<右鍵點選>打開或關閉銀行視窗'
L.Total = '總共'
--databroker plugin tooltips
L.TipShowBank = 'Shift-點擊 開關銀行'
L.TipShowInventory = '點擊 開關背包'
L.TipShowOptions = '右擊 打開設置菜單'PK d>f Bagnon/utility/bagSlotInfo.lua--[[
bagSlotInfo.lua
Generic methods for accessing bag slot information
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local BagSlotInfo = {}
Bagnon.BagSlotInfo = BagSlotInfo
--[[ Slot Info ]]--
--returns true if the given bagSlot is a purchasable bank slot
function BagSlotInfo:IsBankBag(bagSlot)
return bagSlot > NUM_BAG_SLOTS and bagSlot < (NUM_BAG_SLOTS + NUM_BANKBAGSLOTS + 1)
end
--returns true if the given bagSlot is the bank container slot
function BagSlotInfo:IsBank(bagSlot)
return bagSlot == BANK_CONTAINER
end
--returns true if the given bagSlot is the backpack
function BagSlotInfo:IsBackpack(bagSlot)
return bagSlot == BACKPACK_CONTAINER
end
--returns true if the given bagSlot is an optional inventory bag slot
function BagSlotInfo:IsBackpackBag(bagSlot)
return bagSlot > 0 and bagSlot < (NUM_BAG_SLOTS + 1)
end
--returns true if the given bagSlot for the given player is cached
function BagSlotInfo:IsCached(player, bagSlot)
if Bagnon.PlayerInfo:IsCached(player) then
return true
end
if self:IsBank(bagSlot) or self:IsBankBag(bagSlot) then
return not Bagnon.PlayerInfo:AtBank()
end
return false
end
--returns true if the given bagSlot is purchasable for the given player and false otherwise
function BagSlotInfo:IsPurchasable(player, bagSlot)
local purchasedSlots
if self:IsCached(player, bagSlot) then
if BagnonDB then
purchasedSlots = BagnonDB:GetNumBankSlots(player) or 0
else
purchasedSlots = 0
end
else
purchasedSlots = GetNumBankSlots()
end
return bagSlot > (purchasedSlots + NUM_BAG_SLOTS)
end
function BagSlotInfo:IsLocked(player, bagSlot)
if self:IsBackpack(bagSlot) or self:IsBank(bagSlot) or self:IsCached(player, bagSlot) then
return false
end
return IsInventoryItemLocked(self:ToInventorySlot(bagSlot))
end
--[[ Slot Item Info ]]--
--returns how many items can fit in the given bag
function BagSlotInfo:GetSize(player, bagSlot)
local size = 0
if self:IsCached(player, bagSlot) then
if BagnonDB then
size = (BagnonDB:GetBagData(bagSlot, player))
end
elseif self:IsBank(bagSlot) then
size = NUM_BANKGENERIC_SLOTS
else
size = GetContainerNumSlots(bagSlot)
end
return size or 0
end
--returns the itemLink, number of items in, and item icon texture of the given bagSlot
function BagSlotInfo:GetItemInfo(player, bagSlot)
local link, texture, count, size
if self:IsCached(player, bagSlot) then
if BagnonDB then
size, link, count, texture = BagnonDB:GetBagData(bagSlot, player)
end
else
local invSlot = self:ToInventorySlot(bagSlot)
link = GetInventoryItemLink('player', invSlot)
texture = GetInventoryItemTexture('player', invSlot)
count = GetInventoryItemCount('player', invSlot)
end
return link, count, texture
end
--[[ Slot Type Info ]]--
function BagSlotInfo:GetBagType(player, bagSlot)
if self:IsBank(bagSlot) or self:IsBackpack(bagSlot) then
return 0
end
local itemLink = (self:GetItemInfo(player, bagSlot))
if itemLink then
return GetItemFamily(itemLink)
end
return 0
end
-- Stolen from OneBag, since my bitflag knowledge could be better
-- BAGTYPE_PROFESSION = Leather + Inscription + Herb + Enchanting + Engineering + Gem + Mining + Trade
local BAGTYPE_PROFESSION = 0x0008 + 0x0010 + 0x0020 + 0x0040 + 0x0080 + 0x0200 + 0x0400 + 0x8000
function BagSlotInfo:IsTradeBag(player, bagSlot)
return bit.band(self:GetBagType(player, bagSlot), BAGTYPE_PROFESSION) > 0
end
--[[ Conversion Methods ]]--
--converts the given bag slot into an applicable inventory slot
function BagSlotInfo:ToInventorySlot(bagSlot)
if self:IsBackpackBag(bagSlot) then
return ContainerIDToInventoryID(bagSlot)
end
if self:IsBankBag(bagSlot) then
return BankButtonIDToInvSlotID(bagSlot, 1)
end
return nil
endPK d>os Bagnon/utility/callbacks.lua--[[
callBacks.lua
Initializes the Bagnon callback handler
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
Bagnon.Callbacks = Bagnon.Ears:New()PK d>Qn n Bagnon/utility/classy.lua--[[
Classy.lua
Utility methods for constructing a Bagnon object class
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local Classy = {}
Bagnon.Classy = Classy
function Classy:New(frameType, parentClass)
local class = CreateFrame(frameType)
class.mt = {__index = class}
if parentClass then
class = setmetatable(class, {__index = parentClass})
class.super = parentClass
end
class.Bind = function(self, obj)
return setmetatable(obj, self.mt)
end
--callback support
class.RegisterMessage = function(self, ...)
Bagnon.Callbacks:Listen(self, ...)
end
class.SendMessage = function(self, ...)
Bagnon.Callbacks:SendMessage(...)
end
class.UnregisterMessage = function(self, ...)
Bagnon.Callbacks:Ignore(self, ...)
end
class.UnregisterAllMessages = function(self, ...)
Bagnon.Callbacks:IgnoreAll(self, ...)
end
return class
endPK d>B2; ; Bagnon/utility/ears.lua--[[
Ears.lua
A simple message passing object.
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local Ears = {}
Bagnon.Ears = Ears
--ye old constructor
local ears_MT = {__index = Ears}
function Ears:New()
local o = setmetatable({}, ears_MT)
o.listeners = {}
return o
end
--trigger a message, with the given args
function Ears:SendMessage(msg, ...)
assert(msg, 'Usage: Ears:SendMessage(msg[, args])')
assert(type(msg) == 'string', 'String expected for , got: \'' .. type(msg) .. '\'')
local listeners = self.listeners[msg]
if listeners then
for obj, action in pairs(listeners) do
action(obj, msg, ...)
end
end
end
--tells obj to do something when msg happens
function Ears:Listen(obj, msg, method)
assert(obj and msg, 'Usage: Ears:Listen(obj, msg[, method])')
assert(type(msg) == 'string', 'String expected for , got: \'' .. type(msg) .. '\'')
local method = method or msg
local action
if type(method) == 'string' then
assert(obj[method] and type(obj[method]) == 'function', 'Object does not have an instance of ' .. method)
action = obj[method]
else
assert(type(method) == 'function', 'String or function expected for , got: \'' .. type(method) .. '\'')
action = method
end
local listeners = self.listeners[msg] or {}
listeners[obj] = action
self.listeners[msg] = listeners
-- assert(self.listeners[msg] and self.listeners[msg][obj], 'Ears: Failed to register ' .. msg)
end
--tells obj to do nothing when msg happens
function Ears:Ignore(obj, msg)
assert(obj and msg, 'Usage: Ears:Ignore(obj, msg)')
assert(type(msg) == 'string', 'String expected for , got: \'' .. type(msg) .. '\'')
local listeners = self.listeners[msg]
if listeners then
listeners[obj] = nil
if not next(listeners) then
self.listeners[msg] = nil
end
end
-- assert(not(self.listeners[msg] and self.listeners[msg][obj]), 'Ears: Failed to ignore ' .. msg)
end
--ignore all messages for obj
function Ears:IgnoreAll(obj)
assert(obj, 'Usage: Ears:IgnoreAll(obj)')
for msg in pairs(self.listeners) do
self:Ignore(obj, msg)
end
endPK d>Y1gW W Bagnon/utility/itemEvents.lua--[[
BagEvents
A library of functions for accessing and updating bag slot information
Based on SpecialEvents-Bags by Tekkub Stoutwrithe (tekkub@gmail.com)
ITEM_SLOT_ADD
args: bag, slot, link, count, locked, coolingDown
called when a new slot becomes available to the player
ITEM_SLOT_REMOVE
args: bag, slot
called when an item slot is removed from being in use
ITEM_SLOT_UPDATE
args: bag, slot, link, count, locked, coolingDown
called when an item slot's item or item count changes
ITEM_SLOT_UPDATE_COOLDOWN
args: bag, slot, coolingDown
called when an item's cooldown starts/ends
BANK_OPENED
args: none
called when the bank has opened and all of the bagnon events have SendMessaged
BANK_CLOSED
args: none
called when the bank is closed and all of the bagnon events have SendMessaged
BAG_UPDATE_TYPE
args: bag, type
called when the type of a bag changes (aka, what items you can put in it changes)
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local BagEvents = Bagnon.Ears:New()
Bagnon.BagEvents = BagEvents
--[[ privates? ]]--
local slots = {}
local bagTypes = {}
local function ToIndex(bag, slot)
return (bag < 0 and bag*100 - slot) or bag*100 + slot
end
local function GetBagSize(bag)
return (bag == KEYRING_CONTAINER and GetKeyRingSize()) or GetContainerNumSlots(bag)
end
--[[ Startup ]]--
function BagEvents:Load()
self.atBank = false
self.firstVisit = true
self.frame = CreateFrame('Frame')
self.RegisterEvent = function(self, event)
self.frame:RegisterEvent(event)
end
self.OnEvent = function(f, event, ...)
if self[event] then
self[event](self, event, ...)
end
end
self.frame:SetScript('OnEvent', self.OnEvent)
self:RegisterEvent('PLAYER_LOGIN')
end
--[[ Update Functions ]]--
--all info
function BagEvents:AddItem(bag, slot)
local index = ToIndex(bag,slot)
if not slots[index] then slots[index] = {} end
local data = slots[index]
local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(bag, slot)
local start, duration, enable = GetContainerItemCooldown(bag, slot)
local onCooldown = (start > 0 and duration > 0 and enable > 0)
data[1] = link
data[2] = count
data[3] = locked
data[4] = onCooldown
self:SendMessage('ITEM_SLOT_ADD', bag, slot, link, count, locked, onCooldown)
end
function BagEvents:RemoveItem(bag, slot)
local data = slots[ToIndex(bag, slot)]
if data and next(data) then
local prevLink = data[1]
for i in pairs(data) do
data[i] = nil
end
self:SendMessage('ITEM_SLOT_REMOVE', bag, slot, prevLink)
end
end
function BagEvents:UpdateItem(bag, slot)
local data = slots[ToIndex(bag, slot)]
if data then
local prevLink = data[1]
local prevCount = data[2]
local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(bag, slot)
local start, duration, enable = GetContainerItemCooldown(bag, slot)
local onCooldown = (start > 0 and duration > 0 and enable > 0)
if not(prevLink == link and prevCount == count) then
data[1] = link
data[2] = count
data[3] = locked
data[4] = onCooldown
self:SendMessage('ITEM_SLOT_UPDATE', bag, slot, link, count, locked, onCooldown)
end
end
end
function BagEvents:UpdateItems(bag)
for slot = 1, GetBagSize(bag) do
self:UpdateItem(bag, slot)
end
end
--cooldowns
function BagEvents:UpdateCooldown(bag, slot)
local data = slots[ToIndex(bag,slot)]
if data and data[1] then
local start, duration, enable = GetContainerItemCooldown(bag, slot)
local onCooldown = (start > 0 and duration > 0 and enable > 0)
if data[4] ~= onCooldown then
data[4] = onCooldown
self:SendMessage('ITEM_SLOT_UPDATE_COOLDOWN', bag, slot, onCooldown)
end
end
end
function BagEvents:UpdateCooldowns(bag)
for slot = 1, GetBagSize(bag) do
self:UpdateCooldown(bag, slot)
end
end
--bag sizes
function BagEvents:UpdateBagSize(bag)
local prevSize = slots[bag*100] or 0
local newSize = GetBagSize(bag) or 0
slots[bag*100] = newSize
if prevSize > newSize then
for slot = newSize+1, prevSize do
self:RemoveItem(bag, slot)
end
elseif prevSize < newSize then
for slot = prevSize+1, newSize do
self:AddItem(bag, slot)
end
end
end
function BagEvents:UpdateBagType(bag)
local _, newType = GetContainerNumFreeSlots(bag)
local prevType = bagTypes[bag]
if newType ~= prevType then
bagTypes[bag] = newType
self:SendMessage('BAG_UPDATE_TYPE', bag, newType)
end
end
function BagEvents:UpdateBagSizes()
if self:AtBank() then
for bag = 1, NUM_BAG_SLOTS + GetNumBankSlots() do
self:UpdateBagSize(bag)
end
else
for bag = 1, NUM_BAG_SLOTS do
self:UpdateBagSize(bag)
end
end
self:UpdateBagSize(KEYRING_CONTAINER)
end
function BagEvents:UpdateBagTypes()
if self:AtBank() then
for bag = 1, NUM_BAG_SLOTS + GetNumBankSlots() do
self:UpdateBagType(bag)
end
else
for bag = 1, NUM_BAG_SLOTS do
self:UpdateBagType(bag)
end
end
end
--[[ Events ]]--
function BagEvents:PLAYER_LOGIN(...)
self:RegisterEvent('BAG_UPDATE')
self:RegisterEvent('BAG_UPDATE_COOLDOWN')
self:RegisterEvent('PLAYERBANKSLOTS_CHANGED')
self:RegisterEvent('BANKFRAME_OPENED')
self:RegisterEvent('BANKFRAME_CLOSED')
self:UpdateBagSize(KEYRING_CONTAINER)
self:UpdateItems(KEYRING_CONTAINER)
self:UpdateBagSize(BACKPACK_CONTAINER)
self:UpdateItems(BACKPACK_CONTAINER)
end
function BagEvents:BAG_UPDATE(event, bag)
self:UpdateBagTypes()
self:UpdateBagSizes()
self:UpdateItems(bag)
end
function BagEvents:PLAYERBANKSLOTS_CHANGED(...)
self:UpdateBagTypes()
self:UpdateBagSizes()
self:UpdateItems(BANK_CONTAINER)
end
function BagEvents:BANKFRAME_OPENED(...)
self.atBank = true
if self.firstVisit then
self.firstVisit = nil
self:UpdateBagSize(BANK_CONTAINER)
self:UpdateBagTypes()
self:UpdateBagSizes()
end
self:SendMessage('BANK_OPENED')
end
function BagEvents:BANKFRAME_CLOSED(...)
self.atBank = false
self:SendMessage('BANK_CLOSED')
end
function BagEvents:BAG_UPDATE_COOLDOWN(...)
self:UpdateCooldowns(BACKPACK_CONTAINER)
for bag = 1, NUM_BAG_SLOTS do
self:UpdateCooldowns(bag)
end
end
--[[ Accessor Methods ]]--
function BagEvents:AtBank()
return self.atBank
end
--load the thing
BagEvents:Load()PK d>%uL L Bagnon/utility/itemSlotInfo.lua--[[
itemSlotInfo.lua
Generic methods for accessing item slot information
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local ItemSlotInfo = {}
Bagnon.ItemSlotInfo = ItemSlotInfo
function ItemSlotInfo:GetItemInfo(player, bag, slot)
local link, count, texture, quality, readable, locked, lootable
if self:IsCached(player, bag, slot) then
if BagnonDB then
link, count, texture, quality = BagnonDB:GetItemData(bag, slot, player)
end
else
texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(bag, slot)
--GetContainerItemInfo does not return a quality value for all items. If it does not, it returns -1
if link and quality < 0 then
quality = (select(3, GetItemInfo(link)))
end
end
return texture, count, locked, quality, readable, lootable, link
end
function ItemSlotInfo:IsLocked(player, bag, slot)
if self:IsCached(player, bag, slot) then
return false
end
return (select(3, GetContainerItemInfo(bag, slot)))
end
function ItemSlotInfo:IsCached(player, bag, slot)
return Bagnon.BagSlotInfo:IsCached(player, bag)
endPK d>ӌS S Bagnon/utility/playerInfo.lua--[[
player.lua
Generic methods for accessing player information
--]]
--[[ Player Info ]]--
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local PlayerInfo = {}
Bagnon.PlayerInfo = PlayerInfo
local CURRENT_PLAYER = UnitName('player')
function PlayerInfo:IsCached(player)
return player ~= CURRENT_PLAYER
end
function PlayerInfo:GetMoney(player)
local money = 0
if self:IsCached(player) then
if BagnonDB then
money = BagnonDB:GetMoney(player)
end
else
money = GetMoney()
end
return money
end
function PlayerInfo:AtBank()
return Bagnon.BagEvents:AtBank()
endPK 0>@h Bagnon_Config/Bagnon_Config.toc## Interface: 40200
## Title: Bagnon Config
## Notes: Load on demand configuration for Bagnon
## Author: Tuller & Jaliborc (João Libório)
## Dependencies: Bagnon
## LoadOnDemand: 1
localization.xml
widgets.xml
panels.xmlPK )>rE Bagnon_Config/localization.xml
PK )> Bagnon_Config/panels.xml
PK )>G Bagnon_Config/widgets.xml
PK >