mirror of
https://github.com/parnic/breakables.git
synced 2025-06-16 17:40:13 -05:00
- initial import
This commit is contained in:
207
Breakables.lua
Normal file
207
Breakables.lua
Normal file
@ -0,0 +1,207 @@
|
||||
Breakables = LibStub("AceAddon-3.0"):NewAddon("Breakables", "AceConsole-3.0", "AceEvent-3.0")
|
||||
|
||||
local MillingId = 51005
|
||||
local MillingItemSubType = "Herb"
|
||||
local CanMill = false
|
||||
|
||||
local ProspectingId = 31252
|
||||
local ProspectingItemSubType = "Metal & Stone"
|
||||
local CanProspect = false
|
||||
|
||||
local DisenchantId = 1
|
||||
local CanDisenchant = false
|
||||
|
||||
function Breakables:OnInitialize()
|
||||
self.defaults = {
|
||||
buttonFrameLeft = 100,
|
||||
buttonFrameTop = -100,
|
||||
}
|
||||
self.db = LibStub("AceDB-3.0"):New("BreakablesDB", defaults)
|
||||
|
||||
self:RegisterChatCommand("breakables", "OnSlashCommand")
|
||||
self:RegisterChatCommand("brk", "OnSlashCommand")
|
||||
|
||||
-- would have used ITEM_PUSH here, but that seems to fire after looting and before the bag actually gets the item
|
||||
-- another alternative is to parse the chat msg, but that seems lame...however, that should only fire once as opposed to BAG_UPDATE's potential double-fire
|
||||
self:RegisterEvent("BAG_UPDATE", "OnItemReceived")
|
||||
end
|
||||
|
||||
function Breakables:OnEnable()
|
||||
CanMill = IsUsableSpell(GetSpellInfo(MillingId))
|
||||
CanProspect = IsUsableSpell(GetSpellInfo(ProspectingId))
|
||||
CanDisenchant = IsUsableSpell(GetSpellInfo(DisenchantId))
|
||||
|
||||
if CanMill then
|
||||
self:CreateButtonFrame()
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnDisable()
|
||||
|
||||
end
|
||||
|
||||
function Breakables:OnSlashCommand(input)
|
||||
self:FindBreakables()
|
||||
end
|
||||
|
||||
function Breakables:OnItemReceived(bag)
|
||||
self:FindBreakables()
|
||||
end
|
||||
|
||||
function Breakables:CreateButtonFrame()
|
||||
if not self.buttonFrame then
|
||||
self.buttonFrame = CreateFrame("Button", "BreakablesButtonFrame1", UIParent, "SecureActionButtonTemplate")
|
||||
end
|
||||
self.buttonFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", self.db.profile.buttonFrameLeft, self.db.profile.buttonFrameTop)
|
||||
|
||||
if not self.buttonFrame.icon then
|
||||
self.buttonFrame.icon = self.buttonFrame:CreateTexture(nil, "BACKGROUND")
|
||||
end
|
||||
if CanMill or CanProspect or CanDisenchant then
|
||||
self.buttonFrame:SetWidth(40)
|
||||
self.buttonFrame:SetHeight(40)
|
||||
|
||||
self.buttonFrame:EnableMouse(true)
|
||||
self.buttonFrame:RegisterForClicks("LeftButtonUp")
|
||||
|
||||
self.buttonFrame:SetMovable(true)
|
||||
self.buttonFrame:RegisterForDrag("LeftButton")
|
||||
self.buttonFrame:SetScript("OnMouseDown", function() self:OnMouseDown() end)
|
||||
self.buttonFrame:SetScript("OnMouseUp", function() self:OnMouseUp() end)
|
||||
self.buttonFrame:SetClampedToScreen(true)
|
||||
|
||||
self.buttonFrame:SetAttribute("type1", "spell")
|
||||
self.buttonFrame:SetAttribute("spell1", GetSpellInfo(MillingId))
|
||||
|
||||
local _,_,texture = GetSpellInfo((CanMill and MillingId) or (CanProspect and ProspectingId) or DisenchantingId)
|
||||
self.buttonFrame.icon:SetTexture(texture)
|
||||
self.buttonFrame.icon:SetAllPoints(self.buttonFrame)
|
||||
else
|
||||
self.buttonFrame:SetTexture(nil)
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnMouseDown()
|
||||
if IsShiftKeyDown() then
|
||||
self.buttonFrame:StartMoving()
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:OnMouseUp()
|
||||
self.buttonFrame:StopMovingOrSizing()
|
||||
|
||||
local _, _, _, xOff, yOff = self.buttonFrame:GetPoint(1)
|
||||
self.db.profile.buttonFrameLeft = xOff
|
||||
self.db.profile.buttonFrameTop = yOff
|
||||
end
|
||||
|
||||
function Breakables:FindBreakables()
|
||||
local foundBreakables = {}
|
||||
local i=1
|
||||
local numBreakableStacks = 0
|
||||
|
||||
for bagId=1,NUM_BAG_SLOTS do
|
||||
local found = self:FindBreakablesInBag(bagId)
|
||||
for n=1,#found do
|
||||
local addedToExisting = self:MergeBreakables(found[n], foundBreakables)
|
||||
|
||||
if not addedToExisting then
|
||||
foundBreakables[i] = found[n]
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,#foundBreakables do
|
||||
if foundBreakables[i][2] >= 5 then
|
||||
if not self.herbs then
|
||||
self.herbs = {}
|
||||
end
|
||||
|
||||
numBreakableStacks = numBreakableStacks + 1
|
||||
|
||||
if not self.herbs[numBreakableStacks] then
|
||||
self.herbs[numBreakableStacks] = CreateFrame("Button", "BreakablesButtonStackFrame"..numBreakableStacks, self.buttonFrame, "SecureActionButtonTemplate")
|
||||
end
|
||||
self.herbs[numBreakableStacks]:SetPoint("LEFT", numBreakableStacks == 1 and self.buttonFrame or self.herbs[numBreakableStacks - 1], "RIGHT")
|
||||
self.herbs[numBreakableStacks]:SetWidth(40)
|
||||
self.herbs[numBreakableStacks]:SetHeight(40)
|
||||
self.herbs[numBreakableStacks]:EnableMouse(true)
|
||||
self.herbs[numBreakableStacks]:RegisterForClicks("AnyUp")
|
||||
self.herbs[numBreakableStacks]:SetAttribute("type1", "item")
|
||||
self.herbs[numBreakableStacks]:SetAttribute("bag1", foundBreakables[i][5])
|
||||
self.herbs[numBreakableStacks]:SetAttribute("slot1", foundBreakables[i][6])
|
||||
|
||||
if not self.herbs[numBreakableStacks].icon then
|
||||
self.herbs[numBreakableStacks].icon = self.herbs[numBreakableStacks]:CreateTexture(nil, "BACKGROUND")
|
||||
end
|
||||
self.herbs[numBreakableStacks].icon:SetTexture(foundBreakables[i][4])
|
||||
self.herbs[numBreakableStacks].icon:SetAllPoints(self.herbs[numBreakableStacks])
|
||||
end
|
||||
end
|
||||
|
||||
if self.herbs and numBreakableStacks < #self.herbs then
|
||||
for i=numBreakableStacks+1,#self.herbs do
|
||||
self.herbs[i].icon:SetTexture(nil)
|
||||
self.herbs[i]:EnableMouse(false)
|
||||
end
|
||||
end
|
||||
|
||||
if numBreakableStacks == 0 then
|
||||
self.buttonFrame:Hide()
|
||||
else
|
||||
self.buttonFrame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function Breakables:FindBreakablesInBag(bagId)
|
||||
local foundBreakables = {}
|
||||
local i=1
|
||||
|
||||
if GetBagName(bagId) then
|
||||
for slotId=1,GetContainerNumSlots(bagId) do
|
||||
local found = self:FindBreakablesInSlot(bagId, slotId)
|
||||
if found then
|
||||
local addedToExisting = self:MergeBreakables(found, foundBreakables)
|
||||
|
||||
if not addedToExisting then
|
||||
foundBreakables[i] = found
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return foundBreakables
|
||||
end
|
||||
|
||||
function Breakables:FindBreakablesInSlot(bagId, slotId)
|
||||
local texture, itemCount, locked, quality, readable = GetContainerItemInfo(bagId, slotId)
|
||||
if texture then
|
||||
local itemLink = GetContainerItemLink(bagId, slotId)
|
||||
|
||||
|
||||
local _, _, _, _, _, itemType, itemSubType, _, _, itemTexture = GetItemInfo(itemLink)
|
||||
|
||||
if (CanMill and itemSubType == MillingItemSubType)
|
||||
or (CanProspect and itemSubType == ProspectingItemSubType) then
|
||||
return {itemLink, itemCount, itemSubType, itemTexture, bagId, slotId}
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function Breakables:MergeBreakables(foundBreakable, breakableList)
|
||||
for n=1,#breakableList do
|
||||
local existingLink, existingCount, existingType = breakableList[n]
|
||||
local itemLink, itemCount, itemType = foundBreakable
|
||||
|
||||
if foundBreakable[1] == breakableList[n][1] then
|
||||
breakableList[n][2] = breakableList[n][2] + foundBreakable[2]
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
11
Breakables.toc
Normal file
11
Breakables.toc
Normal file
@ -0,0 +1,11 @@
|
||||
## Interface: 30000
|
||||
## Author: Parnic
|
||||
## Name: Breakables
|
||||
## Title: Breakables |cff7fff7f -Ace3-|r
|
||||
## Notes: Tracks herbs/ore/items that can be broken into component pieces
|
||||
## Version: @project-version@ (Revision: @project-revision@)
|
||||
## SavedVariables: BreakablesDB
|
||||
|
||||
embeds.xml
|
||||
|
||||
Breakables.lua
|
8
embeds.xml
Normal file
8
embeds.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
|
||||
<Script file="libs\LibStub\LibStub.lua"/>
|
||||
<Include file="libs\AceAddon-3.0\AceAddon-3.0.xml"/>
|
||||
<Include file="libs\AceConsole-3.0\AceConsole-3.0.xml"/>
|
||||
<Include file="libs\AceDB-3.0\AceDB-3.0.xml"/>
|
||||
<Include file="libs\AceEvent-3.0\AceEvent-3.0.xml"/>
|
||||
<Include file="libs\LibBabble-Inventory-3.0\lib.xml"/>
|
||||
</Ui>
|
448
libs/AceAddon-3.0/AceAddon-3.0.lua
Normal file
448
libs/AceAddon-3.0/AceAddon-3.0.lua
Normal file
@ -0,0 +1,448 @@
|
||||
--[[ $Id: AceAddon-3.0.lua 654 2008-05-21 13:43:29Z ammo $ ]]
|
||||
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
|
||||
|
||||
local tinsert, tconcat = table.insert, table.concat
|
||||
local fmt = string.format
|
||||
local pairs, next, type = pairs, next, type
|
||||
|
||||
--[[
|
||||
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
|
||||
|
||||
-- AceAddon:NewAddon( [object, ]name, [lib, lib, lib, ...] )
|
||||
-- [object] (table) - table to use as the base for the addon
|
||||
-- name (string) - unique addon object name
|
||||
-- [lib] (string) - optional libs to embed in the addon object
|
||||
--
|
||||
-- returns the addon object when succesful
|
||||
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
|
||||
|
||||
|
||||
-- AceAddon:GetAddon( name, [silent])
|
||||
-- name (string) - unique addon object name
|
||||
-- silent (boolean) - if true, addon is optional, silently return nil if its not found
|
||||
--
|
||||
-- throws an error if the addon object can not be found (except silent is set)
|
||||
-- returns the addon object if found
|
||||
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
|
||||
|
||||
-- AceAddon:EmbedLibraries( addon, [lib, lib, lib, ...] )
|
||||
-- addon (object) - addon to embed the libs in
|
||||
-- [lib] (string) - optional libs to embed
|
||||
function AceAddon:EmbedLibraries(addon, ...)
|
||||
for i=1,select("#", ... ) do
|
||||
local libname = select(i, ...)
|
||||
self:EmbedLibrary(addon, libname, false, 4)
|
||||
end
|
||||
end
|
||||
|
||||
-- AceAddon:EmbedLibrary( addon, libname, silent, offset )
|
||||
-- addon (object) - addon to embed the libs in
|
||||
-- libname (string) - lib to embed
|
||||
-- [silent] (boolean) - optional, marks an embed to fail silently if the library doesn't exist.
|
||||
-- [offset] (number) - will push the error messages back to said offset defaults to 2
|
||||
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
|
||||
|
||||
-- addon:GetModule( name, [silent])
|
||||
-- name (string) - unique module object name
|
||||
-- silent (boolean) - if true, module is optional, silently return nil if its not found
|
||||
--
|
||||
-- throws an error if the addon object can not be found (except silent is set)
|
||||
-- returns the module object if found
|
||||
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
|
||||
|
||||
-- addon:NewModule( name, [prototype, [lib, lib, lib, ...] )
|
||||
-- name (string) - unique module object name for this addon
|
||||
-- prototype (object) - object to derive this module from, methods and values from this table will be mixed into the module, if a string is passed a lib is assumed
|
||||
-- [lib] (string) - optional libs to embed in the addon object
|
||||
--
|
||||
-- returns the addon object when succesful
|
||||
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
|
||||
|
||||
--addon:GetName()
|
||||
-- Returns the real name of the addon or module, without any prefix
|
||||
function GetName(self)
|
||||
return self.moduleName or self.name
|
||||
end
|
||||
|
||||
--addon:Enable()
|
||||
-- Enables the Addon if possible, return true or false depending on success
|
||||
function Enable(self)
|
||||
self:SetEnabledState(true)
|
||||
return AceAddon:EnableAddon(self)
|
||||
end
|
||||
|
||||
--addon:Disable()
|
||||
-- Disables the Addon if possible, return true or false depending on success
|
||||
function Disable(self)
|
||||
self:SetEnabledState(false)
|
||||
return AceAddon:DisableAddon(self)
|
||||
end
|
||||
|
||||
-- addon:EnableModule( name )
|
||||
-- name (string) - unique module object name
|
||||
--
|
||||
-- Enables the Module if possible, return true or false depending on success
|
||||
function EnableModule(self, name)
|
||||
local module = self:GetModule( name )
|
||||
return module:Enable()
|
||||
end
|
||||
|
||||
-- addon:DisableModule( name )
|
||||
-- name (string) - unique module object name
|
||||
--
|
||||
-- Disables the Module if possible, return true or false depending on success
|
||||
function DisableModule(self, name)
|
||||
local module = self:GetModule( name )
|
||||
return module:Disable()
|
||||
end
|
||||
|
||||
-- addon:SetDefaultModuleLibraries( [lib, lib, lib, ...] )
|
||||
-- [lib] (string) - libs to embed in every module
|
||||
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
|
||||
|
||||
-- addon:SetDefaultModuleState( state )
|
||||
-- state (boolean) - default state for new modules (enabled=true, disabled=false)
|
||||
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
|
||||
|
||||
-- addon:SetDefaultModulePrototype( prototype )
|
||||
-- prototype (string or table) - the default prototype to use if none is specified on module creation
|
||||
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
|
||||
|
||||
-- addon:SetEnabledState ( state )
|
||||
-- state ( boolean ) - set the state of an addon or module (enabled=true, disabled=false)
|
||||
--
|
||||
-- should only be called before any Enabling actually happend, aka in OnInitialize
|
||||
function SetEnabledState(self, state)
|
||||
self.enabledState = state
|
||||
end
|
||||
|
||||
|
||||
local function IterateModules(self) return pairs(self.modules) end
|
||||
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) 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
|
||||
|
||||
|
||||
-- AceAddon:IntializeAddon( addon )
|
||||
-- addon (object) - addon to intialize
|
||||
--
|
||||
-- calls OnInitialize on the addon object if available
|
||||
-- calls OnEmbedInitialize on embedded libs in the addon object if available
|
||||
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
|
||||
|
||||
-- AceAddon:EnableAddon( addon )
|
||||
-- addon (object) - addon to enable
|
||||
--
|
||||
-- calls OnEnable on the addon object if available
|
||||
-- calls OnEmbedEnable on embedded libs in the addon object if available
|
||||
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
|
||||
|
||||
-- TODO: handle 'first'? Or let addons do it on their own?
|
||||
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
|
||||
|
||||
-- AceAddon:DisableAddon( addon )
|
||||
-- addon (object|string) - addon to disable
|
||||
--
|
||||
-- calls OnDisable on the addon object if available
|
||||
-- calls OnEmbedDisable on embedded libs in the addon object if available
|
||||
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
|
||||
|
||||
--The next few funcs are just because no one should be reaching into the internal registries
|
||||
--Thoughts?
|
||||
function AceAddon:IterateAddons() return pairs(self.addons) end
|
||||
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
|
||||
function AceAddon:IterateAddonStatus() return pairs(self.statuses) 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
|
4
libs/AceAddon-3.0/AceAddon-3.0.xml
Normal file
4
libs/AceAddon-3.0/AceAddon-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceAddon-3.0.lua"/>
|
||||
</Ui>
|
43
libs/AceConfig-3.0/AceConfig-3.0.lua
Normal file
43
libs/AceConfig-3.0/AceConfig-3.0.lua
Normal file
@ -0,0 +1,43 @@
|
||||
--[[ $Id: AceConfig-3.0.lua 494 2008-02-03 13:03:56Z nevcairiel $ ]]
|
||||
--[[
|
||||
AceConfig-3.0
|
||||
|
||||
Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
|
||||
|
||||
Also automatically adds "config", "enable" and "disable" commands to options table as appropriate.
|
||||
|
||||
]]
|
||||
|
||||
local MAJOR, MINOR = "AceConfig-3.0", 2
|
||||
local lib = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not lib then return end
|
||||
|
||||
|
||||
local cfgreg = LibStub("AceConfigRegistry-3.0")
|
||||
local cfgcmd = LibStub("AceConfigCmd-3.0")
|
||||
local cfgdlg = LibStub("AceConfigDialog-3.0")
|
||||
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0")
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- :RegisterOptionsTable(appName, options, slashcmd, persist)
|
||||
--
|
||||
-- - appName - (string) application name
|
||||
-- - options - table or function ref, see AceConfigRegistry
|
||||
-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
|
||||
|
||||
function lib:RegisterOptionsTable(appName, options, slashcmd)
|
||||
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
|
||||
if not ok then error(msg, 2) end
|
||||
|
||||
if slashcmd then
|
||||
if type(slashcmd) == "table" then
|
||||
for _,cmd in pairs(slashcmd) do
|
||||
cfgcmd:CreateChatCommand(cmd, appName)
|
||||
end
|
||||
else
|
||||
cfgcmd:CreateChatCommand(slashcmd, appName)
|
||||
end
|
||||
end
|
||||
end
|
8
libs/AceConfig-3.0/AceConfig-3.0.xml
Normal file
8
libs/AceConfig-3.0/AceConfig-3.0.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
|
||||
<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
|
||||
<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
|
||||
<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
|
||||
<Script file="AceConfig-3.0.lua"/>
|
||||
</Ui>
|
729
libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
Normal file
729
libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
Normal file
@ -0,0 +1,729 @@
|
||||
|
||||
--[[
|
||||
AceConfigCmd-3.0
|
||||
|
||||
Handles commandline optionstable access
|
||||
|
||||
REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
|
||||
|
||||
]]
|
||||
|
||||
-- TODO: handle disabled / hidden
|
||||
-- TODO: implement handlers for all types
|
||||
-- TODO: plugin args
|
||||
|
||||
|
||||
local MAJOR, MINOR = "AceConfigCmd-3.0", 6
|
||||
local lib = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not lib then return end
|
||||
|
||||
lib.commands = lib.commands or {}
|
||||
local commands = lib.commands
|
||||
|
||||
local cfgreg = LibStub("AceConfigRegistry-3.0")
|
||||
local AceConsole -- LoD
|
||||
local AceConsoleName = "AceConsole-3.0"
|
||||
|
||||
|
||||
local L = setmetatable({}, { -- TODO: replace with proper locale
|
||||
__index = function(self,k) return k end
|
||||
})
|
||||
|
||||
|
||||
|
||||
local function print(msg)
|
||||
(SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
|
||||
end
|
||||
|
||||
|
||||
-- pickfirstset() - picks the first non-nil value and returns it
|
||||
|
||||
local function pickfirstset(...)
|
||||
for i=1,select("#",...) do
|
||||
if select(i,...)~=nil then
|
||||
return select(i,...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- err() - produce real error() regarding malformed options tables etc
|
||||
|
||||
local function err(info,inputpos,msg )
|
||||
local cmdstr=" "..strsub(info.input, 1, inputpos-1)
|
||||
error(MAJOR..": /" ..info[0] ..cmdstr ..": "..(msg or "malformed options table"), 2)
|
||||
end
|
||||
|
||||
|
||||
-- usererr() - produce chatframe message regarding bad slash syntax etc
|
||||
|
||||
local function usererr(info,inputpos,msg )
|
||||
local cmdstr=strsub(info.input, 1, inputpos-1);
|
||||
print("/" ..info[0] .. " "..cmdstr ..": "..(msg or "malformed options table"))
|
||||
end
|
||||
|
||||
|
||||
-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
|
||||
|
||||
local function callmethod(info, inputpos, tab, methodtype, ...)
|
||||
local method = info[methodtype]
|
||||
if not method then
|
||||
err(info, inputpos, "'"..methodtype.."': not set")
|
||||
end
|
||||
|
||||
info.arg = tab.arg
|
||||
info.option = tab
|
||||
info.type = tab.type
|
||||
|
||||
if type(method)=="function" then
|
||||
return method(info, ...)
|
||||
elseif type(method)=="string" then
|
||||
if type(info.handler[method])~="function" then
|
||||
err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
|
||||
end
|
||||
return info.handler[method](info.handler, info, ...)
|
||||
else
|
||||
assert(false) -- type should have already been checked on read
|
||||
end
|
||||
end
|
||||
|
||||
-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
|
||||
|
||||
local function callfunction(info, tab, methodtype, ...)
|
||||
local method = tab[methodtype]
|
||||
|
||||
info.arg = tab.arg
|
||||
info.option = tab
|
||||
info.type = tab.type
|
||||
|
||||
if type(method)=="function" then
|
||||
return method(info, ...)
|
||||
else
|
||||
assert(false) -- type should have already been checked on read
|
||||
end
|
||||
end
|
||||
|
||||
-- do_final() - do the final step (set/execute) along with validation and confirmation
|
||||
|
||||
local function do_final(info, inputpos, tab, methodtype, ...)
|
||||
if info.validate then
|
||||
local res = callmethod(info,inputpos,tab,"validate",...)
|
||||
if type(res)=="string" then
|
||||
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
|
||||
return
|
||||
end
|
||||
end
|
||||
-- console ignores .confirm
|
||||
|
||||
callmethod(info,inputpos,tab,methodtype, ...)
|
||||
end
|
||||
|
||||
|
||||
-- getparam() - used by handle() to retreive and store "handler", "get", "set", etc
|
||||
|
||||
local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
|
||||
local old,oldat = info[paramname], info[paramname.."_at"]
|
||||
local val=tab[paramname]
|
||||
if val~=nil then
|
||||
if val==false then
|
||||
val=nil
|
||||
elseif not types[type(val)] then
|
||||
err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
|
||||
end
|
||||
info[paramname] = val
|
||||
info[paramname.."_at"] = depth
|
||||
end
|
||||
return old,oldat
|
||||
end
|
||||
|
||||
|
||||
-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
|
||||
local dummytable={}
|
||||
|
||||
local function iterateargs(tab)
|
||||
if not tab.plugins then
|
||||
return pairs(tab.args)
|
||||
end
|
||||
|
||||
local argtabkey,argtab=next(tab.plugins)
|
||||
local v
|
||||
|
||||
return function(_, k)
|
||||
while argtab do
|
||||
k,v = next(argtab, k)
|
||||
if k then return k,v end
|
||||
if argtab==tab.args then
|
||||
argtab=nil
|
||||
else
|
||||
argtabkey,argtab = next(tab.plugins, argtabkey)
|
||||
if not argtabkey then
|
||||
argtab=tab.args
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function showhelp(info, inputpos, tab, noHead)
|
||||
if not noHead then
|
||||
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
|
||||
end
|
||||
|
||||
local sortTbl = {} -- [1..n]=name
|
||||
local refTbl = {} -- [name]=tableref
|
||||
|
||||
for k,v in iterateargs(tab) do
|
||||
if not refTbl[k] then -- a plugin overriding something in .args
|
||||
table.insert(sortTbl, k)
|
||||
refTbl[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(sortTbl, function(one, two)
|
||||
local o1 = refTbl[one].order or 100
|
||||
local o2 = refTbl[two].order or 100
|
||||
if type(o1) == "function" or type(o1) == "string" then
|
||||
info.order = o1
|
||||
info[#info+1] = one
|
||||
o1 = callmethod(info, inputpos, refTbl[one], "order")
|
||||
info[#info] = nil
|
||||
info.order = nil
|
||||
end
|
||||
if type(o2) == "function" or type(o1) == "string" then
|
||||
info.order = o2
|
||||
info[#info+1] = two
|
||||
o2 = callmethod(info, inputpos, refTbl[two], "order")
|
||||
info[#info] = nil
|
||||
info.order = nil
|
||||
end
|
||||
if o1<0 and o2<0 then return o1<o2 end
|
||||
if o2<0 then return true end
|
||||
if o1<0 then return false end
|
||||
if o1==o2 then return tostring(one)<tostring(two) end -- compare names
|
||||
return o1<o2
|
||||
end)
|
||||
|
||||
for _,k in ipairs(sortTbl) do
|
||||
local v = refTbl[k]
|
||||
if not pickfirstset(v.cmdHidden, v.hidden, false) then
|
||||
-- recursively show all inline groups
|
||||
local name, desc = v.name, v.desc
|
||||
if type(name) == "function" then
|
||||
name = callfunction(info, v, 'name')
|
||||
end
|
||||
if type(desc) == "function" then
|
||||
desc = callfunction(info, v, 'desc')
|
||||
end
|
||||
if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
|
||||
print(" "..(desc or name)..":")
|
||||
showhelp(info, inputpos, v, true)
|
||||
else
|
||||
print(" |cffffff78"..k.."|r - "..(desc or name or ""))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function keybindingValidateFunc(text)
|
||||
if text == nil or text == "NONE" then
|
||||
return nil
|
||||
end
|
||||
text = text:upper()
|
||||
local shift, ctrl, alt
|
||||
local modifier
|
||||
while true do
|
||||
if text == "-" then
|
||||
break
|
||||
end
|
||||
modifier, text = strsplit('-', text, 2)
|
||||
if text then
|
||||
if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
|
||||
return false
|
||||
end
|
||||
if modifier == "SHIFT" then
|
||||
if shift then
|
||||
return false
|
||||
end
|
||||
shift = true
|
||||
end
|
||||
if modifier == "CTRL" then
|
||||
if ctrl then
|
||||
return false
|
||||
end
|
||||
ctrl = true
|
||||
end
|
||||
if modifier == "ALT" then
|
||||
if alt then
|
||||
return false
|
||||
end
|
||||
alt = true
|
||||
end
|
||||
else
|
||||
text = modifier
|
||||
break
|
||||
end
|
||||
end
|
||||
if text == "" then
|
||||
return false
|
||||
end
|
||||
if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
|
||||
return false
|
||||
end
|
||||
local s = text
|
||||
if shift then
|
||||
s = "SHIFT-" .. s
|
||||
end
|
||||
if ctrl then
|
||||
s = "CTRL-" .. s
|
||||
end
|
||||
if alt then
|
||||
s = "ALT-" .. s
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
-- constants used by getparam() calls below
|
||||
|
||||
local handlertypes = {["table"]=true}
|
||||
local handlermsg = "expected a table"
|
||||
|
||||
local functypes = {["function"]=true, ["string"]=true}
|
||||
local funcmsg = "expected function or member name"
|
||||
|
||||
-- handle() - selfrecursing function that processes input->optiontable
|
||||
-- - depth - starts at 0
|
||||
-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
|
||||
|
||||
local function handle(info, inputpos, tab, depth, retfalse)
|
||||
|
||||
if not(type(tab)=="table" and type(tab.type)=="string") then err(info,inputpos) end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Grab hold of handler,set,get,func,etc if set (and remember old ones)
|
||||
-- Note that we do NOT validate if method names are correct at this stage,
|
||||
-- the handler may change before they're actually used!
|
||||
|
||||
local oldhandler,oldhandler_at = getparam(info,inputpos,tab,depth,"handler",handlertypes,handlermsg)
|
||||
local oldset,oldset_at = getparam(info,inputpos,tab,depth,"set",functypes,funcmsg)
|
||||
local oldget,oldget_at = getparam(info,inputpos,tab,depth,"get",functypes,funcmsg)
|
||||
local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
|
||||
local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
|
||||
--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Act according to .type of this table
|
||||
|
||||
if tab.type=="group" then
|
||||
------------ group --------------------------------------------
|
||||
|
||||
if type(tab.args)~="table" then err(info, inputpos) end
|
||||
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
|
||||
|
||||
-- grab next arg from input
|
||||
local _,nextpos,arg = string.find(info.input, " *([^ ]+) *", inputpos)
|
||||
if not arg then
|
||||
showhelp(info, inputpos, tab)
|
||||
return
|
||||
end
|
||||
nextpos=nextpos+1
|
||||
|
||||
-- loop .args and try to find a key with a matching name
|
||||
for k,v in iterateargs(tab) do
|
||||
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
|
||||
|
||||
-- is this child an inline group? if so, traverse into it
|
||||
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
|
||||
info[depth+1] = k
|
||||
if handle(info, inputpos, v, depth+1, true)==false then
|
||||
info[depth+1] = nil
|
||||
-- wasn't found in there, but that's ok, we just keep looking down here
|
||||
else
|
||||
return -- done, name was found in inline group
|
||||
end
|
||||
-- matching name and not a inline group
|
||||
elseif strlower(arg)==strlower(k) then
|
||||
info[depth+1] = k
|
||||
return handle(info,nextpos,v,depth+1)
|
||||
end
|
||||
end
|
||||
|
||||
-- no match
|
||||
if retfalse then
|
||||
-- restore old infotable members and return false to indicate failure
|
||||
info.handler,info.handler_at = oldhandler,oldhandler_at
|
||||
info.set,info.set_at = oldset,oldset_at
|
||||
info.get,info.get_at = oldget,oldget_at
|
||||
info.func,info.func_at = oldfunc,oldfunc_at
|
||||
info.validate,info.validate_at = oldvalidate,oldvalidate_at
|
||||
--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
|
||||
return false
|
||||
end
|
||||
|
||||
-- couldn't find the command, display error
|
||||
usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
|
||||
return
|
||||
end
|
||||
|
||||
local str = strsub(info.input,inputpos);
|
||||
|
||||
if tab.type=="execute" then
|
||||
------------ execute --------------------------------------------
|
||||
do_final(info, inputpos, tab, "func")
|
||||
|
||||
|
||||
|
||||
elseif tab.type=="input" then
|
||||
------------ input --------------------------------------------
|
||||
|
||||
local res = true
|
||||
if tab.pattern then
|
||||
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
|
||||
if not strmatch(str, tab.pattern) then
|
||||
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", str)
|
||||
|
||||
|
||||
|
||||
elseif tab.type=="toggle" then
|
||||
------------ toggle --------------------------------------------
|
||||
local b
|
||||
local str = strtrim(strlower(str))
|
||||
if str=="" then
|
||||
b = callmethod(info, inputpos, tab, "get")
|
||||
|
||||
if tab.tristate then
|
||||
--cycle in true, nil, false order
|
||||
if b then
|
||||
b = nil
|
||||
elseif b == nil then
|
||||
b = false
|
||||
else
|
||||
b = true
|
||||
end
|
||||
else
|
||||
b = not b
|
||||
end
|
||||
|
||||
elseif str==L["on"] then
|
||||
b = true
|
||||
elseif str==L["off"] then
|
||||
b = false
|
||||
elseif tab.tristate and str==L["default"] then
|
||||
b = nil
|
||||
else
|
||||
if tab.tristate then
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'on', 'off' or 'default', or no argument to toggle."], str))
|
||||
else
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'on' or 'off', or no argument to toggle."], str))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", b)
|
||||
|
||||
|
||||
elseif tab.type=="range" then
|
||||
------------ range --------------------------------------------
|
||||
local val = tonumber(str)
|
||||
if not val then
|
||||
usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
|
||||
return
|
||||
end
|
||||
if type(info.step)=="number" then
|
||||
val = val- (val % info.step)
|
||||
end
|
||||
if type(info.min)=="number" and val<info.min then
|
||||
usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
|
||||
return
|
||||
end
|
||||
if type(info.max)=="number" and val>info.max then
|
||||
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", val)
|
||||
|
||||
|
||||
elseif tab.type=="select" then
|
||||
------------ select ------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
if str == "" then
|
||||
--TODO: Show current selection and possible values
|
||||
return
|
||||
end
|
||||
|
||||
local values = tab.values
|
||||
if type(values) == "function" or type(values) == "string" then
|
||||
info.values = values
|
||||
values = callmethod(info, inputpos, tab, "values")
|
||||
info.values = nil
|
||||
end
|
||||
|
||||
local ok
|
||||
for k,v in pairs(values) do
|
||||
if strlower(k)==str then
|
||||
str = k -- overwrite with key (in case of case mismatches)
|
||||
ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not ok then
|
||||
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", str)
|
||||
|
||||
elseif tab.type=="multiselect" then
|
||||
------------ multiselect -------------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
if str == "" then
|
||||
--TODO: Show current values
|
||||
return
|
||||
end
|
||||
|
||||
local values = tab.values
|
||||
if type(values) == "function" or type(values) == "string" then
|
||||
info.values = values
|
||||
values = callmethod(info, inputpos, tab, "values")
|
||||
info.values = nil
|
||||
end
|
||||
|
||||
--build a table of the selections, checking that they exist
|
||||
--parse for =on =off =default in the process
|
||||
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
|
||||
local sels = {}
|
||||
for v in string.gmatch(str, "[^ ]+") do
|
||||
--parse option=on etc
|
||||
local opt, val = string.match(v,'(.+)=(.+)')
|
||||
--get option if toggling
|
||||
if not opt then
|
||||
opt = v
|
||||
end
|
||||
|
||||
--check that the opt is valid
|
||||
local ok
|
||||
for k,v in pairs(values) do
|
||||
if strlower(k)==opt then
|
||||
opt = k -- overwrite with key (in case of case mismatches)
|
||||
ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not ok then
|
||||
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
|
||||
return
|
||||
end
|
||||
|
||||
--check that if val was supplied it is valid
|
||||
if val then
|
||||
if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
|
||||
--val is valid insert it
|
||||
sels[opt] = val
|
||||
else
|
||||
if tab.tristate then
|
||||
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on', 'off' or 'default', or no argument to toggle."], v, val))
|
||||
else
|
||||
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
|
||||
end
|
||||
return
|
||||
end
|
||||
else
|
||||
-- no val supplied, toggle
|
||||
sels[opt] = true
|
||||
end
|
||||
end
|
||||
|
||||
for opt, val in pairs(sels) do
|
||||
local newval
|
||||
|
||||
if (val == true) then
|
||||
--toggle the option
|
||||
local b = callmethod(info, inputpos, tab, "get", opt)
|
||||
|
||||
if tab.tristate then
|
||||
--cycle in true, nil, false order
|
||||
if b then
|
||||
b = nil
|
||||
elseif b == nil then
|
||||
b = false
|
||||
else
|
||||
b = true
|
||||
end
|
||||
else
|
||||
b = not b
|
||||
end
|
||||
newval = b
|
||||
else
|
||||
--set the option as specified
|
||||
if val==L["on"] then
|
||||
newval = true
|
||||
elseif val==L["off"] then
|
||||
newval = false
|
||||
elseif val==L["default"] then
|
||||
newval = nil
|
||||
end
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", opt, newval)
|
||||
end
|
||||
|
||||
|
||||
elseif tab.type=="color" then
|
||||
------------ color --------------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
if str == "" then
|
||||
--TODO: Show current value
|
||||
return
|
||||
end
|
||||
|
||||
local r, g, b, a
|
||||
|
||||
if tab.hasAlpha then
|
||||
if str:len() == 8 and str:find("^%x*$") then
|
||||
--parse a hex string
|
||||
r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
|
||||
else
|
||||
--parse seperate values
|
||||
r,g,b,a = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
||||
r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
|
||||
end
|
||||
if not (r and g and b and a) then
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
|
||||
return
|
||||
end
|
||||
|
||||
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
|
||||
--values are valid
|
||||
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
|
||||
--values are valid 0..255, convert to 0..1
|
||||
r = r / 255
|
||||
g = g / 255
|
||||
b = b / 255
|
||||
a = a / 255
|
||||
else
|
||||
--values are invalid
|
||||
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0..1 or 0..255."], str))
|
||||
end
|
||||
else
|
||||
a = 1.0
|
||||
if str:len() == 6 and str:find("^%x*$") then
|
||||
--parse a hex string
|
||||
r,g,b = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255
|
||||
else
|
||||
--parse seperate values
|
||||
r,g,b = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
||||
r,g,b = tonumber(r), tonumber(g), tonumber(b)
|
||||
end
|
||||
if not (r and g and b) then
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBB' or 'r g b'."], str))
|
||||
return
|
||||
end
|
||||
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 then
|
||||
--values are valid
|
||||
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 then
|
||||
--values are valid 0..255, convert to 0..1
|
||||
r = r / 255
|
||||
g = g / 255
|
||||
b = b / 255
|
||||
else
|
||||
--values are invalid
|
||||
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
|
||||
end
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", r,g,b,a)
|
||||
|
||||
elseif tab.type=="keybinding" then
|
||||
------------ keybinding --------------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
if str == "" then
|
||||
--TODO: Show current value
|
||||
return
|
||||
end
|
||||
local value = keybindingValidateFunc(str:upper())
|
||||
if value == false then
|
||||
usererr(info, inputpos, format(L["'%s' - Invalid Keybinding."], str))
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", value)
|
||||
|
||||
elseif tab.type=="description" then
|
||||
------------ description --------------------
|
||||
-- ignore description, GUI config only
|
||||
else
|
||||
err(info, inputpos, "unknown options table item type '"..tostring(tab.type).."'")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- HandleCommand(slashcmd, appName, input)
|
||||
--
|
||||
-- Call this from a chat command handler to parse the command input as operations on an aceoptions table
|
||||
--
|
||||
-- slashcmd (string) - the slash command WITHOUT leading slash (only used for error output)
|
||||
-- appName (string) - the application name as given to AceConfigRegistry:RegisterOptionsTable()
|
||||
-- input (string) -- the commandline input (as given by the WoW handler, i.e. without the command itself)
|
||||
|
||||
function lib:HandleCommand(slashcmd, appName, input)
|
||||
|
||||
local optgetter = cfgreg:GetOptionsTable(appName)
|
||||
if not optgetter then
|
||||
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
|
||||
end
|
||||
local options = assert( optgetter("cmd", MAJOR) )
|
||||
|
||||
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
|
||||
[0] = slashcmd,
|
||||
appName = appName,
|
||||
options = options,
|
||||
input = input,
|
||||
self = self,
|
||||
handler = self,
|
||||
uiType = "cmd",
|
||||
uiName = MAJOR,
|
||||
}
|
||||
|
||||
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- CreateChatCommand(slashcmd, appName)
|
||||
--
|
||||
-- Utility function to create a slash command handler.
|
||||
-- Also registers tab completion with AceTab
|
||||
--
|
||||
-- slashcmd (string) - the slash command WITHOUT leading slash (only used for error output)
|
||||
-- appName (string) - the application name as given to AceConfigRegistry:RegisterOptionsTable()
|
||||
|
||||
function lib:CreateChatCommand(slashcmd, appName)
|
||||
if not AceConsole then
|
||||
AceConsole = LibStub(AceConsoleName)
|
||||
end
|
||||
if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
|
||||
lib.HandleCommand(self, slashcmd, appName, input) -- upgradable
|
||||
end,
|
||||
true) then -- succesfully registered so lets get the command -> app table in
|
||||
commands[slashcmd] = appName
|
||||
end
|
||||
end
|
||||
|
||||
-- GetChatCommandOptions(slashcmd)
|
||||
--
|
||||
-- Utility function that returns the options table that belongs to a slashcommand
|
||||
-- mainly used by AceTab
|
||||
|
||||
function lib:GetChatCommandOptions(slashcmd)
|
||||
return commands[slashcmd]
|
||||
end
|
4
libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
Normal file
4
libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConfigCmd-3.0.lua"/>
|
||||
</Ui>
|
1755
libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
Normal file
1755
libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConfigDialog-3.0.lua"/>
|
||||
</Ui>
|
@ -0,0 +1,352 @@
|
||||
--[[
|
||||
AceConfigRegistry-3.0:
|
||||
|
||||
Handle central registration of options tables in use by addons and modules. Do nothing else.
|
||||
|
||||
Options tables can be registered as raw tables, or as function refs that return a table.
|
||||
These functions receive two arguments: "uiType" and "uiName".
|
||||
- Valid "uiTypes": "cmd", "dropdown", "dialog". This is verified by the library at call time.
|
||||
- The "uiName" field is expected to contain the full name of the calling addon, including version, e.g. "FooBar-1.0". This is verified by the library at call time.
|
||||
|
||||
:IterateOptionsTables() and :GetOptionsTable() always return a function reference that the requesting config handling addon must call with the above arguments.
|
||||
]]
|
||||
|
||||
local MAJOR, MINOR = "AceConfigRegistry-3.0", 6
|
||||
local lib = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not lib then return end
|
||||
|
||||
lib.tables = lib.tables or {}
|
||||
|
||||
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
||||
|
||||
if not lib.callbacks then
|
||||
lib.callbacks = CallbackHandler:New(lib)
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Validating options table consistency:
|
||||
|
||||
|
||||
lib.validated = {
|
||||
-- list of options table names ran through :ValidateOptionsTable automatically.
|
||||
-- CLEARED ON PURPOSE, since newer versions may have newer validators
|
||||
cmd = {},
|
||||
dropdown = {},
|
||||
dialog = {},
|
||||
}
|
||||
|
||||
|
||||
|
||||
local function err(msg, errlvl, ...)
|
||||
local t = {}
|
||||
for i=select("#",...),1,-1 do
|
||||
tinsert(t, (select(i, ...)))
|
||||
end
|
||||
error(MAJOR..":ValidateOptionsTable(): "..table.concat(t,".")..msg, errlvl+2)
|
||||
end
|
||||
|
||||
|
||||
local isstring={["string"]=true, _="string"}
|
||||
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
|
||||
local istable={["table"]=true, _="table"}
|
||||
local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"}
|
||||
local optstring={["nil"]=true,["string"]=true, _="string"}
|
||||
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
|
||||
local optnumber={["nil"]=true,["number"]=true, _="number"}
|
||||
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
|
||||
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
|
||||
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
|
||||
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
|
||||
local optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=true, _="methodname, funcref or boolean"}
|
||||
local opttable={["nil"]=true,["table"]=true, _="table"}
|
||||
local optbool={["nil"]=true,["boolean"]=true, _="boolean"}
|
||||
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"}
|
||||
|
||||
local basekeys={
|
||||
type=isstring,
|
||||
name=isstringfunc,
|
||||
desc=optstringfunc,
|
||||
order=optmethodnumber,
|
||||
validate=optmethodfalse,
|
||||
confirm=optmethodbool,
|
||||
confirmText=optstring,
|
||||
disabled=optmethodbool,
|
||||
hidden=optmethodbool,
|
||||
guiHidden=optmethodbool,
|
||||
dialogHidden=optmethodbool,
|
||||
dropdownHidden=optmethodbool,
|
||||
cmdHidden=optmethodbool,
|
||||
icon=optstringfunc,
|
||||
iconCoords=optmethodtable,
|
||||
handler=opttable,
|
||||
get=optmethodfalse,
|
||||
set=optmethodfalse,
|
||||
func=optmethodfalse,
|
||||
arg={["*"]=true},
|
||||
width=optstring,
|
||||
}
|
||||
|
||||
local typedkeys={
|
||||
header={},
|
||||
description={
|
||||
image=optstringfunc,
|
||||
imageCoords=optmethodtable,
|
||||
imageHeight=optnumber,
|
||||
imageWidth=optnumber,
|
||||
},
|
||||
group={
|
||||
args=istable,
|
||||
plugins=opttable,
|
||||
inline=optbool,
|
||||
cmdInline=optbool,
|
||||
guiInline=optbool,
|
||||
dropdownInline=optbool,
|
||||
dialogInline=optbool,
|
||||
childGroups=optstring,
|
||||
},
|
||||
execute={
|
||||
-- func={
|
||||
-- ["function"]=true,
|
||||
-- ["string"]=true,
|
||||
-- _="methodname or funcref"
|
||||
-- },
|
||||
},
|
||||
input={
|
||||
pattern=optstring,
|
||||
usage=optstring,
|
||||
control=optstring,
|
||||
dialogControl=optstring,
|
||||
dropdownControl=optstring,
|
||||
multiline=optboolnumber,
|
||||
},
|
||||
toggle={
|
||||
tristate=optbool,
|
||||
},
|
||||
tristate={
|
||||
},
|
||||
range={
|
||||
min=optnumber,
|
||||
max=optnumber,
|
||||
step=optnumber,
|
||||
bigStep=optnumber,
|
||||
isPercent=optbool,
|
||||
},
|
||||
select={
|
||||
values=ismethodtable,
|
||||
style={
|
||||
["nil"]=true,
|
||||
["string"]={dropdown=true,radio=true},
|
||||
_="string: 'dropdown' or 'radio'"
|
||||
},
|
||||
control=optstring,
|
||||
dialogControl=optstring,
|
||||
dropdownControl=optstring,
|
||||
},
|
||||
multiselect={
|
||||
values=ismethodtable,
|
||||
style=optstring,
|
||||
tristate=optbool,
|
||||
control=optstring,
|
||||
dialogControl=optstring,
|
||||
dropdownControl=optstring,
|
||||
},
|
||||
color={
|
||||
hasAlpha=optbool,
|
||||
},
|
||||
keybinding={
|
||||
-- TODO
|
||||
},
|
||||
}
|
||||
|
||||
local function validateKey(k,errlvl,...)
|
||||
errlvl=(errlvl or 0)+1
|
||||
if type(k)~="string" then
|
||||
err("["..tostring(k).."] - key is not a string", errlvl,...)
|
||||
end
|
||||
if strfind(k, "[%c \127]") then
|
||||
err("["..tostring(k).."] - key name contained spaces (or control characters)", errlvl,...)
|
||||
end
|
||||
end
|
||||
|
||||
local function validateVal(v, oktypes, errlvl,...)
|
||||
errlvl=(errlvl or 0)+1
|
||||
local isok=oktypes[type(v)] or oktypes["*"]
|
||||
|
||||
if not isok then
|
||||
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...)
|
||||
end
|
||||
if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
|
||||
if not isok[v] then
|
||||
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function validate(options,errlvl,...)
|
||||
errlvl=(errlvl or 0)+1
|
||||
-- basic consistency
|
||||
if type(options)~="table" then
|
||||
err(": expected a table, got a "..type(options), errlvl,...)
|
||||
end
|
||||
if type(options.type)~="string" then
|
||||
err(".type: expected a string, got a "..type(options.type), errlvl,...)
|
||||
end
|
||||
|
||||
-- get type and 'typedkeys' member
|
||||
local tk = typedkeys[options.type]
|
||||
if not tk then
|
||||
err(".type: unknown type '"..options.type.."'", errlvl,...)
|
||||
end
|
||||
|
||||
-- make sure that all options[] are known parameters
|
||||
for k,v in pairs(options) do
|
||||
if not (tk[k] or basekeys[k]) then
|
||||
err(": unknown parameter", errlvl,tostring(k),...)
|
||||
end
|
||||
end
|
||||
|
||||
-- verify that required params are there, and that everything is the right type
|
||||
for k,oktypes in pairs(basekeys) do
|
||||
validateVal(options[k], oktypes, errlvl,k,...)
|
||||
end
|
||||
for k,oktypes in pairs(tk) do
|
||||
validateVal(options[k], oktypes, errlvl,k,...)
|
||||
end
|
||||
|
||||
-- extra logic for groups
|
||||
if options.type=="group" then
|
||||
for k,v in pairs(options.args) do
|
||||
validateKey(k,errlvl,"args",...)
|
||||
validate(v, errlvl,k,"args",...)
|
||||
end
|
||||
if options.plugins then
|
||||
for plugname,plugin in pairs(options.plugins) do
|
||||
if type(plugin)~="table" then
|
||||
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...)
|
||||
end
|
||||
for k,v in pairs(plugin) do
|
||||
validateKey(k,errlvl,tostring(plugname),"plugins",...)
|
||||
validate(v, errlvl,k,tostring(plugname),"plugins",...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- :ValidateOptionsTable(options,name,errlvl)
|
||||
-- - options - the table
|
||||
-- - name - (string) name of table, used in error reports
|
||||
-- - errlvl - (optional number) error level offset, default 0
|
||||
--
|
||||
-- Validates basic structure and integrity of an options table
|
||||
-- Does NOT verify that get/set etc actually exist, since they can be defined at any depth
|
||||
|
||||
function lib:ValidateOptionsTable(options,name,errlvl)
|
||||
errlvl=(errlvl or 0)+1
|
||||
name = name or "Optionstable"
|
||||
if not options.name then
|
||||
options.name=name -- bit of a hack, the root level doesn't really need a .name :-/
|
||||
end
|
||||
validate(options,errlvl,name)
|
||||
end
|
||||
|
||||
------------------------------
|
||||
-- :NotifyChange(appName)
|
||||
-- - appName - string identifying the addon
|
||||
--
|
||||
-- Fires a ConfigTableChange callback for those listening in on it, allowing config GUIs to refresh
|
||||
------------------------------
|
||||
|
||||
function lib:NotifyChange(appName)
|
||||
if not lib.tables[appName] then return end
|
||||
lib.callbacks:Fire("ConfigTableChange", appName)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- Registering and retreiving options tables:
|
||||
|
||||
|
||||
-- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
|
||||
|
||||
local function validateGetterArgs(uiType, uiName, errlvl)
|
||||
errlvl=(errlvl or 0)+2
|
||||
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
|
||||
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
|
||||
end
|
||||
if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2"
|
||||
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- :RegisterOptionsTable(appName, options)
|
||||
-- - appName - string identifying the addon
|
||||
-- - options - table or function reference
|
||||
|
||||
function lib:RegisterOptionsTable(appName, options)
|
||||
if type(options)=="table" then
|
||||
if options.type~="group" then -- quick sanity checker
|
||||
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
|
||||
end
|
||||
lib.tables[appName] = function(uiType, uiName, errlvl)
|
||||
errlvl=(errlvl or 0)+1
|
||||
validateGetterArgs(uiType, uiName, errlvl)
|
||||
if not lib.validated[uiType][appName] then
|
||||
lib:ValidateOptionsTable(options, appName, errlvl) -- upgradable
|
||||
lib.validated[uiType][appName] = true
|
||||
end
|
||||
return options
|
||||
end
|
||||
elseif type(options)=="function" then
|
||||
lib.tables[appName] = function(uiType, uiName, errlvl)
|
||||
errlvl=(errlvl or 0)+1
|
||||
validateGetterArgs(uiType, uiName, errlvl)
|
||||
local tab = assert(options(uiType, uiName))
|
||||
if not lib.validated[uiType][appName] then
|
||||
lib:ValidateOptionsTable(tab, appName, errlvl) -- upgradable
|
||||
lib.validated[uiType][appName] = true
|
||||
end
|
||||
return tab
|
||||
end
|
||||
else
|
||||
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- :IterateOptionsTables()
|
||||
--
|
||||
-- Returns an iterator of ["appName"]=funcref pairs
|
||||
|
||||
function lib:IterateOptionsTables()
|
||||
return pairs(lib.tables)
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- :GetOptionsTable(appName)
|
||||
-- - appName - which addon to retreive the options table of
|
||||
-- Optional:
|
||||
-- - uiType - "cmd", "dropdown", "dialog"
|
||||
-- - uiName - e.g. "MyLib-1.0"
|
||||
--
|
||||
-- If only appName is given, a function is returned which you
|
||||
-- can call with (uiType,uiName) to get the table.
|
||||
-- If uiType&uiName are given, the table is returned.
|
||||
|
||||
function lib:GetOptionsTable(appName, uiType, uiName)
|
||||
local f = lib.tables[appName]
|
||||
if not f then
|
||||
return nil
|
||||
end
|
||||
|
||||
if uiType then
|
||||
return f(uiType,uiName,1) -- get the table for us
|
||||
else
|
||||
return f -- return the function
|
||||
end
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConfigRegistry-3.0.lua"/>
|
||||
</Ui>
|
221
libs/AceConsole-3.0/AceConsole-3.0.lua
Normal file
221
libs/AceConsole-3.0/AceConsole-3.0.lua
Normal file
@ -0,0 +1,221 @@
|
||||
--[[ $Id: AceConsole-3.0.lua 708 2008-10-19 10:59:58Z arrowmaster $ ]]
|
||||
local MAJOR,MINOR = "AceConsole-3.0", 6
|
||||
|
||||
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
|
||||
|
||||
-- local upvalues
|
||||
local _G = _G
|
||||
local pairs = pairs
|
||||
local select = select
|
||||
local type = type
|
||||
local tostring = tostring
|
||||
local strfind = string.find
|
||||
local strsub = string.sub
|
||||
local max = math.max
|
||||
|
||||
-- AceConsole:Print( [chatframe,] ... )
|
||||
--
|
||||
-- Print to DEFAULT_CHAT_FRAME or given chatframe (anything with an .AddMessage member)
|
||||
function AceConsole:Print(...)
|
||||
local text = ""
|
||||
if self ~= AceConsole then
|
||||
text = "|cff33ff99"..tostring( self ).."|r: "
|
||||
end
|
||||
|
||||
local frame = select(1, ...)
|
||||
if not ( type(frame) == "table" and frame.AddMessage ) then -- Is first argument something with an .AddMessage member?
|
||||
frame=nil
|
||||
end
|
||||
|
||||
for i=(frame and 2 or 1), select("#", ...) do
|
||||
text = text .. tostring( select( i, ...) ) .." "
|
||||
end
|
||||
(frame or DEFAULT_CHAT_FRAME):AddMessage( text )
|
||||
end
|
||||
|
||||
|
||||
-- AceConsole:RegisterChatCommand(. command, func, persist )
|
||||
--
|
||||
-- command (string) - chat command to be registered WITHOUT leading "/"
|
||||
-- func (function|membername) - function to call, or self[membername](self, ...) call
|
||||
-- persist (boolean) - false: the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
|
||||
--
|
||||
-- Register a simple chat command
|
||||
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
|
||||
|
||||
|
||||
-- AceConsole:UnregisterChatCommand( command )
|
||||
--
|
||||
-- Unregister a chatcommand
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
-- AceConsole:GetArgs(string, numargs, startpos)
|
||||
--
|
||||
-- Retreive one or more space-separated arguments from a string.
|
||||
-- Treats quoted strings and itemlinks as non-spaced.
|
||||
--
|
||||
-- string - The raw argument string
|
||||
-- numargs - How many arguments to get (default 1)
|
||||
-- startpos - Where in the string to start scanning (default 1)
|
||||
--
|
||||
-- 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",
|
||||
"RegisterChatCommand",
|
||||
"UnregisterChatCommand",
|
||||
"GetArgs",
|
||||
}
|
||||
|
||||
-- AceConsole:Embed( target )
|
||||
-- target (object) - target object to embed AceBucket in
|
||||
--
|
||||
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
|
||||
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
|
4
libs/AceConsole-3.0/AceConsole-3.0.xml
Normal file
4
libs/AceConsole-3.0/AceConsole-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConsole-3.0.lua"/>
|
||||
</Ui>
|
626
libs/AceDB-3.0/AceDB-3.0.lua
Normal file
626
libs/AceDB-3.0/AceDB-3.0.lua
Normal file
@ -0,0 +1,626 @@
|
||||
--[[ $Id: AceDB-3.0.lua 667 2008-06-11 14:34:58Z nevcairiel $ ]]
|
||||
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 8
|
||||
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
|
||||
|
||||
if not AceDB then return end -- No upgrade needed
|
||||
|
||||
local type = type
|
||||
local pairs, next = pairs, next
|
||||
local rawget, rawset = rawget, rawset
|
||||
local setmetatable = setmetatable
|
||||
|
||||
AceDB.db_registry = AceDB.db_registry or {}
|
||||
AceDB.frame = AceDB.frame or CreateFrame("Frame")
|
||||
|
||||
local CallbackHandler
|
||||
local CallbackDummy = { Fire = function() end }
|
||||
|
||||
local DBObjectLib = {}
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Utility Functions
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
-- Simple shallow copy for copying defaults
|
||||
local function copyTable(src, dest)
|
||||
if type(dest) ~= "table" then dest = {} end
|
||||
if type(src) == "table" then
|
||||
for k,v in pairs(src) do
|
||||
if type(v) == "table" then
|
||||
-- try to index the key first so that the metatable creates the defaults, if set, and use that table
|
||||
v = copyTable(v, dest[k])
|
||||
end
|
||||
dest[k] = v
|
||||
end
|
||||
end
|
||||
return dest
|
||||
end
|
||||
|
||||
-- Called to add defaults to a section of the database
|
||||
--
|
||||
-- When a ["*"] default section is indexed with a new key, a table is returned
|
||||
-- and set in the host table. These tables must be cleaned up by removeDefaults
|
||||
-- in order to ensure we don't write empty default tables.
|
||||
local function copyDefaults(dest, src)
|
||||
-- this happens if some value in the SV overwrites our default value with a non-table
|
||||
--if type(dest) ~= "table" then return end
|
||||
for k, v in pairs(src) do
|
||||
if k == "*" or k == "**" then
|
||||
if type(v) == "table" then
|
||||
-- This is a metatable used for table defaults
|
||||
local mt = {
|
||||
-- This handles the lookup and creation of new subtables
|
||||
__index = function(t,k)
|
||||
if k == nil then return nil end
|
||||
local tbl = {}
|
||||
copyDefaults(tbl, v)
|
||||
rawset(t, k, tbl)
|
||||
return tbl
|
||||
end,
|
||||
}
|
||||
setmetatable(dest, mt)
|
||||
-- handle already existing tables in the SV
|
||||
for dk, dv in pairs(dest) do
|
||||
if not rawget(src, dk) and type(dv) == "table" then
|
||||
copyDefaults(dv, v)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Values are not tables, so this is just a simple return
|
||||
local mt = {__index = function(t,k) return k~=nil and v or nil end}
|
||||
setmetatable(dest, mt)
|
||||
end
|
||||
elseif type(v) == "table" then
|
||||
if not rawget(dest, k) then rawset(dest, k, {}) end
|
||||
if type(dest[k]) == "table" then
|
||||
copyDefaults(dest[k], v)
|
||||
if src['**'] then
|
||||
copyDefaults(dest[k], src['**'])
|
||||
end
|
||||
end
|
||||
else
|
||||
if rawget(dest, k) == nil then
|
||||
rawset(dest, k, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Called to remove all defaults in the default table from the database
|
||||
local function removeDefaults(db, defaults, blocker)
|
||||
for k,v in pairs(defaults) do
|
||||
if k == "*" or k == "**" then
|
||||
if type(v) == "table" then
|
||||
-- Loop through all the actual k,v pairs and remove
|
||||
for key, value in pairs(db) do
|
||||
if type(value) == "table" then
|
||||
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
|
||||
if defaults[key] == nil and (not blocker or blocker[key] == nil) then
|
||||
removeDefaults(value, v)
|
||||
-- if the table is empty afterwards, remove it
|
||||
if not next(value) then
|
||||
db[key] = nil
|
||||
end
|
||||
-- if it was specified, only strip ** content, but block values which were set in the key table
|
||||
elseif k == "**" then
|
||||
removeDefaults(value, v, defaults[key])
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif k == "*" then
|
||||
-- check for non-table default
|
||||
for key, value in pairs(db) do
|
||||
if defaults[key] == nil and v == value then
|
||||
db[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif type(v) == "table" and type(db[k]) == "table" then
|
||||
-- if a blocker was set, dive into it, to allow multi-level defaults
|
||||
removeDefaults(db[k], v, blocker and blocker[k])
|
||||
if not next(db[k]) then
|
||||
db[k] = nil
|
||||
end
|
||||
else
|
||||
-- check if the current value matches the default, and that its not blocked by another defaults table
|
||||
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
|
||||
db[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
-- remove all metatables from the db
|
||||
setmetatable(db, nil)
|
||||
end
|
||||
|
||||
-- This is called when a table section is first accessed, to set up the defaults
|
||||
local function initSection(db, section, svstore, key, defaults)
|
||||
local sv = rawget(db, "sv")
|
||||
|
||||
local tableCreated
|
||||
if not sv[svstore] then sv[svstore] = {} end
|
||||
if not sv[svstore][key] then
|
||||
sv[svstore][key] = {}
|
||||
tableCreated = true
|
||||
end
|
||||
|
||||
local tbl = sv[svstore][key]
|
||||
|
||||
if defaults then
|
||||
copyDefaults(tbl, defaults)
|
||||
end
|
||||
rawset(db, section, tbl)
|
||||
|
||||
return tableCreated, tbl
|
||||
end
|
||||
|
||||
-- Metatable to handle the dynamic creation of sections and copying of sections.
|
||||
local dbmt = {
|
||||
__index = function(t, section)
|
||||
local keys = rawget(t, "keys")
|
||||
local key = keys[section]
|
||||
if key then
|
||||
local defaultTbl = rawget(t, "defaults")
|
||||
local defaults = defaultTbl and defaultTbl[section]
|
||||
|
||||
if section == "profile" then
|
||||
local new = initSection(t, section, "profiles", key, defaults)
|
||||
if new then
|
||||
-- Callback: OnNewProfile, database, newProfileKey
|
||||
t.callbacks:Fire("OnNewProfile", t, key)
|
||||
end
|
||||
elseif section == "profiles" then
|
||||
local sv = rawget(t, "sv")
|
||||
if not sv.profiles then sv.profiles = {} end
|
||||
rawset(t, "profiles", sv.profiles)
|
||||
elseif section == "global" then
|
||||
local sv = rawget(t, "sv")
|
||||
if not sv.global then sv.global = {} end
|
||||
if defaults then
|
||||
copyDefaults(sv.global, defaults)
|
||||
end
|
||||
rawset(t, section, sv.global)
|
||||
else
|
||||
initSection(t, section, section, key, defaults)
|
||||
end
|
||||
end
|
||||
|
||||
return rawget(t, section)
|
||||
end
|
||||
}
|
||||
|
||||
local function validateDefaults(defaults, keyTbl, offset)
|
||||
if not defaults then return end
|
||||
offset = offset or 0
|
||||
for k in pairs(defaults) do
|
||||
if not keyTbl[k] or k == "profiles" then
|
||||
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local preserve_keys = {
|
||||
["callbacks"] = true,
|
||||
["RegisterCallback"] = true,
|
||||
["UnregisterCallback"] = true,
|
||||
["UnregisterAllCallbacks"] = true,
|
||||
["children"] = true,
|
||||
}
|
||||
|
||||
local realmKey = GetRealmName()
|
||||
local charKey = UnitName("player") .. " - " .. realmKey
|
||||
local _, classKey = UnitClass("player")
|
||||
local _, raceKey = UnitRace("player")
|
||||
local factionKey = UnitFactionGroup("player")
|
||||
local factionrealmKey = factionKey .. " - " .. realmKey
|
||||
-- Actual database initialization function
|
||||
local function initdb(sv, defaults, defaultProfile, olddb, parent)
|
||||
-- Generate the database keys for each section
|
||||
|
||||
-- Make a container for profile keys
|
||||
if not sv.profileKeys then sv.profileKeys = {} end
|
||||
|
||||
-- Try to get the profile selected from the char db
|
||||
local profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
|
||||
sv.profileKeys[charKey] = profileKey
|
||||
|
||||
-- This table contains keys that enable the dynamic creation
|
||||
-- of each section of the table. The 'global' and 'profiles'
|
||||
-- have a key of true, since they are handled in a special case
|
||||
local keyTbl= {
|
||||
["char"] = charKey,
|
||||
["realm"] = realmKey,
|
||||
["class"] = classKey,
|
||||
["race"] = raceKey,
|
||||
["faction"] = factionKey,
|
||||
["factionrealm"] = factionrealmKey,
|
||||
["profile"] = profileKey,
|
||||
["global"] = true,
|
||||
["profiles"] = true,
|
||||
}
|
||||
|
||||
validateDefaults(defaults, keyTbl, 1)
|
||||
|
||||
-- This allows us to use this function to reset an entire database
|
||||
-- Clear out the old database
|
||||
if olddb then
|
||||
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
|
||||
end
|
||||
|
||||
-- Give this database the metatable so it initializes dynamically
|
||||
local db = setmetatable(olddb or {}, dbmt)
|
||||
|
||||
if not rawget(db, "callbacks") then
|
||||
-- try to load CallbackHandler-1.0 if it loaded after our library
|
||||
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
|
||||
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
|
||||
end
|
||||
|
||||
-- Copy methods locally into the database object, to avoid hitting
|
||||
-- the metatable when calling methods
|
||||
|
||||
if not parent then
|
||||
for name, func in pairs(DBObjectLib) do
|
||||
db[name] = func
|
||||
end
|
||||
else
|
||||
-- hack this one in
|
||||
db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
||||
db.ResetProfile = DBObjectLib.ResetProfile
|
||||
end
|
||||
|
||||
-- Set some properties in the database object
|
||||
db.profiles = sv.profiles
|
||||
db.keys = keyTbl
|
||||
db.sv = sv
|
||||
--db.sv_name = name
|
||||
db.defaults = defaults
|
||||
db.parent = parent
|
||||
|
||||
-- store the DB in the registry
|
||||
AceDB.db_registry[db] = true
|
||||
|
||||
return db
|
||||
end
|
||||
|
||||
-- handle PLAYER_LOGOUT
|
||||
-- strip all defaults from all databases
|
||||
local function logoutHandler(frame, event)
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
for db in pairs(AceDB.db_registry) do
|
||||
db.callbacks:Fire("OnDatabaseShutdown", db)
|
||||
for section, key in pairs(db.keys) do
|
||||
if db.defaults and db.defaults[section] and rawget(db, section) then
|
||||
removeDefaults(db[section], db.defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
|
||||
AceDB.frame:SetScript("OnEvent", logoutHandler)
|
||||
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Object Method Definitions
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
-- DBObject:RegisterDefaults(defaults)
|
||||
-- defaults (table) - A table of defaults for this database
|
||||
--
|
||||
-- Sets the defaults table for the given database object by clearing any
|
||||
-- that are currently set, and then setting the new defaults.
|
||||
function DBObjectLib:RegisterDefaults(defaults)
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
|
||||
end
|
||||
|
||||
validateDefaults(defaults, self.keys)
|
||||
|
||||
-- Remove any currently set defaults
|
||||
if self.defaults then
|
||||
for section,key in pairs(self.keys) do
|
||||
if self.defaults[section] and rawget(self, section) then
|
||||
removeDefaults(self[section], self.defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the DBObject.defaults table
|
||||
self.defaults = defaults
|
||||
|
||||
-- Copy in any defaults, only touching those sections already created
|
||||
if defaults then
|
||||
for section,key in pairs(self.keys) do
|
||||
if defaults[section] and rawget(self, section) then
|
||||
copyDefaults(self[section], defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- DBObject:SetProfile(name)
|
||||
-- name (string) - The name of the profile to set as the current profile
|
||||
--
|
||||
-- Changes the profile of the database and all of it's namespaces to the
|
||||
-- supplied named profile
|
||||
function DBObjectLib:SetProfile(name)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
-- changing to the same profile, dont do anything
|
||||
if name == self.keys.profile then return end
|
||||
|
||||
local oldProfile = self.profile
|
||||
local defaults = self.defaults and self.defaults.profile
|
||||
|
||||
if oldProfile and defaults then
|
||||
-- Remove the defaults from the old profile
|
||||
removeDefaults(oldProfile, defaults)
|
||||
end
|
||||
|
||||
self.profile = nil
|
||||
self.keys["profile"] = name
|
||||
self.sv.profileKeys[charKey] = name
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.SetProfile(db, name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileChanged, database, newProfileKey
|
||||
self.callbacks:Fire("OnProfileChanged", self, name)
|
||||
end
|
||||
|
||||
-- DBObject:GetProfiles(tbl)
|
||||
-- tbl (table) - A table to store the profile names in (optional)
|
||||
--
|
||||
-- Returns a table with the names of the existing profiles in the database.
|
||||
-- You can optionally supply a table to re-use for this purpose.
|
||||
function DBObjectLib:GetProfiles(tbl)
|
||||
if tbl and type(tbl) ~= "table" then
|
||||
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
|
||||
end
|
||||
|
||||
-- Clear the container table
|
||||
if tbl then
|
||||
for k,v in pairs(tbl) do tbl[k] = nil end
|
||||
else
|
||||
tbl = {}
|
||||
end
|
||||
|
||||
local curProfile = self.keys.profile
|
||||
|
||||
local i = 0
|
||||
for profileKey in pairs(self.profiles) do
|
||||
i = i + 1
|
||||
tbl[i] = profileKey
|
||||
if curProfile and profileKey == curProfile then curProfile = nil end
|
||||
end
|
||||
|
||||
-- Add the current profile, if it hasn't been created yet
|
||||
if curProfile then
|
||||
i = i + 1
|
||||
tbl[i] = curProfile
|
||||
end
|
||||
|
||||
return tbl, i
|
||||
end
|
||||
|
||||
-- DBObject:GetCurrentProfile()
|
||||
--
|
||||
-- Returns the current profile name used by the database
|
||||
function DBObjectLib:GetCurrentProfile()
|
||||
return self.keys.profile
|
||||
end
|
||||
|
||||
-- DBObject:DeleteProfile(name)
|
||||
-- name (string) - The name of the profile to be deleted
|
||||
--
|
||||
-- Deletes a named profile. This profile must not be the active profile.
|
||||
function DBObjectLib:DeleteProfile(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
if self.keys.profile == name then
|
||||
error("Cannot delete the active profile in an AceDBObject.", 2)
|
||||
end
|
||||
|
||||
if not rawget(self.sv.profiles, name) and not silent then
|
||||
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
|
||||
end
|
||||
|
||||
self.sv.profiles[name] = nil
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.DeleteProfile(db, name, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileDeleted, database, profileKey
|
||||
self.callbacks:Fire("OnProfileDeleted", self, name)
|
||||
end
|
||||
|
||||
-- DBObject:CopyProfile(name)
|
||||
-- name (string) - The name of the profile to be copied into the current profile
|
||||
--
|
||||
-- Copies a named profile into the current profile, overwriting any conflicting
|
||||
-- settings.
|
||||
function DBObjectLib:CopyProfile(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
if name == self.keys.profile then
|
||||
error("Cannot have the same source and destination profiles.", 2)
|
||||
end
|
||||
|
||||
if not rawget(self.sv.profiles, name) and not silent then
|
||||
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
|
||||
end
|
||||
|
||||
-- Reset the profile before copying
|
||||
DBObjectLib.ResetProfile(self)
|
||||
|
||||
local profile = self.profile
|
||||
local source = self.sv.profiles[name]
|
||||
|
||||
copyTable(source, profile)
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.CopyProfile(db, name, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileCopied, database, sourceProfileKey
|
||||
self.callbacks:Fire("OnProfileCopied", self, name)
|
||||
end
|
||||
|
||||
-- DBObject:ResetProfile()
|
||||
-- noChildren (boolean) - if set to true, the reset will not be populated to the child namespaces of this DB object
|
||||
--
|
||||
-- Resets the current profile
|
||||
function DBObjectLib:ResetProfile(noChildren)
|
||||
local profile = self.profile
|
||||
|
||||
for k,v in pairs(profile) do
|
||||
profile[k] = nil
|
||||
end
|
||||
|
||||
local defaults = self.defaults and self.defaults.profile
|
||||
if defaults then
|
||||
copyDefaults(profile, defaults)
|
||||
end
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children and not noChildren then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.ResetProfile(db)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileReset, database
|
||||
self.callbacks:Fire("OnProfileReset", self)
|
||||
end
|
||||
|
||||
-- DBObject:ResetDB(defaultProfile)
|
||||
-- defaultProfile (string) - The profile name to use as the default
|
||||
--
|
||||
-- Resets the entire database, using the string defaultProfile as the default
|
||||
-- profile.
|
||||
function DBObjectLib:ResetDB(defaultProfile)
|
||||
if defaultProfile and type(defaultProfile) ~= "string" then
|
||||
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
|
||||
end
|
||||
|
||||
local sv = self.sv
|
||||
for k,v in pairs(sv) do
|
||||
sv[k] = nil
|
||||
end
|
||||
|
||||
local parent = self.parent
|
||||
|
||||
initdb(sv, self.defaults, defaultProfile, self)
|
||||
|
||||
-- fix the child namespaces
|
||||
if self.children then
|
||||
if not sv.namespaces then sv.namespaces = {} end
|
||||
for name, db in pairs(self.children) do
|
||||
if not sv.namespaces[name] then sv.namespaces[name] = {} end
|
||||
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnDatabaseReset, database
|
||||
self.callbacks:Fire("OnDatabaseReset", self)
|
||||
-- Callback: OnProfileChanged, database, profileKey
|
||||
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-- DBObject:RegisterNamespace(name [, defaults])
|
||||
-- name (string) - The name of the new namespace
|
||||
-- defaults (table) - A table of values to use as defaults
|
||||
--
|
||||
-- Creates a new database namespace, directly tied to the database. This
|
||||
-- is a full scale database in it's own rights other than the fact that
|
||||
-- it cannot control its profile individually
|
||||
function DBObjectLib:RegisterNamespace(name, defaults)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
|
||||
end
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
|
||||
end
|
||||
if self.children and self.children[name] then
|
||||
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
|
||||
end
|
||||
|
||||
local sv = self.sv
|
||||
if not sv.namespaces then sv.namespaces = {} end
|
||||
if not sv.namespaces[name] then
|
||||
sv.namespaces[name] = {}
|
||||
end
|
||||
|
||||
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
|
||||
|
||||
if not self.children then self.children = {} end
|
||||
self.children[name] = newDB
|
||||
return newDB
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Exposed Methods
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
-- AceDB:New(name, defaults, defaultProfile)
|
||||
-- name (table or string) - The name of variable, or table to use for the database
|
||||
-- defaults (table) - A table of database defaults
|
||||
-- defaultProfile (string) - The name of the default profile
|
||||
--
|
||||
-- Creates a new database object that can be used to handle database settings
|
||||
-- and profiles.
|
||||
function AceDB:New(tbl, defaults, defaultProfile)
|
||||
if type(tbl) == "string" then
|
||||
local name = tbl
|
||||
tbl = getglobal(name)
|
||||
if not tbl then
|
||||
tbl = {}
|
||||
setglobal(name, tbl)
|
||||
end
|
||||
end
|
||||
|
||||
if type(tbl) ~= "table" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
|
||||
end
|
||||
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
|
||||
end
|
||||
|
||||
if defaultProfile and type(defaultProfile) ~= "string" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string expected.", 2)
|
||||
end
|
||||
|
||||
return initdb(tbl, defaults, defaultProfile)
|
||||
end
|
||||
|
||||
-- upgrade existing databases
|
||||
for db in pairs(AceDB.db_registry) do
|
||||
if not db.parent then
|
||||
for name,func in pairs(DBObjectLib) do
|
||||
db[name] = func
|
||||
end
|
||||
else
|
||||
db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
||||
end
|
||||
end
|
4
libs/AceDB-3.0/AceDB-3.0.xml
Normal file
4
libs/AceDB-3.0/AceDB-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceDB-3.0.lua"/>
|
||||
</Ui>
|
370
libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
Normal file
370
libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
Normal file
@ -0,0 +1,370 @@
|
||||
--[[ $Id: AceDBOptions-3.0.lua 668 2008-07-16 10:08:17Z funkydude $ ]]
|
||||
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 7
|
||||
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
|
||||
|
||||
if not AceDBOptions then return end -- No upgrade needed
|
||||
|
||||
AceDBOptions.optionTables = AceDBOptions.optionTables or {}
|
||||
AceDBOptions.handlers = AceDBOptions.handlers or {}
|
||||
|
||||
--[[
|
||||
Localization of AceDBOptions-3.0
|
||||
]]
|
||||
|
||||
local L = {
|
||||
default = "Default",
|
||||
intro = "You can change the active database profile, so you can have different settings for every character.",
|
||||
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
|
||||
reset = "Reset Profile",
|
||||
reset_sub = "Reset the current profile to the default",
|
||||
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already exisiting profiles.",
|
||||
new = "New",
|
||||
new_sub = "Create a new empty profile.",
|
||||
choose = "Existing Profiles",
|
||||
choose_sub = "Select one of your currently available profiles.",
|
||||
copy_desc = "Copy the settings from one existing profile into the currently active profile.",
|
||||
copy = "Copy From",
|
||||
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
|
||||
delete = "Delete a Profile",
|
||||
delete_sub = "Deletes a profile from the database.",
|
||||
delete_confirm = "Are you sure you want to delete the selected profile?",
|
||||
profiles = "Profiles",
|
||||
profiles_sub = "Manage Profiles",
|
||||
}
|
||||
|
||||
local LOCALE = GetLocale()
|
||||
if LOCALE == "deDE" then
|
||||
L["default"] = "Standard"
|
||||
L["intro"] = "Hier kannst du das aktive Datenbankprofile \195\164ndern, damit du verschiedene Einstellungen f\195\188r jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration m\195\182glich wird."
|
||||
L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zur\195\188ck, f\195\188r den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
|
||||
L["reset"] = "Profil zur\195\188cksetzen"
|
||||
L["reset_sub"] = "Das aktuelle Profil auf Standard zur\195\188cksetzen."
|
||||
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder w\195\164hle eines der vorhandenen Profile aus."
|
||||
L["new"] = "Neu"
|
||||
L["new_sub"] = "Ein neues Profil erstellen."
|
||||
L["choose"] = "Vorhandene Profile"
|
||||
L["choose_sub"] = "W\195\164hlt ein bereits vorhandenes Profil aus."
|
||||
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
|
||||
L["copy"] = "Kopieren von..."
|
||||
L["delete_desc"] = "L\195\182sche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
|
||||
L["delete"] = "Profil l\195\182schen"
|
||||
L["delete_sub"] = "L\195\182scht ein Profil aus der Datenbank."
|
||||
L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?"
|
||||
L["profiles"] = "Profile"
|
||||
L["profiles_sub"] = "Profile verwalten"
|
||||
elseif LOCALE == "frFR" then
|
||||
L["default"] = "D\195\169faut"
|
||||
L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des param\195\168tres diff\195\169rents pour chaque personnage, permettant ainsi d'avoir une configuration tr\195\168s flexible."
|
||||
L["reset_desc"] = "R\195\169initialise le profil actuel au cas o\195\185 votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
|
||||
L["reset"] = "R\195\169initialiser le profil"
|
||||
L["reset_sub"] = "R\195\169initialise le profil actuel avec les param\195\168tres par d\195\169faut."
|
||||
L["choose_desc"] = "Vous pouvez cr\195\169er un nouveau profil en entrant un nouveau nom dans la bo\195\174te de saisie, ou en choississant un des profils d\195\169j\195\160 existants."
|
||||
L["new"] = "Nouveau"
|
||||
L["new_sub"] = "Cr\195\169\195\169e un nouveau profil vierge."
|
||||
L["choose"] = "Profils existants"
|
||||
L["choose_sub"] = "Permet de choisir un des profils d\195\169j\195\160 disponibles."
|
||||
L["copy_desc"] = "Copie les param\195\168tres d'un profil d\195\169j\195\160 existant dans le profil actuellement actif."
|
||||
L["copy"] = "Copier \195\160 partir de"
|
||||
L["delete_desc"] = "Supprime les profils existants inutilis\195\169s de la base de donn\195\169es afin de gagner de la place et de nettoyer le fichier SavedVariables."
|
||||
L["delete"] = "Supprimer un profil"
|
||||
L["delete_sub"] = "Supprime un profil de la base de donn\195\169es."
|
||||
L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?"
|
||||
L["profiles"] = "Profils"
|
||||
L["profiles_sub"] = "Gestion des profils"
|
||||
elseif LOCALE == "koKR" then
|
||||
L["default"] = "기본값"
|
||||
L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
|
||||
L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
|
||||
L["reset"] = "프로필 초기화"
|
||||
L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
|
||||
L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
|
||||
L["new"] = "새로운 프로필"
|
||||
L["new_sub"] = "새로운 프로필을 만듭니다."
|
||||
L["choose"] = "프로필 선택"
|
||||
L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
|
||||
L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
|
||||
L["copy"] = "복사"
|
||||
L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
|
||||
L["delete"] = "프로필 삭제"
|
||||
L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
|
||||
L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
|
||||
L["profiles"] = "프로필"
|
||||
L["profiles_sub"] = "프로필 설정"
|
||||
elseif LOCALE == "esES" then
|
||||
|
||||
elseif LOCALE == "zhTW" then
|
||||
L["default"] = "預設"
|
||||
L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
|
||||
L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
|
||||
L["reset"] = "重置設定檔"
|
||||
L["reset_sub"] = "將當前的設定檔恢復為預設值"
|
||||
L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
|
||||
L["new"] = "新建"
|
||||
L["new_sub"] = "新建一個空的設定檔。"
|
||||
L["choose"] = "現有的設定檔"
|
||||
L["choose_sub"] = "從當前可用的設定檔裏面選擇一個。"
|
||||
L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
|
||||
L["copy"] = "複製自"
|
||||
L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
|
||||
L["delete"] = "刪除一個設定檔"
|
||||
L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
|
||||
L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
|
||||
L["profiles"] = "設定檔"
|
||||
L["profiles_sub"] = "管理設定檔"
|
||||
elseif LOCALE == "zhCN" then
|
||||
L["default"] = "默认"
|
||||
L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
|
||||
L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
|
||||
L["reset"] = "重置配置文件"
|
||||
L["reset_sub"] = "将当前的配置文件恢复为默认值"
|
||||
L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
|
||||
L["new"] = "新建"
|
||||
L["new_sub"] = "新建一个空的配置文件。"
|
||||
L["choose"] = "现有的配置文件"
|
||||
L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
|
||||
L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
|
||||
L["copy"] = "复制自"
|
||||
L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
|
||||
L["delete"] = "删除一个配置文件"
|
||||
L["delete_sub"] = "从数据库里删除一个配置文件。"
|
||||
L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
|
||||
L["profiles"] = "配置文件"
|
||||
L["profiles_sub"] = "管理配置文件"
|
||||
elseif LOCALE == "ruRU" then
|
||||
L["default"] = "По умолчанию"
|
||||
L["intro"] = "Вы можете сменить активный профиль БД, этим вы можете устанавливать различные настройки для каждого персонажа."
|
||||
L["reset_desc"] = "Сброс текущего профиля на его стандартные значения, в том случаи если ваша конфигурация испорчена, или вы желаете всё перенастроить заново."
|
||||
L["reset"] = "Сброс профиля"
|
||||
L["reset"] = "Сброс текущего профиля на стандартный"
|
||||
L["choose_desc"] = "Вы можете создать новый профиль введя название в поле ввода, или выбрать один из уже существующих профилей."
|
||||
L["new"] = "Новый"
|
||||
L["new_sub"] = "Создать новый чистый профиль."
|
||||
L["choose"] = "Профиля"
|
||||
L["choose_sub"] = "Выберите один из уже доступных профилей."
|
||||
L["copy_desc"] = "Скопировать настройки профиля в на данный момент активный профиль."
|
||||
L["copy"] = "Скопировать с"
|
||||
L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
|
||||
L["delete"] = "Удалить профиль"
|
||||
L["delete_sub"] = "Удаления профиля из БД."
|
||||
L["delete_confirm"] = "Вы уверены что вы хотите удалить выбранный профиль?"
|
||||
L["profiles"] = "Профиля"
|
||||
L["profiles_sub"] = "Управление профилями"
|
||||
end
|
||||
|
||||
local defaultProfiles
|
||||
local tmpprofiles = {}
|
||||
|
||||
--[[
|
||||
getProfileList(db, common, nocurrent)
|
||||
|
||||
db - the db object to retrieve the profiles from
|
||||
common (boolean) - if common is true, getProfileList will add the default profiles to the return list, even if they have not been created yet
|
||||
nocurrent (boolean) - if true then getProfileList will not display the current profile in the list
|
||||
]]--
|
||||
local function getProfileList(db, common, nocurrent)
|
||||
local profiles = {}
|
||||
|
||||
-- copy existing profiles into the table
|
||||
local currentProfile = db:GetCurrentProfile()
|
||||
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
|
||||
if not (nocurrent and v == currentProfile) then
|
||||
profiles[v] = v
|
||||
end
|
||||
end
|
||||
|
||||
-- add our default profiles to choose from ( or rename existing profiles)
|
||||
for k,v in pairs(defaultProfiles) do
|
||||
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
|
||||
profiles[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return profiles
|
||||
end
|
||||
|
||||
--[[
|
||||
OptionsHandlerPrototype
|
||||
prototype class for handling the options in a sane way
|
||||
]]
|
||||
local OptionsHandlerPrototype = {}
|
||||
|
||||
--[[ Reset the profile ]]
|
||||
function OptionsHandlerPrototype:Reset()
|
||||
self.db:ResetProfile()
|
||||
end
|
||||
|
||||
--[[ Set the profile to value ]]
|
||||
function OptionsHandlerPrototype:SetProfile(info, value)
|
||||
self.db:SetProfile(value)
|
||||
end
|
||||
|
||||
--[[ returns the currently active profile ]]
|
||||
function OptionsHandlerPrototype:GetCurrentProfile()
|
||||
return self.db:GetCurrentProfile()
|
||||
end
|
||||
|
||||
--[[
|
||||
List all active profiles
|
||||
you can control the output with the .arg variable
|
||||
currently four modes are supported
|
||||
|
||||
(empty) - return all available profiles
|
||||
"nocurrent" - returns all available profiles except the currently active profile
|
||||
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
|
||||
"both" - common except the active profile
|
||||
]]
|
||||
function OptionsHandlerPrototype:ListProfiles(info)
|
||||
local arg = info.arg
|
||||
local profiles
|
||||
if arg == "common" and not self.noDefaultProfiles then
|
||||
profiles = getProfileList(self.db, true, nil)
|
||||
elseif arg == "nocurrent" then
|
||||
profiles = getProfileList(self.db, nil, true)
|
||||
elseif arg == "both" then -- currently not used
|
||||
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
|
||||
else
|
||||
profiles = getProfileList(self.db)
|
||||
end
|
||||
|
||||
return profiles
|
||||
end
|
||||
|
||||
--[[ Copy a profile ]]
|
||||
function OptionsHandlerPrototype:CopyProfile(info, value)
|
||||
self.db:CopyProfile(value)
|
||||
end
|
||||
|
||||
--[[ Delete a profile from the db ]]
|
||||
function OptionsHandlerPrototype:DeleteProfile(info, value)
|
||||
self.db:DeleteProfile(value)
|
||||
end
|
||||
|
||||
--[[ fill defaultProfiles with some generic values ]]
|
||||
local function generateDefaultProfiles(db)
|
||||
defaultProfiles = {
|
||||
["Default"] = L["default"],
|
||||
[db.keys.char] = db.keys.char,
|
||||
[db.keys.realm] = db.keys.realm,
|
||||
[db.keys.class] = UnitClass("player")
|
||||
}
|
||||
end
|
||||
|
||||
--[[ create and return a handler object for the db, or upgrade it if it already existed ]]
|
||||
local function getOptionsHandler(db, noDefaultProfiles)
|
||||
if not defaultProfiles then
|
||||
generateDefaultProfiles(db)
|
||||
end
|
||||
|
||||
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
|
||||
|
||||
for k,v in pairs(OptionsHandlerPrototype) do
|
||||
handler[k] = v
|
||||
end
|
||||
|
||||
AceDBOptions.handlers[db] = handler
|
||||
return handler
|
||||
end
|
||||
|
||||
--[[
|
||||
the real options table
|
||||
]]
|
||||
local optionsTable = {
|
||||
desc = {
|
||||
order = 1,
|
||||
type = "description",
|
||||
name = L["intro"] .. "\n",
|
||||
},
|
||||
descreset = {
|
||||
order = 9,
|
||||
type = "description",
|
||||
name = L["reset_desc"],
|
||||
},
|
||||
reset = {
|
||||
order = 10,
|
||||
type = "execute",
|
||||
name = L["reset"],
|
||||
desc = L["reset_sub"],
|
||||
func = "Reset",
|
||||
},
|
||||
choosedesc = {
|
||||
order = 20,
|
||||
type = "description",
|
||||
name = "\n" .. L["choose_desc"],
|
||||
},
|
||||
new = {
|
||||
name = L["new"],
|
||||
desc = L["new_sub"],
|
||||
type = "input",
|
||||
order = 30,
|
||||
get = false,
|
||||
set = "SetProfile",
|
||||
},
|
||||
choose = {
|
||||
name = L["choose"],
|
||||
desc = L["choose_sub"],
|
||||
type = "select",
|
||||
order = 40,
|
||||
get = "GetCurrentProfile",
|
||||
set = "SetProfile",
|
||||
values = "ListProfiles",
|
||||
arg = "common",
|
||||
},
|
||||
copydesc = {
|
||||
order = 50,
|
||||
type = "description",
|
||||
name = "\n" .. L["copy_desc"],
|
||||
},
|
||||
copyfrom = {
|
||||
order = 60,
|
||||
type = "select",
|
||||
name = L["copy"],
|
||||
desc = L["copy_desc"],
|
||||
get = false,
|
||||
set = "CopyProfile",
|
||||
values = "ListProfiles",
|
||||
arg = "nocurrent",
|
||||
},
|
||||
deldesc = {
|
||||
order = 70,
|
||||
type = "description",
|
||||
name = "\n" .. L["delete_desc"],
|
||||
},
|
||||
delete = {
|
||||
order = 80,
|
||||
type = "select",
|
||||
name = L["delete"],
|
||||
desc = L["delete_sub"],
|
||||
get = false,
|
||||
set = "DeleteProfile",
|
||||
values = "ListProfiles",
|
||||
arg = "nocurrent",
|
||||
confirm = true,
|
||||
confirmText = L["delete_confirm"],
|
||||
},
|
||||
}
|
||||
|
||||
--[[
|
||||
GetOptionsTable(db)
|
||||
db - the database object to create the options table for
|
||||
|
||||
creates and returns a option table to be used in your addon
|
||||
]]
|
||||
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
|
||||
local tbl = AceDBOptions.optionTables[db] or {
|
||||
type = "group",
|
||||
name = L["profiles"],
|
||||
desc = L["profiles_sub"],
|
||||
}
|
||||
|
||||
tbl.handler = getOptionsHandler(db, noDefaultProfiles)
|
||||
tbl.args = optionsTable
|
||||
|
||||
AceDBOptions.optionTables[db] = tbl
|
||||
return tbl
|
||||
end
|
||||
|
||||
-- upgrade existing tables
|
||||
for db,tbl in pairs(AceDBOptions.optionTables) do
|
||||
tbl.handler = getOptionsHandler(db)
|
||||
tbl.args = optionsTable
|
||||
end
|
4
libs/AceDBOptions-3.0/AceDBOptions-3.0.xml
Normal file
4
libs/AceDBOptions-3.0/AceDBOptions-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceDBOptions-3.0.lua"/>
|
||||
</Ui>
|
76
libs/AceEvent-3.0/AceEvent-3.0.lua
Normal file
76
libs/AceEvent-3.0/AceEvent-3.0.lua
Normal file
@ -0,0 +1,76 @@
|
||||
--[[ $Id: AceEvent-3.0.lua 494 2008-02-03 13:03:56Z nevcairiel $ ]]
|
||||
local MAJOR, MINOR = "AceEvent-3.0", 3
|
||||
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceEvent then return end
|
||||
|
||||
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",
|
||||
}
|
||||
|
||||
-- AceEvent:Embed( target )
|
||||
-- target (object) - target object to embed AceEvent in
|
||||
--
|
||||
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
|
||||
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
|
4
libs/AceEvent-3.0/AceEvent-3.0.xml
Normal file
4
libs/AceEvent-3.0/AceEvent-3.0.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceEvent-3.0.lua"/>
|
||||
</Ui>
|
@ -0,0 +1,283 @@
|
||||
------------------------------------------------------------------------
|
||||
r61 | ckknight | 2008-10-14 20:30:09 +0000 (Tue, 14 Oct 2008) | 1 line
|
||||
Changed paths:
|
||||
A /tags/WoW-3.0-release (from /trunk:60)
|
||||
|
||||
Tagging as WoW-3.0-release.
|
||||
------------------------------------------------------------------------
|
||||
r60 | stanzilla | 2008-10-14 16:51:22 +0000 (Tue, 14 Oct 2008) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Inventory-3.0.toc
|
||||
|
||||
Update TOC for WotLK
|
||||
------------------------------------------------------------------------
|
||||
r59 | nevcairiel | 2008-10-12 11:39:18 +0000 (Sun, 12 Oct 2008) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Inventory-3.0.toc
|
||||
|
||||
Patch 3.0 prep: Remove LoD from Libraries that have no load manager (LoD+OptDep Bug)
|
||||
------------------------------------------------------------------------
|
||||
r58 | nevcairiel | 2008-10-09 21:52:00 +0000 (Thu, 09 Oct 2008) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Inventory-3.0.lua
|
||||
|
||||
WoWAce Post-Processing: Virtually inflate Library Revision numbers for proper upgrade path
|
||||
------------------------------------------------------------------------
|
||||
r57 | trasher | 2008-10-05 19:25:35 +0000 (Sun, 05 Oct 2008) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Inventory-3.0.lua
|
||||
|
||||
frFR update
|
||||
------------------------------------------------------------------------
|
||||
r56 | arrowmaster | 2008-10-04 01:31:16 +0000 (Sat, 04 Oct 2008) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Inventory-3.0.lua
|
||||
M /trunk/LibBabble-Inventory-3.0.toc
|
||||
M /trunk/LibStub/LibStub.lua
|
||||
|
||||
Fix autoupdating minor version
|
||||
------------------------------------------------------------------------
|
||||
r55 | root | 2008-09-29 21:46:30 +0000 (Mon, 29 Sep 2008) | 1 line
|
||||
Changed paths:
|
||||
A /trunk/.pkgmeta
|
||||
|
||||
Facilitate WowAce-on-CurseForge transition
|
||||
------------------------------------------------------------------------
|
||||
r53 | root | 2008-09-29 20:58:16 +0000 (Mon, 29 Sep 2008) | 1 line
|
||||
Changed paths:
|
||||
D /tmp/trunk/LibBabble-Inventory-3.0
|
||||
A /trunk (from /tmp/trunk/LibBabble-Inventory-3.0:52)
|
||||
|
||||
Importing old repo data under /trunk
|
||||
------------------------------------------------------------------------
|
||||
r50 | Cybersea | 2008-07-15 14:53:42 +0000 (Tue, 15 Jul 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0
|
||||
- added ruRU translation
|
||||
------------------------------------------------------------------------
|
||||
r49 | scorpio0920 | 2008-05-27 04:42:44 +0000 (Tue, 27 May 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- Update zhTW localization. (Thanks s8095324)
|
||||
------------------------------------------------------------------------
|
||||
r48 | Thaoky | 2008-05-26 10:28:12 +0000 (Mon, 26 May 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- Added a few missing frFR translations (bag types)
|
||||
------------------------------------------------------------------------
|
||||
r47 | archarodim | 2008-05-17 22:55:22 +0000 (Sat, 17 May 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- Fix 'Pet' translation for frFR (many others are missing)
|
||||
------------------------------------------------------------------------
|
||||
r46 | kunda | 2008-05-17 11:04:35 +0000 (Sat, 17 May 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: deDE update
|
||||
------------------------------------------------------------------------
|
||||
r45 | Thaoky | 2008-05-17 06:44:32 +0000 (Sat, 17 May 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- frFR: "Premiers Soins" is now "Secourisme"
|
||||
------------------------------------------------------------------------
|
||||
r44 | ananhaid | 2008-05-16 10:15:13 +0000 (Fri, 16 May 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- zhCN update.
|
||||
------------------------------------------------------------------------
|
||||
r43 | StiviS | 2008-05-14 20:01:05 +0000 (Wed, 14 May 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- esES updated
|
||||
------------------------------------------------------------------------
|
||||
r42 | 7destiny | 2008-05-14 10:17:24 +0000 (Wed, 14 May 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: koKR Update
|
||||
------------------------------------------------------------------------
|
||||
r41 | odlaw | 2008-05-14 08:04:17 +0000 (Wed, 14 May 2008) | 3 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- Added Materials under Trade Goods
|
||||
- Added Mount under Miscellaneous
|
||||
------------------------------------------------------------------------
|
||||
r39 | StiviS | 2008-04-25 08:27:44 +0000 (Fri, 25 Apr 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: esES updated
|
||||
------------------------------------------------------------------------
|
||||
r38 | sayclub | 2008-04-25 04:24:27 +0000 (Fri, 25 Apr 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: koKR update.
|
||||
------------------------------------------------------------------------
|
||||
r37 | maqjav | 2008-04-20 09:51:15 +0000 (Sun, 20 Apr 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: esES update.
|
||||
------------------------------------------------------------------------
|
||||
r36 | bendo | 2008-04-11 00:10:03 +0000 (Fri, 11 Apr 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0
|
||||
- frFR update
|
||||
------------------------------------------------------------------------
|
||||
r35 | bendo | 2008-04-08 19:36:08 +0000 (Tue, 08 Apr 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0
|
||||
- frFR update
|
||||
------------------------------------------------------------------------
|
||||
r34 | scorpio0920 | 2008-04-02 03:09:03 +0000 (Wed, 02 Apr 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0
|
||||
- Update zhTW localization.
|
||||
------------------------------------------------------------------------
|
||||
r33 | arrowmaster | 2008-04-01 07:16:23 +0000 (Tue, 01 Apr 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
|
||||
.You are not a special or unique snowflake. Get back in line and use the 'Lib: ...' title format like everybody else to save the sanity of those of us looking through an alpha sorted addon list
|
||||
------------------------------------------------------------------------
|
||||
r32 | 7destiny | 2008-03-30 20:51:38 +0000 (Sun, 30 Mar 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
|
||||
LibBabble-Inventory-3.0: TOC 20400
|
||||
------------------------------------------------------------------------
|
||||
r30 | sayclub | 2008-03-10 03:44:25 +0000 (Mon, 10 Mar 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0 :
|
||||
- Update locale koKR
|
||||
------------------------------------------------------------------------
|
||||
r29 | cwdg | 2008-03-06 07:05:05 +0000 (Thu, 06 Mar 2008) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: zhCN update
|
||||
------------------------------------------------------------------------
|
||||
r28 | kunda | 2008-03-05 16:16:57 +0000 (Wed, 05 Mar 2008) | 3 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0:
|
||||
- revert to r63629 because r63632 is not UTF-8 encoded
|
||||
- deDE update
|
||||
------------------------------------------------------------------------
|
||||
r27 | sayclub | 2008-03-05 03:04:43 +0000 (Wed, 05 Mar 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0 :
|
||||
- Update locale koKR
|
||||
------------------------------------------------------------------------
|
||||
r26 | next96 | 2008-03-05 02:08:16 +0000 (Wed, 05 Mar 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0 :
|
||||
- Update locale koKR
|
||||
------------------------------------------------------------------------
|
||||
r25 | next96 | 2008-03-05 02:06:17 +0000 (Wed, 05 Mar 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0 :
|
||||
- Update locale koKR
|
||||
------------------------------------------------------------------------
|
||||
r24 | odlaw | 2008-03-04 18:45:56 +0000 (Tue, 04 Mar 2008) | 8 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: enUS additions
|
||||
- Armor SubTypes: Shields, Librams, Idols, Totems
|
||||
- Container: Leatherworking Bag
|
||||
- Weapon Types: Fishing Poles, Ranged
|
||||
- Consumable: Food & Drink, Potion, Elixir, Bandage, Item Enhancement, Scroll, Other
|
||||
- Trade Goods: Elemental, Metal & Stone, Meat, Herb
|
||||
- Recipe: Jewelcrafting, Fishing
|
||||
- Miscellaneous: Pet, Holiday
|
||||
------------------------------------------------------------------------
|
||||
r23 | ckknight | 2008-02-03 02:14:45 +0000 (Sun, 03 Feb 2008) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
.LibBabble-*-3.0 - upgrade LibBabble-3.0 to r2. Fixes an issue with error messages and upgrade issues
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r22 | funkydude | 2007-11-09 06:45:26 +0000 (Fri, 09 Nov 2007) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/lib.xml
|
||||
|
||||
.trunk: revert back to having LibStub in toc's so we don't load 5 billion copies when we have addons with embeds. Authors, if you use a library that uses LibStub, embed the LibStub tag version with it, not the trunk. Carto/CowTip/FuBar/PitBull have been changed accordingly.
|
||||
------------------------------------------------------------------------
|
||||
r21 | ammo | 2007-11-07 09:45:28 +0000 (Wed, 07 Nov 2007) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/lib.xml
|
||||
|
||||
LibBabble-Inventory-3.0: fix LibStub reference to be in lib.xml not in .toc
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r20 | funkydude | 2007-11-07 00:51:32 +0000 (Wed, 07 Nov 2007) | 1 line
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
A /tmp/trunk/LibBabble-Inventory-3.0/LibStub
|
||||
A /tmp/trunk/LibBabble-Inventory-3.0/LibStub/LibStub.lua
|
||||
|
||||
.trunk: Fix various libraries to use LibStub properly
|
||||
------------------------------------------------------------------------
|
||||
r19 | kemayo | 2007-10-30 22:54:33 +0000 (Tue, 30 Oct 2007) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: "Armor" and "Weapon" types.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r18 | kemayo | 2007-10-30 22:09:46 +0000 (Tue, 30 Oct 2007) | 2 lines
|
||||
Changed paths:
|
||||
M /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
|
||||
LibBabble-Inventory-3.0: Add svn:keywords.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r17 | kemayo | 2007-10-30 22:06:38 +0000 (Tue, 30 Oct 2007) | 2 lines
|
||||
Changed paths:
|
||||
A /tmp/trunk/LibBabble-Inventory-3.0
|
||||
A /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
|
||||
A /tmp/trunk/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
|
||||
A /tmp/trunk/LibBabble-Inventory-3.0/lib.xml
|
||||
|
||||
LibBabble-Inventory-3.0: Drycoded update of Babble-Inventory-2.2. Made it less wishy-washy.
|
||||
|
||||
------------------------------------------------------------------------
|
1697
libs/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
Normal file
1697
libs/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua
Normal file
File diff suppressed because it is too large
Load Diff
11
libs/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
Normal file
11
libs/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc
Normal file
@ -0,0 +1,11 @@
|
||||
## Interface: 30000
|
||||
## Title: Lib: Babble-Inventory-3.0
|
||||
## Notes: A library to help with localization of item types and subtypes.
|
||||
## Notes-esES: Una libreria para ayudar con la traduccion de tipos y subtipos de objetos.
|
||||
## Author: ckknight
|
||||
## X-eMail: ckknight@gmail.com
|
||||
## X-Category: Library
|
||||
## X-License: MIT
|
||||
|
||||
LibStub\LibStub.lua
|
||||
lib.xml
|
30
libs/LibBabble-Inventory-3.0/LibStub/LibStub.lua
Normal file
30
libs/LibBabble-Inventory-3.0/LibStub/LibStub.lua
Normal file
@ -0,0 +1,30 @@
|
||||
-- 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
|
4
libs/LibBabble-Inventory-3.0/lib.xml
Normal file
4
libs/LibBabble-Inventory-3.0/lib.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="LibBabble-Inventory-3.0.lua" />
|
||||
</Ui>
|
30
libs/LibStub/LibStub.lua
Normal file
30
libs/LibStub/LibStub.lua
Normal file
@ -0,0 +1,30 @@
|
||||
-- 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
|
Reference in New Issue
Block a user